summaryrefslogtreecommitdiff
path: root/fs/ecryptfs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-11-05 11:57:58 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2020-12-07 11:50:46 -0500
commitd983a32e7902da73c52e80b5dda4bc14d16415ae (patch)
tree4159d4364b90f14c8f4a1cf809acf25535a0a80e /fs/ecryptfs
parent492f2208a8a1788569f67142cab50cc9e13be5ee (diff)
switch inodes to rhashtableinode_work
Diffstat (limited to 'fs/ecryptfs')
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h1
-rw-r--r--fs/ecryptfs/inode.c47
-rw-r--r--fs/ecryptfs/main.c4
3 files changed, 42 insertions, 10 deletions
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index e6ac78c62ca4..8666d4e5a18e 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -544,6 +544,7 @@ extern int ecryptfs_verbosity;
extern unsigned int ecryptfs_message_buf_len;
extern signed long ecryptfs_message_wait_timeout;
extern unsigned int ecryptfs_number_of_users;
+extern const struct rhashtable_params ecryptfs_inode_table_params;
extern struct kmem_cache *ecryptfs_auth_tok_list_item_cache;
extern struct kmem_cache *ecryptfs_file_info_cache;
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index e23752d9a79f..a0d2027e90b4 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -10,6 +10,7 @@
*/
#include <linux/file.h>
+#include <linux/jhash.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/dcache.h>
@@ -21,6 +22,39 @@
#include <asm/unaligned.h>
#include "ecryptfs_kernel.h"
+static u32 ecryptfs_inode_key_hash_fn(const void *data, u32 len, u32 seed)
+{
+ const struct inode *lower_inode = data;
+
+ return jhash(&lower_inode, sizeof(lower_inode), seed);
+}
+
+static u32 ecryptfs_inode_obj_hash_fn(const void *obj, u32 len, u32 seed)
+{
+ const struct inode *inode = obj;
+ const struct inode *lower_inode = ecryptfs_inode_to_lower((struct inode *) inode);
+
+ return jhash(&lower_inode, sizeof(lower_inode), seed);
+}
+
+static int ecryptfs_inode_hash_cmp_fn(struct rhashtable_compare_arg *arg,
+ const void *obj)
+{
+ const struct inode *inode = obj;
+ const struct inode *lower_inode = arg->key;
+
+ if (ecryptfs_inode_to_lower((struct inode *) inode) == lower_inode)
+ return 0;
+ return 1;
+}
+
+const struct rhashtable_params ecryptfs_inode_table_params = {
+ .head_offset = offsetof(struct inode, i_hash),
+ .hashfn = ecryptfs_inode_key_hash_fn,
+ .obj_hashfn = ecryptfs_inode_obj_hash_fn,
+ .obj_cmpfn = ecryptfs_inode_hash_cmp_fn,
+};
+
static struct dentry *lock_parent(struct dentry *dentry)
{
struct dentry *dir;
@@ -36,14 +70,9 @@ static void unlock_dir(struct dentry *dir)
dput(dir);
}
-static int ecryptfs_inode_test(struct inode *inode, void *lower_inode)
-{
- return ecryptfs_inode_to_lower(inode) == lower_inode;
-}
-
-static int ecryptfs_inode_set(struct inode *inode, void *opaque)
+static int ecryptfs_inode_set(struct inode *inode, const void *opaque)
{
- struct inode *lower_inode = opaque;
+ struct inode *lower_inode = (void *) opaque;
ecryptfs_set_inode_lower(inode, lower_inode);
fsstack_copy_attr_all(inode, lower_inode);
@@ -78,9 +107,7 @@ static struct inode *__ecryptfs_get_inode(struct inode *lower_inode,
return ERR_PTR(-EXDEV);
if (!igrab(lower_inode))
return ERR_PTR(-ESTALE);
- inode = iget5_locked(sb, (unsigned long)lower_inode,
- ecryptfs_inode_test, ecryptfs_inode_set,
- lower_inode);
+ inode = iget5_locked(sb, ecryptfs_inode_set, lower_inode);
if (!inode) {
iput(lower_inode);
return ERR_PTR(-EACCES);
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index e63259fdef28..6e9b528b85dd 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -505,6 +505,10 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
goto out;
}
+ rc = super_setup_inode_table(s, &ecryptfs_inode_table_params);
+ if (rc)
+ goto out1;
+
rc = super_setup_bdi(s);
if (rc)
goto out1;