Commit 19ee5f2a authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Use ei_update_lock consistently

This is prep work for using deferred btree updates for inode updates -
the way inodes are done now we're relying on btree locking for ei_inode
and ei_update_lock could probably be removed, but it'll actually be
needed when we switch to deferred updates.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent fc88796d
...@@ -304,13 +304,14 @@ int bch2_set_acl(struct mnt_idmap *idmap, ...@@ -304,13 +304,14 @@ int bch2_set_acl(struct mnt_idmap *idmap,
umode_t mode = inode->v.i_mode; umode_t mode = inode->v.i_mode;
int ret; int ret;
mutex_lock(&inode->ei_update_lock);
bch2_trans_init(&trans, c);
if (type == ACL_TYPE_ACCESS && acl) { if (type == ACL_TYPE_ACCESS && acl) {
ret = posix_acl_update_mode(idmap, &inode->v, &mode, &acl); ret = posix_acl_update_mode(idmap, &inode->v, &mode, &acl);
if (ret) if (ret)
return ret; goto err;
} }
bch2_trans_init(&trans, c);
retry: retry:
bch2_trans_begin(&trans); bch2_trans_begin(&trans);
...@@ -336,6 +337,7 @@ int bch2_set_acl(struct mnt_idmap *idmap, ...@@ -336,6 +337,7 @@ int bch2_set_acl(struct mnt_idmap *idmap,
set_cached_acl(&inode->v, type, acl); set_cached_acl(&inode->v, type, acl);
err: err:
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
mutex_unlock(&inode->ei_update_lock);
return ret; return ret;
} }
......
...@@ -51,6 +51,30 @@ static void journal_seq_copy(struct bch_inode_info *dst, ...@@ -51,6 +51,30 @@ static void journal_seq_copy(struct bch_inode_info *dst,
} while ((v = cmpxchg(&dst->ei_journal_seq, old, journal_seq)) != old); } while ((v = cmpxchg(&dst->ei_journal_seq, old, journal_seq)) != old);
} }
static inline int ptrcmp(void *l, void *r)
{
return (l > r) - (l < r);
}
#define __bch2_lock_inodes(_lock, ...) \
do { \
struct bch_inode_info *a[] = { NULL, __VA_ARGS__ }; \
unsigned i; \
\
bubble_sort(&a[1], ARRAY_SIZE(a) - 1 , ptrcmp); \
\
for (i = ARRAY_SIZE(a) - 1; a[i]; --i) \
if (a[i] != a[i - 1]) { \
if (_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__)
static void __pagecache_lock_put(struct pagecache_lock *lock, long i) static void __pagecache_lock_put(struct pagecache_lock *lock, long i)
{ {
BUG_ON(atomic_long_read(&lock->v) == 0); BUG_ON(atomic_long_read(&lock->v) == 0);
...@@ -161,6 +185,8 @@ int __must_check bch2_write_inode_trans(struct btree_trans *trans, ...@@ -161,6 +185,8 @@ int __must_check bch2_write_inode_trans(struct btree_trans *trans,
struct bkey_inode_buf *inode_p; struct bkey_inode_buf *inode_p;
int ret; int ret;
lockdep_assert_held(&inode->ei_update_lock);
iter = bch2_trans_get_iter(trans, BTREE_ID_INODES, iter = bch2_trans_get_iter(trans, BTREE_ID_INODES,
POS(inode->v.i_ino, 0), POS(inode->v.i_ino, 0),
BTREE_ITER_SLOTS|BTREE_ITER_INTENT); BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
...@@ -422,6 +448,9 @@ __bch2_create(struct mnt_idmap *idmap, ...@@ -422,6 +448,9 @@ __bch2_create(struct mnt_idmap *idmap,
posix_acl_release(acl); posix_acl_release(acl);
return inode; return inode;
err_trans: err_trans:
if (!tmpfile)
mutex_unlock(&dir->ei_update_lock);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
make_bad_inode(&inode->v); make_bad_inode(&inode->v);
iput(&inode->v); iput(&inode->v);
...@@ -490,6 +519,7 @@ static int __bch2_link(struct bch_fs *c, ...@@ -490,6 +519,7 @@ static int __bch2_link(struct bch_fs *c,
struct bch_inode_unpacked inode_u; struct bch_inode_unpacked inode_u;
int ret; int ret;
mutex_lock(&inode->ei_update_lock);
bch2_trans_init(&trans, c); bch2_trans_init(&trans, c);
retry: retry:
bch2_trans_begin(&trans); bch2_trans_begin(&trans);
...@@ -515,6 +545,7 @@ static int __bch2_link(struct bch_fs *c, ...@@ -515,6 +545,7 @@ static int __bch2_link(struct bch_fs *c,
bch2_inode_update_after_write(c, inode, &inode_u, ATTR_CTIME); bch2_inode_update_after_write(c, inode, &inode_u, ATTR_CTIME);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
mutex_unlock(&inode->ei_update_lock);
return ret; return ret;
} }
...@@ -575,6 +606,7 @@ static int bch2_unlink(struct inode *vdir, struct dentry *dentry) ...@@ -575,6 +606,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_trans_init(&trans, c); bch2_trans_init(&trans, c);
retry: retry:
bch2_trans_begin(&trans); bch2_trans_begin(&trans);
...@@ -607,6 +639,7 @@ static int bch2_unlink(struct inode *vdir, struct dentry *dentry) ...@@ -607,6 +639,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);
return ret; return ret;
} }
...@@ -771,6 +804,11 @@ static int bch2_rename2(struct mnt_idmap *idmap, ...@@ -771,6 +804,11 @@ static int bch2_rename2(struct mnt_idmap *idmap,
return ret; return ret;
} }
bch2_lock_inodes(i.src_dir,
i.dst_dir,
i.src_inode,
i.dst_inode);
bch2_trans_init(&trans, c); bch2_trans_init(&trans, c);
retry: retry:
bch2_trans_begin(&trans); bch2_trans_begin(&trans);
...@@ -818,6 +856,10 @@ static int bch2_rename2(struct mnt_idmap *idmap, ...@@ -818,6 +856,10 @@ static int bch2_rename2(struct mnt_idmap *idmap,
ATTR_CTIME); ATTR_CTIME);
err: err:
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
bch2_unlock_inodes(i.src_dir,
i.dst_dir,
i.src_inode,
i.dst_inode);
return ret; return ret;
} }
......
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