Commit 168f4c5f authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Improve bch2_lock_inodes()

Can now be used for the two different types of locks we have so far
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent e812cf38
...@@ -205,7 +205,7 @@ static int bch2_ioc_reinherit_attrs(struct bch_fs *c, ...@@ -205,7 +205,7 @@ static int bch2_ioc_reinherit_attrs(struct bch_fs *c,
if (ret) if (ret)
goto err2; goto err2;
bch2_lock_inodes(src, dst); bch2_lock_inodes(INODE_UPDATE_LOCK, src, dst);
if (inode_attr_changing(src, dst, Inode_opt_project)) { if (inode_attr_changing(src, dst, Inode_opt_project)) {
ret = bch2_fs_quota_transfer(c, dst, ret = bch2_fs_quota_transfer(c, dst,
...@@ -218,7 +218,7 @@ static int bch2_ioc_reinherit_attrs(struct bch_fs *c, ...@@ -218,7 +218,7 @@ static int bch2_ioc_reinherit_attrs(struct bch_fs *c,
ret = bch2_write_inode(c, dst, bch2_reinherit_attrs_fn, src, 0); ret = bch2_write_inode(c, dst, bch2_reinherit_attrs_fn, src, 0);
err3: err3:
bch2_unlock_inodes(src, dst); bch2_unlock_inodes(INODE_UPDATE_LOCK, src, dst);
/* return true if we did work */ /* return true if we did work */
if (ret >= 0) if (ret >= 0)
......
...@@ -657,7 +657,7 @@ static int bch2_unlink(struct inode *vdir, struct dentry *dentry) ...@@ -657,7 +657,7 @@ static int bch2_unlink(struct inode *vdir, struct dentry *dentry)
struct btree_trans trans; struct btree_trans trans;
int ret; int ret;
bch2_lock_inodes(dir, inode); bch2_lock_inodes(INODE_UPDATE_LOCK, dir, inode);
bch2_trans_init(&trans, c, 4, 1024); bch2_trans_init(&trans, c, 4, 1024);
retry: retry:
bch2_trans_begin(&trans); bch2_trans_begin(&trans);
...@@ -690,7 +690,7 @@ static int bch2_unlink(struct inode *vdir, struct dentry *dentry) ...@@ -690,7 +690,7 @@ static int bch2_unlink(struct inode *vdir, struct dentry *dentry)
ATTR_MTIME); ATTR_MTIME);
err: err:
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
bch2_unlock_inodes(dir, inode); bch2_unlock_inodes(INODE_UPDATE_LOCK, dir, inode);
return ret; return ret;
} }
...@@ -871,7 +871,8 @@ static int bch2_rename2(struct mnt_idmap *idmap, ...@@ -871,7 +871,8 @@ static int bch2_rename2(struct mnt_idmap *idmap,
bch2_trans_init(&trans, c, 8, 2048); bch2_trans_init(&trans, c, 8, 2048);
bch2_lock_inodes(i.src_dir, bch2_lock_inodes(INODE_UPDATE_LOCK,
i.src_dir,
i.dst_dir, i.dst_dir,
i.src_inode, i.src_inode,
i.dst_inode); i.dst_inode);
...@@ -969,7 +970,8 @@ static int bch2_rename2(struct mnt_idmap *idmap, ...@@ -969,7 +970,8 @@ static int bch2_rename2(struct mnt_idmap *idmap,
1 << QTYP_PRJ, 1 << QTYP_PRJ,
KEY_TYPE_QUOTA_NOCHECK); KEY_TYPE_QUOTA_NOCHECK);
bch2_unlock_inodes(i.src_dir, bch2_unlock_inodes(INODE_UPDATE_LOCK,
i.src_dir,
i.dst_dir, i.dst_dir,
i.src_inode, i.src_inode,
i.dst_inode); i.dst_inode);
......
...@@ -57,24 +57,42 @@ static inline int ptrcmp(void *l, void *r) ...@@ -57,24 +57,42 @@ static inline int ptrcmp(void *l, void *r)
return cmp_int(l, r); return cmp_int(l, r);
} }
#define __bch2_lock_inodes(_lock, ...) \ enum bch_inode_lock_op {
INODE_LOCK = (1U << 0),
INODE_UPDATE_LOCK = (1U << 1),
};
#define bch2_lock_inodes(_locks, ...) \
do { \ do { \
struct bch_inode_info *a[] = { NULL, __VA_ARGS__ }; \ struct bch_inode_info *a[] = { NULL, __VA_ARGS__ }; \
unsigned i; \ unsigned i; \
\ \
bubble_sort(&a[1], ARRAY_SIZE(a) - 1 , ptrcmp); \ bubble_sort(&a[1], ARRAY_SIZE(a) - 1, ptrcmp); \
\ \
for (i = ARRAY_SIZE(a) - 1; a[i]; --i) \ for (i = 1; i < ARRAY_SIZE(a); i++) \
if (a[i] != a[i - 1]) { \ if (a[i] != a[i - 1]) { \
if (_lock) \ if (_locks & INODE_LOCK) \
down_write_nested(&a[i]->v.i_rwsem, i); \
if (_locks & INODE_UPDATE_LOCK) \
mutex_lock_nested(&a[i]->ei_update_lock, i);\ mutex_lock_nested(&a[i]->ei_update_lock, i);\
else \
mutex_unlock(&a[i]->ei_update_lock); \
} \ } \
} while (0) } while (0)
#define bch2_lock_inodes(...) __bch2_lock_inodes(true, __VA_ARGS__) #define bch2_unlock_inodes(_locks, ...) \
#define bch2_unlock_inodes(...) __bch2_lock_inodes(false, __VA_ARGS__) do { \
struct bch_inode_info *a[] = { NULL, __VA_ARGS__ }; \
unsigned i; \
\
bubble_sort(&a[1], ARRAY_SIZE(a) - 1, ptrcmp); \
\
for (i = 1; i < ARRAY_SIZE(a); i++) \
if (a[i] != a[i - 1]) { \
if (_locks & INODE_LOCK) \
up_write(&a[i]->v.i_rwsem); \
if (_locks & INODE_UPDATE_LOCK) \
mutex_unlock(&a[i]->ei_update_lock); \
} \
} while (0)
static inline struct bch_inode_info *file_bch_inode(struct file *file) static inline struct bch_inode_info *file_bch_inode(struct file *file)
{ {
......
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