diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/ctree.h | 2 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 84 | ||||
-rw-r--r-- | fs/btrfs/super.c | 6 |
3 files changed, 51 insertions, 41 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 9a72896bed2e..23d507971837 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2930,6 +2930,8 @@ void btrfs_inode_safe_disk_i_size_write(struct inode *inode, u64 new_i_size); u64 btrfs_file_extent_end(const struct btrfs_path *path); /* inode.c */ +extern const struct rhashtable_params btrfs_inode_table_params; + struct extent_map *btrfs_get_extent_fiemap(struct btrfs_inode *inode, u64 start, u64 len); noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9570458aa847..223a5430407d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -9,6 +9,7 @@ #include <linux/buffer_head.h> #include <linux/file.h> #include <linux/fs.h> +#include <linux/jhash.h> #include <linux/pagemap.h> #include <linux/highmem.h> #include <linux/time.h> @@ -57,6 +58,43 @@ struct btrfs_iget_args { struct btrfs_root *root; }; +static u32 btrfs_inode_key_hash_fn(const void *data, u32 len, u32 seed) +{ + const struct btrfs_iget_args *args = data; + + return jhash(args, sizeof(*args), seed); +} + +static u32 btrfs_inode_obj_hash_fn(const void *obj, u32 len, u32 seed) +{ + const struct inode *inode = obj; + const struct btrfs_iget_args args = { + BTRFS_I(inode)->location.objectid, + BTRFS_I(inode)->root, + }; + + return jhash(&args, sizeof(args), seed); +} + +static int btrfs_inode_hash_cmp_fn(struct rhashtable_compare_arg *arg, + const void *obj) +{ + const struct inode *inode = obj; + const struct btrfs_iget_args *args = arg->key; + + if (args->ino == BTRFS_I(inode)->location.objectid && + args->root == BTRFS_I(inode)->root) + return 0; + return 1; +} + +const struct rhashtable_params btrfs_inode_table_params = { + .head_offset = offsetof(struct inode, i_hash), + .hashfn = btrfs_inode_key_hash_fn, + .obj_hashfn = btrfs_inode_obj_hash_fn, + .obj_cmpfn = btrfs_inode_hash_cmp_fn, +}; + struct btrfs_dio_data { u64 reserve; u64 unsubmitted_oe_range_start; @@ -5327,10 +5365,9 @@ static void inode_tree_del(struct inode *inode) } } - -static int btrfs_init_locked_inode(struct inode *inode, void *p) +static int btrfs_init_locked_inode(struct inode *inode, const void *p) { - struct btrfs_iget_args *args = p; + const struct btrfs_iget_args *args = p; inode->i_ino = args->ino; BTRFS_I(inode)->location.objectid = args->ino; @@ -5341,30 +5378,6 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p) return 0; } -static int btrfs_find_actor(struct inode *inode, void *opaque) -{ - struct btrfs_iget_args *args = opaque; - - return args->ino == BTRFS_I(inode)->location.objectid && - args->root == BTRFS_I(inode)->root; -} - -static struct inode *btrfs_iget_locked(struct super_block *s, u64 ino, - struct btrfs_root *root) -{ - struct inode *inode; - struct btrfs_iget_args args; - unsigned long hashval = btrfs_inode_hash(ino, root); - - args.ino = ino; - args.root = root; - - inode = iget5_locked(s, hashval, btrfs_find_actor, - btrfs_init_locked_inode, - (void *)&args); - return inode; -} - /* * Get an inode object given its inode number and corresponding root. * Path can be preallocated to prevent recursing back to iget through @@ -5375,8 +5388,9 @@ struct inode *btrfs_iget_path(struct super_block *s, u64 ino, struct btrfs_root *root, struct btrfs_path *path) { struct inode *inode; + struct btrfs_iget_args args = { ino, root }; - inode = btrfs_iget_locked(s, ino, root); + inode = iget5_locked(s, btrfs_init_locked_inode, &args); if (!inode) return ERR_PTR(-ENOMEM); @@ -5876,18 +5890,6 @@ int btrfs_set_inode_index(struct btrfs_inode *dir, u64 *index) return ret; } -static int btrfs_insert_inode_locked(struct inode *inode) -{ - struct btrfs_iget_args args; - - args.ino = BTRFS_I(inode)->location.objectid; - args.root = BTRFS_I(inode)->root; - - return insert_inode_locked4(inode, - btrfs_inode_hash(inode->i_ino, BTRFS_I(inode)->root), - btrfs_find_actor, &args); -} - /* * Inherit flags from the parent inode. * @@ -6020,7 +6022,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, location->offset = 0; location->type = BTRFS_INODE_ITEM_KEY; - ret = btrfs_insert_inode_locked(inode); + ret = insert_inode_locked(inode); if (ret < 0) { iput(inode); goto fail; diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 25967ecaaf0a..3898e5bee791 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1307,6 +1307,12 @@ static int btrfs_fill_super(struct super_block *sb, sb->s_flags |= SB_I_VERSION; sb->s_iflags |= SB_I_CGROUPWB; + err = super_setup_inode_table(sb, &btrfs_inode_table_params); + if (err) { + btrfs_err(fs_info, "super_setup_inode_table failed"); + return err; + } + err = super_setup_bdi(sb); if (err) { btrfs_err(fs_info, "super_setup_bdi failed"); |