mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-09 14:50:19 +00:00
bcachefs: Improve bch2_lock_inodes()
Can now be used for the two different types of locks we have so far Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
e812cf38c5
commit
168f4c5fb3
@ -205,7 +205,7 @@ static int bch2_ioc_reinherit_attrs(struct bch_fs *c,
|
||||
if (ret)
|
||||
goto err2;
|
||||
|
||||
bch2_lock_inodes(src, dst);
|
||||
bch2_lock_inodes(INODE_UPDATE_LOCK, src, dst);
|
||||
|
||||
if (inode_attr_changing(src, dst, Inode_opt_project)) {
|
||||
ret = bch2_fs_quota_transfer(c, dst,
|
||||
@ -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);
|
||||
err3:
|
||||
bch2_unlock_inodes(src, dst);
|
||||
bch2_unlock_inodes(INODE_UPDATE_LOCK, src, dst);
|
||||
|
||||
/* return true if we did work */
|
||||
if (ret >= 0)
|
||||
|
@ -657,7 +657,7 @@ static int bch2_unlink(struct inode *vdir, struct dentry *dentry)
|
||||
struct btree_trans trans;
|
||||
int ret;
|
||||
|
||||
bch2_lock_inodes(dir, inode);
|
||||
bch2_lock_inodes(INODE_UPDATE_LOCK, dir, inode);
|
||||
bch2_trans_init(&trans, c, 4, 1024);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
@ -690,7 +690,7 @@ retry:
|
||||
ATTR_MTIME);
|
||||
err:
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_unlock_inodes(dir, inode);
|
||||
bch2_unlock_inodes(INODE_UPDATE_LOCK, dir, inode);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -871,7 +871,8 @@ static int bch2_rename2(struct mnt_idmap *idmap,
|
||||
|
||||
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.src_inode,
|
||||
i.dst_inode);
|
||||
@ -969,7 +970,8 @@ err:
|
||||
1 << QTYP_PRJ,
|
||||
KEY_TYPE_QUOTA_NOCHECK);
|
||||
|
||||
bch2_unlock_inodes(i.src_dir,
|
||||
bch2_unlock_inodes(INODE_UPDATE_LOCK,
|
||||
i.src_dir,
|
||||
i.dst_dir,
|
||||
i.src_inode,
|
||||
i.dst_inode);
|
||||
|
@ -57,24 +57,42 @@ static inline int ptrcmp(void *l, void *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 { \
|
||||
struct bch_inode_info *a[] = { NULL, __VA_ARGS__ }; \
|
||||
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 (_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);\
|
||||
else \
|
||||
mutex_unlock(&a[i]->ei_update_lock); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define bch2_lock_inodes(...) __bch2_lock_inodes(true, __VA_ARGS__)
|
||||
#define bch2_unlock_inodes(...) __bch2_lock_inodes(false, __VA_ARGS__)
|
||||
#define bch2_unlock_inodes(_locks, ...) \
|
||||
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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user