Commit 63fbf458 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Can't be holding read locks while taking write locks

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 0741d378
......@@ -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,
......
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