diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-06-14 18:16:10 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2021-06-14 20:24:12 -0400 |
commit | ee8c024d338ecabd188f210cf198180ab2accda3 (patch) | |
tree | 405830ce04723e56c62430351b31140d60d90cb7 | |
parent | e9761f8dbfde84011c9c15bc2ebb3a175f31cebc (diff) |
bcachefs: Improve iter->should_be_locked
Adding iter->should_be_locked introduced a regression where it ended up
not being set on the iterator passed to bch2_btree_update_start(), which
is definitely not what we want.
This patch requires it to be set when calling bch2_trans_update(), and
adds various fixups to make that happen.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | fs/bcachefs/btree_iter.h | 6 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_interior.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 10 | ||||
-rw-r--r-- | fs/bcachefs/buckets.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/extent_update.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/fs-common.c | 3 | ||||
-rw-r--r-- | fs/bcachefs/fs-io.c | 3 | ||||
-rw-r--r-- | fs/bcachefs/recovery.c | 15 | ||||
-rw-r--r-- | fs/bcachefs/reflink.c | 6 |
9 files changed, 31 insertions, 20 deletions
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h index 27c685a482ec..6efea281d87f 100644 --- a/fs/bcachefs/btree_iter.h +++ b/fs/bcachefs/btree_iter.h @@ -176,6 +176,12 @@ static inline void bch2_btree_iter_set_pos(struct btree_iter *iter, struct bpos iter->should_be_locked = false; } +static inline void bch2_btree_iter_set_pos_to_extent_start(struct btree_iter *iter) +{ + BUG_ON(!(iter->flags & BTREE_ITER_IS_EXTENTS)); + iter->pos = bkey_start_pos(&iter->k); +} + static inline struct btree_iter *btree_iter_child(struct btree_iter *iter) { return iter->child_idx == U8_MAX ? NULL diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c index 2d8093d1bf00..89011f9f89ed 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -937,6 +937,8 @@ bch2_btree_update_start(struct btree_iter *iter, unsigned level, int journal_flags = 0; int ret = 0; + BUG_ON(!iter->should_be_locked); + if (flags & BTREE_INSERT_JOURNAL_RESERVED) journal_flags |= JOURNAL_RES_GET_RESERVED; diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index 03fd8d00e642..1f025c4e9ffe 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -836,6 +836,10 @@ static int extent_handle_overwrites(struct btree_trans *trans, update_iter = bch2_trans_get_iter(trans, i->btree_id, update->k.p, BTREE_ITER_NOT_EXTENTS| BTREE_ITER_INTENT); + ret = bch2_btree_iter_traverse(update_iter); + if (ret) + goto out; + bch2_trans_update(trans, update_iter, update, i->trigger_flags); bch2_trans_iter_put(trans, update_iter); } @@ -1019,6 +1023,7 @@ int bch2_trans_update(struct btree_trans *trans, struct btree_iter *iter, int ret = 0; BUG_ON(trans->nr_updates >= BTREE_ITER_MAX); + BUG_ON(!iter->should_be_locked); #ifdef CONFIG_BCACHEFS_DEBUG trans_for_each_update(trans, i) @@ -1127,13 +1132,12 @@ int bch2_btree_delete_range_trans(struct btree_trans *trans, enum btree_id id, iter = bch2_trans_get_iter(trans, id, start, BTREE_ITER_INTENT); retry: - while ((k = bch2_btree_iter_peek(iter)).k && + while ((bch2_trans_begin(trans), + (k = bch2_btree_iter_peek(iter)).k) && !(ret = bkey_err(k)) && bkey_cmp(iter->pos, end) < 0) { struct bkey_i delete; - bch2_trans_begin(trans); - bkey_init(&delete.k); /* diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c index 0b4fb05760bf..b06105aea216 100644 --- a/fs/bcachefs/buckets.c +++ b/fs/bcachefs/buckets.c @@ -1813,7 +1813,7 @@ static int __bch2_trans_mark_reflink_p(struct btree_trans *trans, set_bkey_val_u64s(&n->k, 0); } - bch2_btree_iter_set_pos(iter, bkey_start_pos(k.k)); + bch2_btree_iter_set_pos_to_extent_start(iter); ret = bch2_trans_update(trans, iter, n, 0); if (ret) goto err; diff --git a/fs/bcachefs/extent_update.c b/fs/bcachefs/extent_update.c index ef4aaf1c30ed..4a8dd085f7fb 100644 --- a/fs/bcachefs/extent_update.c +++ b/fs/bcachefs/extent_update.c @@ -104,6 +104,10 @@ int bch2_extent_atomic_end(struct btree_iter *iter, unsigned nr_iters = 0; int ret; + ret = bch2_btree_iter_traverse(iter); + if (ret) + return ret; + *end = insert->k.p; /* extent_update_to_keys(): */ diff --git a/fs/bcachefs/fs-common.c b/fs/bcachefs/fs-common.c index 00a63fecb976..60c54438074e 100644 --- a/fs/bcachefs/fs-common.c +++ b/fs/bcachefs/fs-common.c @@ -85,7 +85,8 @@ int bch2_create_trans(struct btree_trans *trans, u64 dir_inum, inode_iter->snapshot = U32_MAX; bch2_btree_iter_set_pos(inode_iter, SPOS(0, new_inode->bi_inum, U32_MAX)); - ret = bch2_inode_write(trans, inode_iter, new_inode); + ret = bch2_btree_iter_traverse(inode_iter) ?: + bch2_inode_write(trans, inode_iter, new_inode); err: bch2_trans_iter_put(trans, inode_iter); bch2_trans_iter_put(trans, dir_iter); diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c index 4310cc104f51..1e3e2cc9f866 100644 --- a/fs/bcachefs/fs-io.c +++ b/fs/bcachefs/fs-io.c @@ -2613,7 +2613,8 @@ reassemble: BUG_ON(ret); } - ret = bch2_trans_update(&trans, del, &delete, trigger_flags) ?: + ret = bch2_btree_iter_traverse(del) ?: + bch2_trans_update(&trans, del, &delete, trigger_flags) ?: bch2_trans_update(&trans, dst, copy.k, trigger_flags) ?: bch2_trans_commit(&trans, &disk_res, &inode->ei_journal_seq, diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index f32414171aab..c6fa4ca31ae9 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -509,16 +509,8 @@ static int __bch2_journal_replay_key(struct btree_trans *trans, iter = bch2_trans_get_node_iter(trans, id, k->k.p, BTREE_MAX_DEPTH, level, - BTREE_ITER_INTENT); - - /* - * iter->flags & BTREE_ITER_IS_EXTENTS triggers the update path to run - * extent_handle_overwrites() and extent_update_to_keys() - but we don't - * want that here, journal replay is supposed to treat extents like - * regular keys: - */ - BUG_ON(iter->flags & BTREE_ITER_IS_EXTENTS); - + BTREE_ITER_INTENT| + BTREE_ITER_NOT_EXTENTS); ret = bch2_btree_iter_traverse(iter) ?: bch2_trans_update(trans, iter, k, BTREE_TRIGGER_NORUN); bch2_trans_iter_put(trans, iter); @@ -546,7 +538,8 @@ static int __bch2_alloc_replay_key(struct btree_trans *trans, struct bkey_i *k) BTREE_ITER_CACHED| BTREE_ITER_CACHED_NOFILL| BTREE_ITER_INTENT); - ret = bch2_trans_update(trans, iter, k, BTREE_TRIGGER_NORUN); + ret = bch2_btree_iter_traverse(iter) ?: + bch2_trans_update(trans, iter, k, BTREE_TRIGGER_NORUN); bch2_trans_iter_put(trans, iter); return ret; } diff --git a/fs/bcachefs/reflink.c b/fs/bcachefs/reflink.c index ba700810a4be..ebf391245470 100644 --- a/fs/bcachefs/reflink.c +++ b/fs/bcachefs/reflink.c @@ -142,7 +142,7 @@ static int bch2_make_extent_indirect(struct btree_trans *trans, goto err; /* rewind iter to start of hole, if necessary: */ - bch2_btree_iter_set_pos(reflink_iter, bkey_start_pos(k.k)); + bch2_btree_iter_set_pos_to_extent_start(reflink_iter); r_v = bch2_trans_kmalloc(trans, sizeof(__le64) + bkey_bytes(&orig->k)); ret = PTR_ERR_OR_ZERO(r_v); @@ -257,11 +257,11 @@ s64 bch2_remap_range(struct bch_fs *c, } if (src_k.k->type != KEY_TYPE_reflink_p) { + bch2_btree_iter_set_pos_to_extent_start(src_iter); + bch2_bkey_buf_reassemble(&new_src, c, src_k); src_k = bkey_i_to_s_c(new_src.k); - bch2_btree_iter_set_pos(src_iter, bkey_start_pos(src_k.k)); - ret = bch2_make_extent_indirect(&trans, src_iter, new_src.k); if (ret) |