mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-01 22:54:01 +00:00
bcachefs: Can't be holding read locks while taking write locks
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
0741d37821
commit
63fbf458cb
6 changed files with 33 additions and 25 deletions
|
@ -451,6 +451,7 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
|
|||
struct bch_fs *c = trans->c;
|
||||
struct bch_fs_usage_online *fs_usage = NULL;
|
||||
struct btree_insert_entry *i;
|
||||
struct btree_iter *iter;
|
||||
unsigned mark_flags = trans->flags & BTREE_INSERT_BUCKET_INVALIDATE
|
||||
? BCH_BUCKET_MARK_BUCKET_INVALIDATE
|
||||
: 0;
|
||||
|
@ -473,6 +474,14 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
|
|||
goto out_clear_replicas;
|
||||
}
|
||||
|
||||
trans_for_each_iter(trans, iter) {
|
||||
if (iter->nodes_locked != iter->nodes_intent_locked) {
|
||||
BUG_ON(iter->flags & BTREE_ITER_KEEP_UNTIL_COMMIT);
|
||||
BUG_ON(trans->iters_live & (1ULL << iter->idx));
|
||||
__bch2_btree_iter_unlock(iter);
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BCACHEFS_DEBUG))
|
||||
trans_for_each_update(trans, i)
|
||||
btree_insert_entry_checks(trans, i);
|
||||
|
|
|
@ -296,10 +296,10 @@ int bch2_dirent_delete(struct bch_fs *c, u64 dir_inum,
|
|||
struct btree_iter *
|
||||
__bch2_dirent_lookup_trans(struct btree_trans *trans, u64 dir_inum,
|
||||
const struct bch_hash_info *hash_info,
|
||||
const struct qstr *name)
|
||||
const struct qstr *name, unsigned flags)
|
||||
{
|
||||
return bch2_hash_lookup(trans, bch2_dirent_hash_desc,
|
||||
hash_info, dir_inum, name, 0);
|
||||
hash_info, dir_inum, name, flags);
|
||||
}
|
||||
|
||||
u64 bch2_dirent_lookup(struct bch_fs *c, u64 dir_inum,
|
||||
|
@ -313,7 +313,8 @@ u64 bch2_dirent_lookup(struct bch_fs *c, u64 dir_inum,
|
|||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
iter = __bch2_dirent_lookup_trans(&trans, dir_inum, hash_info, name);
|
||||
iter = __bch2_dirent_lookup_trans(&trans, dir_inum,
|
||||
hash_info, name, 0);
|
||||
if (IS_ERR(iter)) {
|
||||
BUG_ON(PTR_ERR(iter) == -EINTR);
|
||||
goto out;
|
||||
|
|
|
@ -55,7 +55,7 @@ int bch2_dirent_rename(struct btree_trans *,
|
|||
struct btree_iter *
|
||||
__bch2_dirent_lookup_trans(struct btree_trans *, u64,
|
||||
const struct bch_hash_info *,
|
||||
const struct qstr *);
|
||||
const struct qstr *, unsigned);
|
||||
u64 bch2_dirent_lookup(struct bch_fs *, u64, const struct bch_hash_info *,
|
||||
const struct qstr *);
|
||||
|
||||
|
|
|
@ -24,8 +24,7 @@ int bch2_create_trans(struct btree_trans *trans, u64 dir_inum,
|
|||
u64 now = bch2_current_time(trans->c);
|
||||
int ret;
|
||||
|
||||
dir_iter = bch2_inode_peek(trans, dir_u, dir_inum,
|
||||
name ? BTREE_ITER_INTENT : 0);
|
||||
dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, BTREE_ITER_INTENT);
|
||||
if (IS_ERR(dir_iter))
|
||||
return PTR_ERR(dir_iter);
|
||||
|
||||
|
@ -76,8 +75,7 @@ int bch2_create_trans(struct btree_trans *trans, u64 dir_inum,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int bch2_link_trans(struct btree_trans *trans,
|
||||
u64 dir_inum,
|
||||
int bch2_link_trans(struct btree_trans *trans, u64 dir_inum,
|
||||
u64 inum, struct bch_inode_unpacked *inode_u,
|
||||
const struct qstr *name)
|
||||
{
|
||||
|
@ -86,19 +84,22 @@ int bch2_link_trans(struct btree_trans *trans,
|
|||
struct bch_hash_info dir_hash;
|
||||
u64 now = bch2_current_time(trans->c);
|
||||
|
||||
dir_iter = bch2_inode_peek(trans, &dir_u, dir_inum, 0);
|
||||
if (IS_ERR(dir_iter))
|
||||
return PTR_ERR(dir_iter);
|
||||
|
||||
inode_iter = bch2_inode_peek(trans, inode_u, inum, BTREE_ITER_INTENT);
|
||||
if (IS_ERR(inode_iter))
|
||||
return PTR_ERR(inode_iter);
|
||||
|
||||
dir_hash = bch2_hash_info_init(trans->c, &dir_u);
|
||||
|
||||
inode_u->bi_ctime = now;
|
||||
bch2_inode_nlink_inc(inode_u);
|
||||
|
||||
dir_iter = bch2_inode_peek(trans, &dir_u, dir_inum, 0);
|
||||
if (IS_ERR(dir_iter))
|
||||
return PTR_ERR(dir_iter);
|
||||
|
||||
/* XXX: shouldn't we be updating mtime/ctime on the directory? */
|
||||
|
||||
dir_hash = bch2_hash_info_init(trans->c, &dir_u);
|
||||
bch2_trans_iter_put(trans, dir_iter);
|
||||
|
||||
return bch2_dirent_create(trans, dir_inum, &dir_hash,
|
||||
mode_to_type(inode_u->bi_mode),
|
||||
name, inum, BCH_HASH_SET_MUST_CREATE) ?:
|
||||
|
@ -121,8 +122,8 @@ int bch2_unlink_trans(struct btree_trans *trans,
|
|||
|
||||
dir_hash = bch2_hash_info_init(trans->c, dir_u);
|
||||
|
||||
dirent_iter = __bch2_dirent_lookup_trans(trans, dir_inum,
|
||||
&dir_hash, name);
|
||||
dirent_iter = __bch2_dirent_lookup_trans(trans, dir_inum, &dir_hash,
|
||||
name, BTREE_ITER_INTENT);
|
||||
if (IS_ERR(dirent_iter))
|
||||
return PTR_ERR(dirent_iter);
|
||||
|
||||
|
|
|
@ -12,8 +12,7 @@ int bch2_create_trans(struct btree_trans *, u64,
|
|||
struct posix_acl *,
|
||||
struct posix_acl *);
|
||||
|
||||
int bch2_link_trans(struct btree_trans *,
|
||||
u64,
|
||||
int bch2_link_trans(struct btree_trans *, u64,
|
||||
u64, struct bch_inode_unpacked *,
|
||||
const struct qstr *);
|
||||
|
||||
|
|
|
@ -144,20 +144,18 @@ static int bch2_make_extent_indirect(struct btree_trans *trans,
|
|||
static struct bkey_s_c get_next_src(struct btree_iter *iter, struct bpos end)
|
||||
{
|
||||
struct bkey_s_c k = bch2_btree_iter_peek(iter);
|
||||
int ret;
|
||||
|
||||
while (1) {
|
||||
if (bkey_err(k))
|
||||
return k;
|
||||
|
||||
for_each_btree_key_continue(iter, 0, k, ret) {
|
||||
if (bkey_cmp(iter->pos, end) >= 0)
|
||||
return bkey_s_c_null;
|
||||
|
||||
if (k.k->type == KEY_TYPE_extent ||
|
||||
k.k->type == KEY_TYPE_reflink_p)
|
||||
return k;
|
||||
|
||||
k = bch2_btree_iter_next(iter);
|
||||
break;
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
s64 bch2_remap_range(struct bch_fs *c,
|
||||
|
|
Loading…
Reference in a new issue