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, ...@@ -451,6 +451,7 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
struct bch_fs_usage_online *fs_usage = NULL; struct bch_fs_usage_online *fs_usage = NULL;
struct btree_insert_entry *i; struct btree_insert_entry *i;
struct btree_iter *iter;
unsigned mark_flags = trans->flags & BTREE_INSERT_BUCKET_INVALIDATE unsigned mark_flags = trans->flags & BTREE_INSERT_BUCKET_INVALIDATE
? BCH_BUCKET_MARK_BUCKET_INVALIDATE ? BCH_BUCKET_MARK_BUCKET_INVALIDATE
: 0; : 0;
...@@ -473,6 +474,14 @@ static inline int do_btree_insert_at(struct btree_trans *trans, ...@@ -473,6 +474,14 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
goto out_clear_replicas; 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)) if (IS_ENABLED(CONFIG_BCACHEFS_DEBUG))
trans_for_each_update(trans, i) trans_for_each_update(trans, i)
btree_insert_entry_checks(trans, i); btree_insert_entry_checks(trans, i);
......
...@@ -296,10 +296,10 @@ int bch2_dirent_delete(struct bch_fs *c, u64 dir_inum, ...@@ -296,10 +296,10 @@ int bch2_dirent_delete(struct bch_fs *c, u64 dir_inum,
struct btree_iter * struct btree_iter *
__bch2_dirent_lookup_trans(struct btree_trans *trans, u64 dir_inum, __bch2_dirent_lookup_trans(struct btree_trans *trans, u64 dir_inum,
const struct bch_hash_info *hash_info, 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, 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, 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, ...@@ -313,7 +313,8 @@ u64 bch2_dirent_lookup(struct bch_fs *c, u64 dir_inum,
bch2_trans_init(&trans, c, 0, 0); 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)) { if (IS_ERR(iter)) {
BUG_ON(PTR_ERR(iter) == -EINTR); BUG_ON(PTR_ERR(iter) == -EINTR);
goto out; goto out;
......
...@@ -55,7 +55,7 @@ int bch2_dirent_rename(struct btree_trans *, ...@@ -55,7 +55,7 @@ int bch2_dirent_rename(struct btree_trans *,
struct btree_iter * struct btree_iter *
__bch2_dirent_lookup_trans(struct btree_trans *, u64, __bch2_dirent_lookup_trans(struct btree_trans *, u64,
const struct bch_hash_info *, 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 *, u64 bch2_dirent_lookup(struct bch_fs *, u64, const struct bch_hash_info *,
const struct qstr *); const struct qstr *);
......
...@@ -24,8 +24,7 @@ int bch2_create_trans(struct btree_trans *trans, u64 dir_inum, ...@@ -24,8 +24,7 @@ int bch2_create_trans(struct btree_trans *trans, u64 dir_inum,
u64 now = bch2_current_time(trans->c); u64 now = bch2_current_time(trans->c);
int ret; int ret;
dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, BTREE_ITER_INTENT);
name ? BTREE_ITER_INTENT : 0);
if (IS_ERR(dir_iter)) if (IS_ERR(dir_iter))
return PTR_ERR(dir_iter); return PTR_ERR(dir_iter);
...@@ -76,8 +75,7 @@ int bch2_create_trans(struct btree_trans *trans, u64 dir_inum, ...@@ -76,8 +75,7 @@ int bch2_create_trans(struct btree_trans *trans, u64 dir_inum,
return 0; return 0;
} }
int bch2_link_trans(struct btree_trans *trans, int bch2_link_trans(struct btree_trans *trans, u64 dir_inum,
u64 dir_inum,
u64 inum, struct bch_inode_unpacked *inode_u, u64 inum, struct bch_inode_unpacked *inode_u,
const struct qstr *name) const struct qstr *name)
{ {
...@@ -86,19 +84,22 @@ int bch2_link_trans(struct btree_trans *trans, ...@@ -86,19 +84,22 @@ int bch2_link_trans(struct btree_trans *trans,
struct bch_hash_info dir_hash; struct bch_hash_info dir_hash;
u64 now = bch2_current_time(trans->c); 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); inode_iter = bch2_inode_peek(trans, inode_u, inum, BTREE_ITER_INTENT);
if (IS_ERR(inode_iter)) if (IS_ERR(inode_iter))
return PTR_ERR(inode_iter); return PTR_ERR(inode_iter);
dir_hash = bch2_hash_info_init(trans->c, &dir_u);
inode_u->bi_ctime = now; inode_u->bi_ctime = now;
bch2_inode_nlink_inc(inode_u); 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, return bch2_dirent_create(trans, dir_inum, &dir_hash,
mode_to_type(inode_u->bi_mode), mode_to_type(inode_u->bi_mode),
name, inum, BCH_HASH_SET_MUST_CREATE) ?: name, inum, BCH_HASH_SET_MUST_CREATE) ?:
...@@ -121,8 +122,8 @@ int bch2_unlink_trans(struct btree_trans *trans, ...@@ -121,8 +122,8 @@ int bch2_unlink_trans(struct btree_trans *trans,
dir_hash = bch2_hash_info_init(trans->c, dir_u); dir_hash = bch2_hash_info_init(trans->c, dir_u);
dirent_iter = __bch2_dirent_lookup_trans(trans, dir_inum, dirent_iter = __bch2_dirent_lookup_trans(trans, dir_inum, &dir_hash,
&dir_hash, name); name, BTREE_ITER_INTENT);
if (IS_ERR(dirent_iter)) if (IS_ERR(dirent_iter))
return PTR_ERR(dirent_iter); return PTR_ERR(dirent_iter);
......
...@@ -12,8 +12,7 @@ int bch2_create_trans(struct btree_trans *, u64, ...@@ -12,8 +12,7 @@ int bch2_create_trans(struct btree_trans *, u64,
struct posix_acl *, struct posix_acl *,
struct posix_acl *); struct posix_acl *);
int bch2_link_trans(struct btree_trans *, int bch2_link_trans(struct btree_trans *, u64,
u64,
u64, struct bch_inode_unpacked *, u64, struct bch_inode_unpacked *,
const struct qstr *); const struct qstr *);
......
...@@ -144,20 +144,18 @@ static int bch2_make_extent_indirect(struct btree_trans *trans, ...@@ -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) 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); struct bkey_s_c k = bch2_btree_iter_peek(iter);
int ret;
while (1) { for_each_btree_key_continue(iter, 0, k, ret) {
if (bkey_err(k))
return k;
if (bkey_cmp(iter->pos, end) >= 0) if (bkey_cmp(iter->pos, end) >= 0)
return bkey_s_c_null; return bkey_s_c_null;
if (k.k->type == KEY_TYPE_extent || if (k.k->type == KEY_TYPE_extent ||
k.k->type == KEY_TYPE_reflink_p) k.k->type == KEY_TYPE_reflink_p)
return k; break;
k = bch2_btree_iter_next(iter);
} }
return k;
} }
s64 bch2_remap_range(struct bch_fs *c, 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