Commit 112d21fd authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: switch to rhashtable for vfs inodes hash

the standard vfs inode hash table suffers from painful lock contention -
this is long overdue
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 88d2ae0e
...@@ -361,7 +361,7 @@ int bch2_set_acl(struct mnt_idmap *idmap, ...@@ -361,7 +361,7 @@ int bch2_set_acl(struct mnt_idmap *idmap,
bch2_trans_begin(trans); bch2_trans_begin(trans);
acl = _acl; acl = _acl;
ret = bch2_subvol_is_ro_trans(trans, inode->ei_subvol) ?: ret = bch2_subvol_is_ro_trans(trans, inode->ei_inum.subvol) ?:
bch2_inode_peek(trans, &inode_iter, &inode_u, inode_inum(inode), bch2_inode_peek(trans, &inode_iter, &inode_u, inode_inum(inode),
BTREE_ITER_intent); BTREE_ITER_intent);
if (ret) if (ret)
......
...@@ -1023,6 +1023,7 @@ struct bch_fs { ...@@ -1023,6 +1023,7 @@ struct bch_fs {
/* fs.c */ /* fs.c */
struct list_head vfs_inodes_list; struct list_head vfs_inodes_list;
struct mutex vfs_inodes_lock; struct mutex vfs_inodes_lock;
struct rhashtable vfs_inodes_table;
/* VFS IO PATH - fs-io.c */ /* VFS IO PATH - fs-io.c */
struct bio_set writepage_bioset; struct bio_set writepage_bioset;
......
...@@ -486,7 +486,7 @@ static void bch2_writepage_io_alloc(struct bch_fs *c, ...@@ -486,7 +486,7 @@ static void bch2_writepage_io_alloc(struct bch_fs *c,
op->nr_replicas = nr_replicas; op->nr_replicas = nr_replicas;
op->res.nr_replicas = nr_replicas; op->res.nr_replicas = nr_replicas;
op->write_point = writepoint_hashed(inode->ei_last_dirtied); op->write_point = writepoint_hashed(inode->ei_last_dirtied);
op->subvol = inode->ei_subvol; op->subvol = inode->ei_inum.subvol;
op->pos = POS(inode->v.i_ino, sector); op->pos = POS(inode->v.i_ino, sector);
op->end_io = bch2_writepage_io_done; op->end_io = bch2_writepage_io_done;
op->devs_need_flush = &inode->ei_devs_need_flush; op->devs_need_flush = &inode->ei_devs_need_flush;
......
...@@ -500,7 +500,7 @@ static __always_inline long bch2_dio_write_loop(struct dio_write *dio) ...@@ -500,7 +500,7 @@ static __always_inline long bch2_dio_write_loop(struct dio_write *dio)
dio->op.target = dio->op.opts.foreground_target; dio->op.target = dio->op.opts.foreground_target;
dio->op.write_point = writepoint_hashed((unsigned long) current); dio->op.write_point = writepoint_hashed((unsigned long) current);
dio->op.nr_replicas = dio->op.opts.data_replicas; dio->op.nr_replicas = dio->op.opts.data_replicas;
dio->op.subvol = inode->ei_subvol; dio->op.subvol = inode->ei_inum.subvol;
dio->op.pos = POS(inode->v.i_ino, (u64) req->ki_pos >> 9); dio->op.pos = POS(inode->v.i_ino, (u64) req->ki_pos >> 9);
dio->op.devs_need_flush = &inode->ei_devs_need_flush; dio->op.devs_need_flush = &inode->ei_devs_need_flush;
......
...@@ -267,7 +267,7 @@ static int __bch2_truncate_folio(struct bch_inode_info *inode, ...@@ -267,7 +267,7 @@ static int __bch2_truncate_folio(struct bch_inode_info *inode,
* XXX: we're doing two index lookups when we end up reading the * XXX: we're doing two index lookups when we end up reading the
* folio * folio
*/ */
ret = range_has_data(c, inode->ei_subvol, ret = range_has_data(c, inode->ei_inum.subvol,
POS(inode->v.i_ino, (index << PAGE_SECTORS_SHIFT)), POS(inode->v.i_ino, (index << PAGE_SECTORS_SHIFT)),
POS(inode->v.i_ino, (index << PAGE_SECTORS_SHIFT) + PAGE_SECTORS)); POS(inode->v.i_ino, (index << PAGE_SECTORS_SHIFT) + PAGE_SECTORS));
if (ret <= 0) if (ret <= 0)
...@@ -618,7 +618,7 @@ static noinline int __bchfs_fallocate(struct bch_inode_info *inode, int mode, ...@@ -618,7 +618,7 @@ static noinline int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
bch2_trans_begin(trans); bch2_trans_begin(trans);
ret = bch2_subvolume_get_snapshot(trans, ret = bch2_subvolume_get_snapshot(trans,
inode->ei_subvol, &snapshot); inode->ei_inum.subvol, &snapshot);
if (ret) if (ret)
goto bkey_err; goto bkey_err;
...@@ -823,7 +823,7 @@ static int quota_reserve_range(struct bch_inode_info *inode, ...@@ -823,7 +823,7 @@ static int quota_reserve_range(struct bch_inode_info *inode,
retry: retry:
bch2_trans_begin(trans); bch2_trans_begin(trans);
ret = bch2_subvolume_get_snapshot(trans, inode->ei_subvol, &snapshot); ret = bch2_subvolume_get_snapshot(trans, inode->ei_inum.subvol, &snapshot);
if (ret) if (ret)
goto err; goto err;
......
...@@ -100,7 +100,7 @@ static int bch2_ioc_setflags(struct bch_fs *c, ...@@ -100,7 +100,7 @@ static int bch2_ioc_setflags(struct bch_fs *c,
} }
mutex_lock(&inode->ei_update_lock); mutex_lock(&inode->ei_update_lock);
ret = bch2_subvol_is_ro(c, inode->ei_subvol) ?: ret = bch2_subvol_is_ro(c, inode->ei_inum.subvol) ?:
bch2_write_inode(c, inode, bch2_inode_flags_set, &s, bch2_write_inode(c, inode, bch2_inode_flags_set, &s,
ATTR_CTIME); ATTR_CTIME);
mutex_unlock(&inode->ei_update_lock); mutex_unlock(&inode->ei_update_lock);
...@@ -184,7 +184,7 @@ static int bch2_ioc_fssetxattr(struct bch_fs *c, ...@@ -184,7 +184,7 @@ static int bch2_ioc_fssetxattr(struct bch_fs *c,
} }
mutex_lock(&inode->ei_update_lock); mutex_lock(&inode->ei_update_lock);
ret = bch2_subvol_is_ro(c, inode->ei_subvol) ?: ret = bch2_subvol_is_ro(c, inode->ei_inum.subvol) ?:
bch2_set_projid(c, inode, fa.fsx_projid) ?: bch2_set_projid(c, inode, fa.fsx_projid) ?:
bch2_write_inode(c, inode, fssetxattr_inode_update_fn, &s, bch2_write_inode(c, inode, fssetxattr_inode_update_fn, &s,
ATTR_CTIME); ATTR_CTIME);
......
This diff is collapsed.
...@@ -13,6 +13,9 @@ ...@@ -13,6 +13,9 @@
struct bch_inode_info { struct bch_inode_info {
struct inode v; struct inode v;
struct rhash_head hash;
subvol_inum ei_inum;
struct list_head ei_vfs_inode_list; struct list_head ei_vfs_inode_list;
unsigned long ei_flags; unsigned long ei_flags;
...@@ -24,8 +27,6 @@ struct bch_inode_info { ...@@ -24,8 +27,6 @@ struct bch_inode_info {
struct mutex ei_quota_lock; struct mutex ei_quota_lock;
struct bch_qid ei_qid; struct bch_qid ei_qid;
u32 ei_subvol;
/* /*
* When we've been doing nocow writes we'll need to issue flushes to the * When we've been doing nocow writes we'll need to issue flushes to the
* underlying block devices * underlying block devices
...@@ -50,10 +51,7 @@ struct bch_inode_info { ...@@ -50,10 +51,7 @@ struct bch_inode_info {
static inline subvol_inum inode_inum(struct bch_inode_info *inode) static inline subvol_inum inode_inum(struct bch_inode_info *inode)
{ {
return (subvol_inum) { return inode->ei_inum;
.subvol = inode->ei_subvol,
.inum = inode->ei_inode.bi_inum,
};
} }
struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *, subvol_inum); struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *, subvol_inum);
...@@ -69,6 +67,7 @@ struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *, subvol_inum); ...@@ -69,6 +67,7 @@ struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *, subvol_inum);
* those: * those:
*/ */
#define EI_INODE_SNAPSHOT 1 #define EI_INODE_SNAPSHOT 1
#define EI_INODE_HASHED 2
#define to_bch_ei(_inode) \ #define to_bch_ei(_inode) \
container_of_or_null(_inode, struct bch_inode_info, v) container_of_or_null(_inode, struct bch_inode_info, v)
...@@ -189,6 +188,9 @@ int __bch2_unlink(struct inode *, struct dentry *, bool); ...@@ -189,6 +188,9 @@ int __bch2_unlink(struct inode *, struct dentry *, bool);
void bch2_evict_subvolume_inodes(struct bch_fs *, snapshot_id_list *); void bch2_evict_subvolume_inodes(struct bch_fs *, snapshot_id_list *);
void bch2_fs_vfs_exit(struct bch_fs *);
int bch2_fs_vfs_init(struct bch_fs *);
void bch2_vfs_exit(void); void bch2_vfs_exit(void);
int bch2_vfs_init(void); int bch2_vfs_init(void);
...@@ -203,6 +205,10 @@ static inline struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, su ...@@ -203,6 +205,10 @@ static inline struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, su
static inline void bch2_evict_subvolume_inodes(struct bch_fs *c, static inline void bch2_evict_subvolume_inodes(struct bch_fs *c,
snapshot_id_list *s) {} snapshot_id_list *s) {}
static inline void bch2_fs_vfs_exit(struct bch_fs *c) {}
static inline int bch2_fs_vfs_init(struct bch_fs *c) { return 0; }
static inline void bch2_vfs_exit(void) {} static inline void bch2_vfs_exit(void) {}
static inline int bch2_vfs_init(void) { return 0; } static inline int bch2_vfs_init(void) { return 0; }
......
...@@ -365,7 +365,7 @@ int bch2_inode_peek(struct btree_trans *trans, ...@@ -365,7 +365,7 @@ int bch2_inode_peek(struct btree_trans *trans,
subvol_inum inum, unsigned flags) subvol_inum inum, unsigned flags)
{ {
int ret = bch2_inode_peek_nowarn(trans, iter, inode, inum, flags); int ret = bch2_inode_peek_nowarn(trans, iter, inode, inum, flags);
bch_err_msg(trans->c, ret, "looking up inum %u:%llu:", inum.subvol, inum.inum); bch_err_msg(trans->c, ret, "looking up inum %llu:%llu:", inum.subvol, inum.inum);
return ret; return ret;
} }
......
...@@ -30,7 +30,8 @@ struct snapshot_table { ...@@ -30,7 +30,8 @@ struct snapshot_table {
}; };
typedef struct { typedef struct {
u32 subvol; /* we can't have padding in this struct: */
u64 subvol;
u64 inum; u64 inum;
} subvol_inum; } subvol_inum;
......
...@@ -543,6 +543,7 @@ static void __bch2_fs_free(struct bch_fs *c) ...@@ -543,6 +543,7 @@ static void __bch2_fs_free(struct bch_fs *c)
bch2_fs_fs_io_direct_exit(c); bch2_fs_fs_io_direct_exit(c);
bch2_fs_fs_io_buffered_exit(c); bch2_fs_fs_io_buffered_exit(c);
bch2_fs_fsio_exit(c); bch2_fs_fsio_exit(c);
bch2_fs_vfs_exit(c);
bch2_fs_ec_exit(c); bch2_fs_ec_exit(c);
bch2_fs_encryption_exit(c); bch2_fs_encryption_exit(c);
bch2_fs_nocow_locking_exit(c); bch2_fs_nocow_locking_exit(c);
...@@ -926,6 +927,7 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts) ...@@ -926,6 +927,7 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
bch2_fs_encryption_init(c) ?: bch2_fs_encryption_init(c) ?:
bch2_fs_compress_init(c) ?: bch2_fs_compress_init(c) ?:
bch2_fs_ec_init(c) ?: bch2_fs_ec_init(c) ?:
bch2_fs_vfs_init(c) ?:
bch2_fs_fsio_init(c) ?: bch2_fs_fsio_init(c) ?:
bch2_fs_fs_io_buffered_init(c) ?: bch2_fs_fs_io_buffered_init(c) ?:
bch2_fs_fs_io_direct_init(c); bch2_fs_fs_io_direct_init(c);
......
...@@ -306,7 +306,7 @@ ssize_t bch2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size) ...@@ -306,7 +306,7 @@ ssize_t bch2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
bch2_trans_begin(trans); bch2_trans_begin(trans);
iter = (struct btree_iter) { NULL }; iter = (struct btree_iter) { NULL };
ret = bch2_subvolume_get_snapshot(trans, inode->ei_subvol, &snapshot); ret = bch2_subvolume_get_snapshot(trans, inode->ei_inum.subvol, &snapshot);
if (ret) if (ret)
goto err; goto err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment