diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2020-11-05 11:57:58 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2020-12-07 11:50:46 -0500 |
commit | d983a32e7902da73c52e80b5dda4bc14d16415ae (patch) | |
tree | 4159d4364b90f14c8f4a1cf809acf25535a0a80e /fs/fuse | |
parent | 492f2208a8a1788569f67142cab50cc9e13be5ee (diff) |
switch inodes to rhashtableinode_work
Diffstat (limited to 'fs/fuse')
-rw-r--r-- | fs/fuse/dev.c | 4 | ||||
-rw-r--r-- | fs/fuse/dir.c | 2 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 5 | ||||
-rw-r--r-- | fs/fuse/inode.c | 55 |
4 files changed, 45 insertions, 21 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 02b3c36b3676..8b70e673e31b 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1564,7 +1564,7 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size, if (!fc->sb) goto out_up_killsb; - inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); + inode = ilookup5(fc->sb, &nodeid); if (!inode) goto out_up_killsb; @@ -1732,7 +1732,7 @@ static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size, if (fc->sb) { u64 nodeid = outarg.nodeid; - inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); + inode = ilookup5(fc->sb, &nodeid); if (inode) { err = fuse_retrieve(fc, inode, &outarg); iput(inode); diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 26f028bc760b..8338f3cf6ef1 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1010,7 +1010,7 @@ int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid, struct dentry *dir; struct dentry *entry; - parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid); + parent = ilookup5(sb, &parent_nodeid); if (!parent) return -ENOENT; diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 740a8a7d7ae6..db95e2dbba38 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -794,11 +794,6 @@ extern const struct dentry_operations fuse_dentry_operations; extern const struct dentry_operations fuse_root_dentry_operations; /** - * Inode to nodeid comparison. - */ -int fuse_inode_eq(struct inode *inode, void *_nodeidp); - -/** * Get a filled in inode */ struct inode *fuse_iget(struct super_block *sb, u64 nodeid, diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index bba747520e9b..cc18b77fbd9d 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -23,6 +23,7 @@ #include <linux/exportfs.h> #include <linux/posix_acl.h> #include <linux/pid_namespace.h> +#include <linux/jhash.h> MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); MODULE_DESCRIPTION("Filesystem in Userspace"); @@ -64,6 +65,40 @@ MODULE_PARM_DESC(max_user_congthresh, static struct file_system_type fuseblk_fs_type; #endif +static u32 fuse_inode_key_hash_fn(const void *data, u32 len, u32 seed) +{ + const u64 *nodeid = data; + + return jhash(nodeid, sizeof(*nodeid), seed); +} + +static u32 fuse_inode_obj_hash_fn(const void *obj, u32 len, u32 seed) +{ + const struct fuse_inode *fuse_inode = + container_of(obj, struct fuse_inode, inode); + + return jhash(&fuse_inode->nodeid, sizeof(fuse_inode->nodeid), seed); +} + +static int fuse_inode_hash_cmp_fn(struct rhashtable_compare_arg *arg, + const void *obj) +{ + const struct fuse_inode *fuse_inode = + container_of(obj, struct fuse_inode, inode); + const u64 *nodeid = arg->key; + + if (fuse_inode->nodeid == *nodeid) + return 0; + return 1; +} + +static const struct rhashtable_params fuse_inode_table_params = { + .head_offset = offsetof(struct inode, i_hash), + .hashfn = fuse_inode_key_hash_fn, + .obj_hashfn = fuse_inode_obj_hash_fn, + .obj_cmpfn = fuse_inode_hash_cmp_fn, +}; + struct fuse_forget_link *fuse_alloc_forget(void) { return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL_ACCOUNT); @@ -268,16 +303,7 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr) BUG(); } -int fuse_inode_eq(struct inode *inode, void *_nodeidp) -{ - u64 nodeid = *(u64 *) _nodeidp; - if (get_node_id(inode) == nodeid) - return 1; - else - return 0; -} - -static int fuse_inode_set(struct inode *inode, void *_nodeidp) +static int fuse_inode_set(struct inode *inode, const void *_nodeidp) { u64 nodeid = *(u64 *) _nodeidp; get_fuse_inode(inode)->nodeid = nodeid; @@ -293,7 +319,7 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid, struct fuse_conn *fc = get_fuse_conn_super(sb); retry: - inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid); + inode = iget5_locked(sb, fuse_inode_set, &nodeid); if (!inode) return NULL; @@ -329,7 +355,7 @@ int fuse_reverse_inval_inode(struct super_block *sb, u64 nodeid, pgoff_t pg_start; pgoff_t pg_end; - inode = ilookup5(sb, nodeid, fuse_inode_eq, &nodeid); + inode = ilookup5(sb, &nodeid); if (!inode) return -ENOENT; @@ -693,7 +719,7 @@ static struct dentry *fuse_get_dentry(struct super_block *sb, if (handle->nodeid == 0) goto out_err; - inode = ilookup5(sb, handle->nodeid, fuse_inode_eq, &handle->nodeid); + inode = ilookup5(sb, &handle->nodeid); if (!inode) { struct fuse_entry_out outarg; const struct qstr name = QSTR_INIT(".", 1); @@ -1183,6 +1209,9 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx) fc->dev = sb->s_dev; fc->sb = sb; + err = super_setup_inode_table(sb, &fuse_inode_table_params); + if (err) + goto err_dev_free; err = fuse_bdi_init(fc, sb); if (err) goto err_dev_free; |