]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to ca3cfad39f fixup! bcachefs: Improve iter->should_be_locked
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 23 Jun 2021 00:45:30 +0000 (20:45 -0400)
committerKent Overstreet <kent.overstreet@gmail.com>
Wed, 23 Jun 2021 19:53:37 +0000 (15:53 -0400)
33 files changed:
.bcachefs_revision
Kbuild.include
libbcachefs/bcachefs.h
libbcachefs/btree_gc.c
libbcachefs/btree_io.c
libbcachefs/btree_iter.c
libbcachefs/btree_iter.h
libbcachefs/btree_types.h
libbcachefs/btree_update_interior.c
libbcachefs/btree_update_leaf.c
libbcachefs/buckets.c
libbcachefs/buckets.h
libbcachefs/ec.c
libbcachefs/error.c
libbcachefs/error.h
libbcachefs/extent_update.c
libbcachefs/extents.h
libbcachefs/fs-common.c
libbcachefs/fs-io.c
libbcachefs/fs-io.h
libbcachefs/fs.c
libbcachefs/fs.h
libbcachefs/fsck.c
libbcachefs/inode.c
libbcachefs/journal.c
libbcachefs/recovery.c
libbcachefs/reflink.c
libbcachefs/super-io.c
libbcachefs/super.c
libbcachefs/tests.c
libbcachefs/util.c
libbcachefs/util.h
linux/six.c

index 14415fb2d6305120977d37d5d7ed558fa6cf3a03..57211d2511b03d1bb139ec1a59946134300bb326 100644 (file)
@@ -1 +1 @@
-b00cf89c56077d5e91c134d066ba2b45bc3136d7
+ca3cfad39f915257eecda93599c8b434ce80e0b2
index 08e011175b4c879852a2cc203ea0b2ccf4ce8cfc..509e0856d6533c2c3864d2b89c895a87100459f7 100644 (file)
@@ -141,13 +141,9 @@ cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || e
 # Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y)
 ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3))
 
-# ld-version
-# Note this is mainly for HJ Lu's 3 number binutil versions
-ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh)
-
 # ld-ifversion
 # Usage:  $(call ld-ifversion, -ge, 22252, y)
-ld-ifversion = $(shell [ $(ld-version) $(1) $(2) ] && echo $(3) || echo $(4))
+ld-ifversion = $(shell [ $(CONFIG_LD_VERSION)0 $(1) $(2)0 ] && echo $(3) || echo $(4))
 
 ######
 
index 8be95d81180f0bd6a95871cc9286613644c69f18..125cf0928bcf97b100e867ad8fb875e7b2ac5173 100644 (file)
@@ -497,6 +497,7 @@ enum {
        BCH_FS_ALLOCATOR_STOPPING,
        BCH_FS_INITIAL_GC_DONE,
        BCH_FS_INITIAL_GC_UNFIXED,
+       BCH_FS_TOPOLOGY_REPAIR_DONE,
        BCH_FS_BTREE_INTERIOR_REPLAY_DONE,
        BCH_FS_FSCK_DONE,
        BCH_FS_STARTED,
index 8af6d3216e43c0c57e50b62aa9ce748442a4ecd9..5c03eb937ab4fedcfe9b28e4cfea992d73d86d56 100644 (file)
@@ -86,12 +86,17 @@ static int bch2_gc_check_topology(struct bch_fs *c,
                if (bpos_cmp(expected_start, bp->v.min_key)) {
                        bch2_topology_error(c);
 
-                       if (fsck_err(c, "btree node with incorrect min_key at btree %s level %u:\n"
-                                    "  prev %s\n"
-                                    "  cur %s",
-                                    bch2_btree_ids[b->c.btree_id], b->c.level,
-                                    buf1,
-                                    (bch2_bkey_val_to_text(&PBUF(buf2), c, bkey_i_to_s_c(cur.k)), buf2))) {
+                       if (__fsck_err(c,
+                                 FSCK_CAN_FIX|
+                                 FSCK_CAN_IGNORE|
+                                 FSCK_NO_RATELIMIT,
+                                 "btree node with incorrect min_key at btree %s level %u:\n"
+                                 "  prev %s\n"
+                                 "  cur %s",
+                                 bch2_btree_ids[b->c.btree_id], b->c.level,
+                                 buf1,
+                                 (bch2_bkey_val_to_text(&PBUF(buf2), c, bkey_i_to_s_c(cur.k)), buf2)) &&
+                           !test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags)) {
                                bch_info(c, "Halting mark and sweep to start topology repair pass");
                                return FSCK_ERR_START_TOPOLOGY_REPAIR;
                        } else {
@@ -103,12 +108,17 @@ static int bch2_gc_check_topology(struct bch_fs *c,
        if (is_last && bpos_cmp(cur.k->k.p, node_end)) {
                bch2_topology_error(c);
 
-               if (fsck_err(c, "btree node with incorrect max_key at btree %s level %u:\n"
-                            "  %s\n"
-                            "  expected %s",
-                            bch2_btree_ids[b->c.btree_id], b->c.level,
-                            (bch2_bkey_val_to_text(&PBUF(buf1), c, bkey_i_to_s_c(cur.k)), buf1),
-                            (bch2_bpos_to_text(&PBUF(buf2), node_end), buf2))) {
+               if (__fsck_err(c,
+                         FSCK_CAN_FIX|
+                         FSCK_CAN_IGNORE|
+                         FSCK_NO_RATELIMIT,
+                         "btree node with incorrect max_key at btree %s level %u:\n"
+                         "  %s\n"
+                         "  expected %s",
+                         bch2_btree_ids[b->c.btree_id], b->c.level,
+                         (bch2_bkey_val_to_text(&PBUF(buf1), c, bkey_i_to_s_c(cur.k)), buf1),
+                         (bch2_bpos_to_text(&PBUF(buf2), node_end), buf2)) &&
+                   !test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags)) {
                        bch_info(c, "Halting mark and sweep to start topology repair pass");
                        return FSCK_ERR_START_TOPOLOGY_REPAIR;
                } else {
@@ -286,6 +296,7 @@ static int bch2_btree_repair_topology_recurse(struct bch_fs *c, struct btree *b)
        if (!b->c.level)
                return 0;
 again:
+       prev = NULL;
        have_child = dropped_children = false;
        bch2_bkey_buf_init(&prev_k);
        bch2_bkey_buf_init(&cur_k);
@@ -310,7 +321,7 @@ again:
                        ret = bch2_journal_key_delete(c, b->c.btree_id,
                                                      b->c.level, cur_k.k->k.p);
                        if (ret)
-                               goto err;
+                               break;
                        continue;
                }
 
@@ -328,19 +339,24 @@ again:
                        ret = bch2_journal_key_delete(c, b->c.btree_id,
                                                      b->c.level, cur_k.k->k.p);
                        if (ret)
-                               goto err;
+                               break;
                        continue;
                }
 
                if (prev)
                        six_unlock_read(&prev->c.lock);
+               prev = NULL;
 
                if (ret == DROP_PREV_NODE) {
                        bch2_btree_node_evict(c, prev_k.k);
                        ret = bch2_journal_key_delete(c, b->c.btree_id,
                                                      b->c.level, prev_k.k->k.p);
                        if (ret)
-                               goto err;
+                               break;
+
+                       bch2_btree_and_journal_iter_exit(&iter);
+                       bch2_bkey_buf_exit(&prev_k, c);
+                       bch2_bkey_buf_exit(&cur_k, c);
                        goto again;
                } else if (ret)
                        break;
@@ -640,6 +656,7 @@ static int bch2_gc_mark_key(struct bch_fs *c, enum btree_id btree_id,
        struct bkey_ptrs_c ptrs;
        const struct bch_extent_ptr *ptr;
        unsigned flags =
+               BTREE_TRIGGER_INSERT|
                BTREE_TRIGGER_GC|
                (initial ? BTREE_TRIGGER_NOATOMIC : 0);
        int ret = 0;
@@ -681,7 +698,7 @@ static int bch2_gc_mark_key(struct bch_fs *c, enum btree_id btree_id,
                *max_stale = max(*max_stale, ptr_stale(ca, ptr));
        }
 
-       bch2_mark_key(c, *k, 0, k->k->size, NULL, 0, flags);
+       bch2_mark_key(c, *k, flags);
 fsck_err:
 err:
        if (ret)
@@ -854,11 +871,16 @@ static int bch2_gc_btree_init_recurse(struct bch_fs *c, struct btree *b,
                        if (ret == -EIO) {
                                bch2_topology_error(c);
 
-                               if (fsck_err(c, "Unreadable btree node at btree %s level %u:\n"
-                                       "  %s",
-                                       bch2_btree_ids[b->c.btree_id],
-                                       b->c.level - 1,
-                                       (bch2_bkey_val_to_text(&PBUF(buf), c, bkey_i_to_s_c(cur.k)), buf))) {
+                               if (__fsck_err(c,
+                                         FSCK_CAN_FIX|
+                                         FSCK_CAN_IGNORE|
+                                         FSCK_NO_RATELIMIT,
+                                         "Unreadable btree node at btree %s level %u:\n"
+                                         "  %s",
+                                         bch2_btree_ids[b->c.btree_id],
+                                         b->c.level - 1,
+                                         (bch2_bkey_val_to_text(&PBUF(buf), c, bkey_i_to_s_c(cur.k)), buf)) &&
+                                   !test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags)) {
                                        ret = FSCK_ERR_START_TOPOLOGY_REPAIR;
                                        bch_info(c, "Halting mark and sweep to start topology repair pass");
                                        goto fsck_err;
@@ -1052,8 +1074,7 @@ static void bch2_mark_pending_btree_node_frees(struct bch_fs *c)
        for_each_pending_btree_node_free(c, as, d)
                if (d->index_update_done)
                        bch2_mark_key(c, bkey_i_to_s_c(&d->key),
-                                     0, 0, NULL, 0,
-                                     BTREE_TRIGGER_GC);
+                                     BTREE_TRIGGER_INSERT|BTREE_TRIGGER_GC);
 
        mutex_unlock(&c->btree_interior_update_lock);
 }
@@ -1558,11 +1579,14 @@ again:
                if (ret)
                        goto out;
                bch_info(c, "topology repair pass done");
+
+               set_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags);
        }
 
        ret = bch2_gc_btrees(c, initial, metadata_only);
 
        if (ret == FSCK_ERR_START_TOPOLOGY_REPAIR &&
+           !test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags) &&
            !test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags)) {
                set_bit(BCH_FS_NEED_ANOTHER_GC, &c->flags);
                ret = 0;
index 47cfd8a08f91f18f17f35b4b1af77c5f04cb8c29..f2ccb5f39a6d6a5782ab70aa7309248075c5d58b 100644 (file)
@@ -1179,31 +1179,27 @@ static void btree_node_read_all_replicas_done(struct closure *cl)
                container_of(cl, struct btree_node_read_all, cl);
        struct bch_fs *c = ra->c;
        struct btree *b = ra->b;
-       bool have_good_copy = false;
        bool dump_bset_maps = false;
        bool have_retry = false;
-       int ret = 0, write = READ;
+       int ret = 0, best = -1, write = READ;
        unsigned i, written, written2;
        __le64 seq = b->key.k.type == KEY_TYPE_btree_ptr_v2
                ? bkey_i_to_btree_ptr_v2(&b->key)->v.seq : 0;
 
        for (i = 0; i < ra->nr; i++) {
+               struct btree_node *bn = ra->buf[i];
+
                if (ra->err[i])
                        continue;
 
-               if (!have_good_copy) {
-                       memcpy(b->data, ra->buf[i], btree_bytes(c));
-                       have_good_copy = true;
-                       written = btree_node_sectors_written(c, b->data);
-               }
+               if (le64_to_cpu(bn->magic) != bset_magic(c) ||
+                   (seq && seq != bn->keys.seq))
+                       continue;
 
-               /* Try to get the right btree node: */
-               if (have_good_copy &&
-                   seq &&
-                   b->data->keys.seq != seq &&
-                   ((struct btree_node *) ra->buf[i])->keys.seq == seq) {
-                       memcpy(b->data, ra->buf[i], btree_bytes(c));
-                       written = btree_node_sectors_written(c, b->data);
+               if (best < 0) {
+                       best = i;
+                       written = btree_node_sectors_written(c, bn);
+                       continue;
                }
 
                written2 = btree_node_sectors_written(c, ra->buf[i]);
@@ -1213,14 +1209,14 @@ static void btree_node_read_all_replicas_done(struct closure *cl)
                    btree_err_on(btree_node_has_extra_bsets(c, written2, ra->buf[i]),
                                 BTREE_ERR_FIXABLE, c, NULL, b, NULL,
                                 "found bset signature after last bset") ||
-                   btree_err_on(memcmp(b->data, ra->buf[i], written << 9),
+                   btree_err_on(memcmp(ra->buf[best], ra->buf[i], written << 9),
                                 BTREE_ERR_FIXABLE, c, NULL, b, NULL,
                                 "btree node replicas content mismatch"))
                        dump_bset_maps = true;
 
                if (written2 > written) {
                        written = written2;
-                       memcpy(b->data, ra->buf[i], btree_bytes(c));
+                       best = i;
                }
        }
 fsck_err:
@@ -1273,9 +1269,14 @@ fsck_err:
                }
        }
 
-       if (have_good_copy)
-               bch2_btree_node_read_done(c, NULL, b, false);
-       else
+       if (best >= 0) {
+               memcpy(b->data, ra->buf[best], btree_bytes(c));
+               ret = bch2_btree_node_read_done(c, NULL, b, false);
+       } else {
+               ret = -1;
+       }
+
+       if (ret)
                set_btree_node_read_error(b);
 
        for (i = 0; i < ra->nr; i++) {
index 64ceea45808e91eb0860a8ebf95bc562036c92a8..c356032be3ec43938eed81339740abde9d247e13 100644 (file)
@@ -1808,35 +1808,54 @@ struct bkey_s_c bch2_btree_iter_prev(struct btree_iter *iter)
 
 struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter)
 {
-       struct bpos search_key = btree_iter_search_key(iter);
+       struct bpos search_key;
        struct bkey_s_c k;
        int ret;
 
-       EBUG_ON(btree_iter_type(iter) != BTREE_ITER_KEYS);
+       EBUG_ON(btree_iter_type(iter) != BTREE_ITER_KEYS &&
+               btree_iter_type(iter) != BTREE_ITER_CACHED);
        bch2_btree_iter_verify(iter);
        bch2_btree_iter_verify_entry_exit(iter);
 
-       btree_iter_set_search_pos(iter, search_key);
-
        /* extents can't span inode numbers: */
        if ((iter->flags & BTREE_ITER_IS_EXTENTS) &&
-           iter->pos.offset == KEY_OFFSET_MAX) {
+           unlikely(iter->pos.offset == KEY_OFFSET_MAX)) {
                if (iter->pos.inode == KEY_INODE_MAX)
                        return bkey_s_c_null;
 
                bch2_btree_iter_set_pos(iter, bpos_nosnap_successor(iter->pos));
        }
 
+       search_key = btree_iter_search_key(iter);
+       btree_iter_set_search_pos(iter, search_key);
+
        ret = btree_iter_traverse(iter);
        if (unlikely(ret))
                return bkey_s_c_err(ret);
 
-       if (!(iter->flags & BTREE_ITER_IS_EXTENTS)) {
-               struct bkey_i *next_update = btree_trans_peek_updates(iter, search_key);
+       if (btree_iter_type(iter) == BTREE_ITER_CACHED ||
+           !(iter->flags & BTREE_ITER_IS_EXTENTS)) {
+               struct bkey_i *next_update;
+               struct bkey_cached *ck;
 
-               k = btree_iter_level_peek_all(iter, &iter->l[0]);
-               EBUG_ON(k.k && bkey_deleted(k.k) && bkey_cmp(k.k->p, iter->pos) == 0);
+               switch (btree_iter_type(iter)) {
+               case BTREE_ITER_KEYS:
+                       k = btree_iter_level_peek_all(iter, &iter->l[0]);
+                       EBUG_ON(k.k && bkey_deleted(k.k) && bkey_cmp(k.k->p, iter->pos) == 0);
+                       break;
+               case BTREE_ITER_CACHED:
+                       ck = (void *) iter->l[0].b;
+                       EBUG_ON(iter->btree_id != ck->key.btree_id ||
+                               bkey_cmp(iter->pos, ck->key.pos));
+                       BUG_ON(!ck->valid);
 
+                       k = bkey_i_to_s_c(ck->k);
+                       break;
+               case BTREE_ITER_NODES:
+                       BUG();
+               }
+
+               next_update = btree_trans_peek_updates(iter, search_key);
                if (next_update &&
                    (!k.k || bpos_cmp(next_update->k.p, k.k->p) <= 0)) {
                        iter->k = next_update->k;
@@ -1913,34 +1932,6 @@ struct bkey_s_c bch2_btree_iter_prev_slot(struct btree_iter *iter)
        return bch2_btree_iter_peek_slot(iter);
 }
 
-struct bkey_s_c bch2_btree_iter_peek_cached(struct btree_iter *iter)
-{
-       struct bkey_i *next_update;
-       struct bkey_cached *ck;
-       int ret;
-
-       EBUG_ON(btree_iter_type(iter) != BTREE_ITER_CACHED);
-       bch2_btree_iter_verify(iter);
-
-       next_update = btree_trans_peek_updates(iter, iter->pos);
-       if (next_update && !bpos_cmp(next_update->k.p, iter->pos))
-               return bkey_i_to_s_c(next_update);
-
-       ret = btree_iter_traverse(iter);
-       if (unlikely(ret))
-               return bkey_s_c_err(ret);
-
-       ck = (void *) iter->l[0].b;
-
-       EBUG_ON(iter->btree_id != ck->key.btree_id ||
-               bkey_cmp(iter->pos, ck->key.pos));
-       BUG_ON(!ck->valid);
-
-       iter->should_be_locked = true;
-
-       return bkey_i_to_s_c(ck->k);
-}
-
 static inline void bch2_btree_iter_init(struct btree_trans *trans,
                        struct btree_iter *iter, enum btree_id btree_id)
 {
@@ -2304,9 +2295,11 @@ void bch2_trans_reset(struct btree_trans *trans, unsigned flags)
 {
        struct btree_iter *iter;
 
-       trans_for_each_iter(trans, iter)
+       trans_for_each_iter(trans, iter) {
                iter->flags &= ~(BTREE_ITER_KEEP_UNTIL_COMMIT|
                                 BTREE_ITER_SET_POS_AFTER_COMMIT);
+               iter->should_be_locked = false;
+       }
 
        bch2_trans_unlink_iters(trans);
 
index ba98cfea4d6086785ce044d10d0a506d9d728cc6..6efea281d87f6aa6ed7f83ed1e1ba455d82b3027 100644 (file)
@@ -160,8 +160,6 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *);
 struct bkey_s_c bch2_btree_iter_next_slot(struct btree_iter *);
 struct bkey_s_c bch2_btree_iter_prev_slot(struct btree_iter *);
 
-struct bkey_s_c bch2_btree_iter_peek_cached(struct btree_iter *);
-
 bool bch2_btree_iter_advance(struct btree_iter *);
 bool bch2_btree_iter_rewind(struct btree_iter *);
 
@@ -178,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
@@ -224,12 +228,9 @@ static inline int bch2_trans_cond_resched(struct btree_trans *trans)
 static inline struct bkey_s_c __bch2_btree_iter_peek(struct btree_iter *iter,
                                                     unsigned flags)
 {
-       if ((flags & BTREE_ITER_TYPE) == BTREE_ITER_CACHED)
-               return bch2_btree_iter_peek_cached(iter);
-       else
-               return flags & BTREE_ITER_SLOTS
-                       ? bch2_btree_iter_peek_slot(iter)
-                       : bch2_btree_iter_peek(iter);
+       return flags & BTREE_ITER_SLOTS
+               ? bch2_btree_iter_peek_slot(iter)
+               : bch2_btree_iter_peek(iter);
 }
 
 static inline struct bkey_s_c __bch2_btree_iter_next(struct btree_iter *iter,
index 982a3b1fce47890a630c5d469db10b8bf25ee43f..a923757c07da580f772171ef34c72df27f9d4296 100644 (file)
@@ -644,7 +644,6 @@ enum btree_trigger_flags {
 
        __BTREE_TRIGGER_INSERT,
        __BTREE_TRIGGER_OVERWRITE,
-       __BTREE_TRIGGER_OVERWRITE_SPLIT,
 
        __BTREE_TRIGGER_GC,
        __BTREE_TRIGGER_BUCKET_INVALIDATE,
@@ -655,12 +654,15 @@ enum btree_trigger_flags {
 
 #define BTREE_TRIGGER_INSERT           (1U << __BTREE_TRIGGER_INSERT)
 #define BTREE_TRIGGER_OVERWRITE                (1U << __BTREE_TRIGGER_OVERWRITE)
-#define BTREE_TRIGGER_OVERWRITE_SPLIT  (1U << __BTREE_TRIGGER_OVERWRITE_SPLIT)
 
 #define BTREE_TRIGGER_GC               (1U << __BTREE_TRIGGER_GC)
 #define BTREE_TRIGGER_BUCKET_INVALIDATE        (1U << __BTREE_TRIGGER_BUCKET_INVALIDATE)
 #define BTREE_TRIGGER_NOATOMIC         (1U << __BTREE_TRIGGER_NOATOMIC)
 
+#define BTREE_TRIGGER_WANTS_OLD_AND_NEW                \
+       ((1U << KEY_TYPE_stripe)|               \
+        (1U << KEY_TYPE_inode))
+
 static inline bool btree_node_type_needs_gc(enum btree_node_type type)
 {
        return BTREE_NODE_TYPE_HAS_TRIGGERS & (1U << type);
index 2d8093d1bf00b1dddf67bfd09098ab9b0061d994..cd214599a03f194fc5212801a92659bffceb6b37 100644 (file)
@@ -511,7 +511,7 @@ static int btree_update_nodes_written_trans(struct btree_trans *trans,
                ret = bch2_trans_mark_key(trans,
                                          bkey_s_c_null,
                                          bkey_i_to_s_c(k),
-                                         0, 0, BTREE_TRIGGER_INSERT);
+                                         BTREE_TRIGGER_INSERT);
                if (ret)
                        return ret;
        }
@@ -520,7 +520,7 @@ static int btree_update_nodes_written_trans(struct btree_trans *trans,
                ret = bch2_trans_mark_key(trans,
                                          bkey_i_to_s_c(k),
                                          bkey_s_c_null,
-                                         0, 0, BTREE_TRIGGER_OVERWRITE);
+                                         BTREE_TRIGGER_OVERWRITE);
                if (ret)
                        return ret;
        }
@@ -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;
 
index 7939fbbb1863260d021a10d16069d56a5e8bc9f6..fa08470b6ca3e99e830926ad576b9b7e51755579 100644 (file)
@@ -362,7 +362,7 @@ static noinline void bch2_trans_mark_gc(struct btree_trans *trans)
                BUG_ON(btree_iter_type(i->iter) == BTREE_ITER_CACHED);
 
                if (gc_visited(c, gc_pos_btree_node(i->iter->l[0].b)))
-                       bch2_mark_update(trans, i->iter, i->k, NULL,
+                       bch2_mark_update(trans, i->iter, i->k,
                                         i->trigger_flags|BTREE_TRIGGER_GC);
        }
 }
@@ -468,7 +468,7 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
        trans_for_each_update(trans, i)
                if (BTREE_NODE_TYPE_HAS_MEM_TRIGGERS & (1U << i->bkey_type))
                        bch2_mark_update(trans, i->iter, i->k,
-                                        NULL, i->trigger_flags);
+                                        i->trigger_flags);
 
        if (marking && trans->fs_usage_deltas)
                bch2_trans_fs_usage_apply(trans, trans->fs_usage_deltas);
@@ -771,28 +771,6 @@ bch2_trans_commit_get_rw_cold(struct btree_trans *trans)
        return 0;
 }
 
-static int __btree_delete_at(struct btree_trans *trans, enum btree_id btree_id,
-                            struct bpos pos, unsigned trigger_flags)
-{
-       struct btree_iter *iter;
-       struct bkey_i *update;
-       int ret;
-
-       update = bch2_trans_kmalloc(trans, sizeof(struct bkey));
-       if ((ret = PTR_ERR_OR_ZERO(update)))
-               return ret;
-
-       bkey_init(&update->k);
-       update->k.p = pos;
-
-       iter = bch2_trans_get_iter(trans, btree_id, pos,
-                                  BTREE_ITER_NOT_EXTENTS|
-                                  BTREE_ITER_INTENT);
-       bch2_trans_update(trans, iter, update, trigger_flags);
-       bch2_trans_iter_put(trans, iter);
-       return 0;
-}
-
 static int extent_handle_overwrites(struct btree_trans *trans,
                                    struct btree_insert_entry *i)
 {
@@ -812,8 +790,6 @@ static int extent_handle_overwrites(struct btree_trans *trans,
                goto out;
 
        if (bch2_bkey_maybe_mergable(k.k, &i->k->k)) {
-               struct bpos l_pos = k.k->p;
-
                update = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
                if ((ret = PTR_ERR_OR_ZERO(update)))
                        goto out;
@@ -821,8 +797,11 @@ static int extent_handle_overwrites(struct btree_trans *trans,
                bkey_reassemble(update, k);
 
                if (bch2_bkey_merge(c, bkey_i_to_s(update), bkey_i_to_s_c(i->k))) {
-                       ret = __btree_delete_at(trans, i->btree_id, l_pos,
-                                               i->trigger_flags);
+                       update_iter = bch2_trans_copy_iter(trans, iter);
+                       ret = bch2_btree_delete_at(trans, update_iter,
+                                                  i->trigger_flags);
+                       bch2_trans_iter_put(trans, update_iter);
+
                        if (ret)
                                goto out;
 
@@ -857,13 +836,20 @@ 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);
                }
 
                if (bkey_cmp(k.k->p, i->k->k.p) <= 0) {
-                       ret = __btree_delete_at(trans, i->btree_id, k.k->p,
-                                               i->trigger_flags);
+                       update_iter = bch2_trans_copy_iter(trans, iter);
+                       ret = bch2_btree_delete_at(trans, update_iter,
+                                                  i->trigger_flags);
+                       bch2_trans_iter_put(trans, update_iter);
+
                        if (ret)
                                goto out;
                }
@@ -876,12 +862,7 @@ static int extent_handle_overwrites(struct btree_trans *trans,
                        bkey_reassemble(update, k);
                        bch2_cut_front(i->k->k.p, update);
 
-                       update_iter = bch2_trans_get_iter(trans, i->btree_id, update->k.p,
-                                                         BTREE_ITER_NOT_EXTENTS|
-                                                         BTREE_ITER_INTENT);
-                       bch2_trans_update(trans, update_iter, update,
-                                         i->trigger_flags);
-                       bch2_trans_iter_put(trans, update_iter);
+                       bch2_trans_update(trans, iter, update, i->trigger_flags);
                        goto out;
                }
 next:
@@ -1042,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)
@@ -1105,7 +1087,8 @@ int __bch2_btree_insert(struct btree_trans *trans,
        iter = bch2_trans_get_iter(trans, id, bkey_start_pos(&k->k),
                                   BTREE_ITER_INTENT);
 
-       ret = bch2_trans_update(trans, iter, k, 0);
+       ret   = bch2_btree_iter_traverse(iter) ?:
+               bch2_trans_update(trans, iter, k, 0);
        bch2_trans_iter_put(trans, iter);
        return ret;
 }
@@ -1127,16 +1110,17 @@ int bch2_btree_insert(struct bch_fs *c, enum btree_id id,
 }
 
 int bch2_btree_delete_at(struct btree_trans *trans,
-                        struct btree_iter *iter, unsigned flags)
+                        struct btree_iter *iter, unsigned trigger_flags)
 {
-       struct bkey_i k;
+       struct bkey_i *k;
 
-       bkey_init(&k.k);
-       k.k.p = iter->pos;
+       k = bch2_trans_kmalloc(trans, sizeof(*k));
+       if (IS_ERR(k))
+               return PTR_ERR(k);
 
-       return  bch2_trans_update(trans, iter, &k, 0) ?:
-               bch2_trans_commit(trans, NULL, NULL,
-                                 BTREE_INSERT_NOFAIL|flags);
+       bkey_init(&k->k);
+       k->k.p = iter->pos;
+       return  bch2_trans_update(trans, iter, k, trigger_flags);
 }
 
 int bch2_btree_delete_range_trans(struct btree_trans *trans, enum btree_id id,
@@ -1149,13 +1133,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);
 
                /*
index 20862a4a77f251f4a66c188d160a06f269a8efaf..76945e50e4b15a4f660ed3080db79fe7d822722c 100644 (file)
@@ -351,17 +351,16 @@ static inline void account_bucket(struct bch_fs_usage *fs_usage,
 }
 
 static void bch2_dev_usage_update(struct bch_fs *c, struct bch_dev *ca,
-                                 struct bch_fs_usage *fs_usage,
                                  struct bucket_mark old, struct bucket_mark new,
                                  u64 journal_seq, bool gc)
 {
+       struct bch_fs_usage *fs_usage;
        struct bch_dev_usage *u;
 
        percpu_rwsem_assert_held(&c->mark_lock);
 
        preempt_disable();
-       if (!fs_usage)
-               fs_usage = fs_usage_ptr(c, journal_seq, gc);
+       fs_usage = fs_usage_ptr(c, journal_seq, gc);
        u = dev_usage_ptr(ca, journal_seq, gc);
 
        if (bucket_type(old))
@@ -390,30 +389,48 @@ static void bch2_dev_usage_update(struct bch_fs *c, struct bch_dev *ca,
                bch2_wake_allocator(ca);
 }
 
+static inline int __update_replicas(struct bch_fs *c,
+                                   struct bch_fs_usage *fs_usage,
+                                   struct bch_replicas_entry *r,
+                                   s64 sectors)
+{
+       int idx = bch2_replicas_entry_idx(c, r);
+
+       if (idx < 0)
+               return -1;
+
+       fs_usage_data_type_to_base(fs_usage, r->data_type, sectors);
+       fs_usage->replicas[idx]         += sectors;
+       return 0;
+}
+
 static inline int update_replicas(struct bch_fs *c,
-                                  struct bch_fs_usage *fs_usage,
-                                  struct bch_replicas_entry *r,
-                                  s64 sectors)
+                       struct bch_replicas_entry *r, s64 sectors,
+                       unsigned journal_seq, bool gc)
 {
+       struct bch_fs_usage __percpu *fs_usage;
        int idx = bch2_replicas_entry_idx(c, r);
 
        if (idx < 0)
                return -1;
 
+       preempt_disable();
+       fs_usage = fs_usage_ptr(c, journal_seq, gc);
        fs_usage_data_type_to_base(fs_usage, r->data_type, sectors);
        fs_usage->replicas[idx]         += sectors;
+       preempt_enable();
        return 0;
 }
 
 static inline int update_cached_sectors(struct bch_fs *c,
-                                        struct bch_fs_usage *fs_usage,
-                                        unsigned dev, s64 sectors)
+                       unsigned dev, s64 sectors,
+                       unsigned journal_seq, bool gc)
 {
        struct bch_replicas_padded r;
 
        bch2_replicas_entry_cached(&r.e, dev);
 
-       return update_replicas(c, fs_usage, &r.e, sectors);
+       return update_replicas(c, &r.e, sectors, journal_seq, gc);
 }
 
 static struct replicas_delta_list *
@@ -507,7 +524,6 @@ void bch2_mark_alloc_bucket(struct bch_fs *c, struct bch_dev *ca,
 
 static int bch2_mark_alloc(struct bch_fs *c,
                           struct bkey_s_c old, struct bkey_s_c new,
-                          struct bch_fs_usage *fs_usage,
                           u64 journal_seq, unsigned flags)
 {
        bool gc = flags & BTREE_TRIGGER_GC;
@@ -549,7 +565,7 @@ static int bch2_mark_alloc(struct bch_fs *c,
                }
        }));
 
-       bch2_dev_usage_update(c, ca, fs_usage, old_m, m, journal_seq, gc);
+       bch2_dev_usage_update(c, ca, old_m, m, journal_seq, gc);
 
        g->io_time[READ]        = u.read_time;
        g->io_time[WRITE]       = u.write_time;
@@ -565,8 +581,8 @@ static int bch2_mark_alloc(struct bch_fs *c,
 
        if ((flags & BTREE_TRIGGER_BUCKET_INVALIDATE) &&
            old_m.cached_sectors) {
-               if (update_cached_sectors(c, fs_usage, ca->dev_idx,
-                                     -old_m.cached_sectors)) {
+               if (update_cached_sectors(c, ca->dev_idx, -old_m.cached_sectors,
+                                         journal_seq, gc)) {
                        bch2_fs_fatal_error(c, "bch2_mark_alloc(): no replicas entry while updating cached sectors");
                        return -1;
                }
@@ -617,8 +633,7 @@ static int __bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca,
                old.dirty_sectors, sectors);
 
        if (c)
-               bch2_dev_usage_update(c, ca, fs_usage_ptr(c, 0, gc),
-                                     old, new, 0, gc);
+               bch2_dev_usage_update(c, ca, old, new, 0, gc);
 
        return 0;
 }
@@ -637,54 +652,20 @@ void bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca,
        if (b >= ca->mi.nbuckets)
                return;
 
-       preempt_disable();
-
        if (likely(c)) {
                do_mark_fn(__bch2_mark_metadata_bucket, c, pos, flags,
                           ca, b, type, sectors);
        } else {
                __bch2_mark_metadata_bucket(c, ca, b, type, sectors, 0);
        }
-
-       preempt_enable();
 }
 
-static s64 disk_sectors_scaled(unsigned n, unsigned d, unsigned sectors)
+static s64 ptr_disk_sectors(s64 sectors, struct extent_ptr_decoded p)
 {
-       return DIV_ROUND_UP(sectors * n, d);
-}
-
-static s64 __ptr_disk_sectors_delta(unsigned old_size,
-                                   unsigned offset, s64 delta,
-                                   unsigned flags,
-                                   unsigned n, unsigned d)
-{
-       BUG_ON(!n || !d);
-
-       if (flags & BTREE_TRIGGER_OVERWRITE_SPLIT) {
-               BUG_ON(offset + -delta > old_size);
-
-               return -disk_sectors_scaled(n, d, old_size) +
-                       disk_sectors_scaled(n, d, offset) +
-                       disk_sectors_scaled(n, d, old_size - offset + delta);
-       } else if (flags & BTREE_TRIGGER_OVERWRITE) {
-               BUG_ON(offset + -delta > old_size);
-
-               return -disk_sectors_scaled(n, d, old_size) +
-                       disk_sectors_scaled(n, d, old_size + delta);
-       } else {
-               return  disk_sectors_scaled(n, d, delta);
-       }
-}
-
-static s64 ptr_disk_sectors_delta(struct extent_ptr_decoded p,
-                                 unsigned offset, s64 delta,
-                                 unsigned flags)
-{
-       return __ptr_disk_sectors_delta(p.crc.live_size,
-                                       offset, delta, flags,
-                                       p.crc.compressed_size,
-                                       p.crc.uncompressed_size);
+       return p.crc.compression_type
+               ? DIV_ROUND_UP(sectors * p.crc.compressed_size,
+                              p.crc.uncompressed_size)
+               : sectors;
 }
 
 static int check_bucket_ref(struct bch_fs *c, struct bkey_s_c k,
@@ -763,7 +744,6 @@ static int check_bucket_ref(struct bch_fs *c, struct bkey_s_c k,
 
 static int mark_stripe_bucket(struct bch_fs *c, struct bkey_s_c k,
                             unsigned ptr_idx,
-                            struct bch_fs_usage *fs_usage,
                             u64 journal_seq, unsigned flags)
 {
        const struct bch_stripe *s = bkey_s_c_to_stripe(k).v;
@@ -805,7 +785,7 @@ static int mark_stripe_bucket(struct bch_fs *c, struct bkey_s_c k,
        g->stripe               = k.k->p.offset;
        g->stripe_redundancy    = s->nr_redundant;
 
-       bch2_dev_usage_update(c, ca, fs_usage, old, new, journal_seq, gc);
+       bch2_dev_usage_update(c, ca, old, new, journal_seq, gc);
        return 0;
 }
 
@@ -834,7 +814,6 @@ static int __mark_pointer(struct bch_fs *c, struct bkey_s_c k,
 static int bch2_mark_pointer(struct bch_fs *c, struct bkey_s_c k,
                             struct extent_ptr_decoded p,
                             s64 sectors, enum bch_data_type data_type,
-                            struct bch_fs_usage *fs_usage,
                             u64 journal_seq, unsigned flags)
 {
        bool gc = flags & BTREE_TRIGGER_GC;
@@ -872,7 +851,7 @@ static int bch2_mark_pointer(struct bch_fs *c, struct bkey_s_c k,
                              old.v.counter,
                              new.v.counter)) != old.v.counter);
 
-       bch2_dev_usage_update(c, ca, fs_usage, old, new, journal_seq, gc);
+       bch2_dev_usage_update(c, ca, old, new, journal_seq, gc);
 
        BUG_ON(!gc && bucket_became_unavailable(old, new));
 
@@ -882,8 +861,8 @@ static int bch2_mark_pointer(struct bch_fs *c, struct bkey_s_c k,
 static int bch2_mark_stripe_ptr(struct bch_fs *c,
                                struct bch_extent_stripe_ptr p,
                                enum bch_data_type data_type,
-                               struct bch_fs_usage *fs_usage,
-                               s64 sectors, unsigned flags)
+                               s64 sectors,
+                               unsigned journal_seq, unsigned flags)
 {
        bool gc = flags & BTREE_TRIGGER_GC;
        struct bch_replicas_padded r;
@@ -918,40 +897,46 @@ static int bch2_mark_stripe_ptr(struct bch_fs *c,
        spin_unlock(&c->ec_stripes_heap_lock);
 
        r.e.data_type = data_type;
-       update_replicas(c, fs_usage, &r.e, sectors);
+       update_replicas(c, &r.e, sectors, journal_seq, gc);
 
        return 0;
 }
 
 static int bch2_mark_extent(struct bch_fs *c,
                            struct bkey_s_c old, struct bkey_s_c new,
-                           unsigned offset, s64 sectors,
-                           enum bch_data_type data_type,
-                           struct bch_fs_usage *fs_usage,
                            unsigned journal_seq, unsigned flags)
 {
+       bool gc = flags & BTREE_TRIGGER_GC;
        struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
        struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
        const union bch_extent_entry *entry;
        struct extent_ptr_decoded p;
        struct bch_replicas_padded r;
+       enum bch_data_type data_type = bkey_is_btree_ptr(k.k)
+               ? BCH_DATA_btree
+               : BCH_DATA_user;
+       s64 sectors = bkey_is_btree_ptr(k.k)
+               ? c->opts.btree_node_size
+               : k.k->size;
        s64 dirty_sectors = 0;
        bool stale;
        int ret;
 
+       BUG_ON((flags & (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE)) ==
+              (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE));
+
+       if (flags & BTREE_TRIGGER_OVERWRITE)
+               sectors = -sectors;
+
        r.e.data_type   = data_type;
        r.e.nr_devs     = 0;
        r.e.nr_required = 1;
 
-       BUG_ON(!sectors);
-
        bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
-               s64 disk_sectors = data_type == BCH_DATA_btree
-                       ? sectors
-                       : ptr_disk_sectors_delta(p, offset, sectors, flags);
+               s64 disk_sectors = ptr_disk_sectors(sectors, p);
 
                ret = bch2_mark_pointer(c, k, p, disk_sectors, data_type,
-                                       fs_usage, journal_seq, flags);
+                                       journal_seq, flags);
                if (ret < 0)
                        return ret;
 
@@ -959,8 +944,8 @@ static int bch2_mark_extent(struct bch_fs *c,
 
                if (p.ptr.cached) {
                        if (!stale)
-                               if (update_cached_sectors(c, fs_usage, p.ptr.dev,
-                                                         disk_sectors)) {
+                               if (update_cached_sectors(c, p.ptr.dev, disk_sectors,
+                                                         journal_seq, gc)) {
                                        bch2_fs_fatal_error(c, "bch2_mark_extent(): no replicas entry while updating cached sectors");
                                        return -1;
 
@@ -970,7 +955,7 @@ static int bch2_mark_extent(struct bch_fs *c,
                        r.e.devs[r.e.nr_devs++] = p.ptr.dev;
                } else {
                        ret = bch2_mark_stripe_ptr(c, p.ec, data_type,
-                                       fs_usage, disk_sectors, flags);
+                                       disk_sectors, journal_seq, flags);
                        if (ret)
                                return ret;
 
@@ -984,7 +969,7 @@ static int bch2_mark_extent(struct bch_fs *c,
        }
 
        if (r.e.nr_devs) {
-               if (update_replicas(c, fs_usage, &r.e, dirty_sectors)) {
+               if (update_replicas(c, &r.e, dirty_sectors, journal_seq, gc)) {
                        char buf[200];
 
                        bch2_bkey_val_to_text(&PBUF(buf), c, k);
@@ -997,9 +982,8 @@ static int bch2_mark_extent(struct bch_fs *c,
 }
 
 static int bch2_mark_stripe(struct bch_fs *c,
-                           struct bkey_s_c old, struct bkey_s_c new,
-                           struct bch_fs_usage *fs_usage,
-                           u64 journal_seq, unsigned flags)
+                       struct bkey_s_c old, struct bkey_s_c new,
+                       u64 journal_seq, unsigned flags)
 {
        bool gc = flags & BTREE_TRIGGER_GC;
        size_t idx = new.k->p.offset;
@@ -1060,14 +1044,14 @@ static int bch2_mark_stripe(struct bch_fs *c,
                m->blocks_nonempty = 0;
 
                for (i = 0; i < new_s->nr_blocks; i++) {
-                       ret = mark_stripe_bucket(c, new, i, fs_usage,
-                                                journal_seq, flags);
+                       ret = mark_stripe_bucket(c, new, i, journal_seq, flags);
                        if (ret)
                                return ret;
                }
 
-               if (update_replicas(c, fs_usage, &m->r.e,
-                               ((s64) m->sectors * m->nr_redundant))) {
+               if (update_replicas(c, &m->r.e,
+                                   ((s64) m->sectors * m->nr_redundant),
+                                   journal_seq, gc)) {
                        char buf[200];
 
                        bch2_bkey_val_to_text(&PBUF(buf), c, new);
@@ -1079,13 +1063,47 @@ static int bch2_mark_stripe(struct bch_fs *c,
        return 0;
 }
 
-static int __bch2_mark_reflink_p(struct bch_fs *c,
-                       struct bkey_s_c_reflink_p p,
-                       u64 idx, unsigned sectors,
-                       unsigned front_frag,
-                       unsigned back_frag,
-                       unsigned flags,
-                       size_t *r_idx)
+static int bch2_mark_inode(struct bch_fs *c,
+                       struct bkey_s_c old, struct bkey_s_c new,
+                       u64 journal_seq, unsigned flags)
+{
+       struct bch_fs_usage __percpu *fs_usage;
+
+       preempt_disable();
+       fs_usage = fs_usage_ptr(c, journal_seq, flags & BTREE_TRIGGER_GC);
+       fs_usage->nr_inodes += new.k->type == KEY_TYPE_inode;
+       fs_usage->nr_inodes -= old.k->type == KEY_TYPE_inode;
+       preempt_enable();
+       return 0;
+}
+
+static int bch2_mark_reservation(struct bch_fs *c,
+                       struct bkey_s_c old, struct bkey_s_c new,
+                       u64 journal_seq, unsigned flags)
+{
+       struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
+       struct bch_fs_usage __percpu *fs_usage;
+       unsigned replicas = bkey_s_c_to_reservation(k).v->nr_replicas;
+       s64 sectors = (s64) k.k->size;
+
+       if (flags & BTREE_TRIGGER_OVERWRITE)
+               sectors = -sectors;
+       sectors *= replicas;
+
+       preempt_disable();
+       fs_usage = fs_usage_ptr(c, journal_seq, flags & BTREE_TRIGGER_GC);
+       replicas = clamp_t(unsigned, replicas, 1,
+                          ARRAY_SIZE(fs_usage->persistent_reserved));
+
+       fs_usage->reserved                              += sectors;
+       fs_usage->persistent_reserved[replicas - 1]     += sectors;
+       preempt_enable();
+
+       return 0;
+}
+
+static s64 __bch2_mark_reflink_p(struct bch_fs *c, struct bkey_s_c_reflink_p p,
+                                u64 idx, unsigned flags, size_t *r_idx)
 {
        struct reflink_gc *r;
        int add = !(flags & BTREE_TRIGGER_OVERWRITE) ? 1 : -1;
@@ -1096,7 +1114,7 @@ static int __bch2_mark_reflink_p(struct bch_fs *c,
                r = genradix_ptr(&c->reflink_gc_table, *r_idx);
                BUG_ON(!r);
 
-               if (r->offset > idx)
+               if (idx < r->offset)
                        break;
                (*r_idx)++;
        }
@@ -1104,7 +1122,7 @@ static int __bch2_mark_reflink_p(struct bch_fs *c,
        BUG_ON((s64) r->refcount + add < 0);
 
        r->refcount += add;
-       return min_t(u64, sectors, r->offset - idx);
+       return r->offset - idx;
 not_found:
        bch2_fs_inconsistent(c,
                "%llu:%llu len %u points to nonexistent indirect extent %llu",
@@ -1114,22 +1132,19 @@ not_found:
 }
 
 static int bch2_mark_reflink_p(struct bch_fs *c,
-                              struct bkey_s_c_reflink_p p, unsigned offset,
-                              s64 sectors, unsigned flags)
+                       struct bkey_s_c old, struct bkey_s_c new,
+                       u64 journal_seq, unsigned flags)
 {
-       u64 idx = le64_to_cpu(p.v->idx) + offset;
+       struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
+       struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k);
        struct reflink_gc *ref;
        size_t l, r, m;
-       unsigned front_frag, back_frag;
+       u64 idx = le64_to_cpu(p.v->idx);
+       unsigned sectors = p.k->size;
        s64 ret = 0;
 
-       if (sectors < 0)
-               sectors = -sectors;
-
-       BUG_ON(offset + sectors > p.k->size);
-
-       front_frag = offset;
-       back_frag = offset + sectors;
+       BUG_ON((flags & (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE)) ==
+              (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE));
 
        l = 0;
        r = c->reflink_gc_nr;
@@ -1144,11 +1159,11 @@ static int bch2_mark_reflink_p(struct bch_fs *c,
        }
 
        while (sectors) {
-               ret = __bch2_mark_reflink_p(c, p, idx, sectors,
-                               front_frag, back_frag, flags, &l);
+               ret = __bch2_mark_reflink_p(c, p, idx, flags, &l);
                if (ret < 0)
                        return ret;
 
+               ret = min_t(s64, ret, sectors);
                idx     += ret;
                sectors -= ret;
        }
@@ -1159,99 +1174,55 @@ static int bch2_mark_reflink_p(struct bch_fs *c,
 static int bch2_mark_key_locked(struct bch_fs *c,
                   struct bkey_s_c old,
                   struct bkey_s_c new,
-                  unsigned offset, s64 sectors,
-                  struct bch_fs_usage *fs_usage,
                   u64 journal_seq, unsigned flags)
 {
        struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
-       int ret = 0;
 
        BUG_ON(!(flags & (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE)));
 
-       preempt_disable();
-
-       if (!fs_usage || (flags & BTREE_TRIGGER_GC))
-               fs_usage = fs_usage_ptr(c, journal_seq,
-                                       flags & BTREE_TRIGGER_GC);
-
        switch (k.k->type) {
        case KEY_TYPE_alloc:
        case KEY_TYPE_alloc_v2:
-               ret = bch2_mark_alloc(c, old, new, fs_usage, journal_seq, flags);
-               break;
+               return bch2_mark_alloc(c, old, new, journal_seq, flags);
        case KEY_TYPE_btree_ptr:
        case KEY_TYPE_btree_ptr_v2:
-               sectors = !(flags & BTREE_TRIGGER_OVERWRITE)
-                       ?  c->opts.btree_node_size
-                       : -c->opts.btree_node_size;
-
-               ret = bch2_mark_extent(c, old, new, offset, sectors,
-                               BCH_DATA_btree, fs_usage, journal_seq, flags);
-               break;
        case KEY_TYPE_extent:
        case KEY_TYPE_reflink_v:
-               ret = bch2_mark_extent(c, old, new, offset, sectors,
-                               BCH_DATA_user, fs_usage, journal_seq, flags);
-               break;
+               return bch2_mark_extent(c, old, new, journal_seq, flags);
        case KEY_TYPE_stripe:
-               ret = bch2_mark_stripe(c, old, new, fs_usage, journal_seq, flags);
-               break;
+               return bch2_mark_stripe(c, old, new, journal_seq, flags);
        case KEY_TYPE_inode:
-               fs_usage->nr_inodes += new.k->type == KEY_TYPE_inode;
-               fs_usage->nr_inodes -= old.k->type == KEY_TYPE_inode;
-               break;
-       case KEY_TYPE_reservation: {
-               unsigned replicas = bkey_s_c_to_reservation(k).v->nr_replicas;
-
-               sectors *= replicas;
-               replicas = clamp_t(unsigned, replicas, 1,
-                                  ARRAY_SIZE(fs_usage->persistent_reserved));
-
-               fs_usage->reserved                              += sectors;
-               fs_usage->persistent_reserved[replicas - 1]     += sectors;
-               break;
-       }
+               return bch2_mark_inode(c, old, new, journal_seq, flags);
+       case KEY_TYPE_reservation:
+               return bch2_mark_reservation(c, old, new, journal_seq, flags);
        case KEY_TYPE_reflink_p:
-               ret = bch2_mark_reflink_p(c, bkey_s_c_to_reflink_p(k),
-                                         offset, sectors, flags);
-               break;
+               return bch2_mark_reflink_p(c, old, new, journal_seq, flags);
+       default:
+               return 0;
        }
-
-       preempt_enable();
-
-       return ret;
 }
 
-int bch2_mark_key(struct bch_fs *c, struct bkey_s_c new,
-                 unsigned offset, s64 sectors,
-                 struct bch_fs_usage *fs_usage,
-                 u64 journal_seq, unsigned flags)
+int bch2_mark_key(struct bch_fs *c, struct bkey_s_c new, unsigned flags)
 {
-       struct bkey deleted;
+       struct bkey deleted = KEY(0, 0, 0);
        struct bkey_s_c old = (struct bkey_s_c) { &deleted, NULL };
        int ret;
 
-       bkey_init(&deleted);
-
        percpu_down_read(&c->mark_lock);
-       ret = bch2_mark_key_locked(c, old, new, offset, sectors,
-                                  fs_usage, journal_seq,
-                                  BTREE_TRIGGER_INSERT|flags);
+       ret = bch2_mark_key_locked(c, old, new, 0, flags);
        percpu_up_read(&c->mark_lock);
 
        return ret;
 }
 
-int bch2_mark_update(struct btree_trans *trans,
-                    struct btree_iter *iter,
-                    struct bkey_i *new,
-                    struct bch_fs_usage *fs_usage,
-                    unsigned flags)
+int bch2_mark_update(struct btree_trans *trans, struct btree_iter *iter,
+                    struct bkey_i *new, unsigned flags)
 {
        struct bch_fs           *c = trans->c;
+       struct bkey             _deleted = KEY(0, 0, 0);
+       struct bkey_s_c         deleted = (struct bkey_s_c) { &_deleted, NULL };
        struct bkey_s_c         old;
-       struct bkey             unpacked;
-       int ret = 0;
+       int iter_flags, ret;
 
        if (unlikely(flags & BTREE_TRIGGER_NORUN))
                return 0;
@@ -1259,87 +1230,36 @@ int bch2_mark_update(struct btree_trans *trans,
        if (!btree_node_type_needs_gc(iter->btree_id))
                return 0;
 
-       bkey_init(&unpacked);
-       old = (struct bkey_s_c) { &unpacked, NULL };
+       if (likely(!(iter->flags & BTREE_ITER_CACHED_NOFILL))) {
+               iter_flags = iter->flags & BTREE_ITER_WITH_UPDATES;
+               iter->flags &= ~BTREE_ITER_WITH_UPDATES;
 
-       if (!btree_node_type_is_extents(iter->btree_id)) {
-               /* iterators should be uptodate, shouldn't get errors here: */
-               if (btree_iter_type(iter) != BTREE_ITER_CACHED) {
-                       old = bch2_btree_iter_peek_slot(iter);
-                       BUG_ON(bkey_err(old));
-               } else {
-                       struct bkey_cached *ck = (void *) iter->l[0].b;
+               old = bch2_btree_iter_peek_slot(iter);
+               iter->flags |= iter_flags;
 
-                       if (ck->valid)
-                               old = bkey_i_to_s_c(ck->k);
-               }
+               ret = bkey_err(old);
+               if (ret)
+                       return ret;
+       } else {
+               /*
+                * If BTREE_ITER_CACHED_NOFILL was used, we better not be
+                * running triggers that do anything on removal (alloc btree):
+                */
+               old = deleted;
+       }
 
-               if (old.k->type == new->k.type) {
-                       bch2_mark_key_locked(c, old, bkey_i_to_s_c(new), 0, 0,
-                               fs_usage, trans->journal_res.seq,
+       if (old.k->type == new->k.type &&
+           ((1U << old.k->type) & BTREE_TRIGGER_WANTS_OLD_AND_NEW)) {
+               ret   = bch2_mark_key_locked(c, old, bkey_i_to_s_c(new),
+                               trans->journal_res.seq,
                                BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE|flags);
-
-               } else {
-                       bch2_mark_key_locked(c, old, bkey_i_to_s_c(new), 0, 0,
-                               fs_usage, trans->journal_res.seq,
-                               BTREE_TRIGGER_INSERT|flags);
-                       bch2_mark_key_locked(c, old, bkey_i_to_s_c(new), 0, 0,
-                               fs_usage, trans->journal_res.seq,
-                               BTREE_TRIGGER_OVERWRITE|flags);
-               }
        } else {
-               struct btree_iter *copy;
-
-               BUG_ON(btree_iter_type(iter) == BTREE_ITER_CACHED);
-               bch2_mark_key_locked(c, old, bkey_i_to_s_c(new),
-                       0, new->k.size,
-                       fs_usage, trans->journal_res.seq,
-                       BTREE_TRIGGER_INSERT|flags);
-
-               copy = bch2_trans_copy_iter(trans, iter);
-
-               for_each_btree_key_continue(copy, 0, old, ret) {
-                       unsigned offset = 0;
-                       s64 sectors = -((s64) old.k->size);
-
-                       flags |= BTREE_TRIGGER_OVERWRITE;
-
-                       if (bkey_cmp(new->k.p, bkey_start_pos(old.k)) <= 0)
-                               break;
-
-                       switch (bch2_extent_overlap(&new->k, old.k)) {
-                       case BCH_EXTENT_OVERLAP_ALL:
-                               offset = 0;
-                               sectors = -((s64) old.k->size);
-                               break;
-                       case BCH_EXTENT_OVERLAP_BACK:
-                               offset = bkey_start_offset(&new->k) -
-                                       bkey_start_offset(old.k);
-                               sectors = bkey_start_offset(&new->k) -
-                                       old.k->p.offset;
-                               break;
-                       case BCH_EXTENT_OVERLAP_FRONT:
-                               offset = 0;
-                               sectors = bkey_start_offset(old.k) -
-                                       new->k.p.offset;
-                               break;
-                       case BCH_EXTENT_OVERLAP_MIDDLE:
-                               offset = bkey_start_offset(&new->k) -
-                                       bkey_start_offset(old.k);
-                               sectors = -((s64) new->k.size);
-                               flags |= BTREE_TRIGGER_OVERWRITE_SPLIT;
-                               break;
-                       }
-
-                       BUG_ON(sectors >= 0);
-
-                       ret = bch2_mark_key_locked(c, old, bkey_i_to_s_c(new),
-                                       offset, sectors, fs_usage,
-                                       trans->journal_res.seq, flags) ?: 1;
-                       if (ret <= 0)
-                               break;
-               }
-               bch2_trans_iter_put(trans, copy);
+               ret   = bch2_mark_key_locked(c, deleted, bkey_i_to_s_c(new),
+                               trans->journal_res.seq,
+                               BTREE_TRIGGER_INSERT|flags) ?:
+                       bch2_mark_key_locked(c, old, deleted,
+                               trans->journal_res.seq,
+                               BTREE_TRIGGER_OVERWRITE|flags);
        }
 
        return ret;
@@ -1416,7 +1336,7 @@ void bch2_trans_fs_usage_apply(struct btree_trans *trans,
                        added += d->delta;
                }
 
-               BUG_ON(update_replicas(c, dst, &d->r, d->delta));
+               BUG_ON(__update_replicas(c, dst, &d->r, d->delta));
        }
 
        dst->nr_inodes += deltas->nr_inodes;
@@ -1433,7 +1353,14 @@ void bch2_trans_fs_usage_apply(struct btree_trans *trans,
         */
        should_not_have_added = added - (s64) disk_res_sectors;
        if (unlikely(should_not_have_added > 0)) {
-               atomic64_sub(should_not_have_added, &c->sectors_available);
+               u64 old, new, v = atomic64_read(&c->sectors_available);
+
+               do {
+                       old = v;
+                       new = max_t(s64, 0, old - should_not_have_added);
+               } while ((v = atomic64_cmpxchg(&c->sectors_available,
+                                              old, new)) != old);
+
                added -= should_not_have_added;
                warn = true;
        }
@@ -1598,31 +1525,38 @@ err:
 }
 
 static int bch2_trans_mark_extent(struct btree_trans *trans,
-                       struct bkey_s_c k, unsigned offset,
-                       s64 sectors, unsigned flags,
-                       enum bch_data_type data_type)
+                       struct bkey_s_c k, unsigned flags)
 {
+       struct bch_fs *c = trans->c;
        struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
        const union bch_extent_entry *entry;
        struct extent_ptr_decoded p;
        struct bch_replicas_padded r;
+       enum bch_data_type data_type = bkey_is_btree_ptr(k.k)
+               ? BCH_DATA_btree
+               : BCH_DATA_user;
+       s64 sectors = bkey_is_btree_ptr(k.k)
+               ? c->opts.btree_node_size
+               : k.k->size;
        s64 dirty_sectors = 0;
        bool stale;
        int ret;
 
+       BUG_ON((flags & (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE)) ==
+              (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE));
+
+       if (flags & BTREE_TRIGGER_OVERWRITE)
+               sectors = -sectors;
+
        r.e.data_type   = data_type;
        r.e.nr_devs     = 0;
        r.e.nr_required = 1;
 
-       BUG_ON(!sectors);
-
        bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
-               s64 disk_sectors = data_type == BCH_DATA_btree
-                       ? sectors
-                       : ptr_disk_sectors_delta(p, offset, sectors, flags);
+               s64 disk_sectors = ptr_disk_sectors(sectors, p);
 
-               ret = bch2_trans_mark_pointer(trans, k, p, disk_sectors,
-                                             data_type);
+               ret = bch2_trans_mark_pointer(trans, k, p,
+                                       disk_sectors, data_type);
                if (ret < 0)
                        return ret;
 
@@ -1758,10 +1692,49 @@ static int bch2_trans_mark_stripe(struct btree_trans *trans,
        return ret;
 }
 
+static int bch2_trans_mark_inode(struct btree_trans *trans,
+                                struct bkey_s_c old,
+                                struct bkey_s_c new,
+                                unsigned flags)
+{
+       int nr = (new.k->type == KEY_TYPE_inode) -
+               (old.k->type == KEY_TYPE_inode);
+
+       if (nr) {
+               struct replicas_delta_list *d =
+                       replicas_deltas_realloc(trans, 0);
+               d->nr_inodes += nr;
+       }
+
+       return 0;
+}
+
+static int bch2_trans_mark_reservation(struct btree_trans *trans,
+                                      struct bkey_s_c k, unsigned flags)
+{
+       unsigned replicas = bkey_s_c_to_reservation(k).v->nr_replicas;
+       s64 sectors = (s64) k.k->size;
+       struct replicas_delta_list *d;
+
+       BUG_ON((flags & (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE)) ==
+              (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE));
+
+       if (flags & BTREE_TRIGGER_OVERWRITE)
+               sectors = -sectors;
+       sectors *= replicas;
+
+       d = replicas_deltas_realloc(trans, 0);
+
+       replicas = clamp_t(unsigned, replicas, 1,
+                          ARRAY_SIZE(d->persistent_reserved));
+
+       d->persistent_reserved[replicas - 1] += sectors;
+       return 0;
+}
+
 static int __bch2_trans_mark_reflink_p(struct btree_trans *trans,
                        struct bkey_s_c_reflink_p p,
-                       u64 idx, unsigned sectors,
-                       unsigned flags)
+                       u64 idx, unsigned flags)
 {
        struct bch_fs *c = trans->c;
        struct btree_iter *iter;
@@ -1779,8 +1752,6 @@ static int __bch2_trans_mark_reflink_p(struct btree_trans *trans,
        if (ret)
                goto err;
 
-       sectors = min_t(u64, sectors, k.k->p.offset - idx);
-
        n = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
        ret = PTR_ERR_OR_ZERO(n);
        if (ret)
@@ -1806,34 +1777,31 @@ 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;
 
-       ret = sectors;
+       ret = k.k->p.offset - idx;
 err:
        bch2_trans_iter_put(trans, iter);
        return ret;
 }
 
 static int bch2_trans_mark_reflink_p(struct btree_trans *trans,
-                       struct bkey_s_c_reflink_p p, unsigned offset,
-                       s64 sectors, unsigned flags)
+                                    struct bkey_s_c k, unsigned flags)
 {
-       u64 idx = le64_to_cpu(p.v->idx) + offset;
+       struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k);
+       u64 idx = le64_to_cpu(p.v->idx);
+       unsigned sectors = p.k->size;
        s64 ret = 0;
 
-       if (sectors < 0)
-               sectors = -sectors;
-
-       BUG_ON(offset || sectors != p.k->size);
-
        while (sectors) {
-               ret = __bch2_trans_mark_reflink_p(trans, p, idx, sectors, flags);
+               ret = __bch2_trans_mark_reflink_p(trans, p, idx, flags);
                if (ret < 0)
                        return ret;
 
+               ret = min_t(s64, ret, sectors);
                idx     += ret;
                sectors -= ret;
        }
@@ -1841,59 +1809,27 @@ static int bch2_trans_mark_reflink_p(struct btree_trans *trans,
        return 0;
 }
 
-int bch2_trans_mark_key(struct btree_trans *trans,
-                       struct bkey_s_c old,
-                       struct bkey_s_c new,
-                       unsigned offset, s64 sectors, unsigned flags)
+int bch2_trans_mark_key(struct btree_trans *trans, struct bkey_s_c old,
+                       struct bkey_s_c new, unsigned flags)
 {
-       struct bch_fs *c = trans->c;
        struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
-       struct replicas_delta_list *d;
 
        BUG_ON(!(flags & (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE)));
 
        switch (k.k->type) {
        case KEY_TYPE_btree_ptr:
        case KEY_TYPE_btree_ptr_v2:
-               sectors = !(flags & BTREE_TRIGGER_OVERWRITE)
-                       ?  c->opts.btree_node_size
-                       : -c->opts.btree_node_size;
-
-               return bch2_trans_mark_extent(trans, k, offset, sectors,
-                                             flags, BCH_DATA_btree);
        case KEY_TYPE_extent:
        case KEY_TYPE_reflink_v:
-               return bch2_trans_mark_extent(trans, k, offset, sectors,
-                                             flags, BCH_DATA_user);
+               return bch2_trans_mark_extent(trans, k, flags);
        case KEY_TYPE_stripe:
                return bch2_trans_mark_stripe(trans, old, new, flags);
-       case KEY_TYPE_inode: {
-               int nr = (new.k->type == KEY_TYPE_inode) -
-                        (old.k->type == KEY_TYPE_inode);
-
-               if (nr) {
-                       d = replicas_deltas_realloc(trans, 0);
-                       d->nr_inodes += nr;
-               }
-
-               return 0;
-       }
-       case KEY_TYPE_reservation: {
-               unsigned replicas = bkey_s_c_to_reservation(k).v->nr_replicas;
-
-               d = replicas_deltas_realloc(trans, 0);
-
-               sectors *= replicas;
-               replicas = clamp_t(unsigned, replicas, 1,
-                                  ARRAY_SIZE(d->persistent_reserved));
-
-               d->persistent_reserved[replicas - 1] += sectors;
-               return 0;
-       }
+       case KEY_TYPE_inode:
+               return bch2_trans_mark_inode(trans, old, new, flags);
+       case KEY_TYPE_reservation:
+               return bch2_trans_mark_reservation(trans, k, flags);
        case KEY_TYPE_reflink_p:
-               return bch2_trans_mark_reflink_p(trans,
-                                       bkey_s_c_to_reflink_p(k),
-                                       offset, sectors, flags);
+               return bch2_trans_mark_reflink_p(trans, k, flags);
        default:
                return 0;
        }
@@ -1904,8 +1840,10 @@ int bch2_trans_mark_update(struct btree_trans *trans,
                           struct bkey_i *new,
                           unsigned flags)
 {
-       struct bkey_s_c old;
-       int ret;
+       struct bkey             _deleted = KEY(0, 0, 0);
+       struct bkey_s_c         deleted = (struct bkey_s_c) { &_deleted, NULL };
+       struct bkey_s_c         old;
+       int iter_flags, ret;
 
        if (unlikely(flags & BTREE_TRIGGER_NORUN))
                return 0;
@@ -1913,26 +1851,33 @@ int bch2_trans_mark_update(struct btree_trans *trans,
        if (!btree_node_type_needs_gc(iter->btree_id))
                return 0;
 
-       if (btree_iter_type(iter) != BTREE_ITER_CACHED) {
+
+       if (likely(!(iter->flags & BTREE_ITER_CACHED_NOFILL))) {
+               iter_flags = iter->flags & BTREE_ITER_WITH_UPDATES;
+               iter->flags &= ~BTREE_ITER_WITH_UPDATES;
+
                old = bch2_btree_iter_peek_slot(iter);
+               iter->flags |= iter_flags;
+
                ret = bkey_err(old);
                if (ret)
                        return ret;
        } else {
-               struct bkey_cached *ck = (void *) iter->l[0].b;
-
-               BUG_ON(!ck->valid);
-               old = bkey_i_to_s_c(ck->k);
+               /*
+                * If BTREE_ITER_CACHED_NOFILL was used, we better not be
+                * running triggers that do anything on removal (alloc btree):
+                */
+               old = deleted;
        }
 
        if (old.k->type == new->k.type &&
-           !btree_node_type_is_extents(iter->btree_id)) {
-               ret   = bch2_trans_mark_key(trans, old, bkey_i_to_s_c(new), 0, 0,
+           ((1U << old.k->type) & BTREE_TRIGGER_WANTS_OLD_AND_NEW)) {
+               ret   = bch2_trans_mark_key(trans, old, bkey_i_to_s_c(new),
                                BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE|flags);
        } else {
-               ret   = bch2_trans_mark_key(trans, old, bkey_i_to_s_c(new), 0, new->k.size,
+               ret   = bch2_trans_mark_key(trans, deleted, bkey_i_to_s_c(new),
                                BTREE_TRIGGER_INSERT|flags) ?:
-                       bch2_trans_mark_key(trans, old, bkey_i_to_s_c(new), 0, -((s64) old.k->size),
+                       bch2_trans_mark_key(trans, old, deleted,
                                BTREE_TRIGGER_OVERWRITE|flags);
        }
 
index 04a2a9310cdd9e9fc4d4ceb7a003d618540d7205..0f544b62fc908f3fea5fd54c866741277d89dbf6 100644 (file)
@@ -125,20 +125,6 @@ static inline u8 ptr_stale(struct bch_dev *ca,
        return gen_after(ptr_bucket_mark(ca, ptr).gen, ptr->gen);
 }
 
-static inline s64 __ptr_disk_sectors(struct extent_ptr_decoded p,
-                                    unsigned live_size)
-{
-       return live_size && p.crc.compression_type
-               ? max(1U, DIV_ROUND_UP(live_size * p.crc.compressed_size,
-                                      p.crc.uncompressed_size))
-               : live_size;
-}
-
-static inline s64 ptr_disk_sectors(struct extent_ptr_decoded p)
-{
-       return __ptr_disk_sectors(p, p.crc.live_size);
-}
-
 /* bucket gc marks */
 
 static inline unsigned bucket_sectors_used(struct bucket_mark mark)
@@ -240,14 +226,13 @@ void bch2_mark_metadata_bucket(struct bch_fs *, struct bch_dev *,
                               size_t, enum bch_data_type, unsigned,
                               struct gc_pos, unsigned);
 
-int bch2_mark_key(struct bch_fs *, struct bkey_s_c, unsigned,
-                 s64, struct bch_fs_usage *, u64, unsigned);
+int bch2_mark_key(struct bch_fs *, struct bkey_s_c, unsigned);
 
 int bch2_mark_update(struct btree_trans *, struct btree_iter *,
-                    struct bkey_i *, struct bch_fs_usage *, unsigned);
+                    struct bkey_i *, unsigned);
 
-int bch2_trans_mark_key(struct btree_trans *, struct bkey_s_c, struct bkey_s_c,
-                       unsigned, s64, unsigned);
+int bch2_trans_mark_key(struct btree_trans *, struct bkey_s_c,
+                       struct bkey_s_c, unsigned);
 int bch2_trans_mark_update(struct btree_trans *, struct btree_iter *iter,
                           struct bkey_i *insert, unsigned);
 void bch2_trans_fs_usage_apply(struct btree_trans *, struct replicas_delta_list *);
index 48f9232e61ebfcd6b6255d108098ddc43a939abb..328e0429b5d77329d04ed061ebade45536648fcd 100644 (file)
@@ -863,7 +863,8 @@ static int ec_stripe_update_ptrs(struct bch_fs *c,
                extent_stripe_ptr_add(e, s, ec_ptr, block);
 
                bch2_btree_iter_set_pos(iter, bkey_start_pos(&sk.k->k));
-               ret   = bch2_trans_update(&trans, iter, sk.k, 0) ?:
+               ret   = bch2_btree_iter_traverse(iter) ?:
+                       bch2_trans_update(&trans, iter, sk.k, 0) ?:
                        bch2_trans_commit(&trans, NULL, NULL,
                                        BTREE_INSERT_NOFAIL);
                if (ret == -EINTR)
@@ -1633,7 +1634,8 @@ static int bch2_stripes_read_fn(struct bch_fs *c, struct bkey_s_c k)
 
        if (k.k->type == KEY_TYPE_stripe)
                ret = __ec_stripe_mem_alloc(c, k.k->p.offset, GFP_KERNEL) ?:
-                       bch2_mark_key(c, k, 0, 0, NULL, 0,
+                       bch2_mark_key(c, k,
+                                     BTREE_TRIGGER_INSERT|
                                      BTREE_TRIGGER_NOATOMIC);
 
        return ret;
index 90c3b986c264020253a2938941c6c9e6b1ae9bdf..2cea694575e99a4df6c4af282c76cbc77230f06e 100644 (file)
@@ -111,6 +111,7 @@ found:
        list_move(&s->list, &c->fsck_errors);
        s->nr++;
        if (c->opts.ratelimit_errors &&
+           !(flags & FSCK_NO_RATELIMIT) &&
            s->nr >= FSCK_ERR_RATELIMIT_NR) {
                if (s->nr == FSCK_ERR_RATELIMIT_NR)
                        suppressing = true;
index d8cd19b3f63c83c73b675b54ed767607eb638cf9..986938298adc4d4e8e5e35c2a7555e2f338741c6 100644 (file)
@@ -104,6 +104,7 @@ struct fsck_err_state {
 #define FSCK_CAN_FIX           (1 << 0)
 #define FSCK_CAN_IGNORE                (1 << 1)
 #define FSCK_NEED_FSCK         (1 << 2)
+#define FSCK_NO_RATELIMIT      (1 << 3)
 
 __printf(3, 4) __cold
 enum fsck_err_ret bch2_fsck_err(struct bch_fs *,
index ef4aaf1c30ed50cc909147543c082271bc54f130..4a8dd085f7fb80b2650f5bab433cae077343d1e3 100644 (file)
@@ -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(): */
index 3f6224f75ce82f7a8a25fe75796758e524af968f..43cef0a3bdf3870f47afc849f5f54700e3664824 100644 (file)
@@ -426,6 +426,17 @@ void bch2_extent_crc_append(struct bkey_i *,
 
 /* Generic code for keys with pointers: */
 
+static inline bool bkey_is_btree_ptr(const struct bkey *k)
+{
+       switch (k->type) {
+       case KEY_TYPE_btree_ptr:
+       case KEY_TYPE_btree_ptr_v2:
+               return true;
+       default:
+               return false;
+       }
+}
+
 static inline bool bkey_extent_is_direct_data(const struct bkey *k)
 {
        switch (k->type) {
index 00a63fecb976e6da858c1adc64de69d40fcf3710..60c54438074e711ba2f9fcc1a34279dbe79a0ad8 100644 (file)
@@ -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);
index 4ec3360b6703ce835de6efda4f5439874b8994fa..0fbfa622586ecf14f36cfe559032ad28b4e1b892 100644 (file)
@@ -2028,7 +2028,9 @@ ssize_t bch2_direct_write(struct kiocb *req, struct iov_iter *iter)
        }
 
        bio = bio_alloc_bioset(GFP_KERNEL,
-                              iov_iter_npages(iter, BIO_MAX_VECS),
+                              iov_iter_is_bvec(iter)
+                              ? 0
+                              : iov_iter_npages(iter, BIO_MAX_VECS),
                               &c->dio_write_bioset);
        dio = container_of(bio, struct dio_write, op.wbio.bio);
        init_completion(&dio->done);
@@ -2252,11 +2254,11 @@ static int bch2_truncate_page(struct bch_inode_info *inode, loff_t from)
                                    from, round_up(from, PAGE_SIZE));
 }
 
-static int bch2_extend(struct bch_inode_info *inode,
+static int bch2_extend(struct user_namespace *mnt_userns,
+                      struct bch_inode_info *inode,
                       struct bch_inode_unpacked *inode_u,
                       struct iattr *iattr)
 {
-       struct bch_fs *c = inode->v.i_sb->s_fs_info;
        struct address_space *mapping = inode->v.i_mapping;
        int ret;
 
@@ -2270,25 +2272,15 @@ static int bch2_extend(struct bch_inode_info *inode,
                return ret;
 
        truncate_setsize(&inode->v, iattr->ia_size);
-       /* ATTR_MODE will never be set here, ns argument isn't needed: */
-       setattr_copy(NULL, &inode->v, iattr);
-
-       mutex_lock(&inode->ei_update_lock);
-       ret = bch2_write_inode_size(c, inode, inode->v.i_size,
-                                   ATTR_MTIME|ATTR_CTIME);
-       mutex_unlock(&inode->ei_update_lock);
 
-       return ret;
+       return bch2_setattr_nonsize(mnt_userns, inode, iattr);
 }
 
 static int bch2_truncate_finish_fn(struct bch_inode_info *inode,
                                   struct bch_inode_unpacked *bi,
                                   void *p)
 {
-       struct bch_fs *c = inode->v.i_sb->s_fs_info;
-
        bi->bi_flags &= ~BCH_INODE_I_SIZE_DIRTY;
-       bi->bi_mtime = bi->bi_ctime = bch2_current_time(c);
        return 0;
 }
 
@@ -2302,7 +2294,8 @@ static int bch2_truncate_start_fn(struct bch_inode_info *inode,
        return 0;
 }
 
-int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
+int bch2_truncate(struct user_namespace *mnt_userns,
+                 struct bch_inode_info *inode, struct iattr *iattr)
 {
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
        struct address_space *mapping = inode->v.i_mapping;
@@ -2313,6 +2306,18 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
        s64 i_sectors_delta = 0;
        int ret = 0;
 
+       /*
+        * Don't update timestamps if we're not doing anything:
+        */
+       if (iattr->ia_size == inode->v.i_size)
+               return 0;
+
+       if (!(iattr->ia_valid & ATTR_MTIME))
+               ktime_get_coarse_real_ts64(&iattr->ia_mtime);
+       if (!(iattr->ia_valid & ATTR_CTIME))
+               ktime_get_coarse_real_ts64(&iattr->ia_ctime);
+       iattr->ia_valid |= ATTR_MTIME|ATTR_CTIME;
+
        inode_dio_wait(&inode->v);
        bch2_pagecache_block_get(&inode->ei_pagecache_lock);
 
@@ -2342,10 +2347,12 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
                inode->v.i_size < inode_u.bi_size);
 
        if (iattr->ia_size > inode->v.i_size) {
-               ret = bch2_extend(inode, &inode_u, iattr);
+               ret = bch2_extend(mnt_userns, inode, &inode_u, iattr);
                goto err;
        }
 
+       iattr->ia_valid &= ~ATTR_SIZE;
+
        ret = bch2_truncate_page(inode, iattr->ia_size);
        if (unlikely(ret))
                goto err;
@@ -2389,13 +2396,11 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
        if (unlikely(ret))
                goto err;
 
-       /* ATTR_MODE will never be set here, ns argument isn't needed: */
-       setattr_copy(NULL, &inode->v, iattr);
-
        mutex_lock(&inode->ei_update_lock);
-       ret = bch2_write_inode(c, inode, bch2_truncate_finish_fn, NULL,
-                              ATTR_MTIME|ATTR_CTIME);
+       ret = bch2_write_inode(c, inode, bch2_truncate_finish_fn, NULL, 0);
        mutex_unlock(&inode->ei_update_lock);
+
+       ret = bch2_setattr_nonsize(mnt_userns, inode, iattr);
 err:
        bch2_pagecache_block_put(&inode->ei_pagecache_lock);
        return ret;
@@ -2611,7 +2616,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,
index 2537a3d25ede1dd585f284353c8e2d58d1d21a78..b24efeaf343e75279507009c6f9147916ad5c5c6 100644 (file)
@@ -31,7 +31,8 @@ ssize_t bch2_write_iter(struct kiocb *, struct iov_iter *);
 
 int bch2_fsync(struct file *, loff_t, loff_t, int);
 
-int bch2_truncate(struct bch_inode_info *, struct iattr *);
+int bch2_truncate(struct user_namespace *,
+                 struct bch_inode_info *, struct iattr *);
 long bch2_fallocate_dispatch(struct file *, int, loff_t, loff_t);
 
 loff_t bch2_remap_file_range(struct file *, loff_t, struct file *,
index 07e1edcf7eae39ff70ab90f2be8c360fa0e027d5..d2133053fbd3cf694a3530e25ebc8578cd02259c 100644 (file)
@@ -647,10 +647,10 @@ err:
        return ret;
 }
 
-void bch2_setattr_copy(struct user_namespace *mnt_userns,
-                      struct bch_inode_info *inode,
-                      struct bch_inode_unpacked *bi,
-                      struct iattr *attr)
+static void bch2_setattr_copy(struct user_namespace *mnt_userns,
+                             struct bch_inode_info *inode,
+                             struct bch_inode_unpacked *bi,
+                             struct iattr *attr)
 {
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
        unsigned int ia_valid = attr->ia_valid;
@@ -660,6 +660,9 @@ void bch2_setattr_copy(struct user_namespace *mnt_userns,
        if (ia_valid & ATTR_GID)
                bi->bi_gid = from_kgid(mnt_userns, attr->ia_gid);
 
+       if (ia_valid & ATTR_SIZE)
+               bi->bi_size = attr->ia_size;
+
        if (ia_valid & ATTR_ATIME)
                bi->bi_atime = timespec_to_bch2_time(c, attr->ia_atime);
        if (ia_valid & ATTR_MTIME)
@@ -680,9 +683,9 @@ void bch2_setattr_copy(struct user_namespace *mnt_userns,
        }
 }
 
-static int bch2_setattr_nonsize(struct user_namespace *mnt_userns,
-                               struct bch_inode_info *inode,
-                               struct iattr *attr)
+int bch2_setattr_nonsize(struct user_namespace *mnt_userns,
+                        struct bch_inode_info *inode,
+                        struct iattr *attr)
 {
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
        struct bch_qid qid;
@@ -806,7 +809,7 @@ static int bch2_setattr(struct user_namespace *mnt_userns,
                return ret;
 
        return iattr->ia_valid & ATTR_SIZE
-               ? bch2_truncate(inode, iattr)
+               ? bch2_truncate(mnt_userns, inode, iattr)
                : bch2_setattr_nonsize(mnt_userns, inode, iattr);
 }
 
index 2d82ed7dd740f8dab4d233365f90e2999cbbb41d..36cc6ba2d644f3c10b3ef3c2428bb21b6e84ed43 100644 (file)
@@ -167,6 +167,10 @@ void bch2_inode_update_after_write(struct bch_fs *,
 int __must_check bch2_write_inode(struct bch_fs *, struct bch_inode_info *,
                                  inode_set_fn, void *, unsigned);
 
+int bch2_setattr_nonsize(struct user_namespace *,
+                        struct bch_inode_info *,
+                        struct iattr *);
+
 void bch2_vfs_exit(void);
 int bch2_vfs_init(void);
 
index 89a130d9c5373c5f668245a395b3226c8388073f..7ea1a41ac637fa02a1160b10ee929280cd36d73f 100644 (file)
@@ -78,7 +78,8 @@ static int __write_inode(struct btree_trans *trans,
                bch2_trans_get_iter(trans, BTREE_ID_inodes,
                                    SPOS(0, inode->bi_inum, snapshot),
                                    BTREE_ITER_INTENT);
-       int ret = bch2_inode_write(trans, inode_iter, inode);
+       int ret = bch2_btree_iter_traverse(inode_iter) ?:
+               bch2_inode_write(trans, inode_iter, inode);
        bch2_trans_iter_put(trans, inode_iter);
        return ret;
 }
@@ -305,7 +306,8 @@ static int hash_redo_key(struct btree_trans *trans,
 
        bkey_init(&delete->k);
        delete->k.p = k_iter->pos;
-       return  bch2_trans_update(trans, k_iter, delete, 0) ?:
+       return  bch2_btree_iter_traverse(k_iter) ?:
+               bch2_trans_update(trans, k_iter, delete, 0) ?:
                bch2_hash_set(trans, desc, hash_info, k_iter->pos.inode, tmp, 0);
 }
 
@@ -491,6 +493,7 @@ static int check_inode(struct btree_trans *trans,
                ret = __bch2_trans_do(trans, NULL, NULL,
                                      BTREE_INSERT_NOFAIL|
                                      BTREE_INSERT_LAZY_RW,
+                               bch2_btree_iter_traverse(iter) ?:
                                bch2_inode_write(trans, iter, &u));
                if (ret)
                        bch_err(c, "error in fsck: error %i "
@@ -562,7 +565,8 @@ static int fix_overlapping_extent(struct btree_trans *trans,
                                   BTREE_ITER_INTENT|BTREE_ITER_NOT_EXTENTS);
 
        BUG_ON(iter->flags & BTREE_ITER_IS_EXTENTS);
-       ret   = bch2_trans_update(trans, iter, u, BTREE_TRIGGER_NORUN) ?:
+       ret   = bch2_btree_iter_traverse(iter) ?:
+               bch2_trans_update(trans, iter, u, BTREE_TRIGGER_NORUN) ?:
                bch2_trans_commit(trans, NULL, NULL,
                                  BTREE_INSERT_NOFAIL|
                                  BTREE_INSERT_LAZY_RW);
@@ -761,7 +765,7 @@ retry:
                                mode_to_type(w.inode.bi_mode),
                                (bch2_bkey_val_to_text(&PBUF(buf), c,
                                                       k), buf))) {
-                       ret = lockrestart_do(&trans,
+                       ret = __bch2_trans_do(&trans, NULL, NULL, 0,
                                        bch2_btree_delete_at(&trans, iter, 0));
                        if (ret)
                                goto err;
@@ -886,6 +890,7 @@ retry:
                        ret = __bch2_trans_do(&trans, NULL, NULL,
                                              BTREE_INSERT_NOFAIL|
                                              BTREE_INSERT_LAZY_RW,
+                               bch2_btree_iter_traverse(iter) ?:
                                bch2_trans_update(&trans, iter, &n->k_i, 0));
                        kfree(n);
                        if (ret)
@@ -1338,6 +1343,7 @@ static int check_nlinks_update_hardlinks(struct bch_fs *c,
                        ret = __bch2_trans_do(&trans, NULL, NULL,
                                              BTREE_INSERT_NOFAIL|
                                              BTREE_INSERT_LAZY_RW,
+                                             bch2_btree_iter_traverse(iter) ?:
                                        bch2_inode_write(&trans, iter, &u));
                        if (ret)
                                bch_err(c, "error in fsck: error %i updating inode", ret);
index 17d8eb5223cd3c418f61d4d8f5e1e9ea5aaee4cd..59edb4cea5f1a0c57a4b542c2a3606d8949cf55c 100644 (file)
@@ -302,7 +302,7 @@ struct btree_iter *bch2_inode_peek(struct btree_trans *trans,
 
        iter = bch2_trans_get_iter(trans, BTREE_ID_inodes, POS(0, inum),
                                   BTREE_ITER_CACHED|flags);
-       k = bch2_btree_iter_peek_cached(iter);
+       k = bch2_btree_iter_peek_slot(iter);
        ret = bkey_err(k);
        if (ret)
                goto err;
@@ -600,15 +600,12 @@ int bch2_inode_rm(struct bch_fs *c, u64 inode_nr, bool cached)
 retry:
        bch2_trans_begin(&trans);
 
-       if (cached) {
-               iter = bch2_trans_get_iter(&trans, BTREE_ID_inodes, POS(0, inode_nr),
-                                          BTREE_ITER_CACHED|BTREE_ITER_INTENT);
-               k = bch2_btree_iter_peek_cached(iter);
-       } else {
-               iter = bch2_trans_get_iter(&trans, BTREE_ID_inodes, POS(0, inode_nr),
-                                          BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
-               k = bch2_btree_iter_peek_slot(iter);
-       }
+       iter = bch2_trans_get_iter(&trans, BTREE_ID_inodes, POS(0, inode_nr),
+                                  (cached
+                                   ? BTREE_ITER_CACHED
+                                   : BTREE_ITER_SLOTS)|
+                                  BTREE_ITER_INTENT);
+       k = bch2_btree_iter_peek_slot(iter);
 
        ret = bkey_err(k);
        if (ret)
index d714779a28d0461bb79970237a47ca103e68581d..ac4071fc4e80f05d9ec73f0ab85761dcfb98ee6d 100644 (file)
@@ -1071,7 +1071,7 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq,
        bch2_journal_space_available(j);
        spin_unlock(&j->lock);
 
-       return 0;
+       return bch2_journal_reclaim_start(j);
 }
 
 /* init/exit: */
index f32414171aab82e062f6f3c43cd3f9a09e18d1e0..c6fa4ca31ae9163581713af436f68a20da74259f 100644 (file)
@@ -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;
 }
index ba700810a4bee67223264c01a877011ef1a16676..ebf391245470f2b2e49a528ade8c1715791f861d 100644 (file)
@@ -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)
index 977885166d55f0eba89e52ed454ab081f4acb362..c771b92d9496980eebf39f6a30b60e7022b2b245 100644 (file)
@@ -680,7 +680,7 @@ static void write_one_super(struct bch_fs *c, struct bch_dev *ca, unsigned idx)
 
        sb->offset = sb->layout.sb_offset[idx];
 
-       SET_BCH_SB_CSUM_TYPE(sb, c->opts.metadata_checksum);
+       SET_BCH_SB_CSUM_TYPE(sb, bch2_csum_opt_to_type(c->opts.metadata_checksum, false));
        sb->csum = csum_vstruct(c, BCH_SB_CSUM_TYPE(sb),
                                null_nonce(), sb);
 
index 2a570eb0763ee32385acba222ae0c6ee7ac93443..13a5ca713e7ab48dc29a878a1ae6f411014e147e 100644 (file)
@@ -269,7 +269,7 @@ static void bch2_writes_disabled(struct percpu_ref *writes)
 void bch2_fs_read_only(struct bch_fs *c)
 {
        if (!test_bit(BCH_FS_RW, &c->flags)) {
-               BUG_ON(c->journal.reclaim_thread);
+               bch2_journal_reclaim_stop(&c->journal);
                return;
        }
 
@@ -431,12 +431,6 @@ static int __bch2_fs_read_write(struct bch_fs *c, bool early)
        for_each_rw_member(ca, c, i)
                bch2_wake_allocator(ca);
 
-       ret = bch2_journal_reclaim_start(&c->journal);
-       if (ret) {
-               bch_err(c, "error starting journal reclaim: %i", ret);
-               return ret;
-       }
-
        if (!early) {
                ret = bch2_fs_read_write_late(c);
                if (ret)
index 63f4a83ad1de8844a1736c1d7bd748313bd6912c..59f34b40fd5b1761a9613a97e6191057e268cabf 100644 (file)
@@ -54,14 +54,16 @@ static int test_delete(struct bch_fs *c, u64 nr)
        }
 
        pr_info("deleting once");
-       ret = bch2_btree_delete_at(&trans, iter, 0);
+       ret = __bch2_trans_do(&trans, NULL, NULL, 0,
+                        bch2_btree_delete_at(&trans, iter, 0));
        if (ret) {
                bch_err(c, "delete error (first) in test_delete: %i", ret);
                goto err;
        }
 
        pr_info("deleting twice");
-       ret = bch2_btree_delete_at(&trans, iter, 0);
+       ret = __bch2_trans_do(&trans, NULL, NULL, 0,
+                        bch2_btree_delete_at(&trans, iter, 0));
        if (ret) {
                bch_err(c, "delete error (second) in test_delete: %i", ret);
                goto err;
@@ -101,7 +103,8 @@ static int test_delete_written(struct bch_fs *c, u64 nr)
 
        bch2_journal_flush_all_pins(&c->journal);
 
-       ret = bch2_btree_delete_at(&trans, iter, 0);
+       ret = __bch2_trans_do(&trans, NULL, NULL, 0,
+                        bch2_btree_delete_at(&trans, iter, 0));
        if (ret) {
                bch_err(c, "delete error in test_delete_written: %i", ret);
                goto err;
index e3ad26e244ab4cd161baf57d735dc022c386a343..463260c0458575c2492c165087e4e6eb05c3d58f 100644 (file)
@@ -887,13 +887,9 @@ void eytzinger0_find_test(void)
  */
 u64 *bch2_acc_percpu_u64s(u64 __percpu *p, unsigned nr)
 {
-       u64 *ret;
+       u64 *ret = this_cpu_ptr(p);
        int cpu;
 
-       preempt_disable();
-       ret = this_cpu_ptr(p);
-       preempt_enable();
-
        for_each_possible_cpu(cpu) {
                u64 *i = per_cpu_ptr(p, cpu);
 
index c69b05deec41dc69ba387803305d1f364551849d..84ef4d6d36f62c31a62dcdc9efb1b5ec742a6cc1 100644 (file)
@@ -712,10 +712,7 @@ static inline void percpu_u64_set(u64 __percpu *dst, u64 src)
 
        for_each_possible_cpu(cpu)
                *per_cpu_ptr(dst, cpu) = 0;
-
-       preempt_disable();
-       *this_cpu_ptr(dst) = src;
-       preempt_enable();
+       this_cpu_write(*dst, src);
 }
 
 static inline void acc_u64s(u64 *acc, const u64 *src, unsigned nr)
index c4ae4e0d112257616e83f67da09994d5f8d76622..fca1208720b67dfd7e96915679572737dd626dba 100644 (file)
@@ -142,8 +142,6 @@ static __always_inline bool do_six_trylock_type(struct six_lock *lock,
        union six_lock_state old, new;
        bool ret;
        u64 v;
-       old.v = 0;
-       new.v = 0;
 
        EBUG_ON(type == SIX_LOCK_write && lock->owner != current);
        EBUG_ON(type == SIX_LOCK_write && (lock->state.seq & 1));