]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to 043cfba30c fixup! bcachefs: Improve transaction restart...
authorKent Overstreet <kent.overstreet@gmail.com>
Mon, 1 Nov 2021 10:39:12 +0000 (06:39 -0400)
committerKent Overstreet <kent.overstreet@gmail.com>
Mon, 1 Nov 2021 10:39:12 +0000 (06:39 -0400)
20 files changed:
.bcachefs_revision
libbcachefs/alloc_background.c
libbcachefs/btree_gc.c
libbcachefs/btree_iter.c
libbcachefs/buckets.c
libbcachefs/buckets.h
libbcachefs/ec.c
libbcachefs/ec.h
libbcachefs/fsck.c
libbcachefs/io.c
libbcachefs/journal.h
libbcachefs/journal_io.c
libbcachefs/journal_reclaim.c
libbcachefs/journal_types.h
libbcachefs/move.c
libbcachefs/recovery.c
libbcachefs/recovery.h
libbcachefs/subvolume.c
libbcachefs/subvolume.h
libbcachefs/super.c

index 7b077a6ea7e41c241db41222ad7a28babf0ddc45..18cf255949f513f73132ad067c9d6cf3852ded02 100644 (file)
@@ -1 +1 @@
-82c5cc8f00d08f4a315f99595e328d7b74cbd2b7
+043cfba30c743a6faa4e53c5a88a259f8726ac01
index 93fa9bf931d20d1cb5d8c99dca87f5d24c33bbc5..67b24576eaf1933992497c8a0376944581da82c1 100644 (file)
@@ -261,8 +261,9 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c,
 #undef  x
 }
 
-static int bch2_alloc_read_fn(struct bch_fs *c, struct bkey_s_c k)
+static int bch2_alloc_read_fn(struct btree_trans *trans, struct bkey_s_c k)
 {
+       struct bch_fs *c = trans->c;
        struct bch_dev *ca;
        struct bucket *g;
        struct bkey_alloc_unpacked u;
@@ -289,11 +290,14 @@ static int bch2_alloc_read_fn(struct bch_fs *c, struct bkey_s_c k)
 
 int bch2_alloc_read(struct bch_fs *c)
 {
+       struct btree_trans trans;
        int ret;
 
+       bch2_trans_init(&trans, c, 0, 0);
        down_read(&c->gc_lock);
-       ret = bch2_btree_and_journal_walk(c, BTREE_ID_alloc, bch2_alloc_read_fn);
+       ret = bch2_btree_and_journal_walk(&trans, BTREE_ID_alloc, bch2_alloc_read_fn);
        up_read(&c->gc_lock);
+       bch2_trans_exit(&trans);
        if (ret) {
                bch_err(c, "error reading alloc info: %i", ret);
                return ret;
index 54b3d0d97a3b20d2aa3fbe9c81c301c1c6d02ce3..b4340df677b7ee74f2519dd2aa9b542498400553 100644 (file)
@@ -688,17 +688,18 @@ fsck_err:
 
 /* marking of btree keys/nodes: */
 
-static int bch2_gc_mark_key(struct bch_fs *c, enum btree_id btree_id,
+static int bch2_gc_mark_key(struct btree_trans *trans, enum btree_id btree_id,
                            unsigned level, bool is_root,
                            struct bkey_s_c *k,
                            u8 *max_stale, bool initial)
 {
+       struct bch_fs *c = trans->c;
        struct bkey_ptrs_c ptrs;
        const struct bch_extent_ptr *ptr;
        unsigned flags =
-               BTREE_TRIGGER_INSERT|
                BTREE_TRIGGER_GC|
                (initial ? BTREE_TRIGGER_NOATOMIC : 0);
+       char buf[200];
        int ret = 0;
 
        if (initial) {
@@ -717,8 +718,9 @@ static int bch2_gc_mark_key(struct bch_fs *c, enum btree_id btree_id,
 
                if (test_bit(BCH_FS_REBUILD_REPLICAS, &c->flags) ||
                    fsck_err_on(!bch2_bkey_replicas_marked(c, *k), c,
-                               "superblock not marked as containing replicas (type %u)",
-                               k->k->type)) {
+                               "superblock not marked as containing replicas\n"
+                               "  while marking %s",
+                               (bch2_bkey_val_to_text(&PBUF(buf), c, *k), buf))) {
                        ret = bch2_mark_bkey_replicas(c, *k);
                        if (ret) {
                                bch_err(c, "error marking bkey replicas: %i", ret);
@@ -738,7 +740,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));
        }
 
-       ret = bch2_mark_key(c, *k, flags);
+       ret = bch2_mark_key(trans, *k, flags);
 fsck_err:
 err:
        if (ret)
@@ -746,9 +748,10 @@ err:
        return ret;
 }
 
-static int btree_gc_mark_node(struct bch_fs *c, struct btree *b, u8 *max_stale,
+static int btree_gc_mark_node(struct btree_trans *trans, struct btree *b, u8 *max_stale,
                              bool initial)
 {
+       struct bch_fs *c = trans->c;
        struct btree_node_iter iter;
        struct bkey unpacked;
        struct bkey_s_c k;
@@ -766,7 +769,7 @@ static int btree_gc_mark_node(struct bch_fs *c, struct btree *b, u8 *max_stale,
        bkey_init(&prev.k->k);
 
        while ((k = bch2_btree_node_iter_peek_unpack(&iter, b, &unpacked)).k) {
-               ret = bch2_gc_mark_key(c, b->c.btree_id, b->c.level, false,
+               ret = bch2_gc_mark_key(trans, b->c.btree_id, b->c.level, false,
                                       &k, max_stale, initial);
                if (ret)
                        break;
@@ -788,10 +791,10 @@ static int btree_gc_mark_node(struct bch_fs *c, struct btree *b, u8 *max_stale,
        return ret;
 }
 
-static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
+static int bch2_gc_btree(struct btree_trans *trans, enum btree_id btree_id,
                         bool initial, bool metadata_only)
 {
-       struct btree_trans trans;
+       struct bch_fs *c = trans->c;
        struct btree_iter iter;
        struct btree *b;
        unsigned depth = metadata_only                  ? 1
@@ -801,35 +804,32 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
        u8 max_stale = 0;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        gc_pos_set(c, gc_pos_btree(btree_id, POS_MIN, 0));
 
-       __for_each_btree_node(&trans, iter, btree_id, POS_MIN,
+       __for_each_btree_node(trans, iter, btree_id, POS_MIN,
                              0, depth, BTREE_ITER_PREFETCH, b, ret) {
                bch2_verify_btree_nr_keys(b);
 
                gc_pos_set(c, gc_pos_btree_node(b));
 
-               ret = btree_gc_mark_node(c, b, &max_stale, initial);
+               ret = btree_gc_mark_node(trans, b, &max_stale, initial);
                if (ret)
                        break;
 
                if (!initial) {
                        if (max_stale > 64)
-                               bch2_btree_node_rewrite(&trans, &iter, b,
+                               bch2_btree_node_rewrite(trans, &iter, b,
                                                BTREE_INSERT_NOWAIT|
                                                BTREE_INSERT_GC_LOCK_HELD);
                        else if (!bch2_btree_gc_rewrite_disabled &&
                                 (bch2_btree_gc_always_rewrite || max_stale > 16))
-                               bch2_btree_node_rewrite(&trans, &iter,
+                               bch2_btree_node_rewrite(trans, &iter,
                                                b, BTREE_INSERT_NOWAIT|
                                                BTREE_INSERT_GC_LOCK_HELD);
                }
        }
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 
-       bch2_trans_exit(&trans);
        if (ret)
                return ret;
 
@@ -838,7 +838,7 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
        if (!btree_node_fake(b)) {
                struct bkey_s_c k = bkey_i_to_s_c(&b->key);
 
-               ret = bch2_gc_mark_key(c, b->c.btree_id, b->c.level, true,
+               ret = bch2_gc_mark_key(trans, b->c.btree_id, b->c.level, true,
                                       &k, &max_stale, initial);
        }
        gc_pos_set(c, gc_pos_btree_root(b->c.btree_id));
@@ -847,9 +847,10 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
        return ret;
 }
 
-static int bch2_gc_btree_init_recurse(struct bch_fs *c, struct btree *b,
+static int bch2_gc_btree_init_recurse(struct btree_trans *trans, struct btree *b,
                                      unsigned target_depth)
 {
+       struct bch_fs *c = trans->c;
        struct btree_and_journal_iter iter;
        struct bkey_s_c k;
        struct bkey_buf cur, prev;
@@ -866,7 +867,7 @@ static int bch2_gc_btree_init_recurse(struct bch_fs *c, struct btree *b,
                BUG_ON(bpos_cmp(k.k->p, b->data->min_key) < 0);
                BUG_ON(bpos_cmp(k.k->p, b->data->max_key) > 0);
 
-               ret = bch2_gc_mark_key(c, b->c.btree_id, b->c.level, false,
+               ret = bch2_gc_mark_key(trans, b->c.btree_id, b->c.level, false,
                                       &k, &max_stale, true);
                if (ret) {
                        bch_err(c, "%s: error %i from bch2_gc_mark_key", __func__, ret);
@@ -933,7 +934,7 @@ static int bch2_gc_btree_init_recurse(struct bch_fs *c, struct btree *b,
                                break;
                        }
 
-                       ret = bch2_gc_btree_init_recurse(c, child,
+                       ret = bch2_gc_btree_init_recurse(trans, child,
                                                         target_depth);
                        six_unlock_read(&child->c.lock);
 
@@ -948,10 +949,11 @@ fsck_err:
        return ret;
 }
 
-static int bch2_gc_btree_init(struct bch_fs *c,
+static int bch2_gc_btree_init(struct btree_trans *trans,
                              enum btree_id btree_id,
                              bool metadata_only)
 {
+       struct bch_fs *c = trans->c;
        struct btree *b;
        unsigned target_depth = metadata_only           ? 1
                : bch2_expensive_debug_checks           ? 0
@@ -984,12 +986,12 @@ static int bch2_gc_btree_init(struct bch_fs *c,
        }
 
        if (b->c.level >= target_depth)
-               ret = bch2_gc_btree_init_recurse(c, b, target_depth);
+               ret = bch2_gc_btree_init_recurse(trans, b, target_depth);
 
        if (!ret) {
                struct bkey_s_c k = bkey_i_to_s_c(&b->key);
 
-               ret = bch2_gc_mark_key(c, b->c.btree_id, b->c.level, true,
+               ret = bch2_gc_mark_key(trans, b->c.btree_id, b->c.level, true,
                                       &k, &max_stale, true);
        }
 fsck_err:
@@ -1008,21 +1010,26 @@ static inline int btree_id_gc_phase_cmp(enum btree_id l, enum btree_id r)
 
 static int bch2_gc_btrees(struct bch_fs *c, bool initial, bool metadata_only)
 {
+       struct btree_trans trans;
        enum btree_id ids[BTREE_ID_NR];
        unsigned i;
        int ret = 0;
 
+       bch2_trans_init(&trans, c, 0, 0);
+
        for (i = 0; i < BTREE_ID_NR; i++)
                ids[i] = i;
        bubble_sort(ids, BTREE_ID_NR, btree_id_gc_phase_cmp);
 
        for (i = 0; i < BTREE_ID_NR && !ret; i++)
                ret = initial
-                       ? bch2_gc_btree_init(c, ids[i], metadata_only)
-                       : bch2_gc_btree(c, ids[i], initial, metadata_only);
+                       ? bch2_gc_btree_init(&trans, ids[i], metadata_only)
+                       : bch2_gc_btree(&trans, ids[i], initial, metadata_only);
 
        if (ret < 0)
                bch_err(c, "%s: ret %i", __func__, ret);
+
+       bch2_trans_exit(&trans);
        return ret;
 }
 
@@ -1109,8 +1116,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),
-                                     BTREE_TRIGGER_INSERT|BTREE_TRIGGER_GC);
+                       bch2_mark_key(c, bkey_i_to_s_c(&d->key), BTREE_TRIGGER_GC);
 
        mutex_unlock(&c->btree_interior_update_lock);
 }
@@ -1371,8 +1377,10 @@ static int bch2_gc_start(struct bch_fs *c,
        return 0;
 }
 
-static int bch2_gc_reflink_done_initial_fn(struct bch_fs *c, struct bkey_s_c k)
+static int bch2_gc_reflink_done_initial_fn(struct btree_trans *trans,
+                                          struct bkey_s_c k)
 {
+       struct bch_fs *c = trans->c;
        struct reflink_gc *r;
        const __le64 *refcount = bkey_refcount_c(k);
        char buf[200];
@@ -1437,16 +1445,16 @@ static int bch2_gc_reflink_done(struct bch_fs *c, bool initial,
        if (metadata_only)
                return 0;
 
+       bch2_trans_init(&trans, c, 0, 0);
+
        if (initial) {
                c->reflink_gc_idx = 0;
 
-               ret = bch2_btree_and_journal_walk(c, BTREE_ID_reflink,
+               ret = bch2_btree_and_journal_walk(&trans, BTREE_ID_reflink,
                                bch2_gc_reflink_done_initial_fn);
                goto out;
        }
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        for_each_btree_key(&trans, iter, BTREE_ID_reflink, POS_MIN,
                           BTREE_ITER_PREFETCH, k, ret) {
                const __le64 *refcount = bkey_refcount_c(k);
@@ -1494,16 +1502,18 @@ static int bch2_gc_reflink_done(struct bch_fs *c, bool initial,
        }
 fsck_err:
        bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
 out:
        genradix_free(&c->reflink_gc_table);
        c->reflink_gc_nr = 0;
+       bch2_trans_exit(&trans);
        return ret;
 }
 
-static int bch2_gc_reflink_start_initial_fn(struct bch_fs *c, struct bkey_s_c k)
+static int bch2_gc_reflink_start_initial_fn(struct btree_trans *trans,
+                                           struct bkey_s_c k)
 {
 
+       struct bch_fs *c = trans->c;
        struct reflink_gc *r;
        const __le64 *refcount = bkey_refcount_c(k);
 
@@ -1528,19 +1538,20 @@ static int bch2_gc_reflink_start(struct bch_fs *c, bool initial,
        struct btree_iter iter;
        struct bkey_s_c k;
        struct reflink_gc *r;
-       int ret;
+       int ret = 0;
 
        if (metadata_only)
                return 0;
 
+       bch2_trans_init(&trans, c, 0, 0);
        genradix_free(&c->reflink_gc_table);
        c->reflink_gc_nr = 0;
 
-       if (initial)
-               return bch2_btree_and_journal_walk(c, BTREE_ID_reflink,
-                               bch2_gc_reflink_start_initial_fn);
-
-       bch2_trans_init(&trans, c, 0, 0);
+       if (initial) {
+               ret = bch2_btree_and_journal_walk(&trans, BTREE_ID_reflink,
+                                               bch2_gc_reflink_start_initial_fn);
+               goto out;
+       }
 
        for_each_btree_key(&trans, iter, BTREE_ID_reflink, POS_MIN,
                           BTREE_ITER_PREFETCH, k, ret) {
@@ -1561,9 +1572,9 @@ static int bch2_gc_reflink_start(struct bch_fs *c, bool initial,
                r->refcount     = 0;
        }
        bch2_trans_iter_exit(&trans, &iter);
-
+out:
        bch2_trans_exit(&trans);
-       return 0;
+       return ret;
 }
 
 /**
index b530829e8ffc9c29e94f4a3bd658c5a945a3c386..8c7fc74f1a77d37cc71dad4c50ff42ea4df7c7b4 100644 (file)
@@ -659,7 +659,8 @@ static void bch2_btree_path_verify(struct btree_trans *trans,
 
        for (i = 0; i < (!path->cached ? BTREE_MAX_DEPTH : 1); i++) {
                if (!path->l[i].b) {
-                       BUG_ON(c->btree_roots[path->btree_id].b->c.level > i);
+                       BUG_ON(!path->cached &&
+                              c->btree_roots[path->btree_id].b->c.level > i);
                        break;
                }
 
@@ -2646,6 +2647,7 @@ void bch2_trans_begin(struct btree_trans *trans)
        trans_for_each_update(trans, i)
                __btree_path_put(i->path, true);
 
+       memset(&trans->journal_res, 0, sizeof(trans->journal_res));
        trans->extra_journal_res        = 0;
        trans->nr_updates               = 0;
        trans->mem_top                  = 0;
index 40084edd1376145680d52a6cf00ef7790f2c9443..699a0865c9b8ed3fe6daa6515b8e6547cac81feb 100644 (file)
@@ -524,11 +524,13 @@ void bch2_mark_alloc_bucket(struct bch_fs *c, struct bch_dev *ca,
        BUG_ON(owned_by_allocator == old.owned_by_allocator);
 }
 
-static int bch2_mark_alloc(struct bch_fs *c,
+static int bch2_mark_alloc(struct btree_trans *trans,
                           struct bkey_s_c old, struct bkey_s_c new,
-                          u64 journal_seq, unsigned flags)
+                          unsigned flags)
 {
        bool gc = flags & BTREE_TRIGGER_GC;
+       u64 journal_seq = trans->journal_res.seq;
+       struct bch_fs *c = trans->c;
        struct bkey_alloc_unpacked u;
        struct bch_dev *ca;
        struct bucket *g;
@@ -673,7 +675,8 @@ static s64 ptr_disk_sectors(s64 sectors, struct extent_ptr_decoded p)
                : sectors;
 }
 
-static int check_bucket_ref(struct bch_fs *c, struct bkey_s_c k,
+static int check_bucket_ref(struct bch_fs *c,
+                           struct bkey_s_c k,
                            const struct bch_extent_ptr *ptr,
                            s64 sectors, enum bch_data_type ptr_data_type,
                            u8 bucket_gen, u8 bucket_data_type,
@@ -747,10 +750,12 @@ static int check_bucket_ref(struct bch_fs *c, struct bkey_s_c k,
        return 0;
 }
 
-static int mark_stripe_bucket(struct bch_fs *c, struct bkey_s_c k,
-                            unsigned ptr_idx,
-                            u64 journal_seq, unsigned flags)
+static int mark_stripe_bucket(struct btree_trans *trans,
+                             struct bkey_s_c k,
+                             unsigned ptr_idx,
+                             u64 journal_seq, unsigned flags)
 {
+       struct bch_fs *c = trans->c;
        const struct bch_stripe *s = bkey_s_c_to_stripe(k).v;
        unsigned nr_data = s->nr_blocks - s->nr_redundant;
        bool parity = ptr_idx >= nr_data;
@@ -794,7 +799,8 @@ static int mark_stripe_bucket(struct bch_fs *c, struct bkey_s_c k,
        return 0;
 }
 
-static int __mark_pointer(struct bch_fs *c, struct bkey_s_c k,
+static int __mark_pointer(struct btree_trans *trans,
+                         struct bkey_s_c k,
                          const struct bch_extent_ptr *ptr,
                          s64 sectors, enum bch_data_type ptr_data_type,
                          u8 bucket_gen, u8 *bucket_data_type,
@@ -803,7 +809,7 @@ static int __mark_pointer(struct bch_fs *c, struct bkey_s_c k,
        u16 *dst_sectors = !ptr->cached
                ? dirty_sectors
                : cached_sectors;
-       int ret = check_bucket_ref(c, k, ptr, sectors, ptr_data_type,
+       int ret = check_bucket_ref(trans->c, k, ptr, sectors, ptr_data_type,
                                   bucket_gen, *bucket_data_type,
                                   *dirty_sectors, *cached_sectors);
 
@@ -816,12 +822,15 @@ static int __mark_pointer(struct bch_fs *c, struct bkey_s_c k,
        return 0;
 }
 
-static int bch2_mark_pointer(struct bch_fs *c, struct bkey_s_c k,
+static int bch2_mark_pointer(struct btree_trans *trans,
+                            struct bkey_s_c k,
                             struct extent_ptr_decoded p,
                             s64 sectors, enum bch_data_type data_type,
-                            u64 journal_seq, unsigned flags)
+                            unsigned flags)
 {
        bool gc = flags & BTREE_TRIGGER_GC;
+       u64 journal_seq = trans->journal_res.seq;
+       struct bch_fs *c = trans->c;
        struct bucket_mark old, new;
        struct bch_dev *ca = bch_dev_bkey_exists(c, p.ptr.dev);
        struct bucket *g = PTR_BUCKET(ca, &p.ptr, gc);
@@ -834,7 +843,8 @@ static int bch2_mark_pointer(struct bch_fs *c, struct bkey_s_c k,
                new.v.counter = old.v.counter = v;
                bucket_data_type = new.data_type;
 
-               ret = __mark_pointer(c, k, &p.ptr, sectors, data_type, new.gen,
+               ret = __mark_pointer(trans, k, &p.ptr, sectors,
+                                    data_type, new.gen,
                                     &bucket_data_type,
                                     &new.dirty_sectors,
                                     &new.cached_sectors);
@@ -863,13 +873,14 @@ static int bch2_mark_pointer(struct bch_fs *c, struct bkey_s_c k,
        return 0;
 }
 
-static int bch2_mark_stripe_ptr(struct bch_fs *c,
+static int bch2_mark_stripe_ptr(struct btree_trans *trans,
                                struct bch_extent_stripe_ptr p,
                                enum bch_data_type data_type,
                                s64 sectors,
-                               unsigned journal_seq, unsigned flags)
+                               unsigned flags)
 {
        bool gc = flags & BTREE_TRIGGER_GC;
+       struct bch_fs *c = trans->c;
        struct bch_replicas_padded r;
        struct stripe *m;
        unsigned i, blocks_nonempty = 0;
@@ -902,17 +913,19 @@ 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, &r.e, sectors, journal_seq, gc);
+       update_replicas(c, &r.e, sectors, trans->journal_res.seq, gc);
 
        return 0;
 }
 
-static int bch2_mark_extent(struct bch_fs *c,
+static int bch2_mark_extent(struct btree_trans *trans,
                            struct bkey_s_c old, struct bkey_s_c new,
-                           unsigned journal_seq, unsigned flags)
+                           unsigned flags)
 {
        bool gc = flags & BTREE_TRIGGER_GC;
-       struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
+       u64 journal_seq = trans->journal_res.seq;
+       struct bch_fs *c = trans->c;
+       struct bkey_s_c k = flags & BTREE_TRIGGER_OVERWRITE ? old: new;
        struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
        const union bch_extent_entry *entry;
        struct extent_ptr_decoded p;
@@ -927,9 +940,6 @@ static int bch2_mark_extent(struct bch_fs *c,
        bool stale;
        int ret;
 
-       BUG_ON((flags & (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE)) ==
-              (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE));
-
        r.e.data_type   = data_type;
        r.e.nr_devs     = 0;
        r.e.nr_required = 1;
@@ -940,8 +950,8 @@ static int bch2_mark_extent(struct bch_fs *c,
                if (flags & BTREE_TRIGGER_OVERWRITE)
                        disk_sectors = -disk_sectors;
 
-               ret = bch2_mark_pointer(c, k, p, disk_sectors, data_type,
-                                       journal_seq, flags);
+               ret = bch2_mark_pointer(trans, k, p, disk_sectors,
+                                       data_type, flags);
                if (ret < 0)
                        return ret;
 
@@ -959,8 +969,8 @@ static int bch2_mark_extent(struct bch_fs *c,
                        dirty_sectors          += disk_sectors;
                        r.e.devs[r.e.nr_devs++] = p.ptr.dev;
                } else {
-                       ret = bch2_mark_stripe_ptr(c, p.ec, data_type,
-                                       disk_sectors, journal_seq, flags);
+                       ret = bch2_mark_stripe_ptr(trans, p.ec, data_type,
+                                       disk_sectors, flags);
                        if (ret)
                                return ret;
 
@@ -986,11 +996,13 @@ static int bch2_mark_extent(struct bch_fs *c,
        return 0;
 }
 
-static int bch2_mark_stripe(struct bch_fs *c,
-                       struct bkey_s_c old, struct bkey_s_c new,
-                       u64 journal_seq, unsigned flags)
+static int bch2_mark_stripe(struct btree_trans *trans,
+                           struct bkey_s_c old, struct bkey_s_c new,
+                           unsigned flags)
 {
        bool gc = flags & BTREE_TRIGGER_GC;
+       u64 journal_seq = trans->journal_res.seq;
+       struct bch_fs *c = trans->c;
        size_t idx = new.k->p.offset;
        const struct bch_stripe *old_s = old.k->type == KEY_TYPE_stripe
                ? bkey_s_c_to_stripe(old).v : NULL;
@@ -1003,8 +1015,13 @@ static int bch2_mark_stripe(struct bch_fs *c,
        BUG_ON(gc && old_s);
 
        if (!m || (old_s && !m->alive)) {
-               bch_err_ratelimited(c, "error marking nonexistent stripe %zu",
-                                   idx);
+               char buf1[200], buf2[200];
+
+               bch2_bkey_val_to_text(&PBUF(buf1), c, old);
+               bch2_bkey_val_to_text(&PBUF(buf2), c, new);
+               bch_err_ratelimited(c, "error marking nonexistent stripe %zu while marking\n"
+                                   "old %s\n"
+                                   "new %s", idx, buf1, buf2);
                bch2_inconsistent_error(c);
                return -1;
        }
@@ -1049,7 +1066,7 @@ 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, journal_seq, flags);
+                       ret = mark_stripe_bucket(trans, new, i, journal_seq, flags);
                        if (ret)
                                return ret;
                }
@@ -1068,25 +1085,27 @@ static int bch2_mark_stripe(struct bch_fs *c,
        return 0;
 }
 
-static int bch2_mark_inode(struct bch_fs *c,
-                       struct bkey_s_c old, struct bkey_s_c new,
-                       u64 journal_seq, unsigned flags)
+static int bch2_mark_inode(struct btree_trans *trans,
+                          struct bkey_s_c old, struct bkey_s_c new,
+                          unsigned flags)
 {
+       struct bch_fs *c = trans->c;
        struct bch_fs_usage __percpu *fs_usage;
 
        preempt_disable();
-       fs_usage = fs_usage_ptr(c, journal_seq, flags & BTREE_TRIGGER_GC);
+       fs_usage = fs_usage_ptr(c, trans->journal_res.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)
+static int bch2_mark_reservation(struct btree_trans *trans,
+                                struct bkey_s_c old, struct bkey_s_c new,
+                                unsigned flags)
 {
-       struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
+       struct bch_fs *c = trans->c;
+       struct bkey_s_c k = flags & BTREE_TRIGGER_OVERWRITE ? old: new;
        struct bch_fs_usage __percpu *fs_usage;
        unsigned replicas = bkey_s_c_to_reservation(k).v->nr_replicas;
        s64 sectors = (s64) k.k->size;
@@ -1096,7 +1115,7 @@ static int bch2_mark_reservation(struct bch_fs *c,
        sectors *= replicas;
 
        preempt_disable();
-       fs_usage = fs_usage_ptr(c, journal_seq, flags & BTREE_TRIGGER_GC);
+       fs_usage = fs_usage_ptr(c, trans->journal_res.seq, flags & BTREE_TRIGGER_GC);
        replicas = clamp_t(unsigned, replicas, 1,
                           ARRAY_SIZE(fs_usage->persistent_reserved));
 
@@ -1154,11 +1173,12 @@ fsck_err:
        return ret;
 }
 
-static int bch2_mark_reflink_p(struct bch_fs *c,
-                       struct bkey_s_c old, struct bkey_s_c new,
-                       u64 journal_seq, unsigned flags)
+static int bch2_mark_reflink_p(struct btree_trans *trans,
+                              struct bkey_s_c old, struct bkey_s_c new,
+                              unsigned flags)
 {
-       struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
+       struct bch_fs *c = trans->c;
+       struct bkey_s_c k = flags & BTREE_TRIGGER_OVERWRITE ? old: new;
        struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k);
        struct reflink_gc *ref;
        size_t l, r, m;
@@ -1167,9 +1187,6 @@ static int bch2_mark_reflink_p(struct bch_fs *c,
                le32_to_cpu(p.v->back_pad);
        int ret = 0;
 
-       BUG_ON((flags & (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE)) ==
-              (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE));
-
        l = 0;
        r = c->reflink_gc_nr;
        while (l < r) {
@@ -1188,47 +1205,48 @@ static int bch2_mark_reflink_p(struct bch_fs *c,
        return ret;
 }
 
-static int bch2_mark_key_locked(struct bch_fs *c,
+static int bch2_mark_key_locked(struct btree_trans *trans,
                   struct bkey_s_c old,
                   struct bkey_s_c new,
-                  u64 journal_seq, unsigned flags)
+                  unsigned flags)
 {
-       struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
-
-       BUG_ON(!(flags & (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE)));
+       struct bkey_s_c k = flags & BTREE_TRIGGER_OVERWRITE ? old: new;
 
        switch (k.k->type) {
        case KEY_TYPE_alloc:
        case KEY_TYPE_alloc_v2:
-               return bch2_mark_alloc(c, old, new, journal_seq, flags);
+               return bch2_mark_alloc(trans, old, new, flags);
        case KEY_TYPE_btree_ptr:
        case KEY_TYPE_btree_ptr_v2:
        case KEY_TYPE_extent:
        case KEY_TYPE_reflink_v:
-               return bch2_mark_extent(c, old, new, journal_seq, flags);
+               return bch2_mark_extent(trans, old, new, flags);
        case KEY_TYPE_stripe:
-               return bch2_mark_stripe(c, old, new, journal_seq, flags);
+               return bch2_mark_stripe(trans, old, new, flags);
        case KEY_TYPE_inode:
-               return bch2_mark_inode(c, old, new, journal_seq, flags);
+               return bch2_mark_inode(trans, old, new, flags);
        case KEY_TYPE_reservation:
-               return bch2_mark_reservation(c, old, new, journal_seq, flags);
+               return bch2_mark_reservation(trans, old, new, flags);
        case KEY_TYPE_reflink_p:
-               return bch2_mark_reflink_p(c, old, new, journal_seq, flags);
+               return bch2_mark_reflink_p(trans, old, new, flags);
        case KEY_TYPE_snapshot:
-               return bch2_mark_snapshot(c, old, new, journal_seq, flags);
+               return bch2_mark_snapshot(trans, old, new, flags);
        default:
                return 0;
        }
 }
 
-int bch2_mark_key(struct bch_fs *c, struct bkey_s_c new, unsigned flags)
+int bch2_mark_key(struct btree_trans *trans, struct bkey_s_c new, unsigned flags)
 {
+       struct bch_fs *c = trans->c;
        struct bkey deleted = KEY(0, 0, 0);
        struct bkey_s_c old = (struct bkey_s_c) { &deleted, NULL };
        int ret;
 
+       deleted.p = new.k->p;
+
        percpu_down_read(&c->mark_lock);
-       ret = bch2_mark_key_locked(c, old, new, 0, flags);
+       ret = bch2_mark_key_locked(trans, old, new, flags);
        percpu_up_read(&c->mark_lock);
 
        return ret;
@@ -1237,13 +1255,14 @@ int bch2_mark_key(struct bch_fs *c, struct bkey_s_c new, unsigned flags)
 int bch2_mark_update(struct btree_trans *trans, struct btree_path *path,
                     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;
 
+       _deleted.p = path->pos;
+
        if (unlikely(flags & BTREE_TRIGGER_NORUN))
                return 0;
 
@@ -1254,15 +1273,12 @@ int bch2_mark_update(struct btree_trans *trans, struct btree_path *path,
 
        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,
+               ret   = bch2_mark_key_locked(trans, old, bkey_i_to_s_c(new),
                                BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE|flags);
        } else {
-               ret   = bch2_mark_key_locked(c, deleted, bkey_i_to_s_c(new),
-                               trans->journal_res.seq,
+               ret   = bch2_mark_key_locked(trans, deleted, bkey_i_to_s_c(new),
                                BTREE_TRIGGER_INSERT|flags) ?:
-                       bch2_mark_key_locked(c, old, deleted,
-                               trans->journal_res.seq,
+                       bch2_mark_key_locked(trans, old, deleted,
                                BTREE_TRIGGER_OVERWRITE|flags);
        }
 
@@ -1426,7 +1442,8 @@ static int bch2_trans_mark_pointer(struct btree_trans *trans,
        if (IS_ERR(a))
                return PTR_ERR(a);
 
-       ret = __mark_pointer(c, k, &p.ptr, sectors, data_type, u.gen, &u.data_type,
+       ret = __mark_pointer(trans, k, &p.ptr, sectors, data_type,
+                            u.gen, &u.data_type,
                             &u.dirty_sectors, &u.cached_sectors);
        if (ret)
                goto out;
@@ -1511,9 +1528,6 @@ static int bch2_trans_mark_extent(struct btree_trans *trans,
        bool stale;
        int ret;
 
-       BUG_ON((flags & (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE)) ==
-              (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE));
-
        r.e.data_type   = data_type;
        r.e.nr_devs     = 0;
        r.e.nr_required = 1;
@@ -1685,9 +1699,6 @@ static int bch2_trans_mark_reservation(struct btree_trans *trans,
        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;
@@ -1807,9 +1818,7 @@ static int bch2_trans_mark_reflink_p(struct btree_trans *trans,
 int bch2_trans_mark_key(struct btree_trans *trans, struct bkey_s_c old,
                        struct bkey_s_c new, unsigned flags)
 {
-       struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
-
-       BUG_ON(!(flags & (BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE)));
+       struct bkey_s_c k = flags & BTREE_TRIGGER_OVERWRITE ? old: new;
 
        switch (k.k->type) {
        case KEY_TYPE_btree_ptr:
@@ -1841,6 +1850,8 @@ int bch2_trans_mark_update(struct btree_trans *trans,
        struct bkey             unpacked;
        int ret;
 
+       _deleted.p = path->pos;
+
        if (unlikely(flags & BTREE_TRIGGER_NORUN))
                return 0;
 
index 61c2c0f9ff8f1d2e9cbd337539f88c45d4f7d292..8a9b2b565d48782dc658305042edc98d0221597c 100644 (file)
@@ -226,7 +226,7 @@ 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);
+int bch2_mark_key(struct btree_trans *, struct bkey_s_c, unsigned);
 
 int bch2_mark_update(struct btree_trans *, struct btree_path *,
                     struct bkey_i *, unsigned);
index 9f87e2bc44688416270f012a369d8f49c60fcf31..bfa512d785385d3ff2a485bb6050deed5bc3ddcc 100644 (file)
@@ -837,8 +837,9 @@ static int ec_stripe_update_ptrs(struct bch_fs *c,
        bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
                             bkey_start_pos(pos),
                             BTREE_ITER_INTENT);
-
-       while ((k = bch2_btree_iter_peek(&iter)).k &&
+retry:
+       while (bch2_trans_begin(&trans),
+              (k = bch2_btree_iter_peek(&iter)).k &&
               !(ret = bkey_err(k)) &&
               bkey_cmp(bkey_start_pos(k.k), pos->p) < 0) {
                struct bch_extent_ptr *ptr, *ec_ptr = NULL;
@@ -874,11 +875,11 @@ static int ec_stripe_update_ptrs(struct bch_fs *c,
                                        BTREE_INSERT_NOFAIL);
                if (!ret)
                        bch2_btree_iter_set_pos(&iter, next_pos);
-               if (ret == -EINTR)
-                       ret = 0;
                if (ret)
                        break;
        }
+       if (ret == -EINTR)
+               goto retry;
        bch2_trans_iter_exit(&trans, &iter);
 
        bch2_trans_exit(&trans);
@@ -1069,16 +1070,14 @@ void *bch2_writepoint_ec_buf(struct bch_fs *c, struct write_point *wp)
        return ob->ec->new_stripe.data[ob->ec_idx] + (offset << 9);
 }
 
-void bch2_ec_add_backpointer(struct bch_fs *c, struct write_point *wp,
-                            struct bpos pos, unsigned sectors)
+void bch2_ob_add_backpointer(struct bch_fs *c, struct open_bucket *ob,
+                            struct bkey *k)
 {
-       struct open_bucket *ob = ec_open_bucket(c, &wp->ptrs);
-       struct ec_stripe_new *ec;
+       struct ec_stripe_new *ec = ob->ec;
 
-       if (!ob)
+       if (!ec)
                return;
 
-       ec = ob->ec;
        mutex_lock(&ec->lock);
 
        if (bch2_keylist_realloc(&ec->keys, ec->inline_keys,
@@ -1088,8 +1087,8 @@ void bch2_ec_add_backpointer(struct bch_fs *c, struct write_point *wp,
        }
 
        bkey_init(&ec->keys.top->k);
-       ec->keys.top->k.p       = pos;
-       bch2_key_resize(&ec->keys.top->k, sectors);
+       ec->keys.top->k.p       = k->p;
+       ec->keys.top->k.size    = k->size;
        bch2_keylist_push(&ec->keys);
 
        mutex_unlock(&ec->lock);
@@ -1635,14 +1634,14 @@ int bch2_stripes_write(struct bch_fs *c, unsigned flags)
        return ret;
 }
 
-static int bch2_stripes_read_fn(struct bch_fs *c, struct bkey_s_c k)
+static int bch2_stripes_read_fn(struct btree_trans *trans, struct bkey_s_c k)
 {
+       struct bch_fs *c = trans->c;
        int ret = 0;
 
        if (k.k->type == KEY_TYPE_stripe)
                ret = __ec_stripe_mem_alloc(c, k.k->p.offset, GFP_KERNEL) ?:
-                       bch2_mark_key(c, k,
-                                     BTREE_TRIGGER_INSERT|
+                       bch2_mark_key(trans, k,
                                      BTREE_TRIGGER_NOATOMIC);
 
        return ret;
@@ -1650,8 +1649,13 @@ static int bch2_stripes_read_fn(struct bch_fs *c, struct bkey_s_c k)
 
 int bch2_stripes_read(struct bch_fs *c)
 {
-       int ret = bch2_btree_and_journal_walk(c, BTREE_ID_stripes,
-                                             bch2_stripes_read_fn);
+       struct btree_trans trans;
+       int ret;
+
+       bch2_trans_init(&trans, c, 0, 0);
+       ret = bch2_btree_and_journal_walk(&trans, BTREE_ID_stripes,
+                                         bch2_stripes_read_fn);
+       bch2_trans_exit(&trans);
        if (ret)
                bch_err(c, "error reading stripes: %i", ret);
 
index e79626b59509a3082ecef7f06acba9afbabeb21f..eb16e140e2c814e3cda734ff3c99b57131032332 100644 (file)
@@ -193,8 +193,8 @@ struct ec_stripe_head {
 int bch2_ec_read_extent(struct bch_fs *, struct bch_read_bio *);
 
 void *bch2_writepoint_ec_buf(struct bch_fs *, struct write_point *);
-void bch2_ec_add_backpointer(struct bch_fs *, struct write_point *,
-                            struct bpos, unsigned);
+void bch2_ob_add_backpointer(struct bch_fs *, struct open_bucket *,
+                            struct bkey *);
 
 void bch2_ec_bucket_written(struct bch_fs *, struct open_bucket *);
 void bch2_ec_bucket_cancel(struct bch_fs *, struct open_bucket *);
index 2da1d5d743481ac2ad29f4f230532423985170c3..5bc04c7bbb83092e179bc31111f55618cddde79a 100644 (file)
@@ -1184,9 +1184,8 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
        if (fsck_err_on(ret == INT_MAX, c,
                        "extent in missing inode:\n  %s",
                        (bch2_bkey_val_to_text(&PBUF(buf), c, k), buf)))
-               return __bch2_trans_do(trans, NULL, NULL, BTREE_INSERT_LAZY_RW,
-                       bch2_btree_delete_at(trans, iter,
-                                            BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE));
+               return bch2_btree_delete_at(trans, iter,
+                                           BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE);
 
        if (ret == INT_MAX)
                return 0;
@@ -1199,9 +1198,8 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
                        "extent in non regular inode mode %o:\n  %s",
                        i->inode.bi_mode,
                        (bch2_bkey_val_to_text(&PBUF(buf), c, k), buf)))
-               return __bch2_trans_do(trans, NULL, NULL, BTREE_INSERT_LAZY_RW,
-                        bch2_btree_delete_at(trans, iter,
-                                             BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE));
+               return bch2_btree_delete_at(trans, iter,
+                                           BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE);
 
        if (!bch2_snapshot_internal_node(c, k.k->p.snapshot)) {
                for_each_visible_inode(c, s, inode, k.k->p.snapshot, i) {
@@ -1261,7 +1259,9 @@ static int check_extents(struct bch_fs *c)
                             BTREE_ITER_ALL_SNAPSHOTS);
 
        do {
-               ret = lockrestart_do(&trans,
+               ret = __bch2_trans_do(&trans, NULL, NULL,
+                                     BTREE_INSERT_LAZY_RW|
+                                     BTREE_INSERT_NOFAIL,
                        check_extent(&trans, &iter, &w, &s));
                if (ret)
                        break;
index c4c28559a49c43d80f51d8c2a61800da99bfa7c9..017fc689801a4ce6770bb6686030b37c88fe0dc7 100644 (file)
@@ -460,6 +460,7 @@ int bch2_write_index_default(struct bch_write_op *op)
 {
        struct bch_fs *c = op->c;
        struct bkey_buf sk;
+       struct open_bucket *ec_ob = ec_open_bucket(c, &op->open_buckets);
        struct keylist *keys = &op->insert_keys;
        struct bkey_i *k = bch2_keylist_front(keys);
        struct btree_trans trans;
@@ -503,6 +504,9 @@ int bch2_write_index_default(struct bch_write_op *op)
                if (ret)
                        break;
 
+               if (ec_ob)
+                       bch2_ob_add_backpointer(c, ec_ob, &sk.k->k);
+
                if (bkey_cmp(iter.pos, k->k.p) >= 0)
                        bch2_keylist_pop_front(&op->insert_keys);
                else
@@ -949,7 +953,6 @@ static int bch2_write_extent(struct bch_write_op *op, struct write_point *wp,
        struct bio *src = &op->wbio.bio, *dst = src;
        struct bvec_iter saved_iter;
        void *ec_buf;
-       struct bpos ec_pos = op->pos;
        unsigned total_output = 0, total_input = 0;
        bool bounce = false;
        bool page_alloc_failed = false;
@@ -1119,9 +1122,6 @@ static int bch2_write_extent(struct bch_write_op *op, struct write_point *wp,
 
        dst->bi_iter.bi_size = total_output;
 do_write:
-       /* might have done a realloc... */
-       bch2_ec_add_backpointer(c, wp, ec_pos, total_input >> 9);
-
        *_dst = dst;
        return more;
 csum_err:
index 1d556790b38ee09d3eb2450efbc9904b9dd1dcb0..99fd253648bf675960d0f348169010a05744ff23 100644 (file)
@@ -446,6 +446,7 @@ static inline int bch2_journal_preres_get_fast(struct journal *j,
                ret = 0;
 
                if ((flags & JOURNAL_RES_GET_RESERVED) ||
+                   test_bit(JOURNAL_NOCHANGES, &j->flags) ||
                    new.reserved + d < new.remaining) {
                        new.reserved += d;
                        ret = 1;
index 66a0e267b3f4b29adadbe89396f765dd08307130..53aad1d0c9a9960c77bf354e49857d39c058a451 100644 (file)
@@ -1515,7 +1515,7 @@ retry_alloc:
 
        w->devs_written = bch2_bkey_devs(bkey_i_to_s_c(&w->key));
 
-       if (c->opts.nochanges)
+       if (test_bit(JOURNAL_NOCHANGES, &j->flags))
                goto no_io;
 
        for_each_rw_member(ca, c, i)
index c468d597d4276c414803ee3891407fd45e941484..a93f5b189248a4d1309d2186af1868d8d5756c2e 100644 (file)
@@ -34,8 +34,10 @@ unsigned bch2_journal_dev_buckets_available(struct journal *j,
                                            struct journal_device *ja,
                                            enum journal_space_from from)
 {
-       unsigned available = (journal_space_from(ja, from) -
-                             ja->cur_idx - 1 + ja->nr) % ja->nr;
+       unsigned available = !test_bit(JOURNAL_NOCHANGES, &j->flags)
+               ? ((journal_space_from(ja, from) -
+                   ja->cur_idx - 1 + ja->nr) % ja->nr)
+               : ja->nr;
 
        /*
         * Don't use the last bucket unless writing the new last_seq
index 61674ae1ab5fee1e3adc5696b8e193968552a4d6..cc10e1d7895c79b659cc5a5eba70a04900f87871 100644 (file)
@@ -154,6 +154,7 @@ enum {
        JOURNAL_NEED_WRITE,
        JOURNAL_MAY_GET_UNRESERVED,
        JOURNAL_MAY_SKIP_FLUSH,
+       JOURNAL_NOCHANGES,
 };
 
 /* Embedded in struct bch_fs */
index fae26009795008937bc5ce1d8beec426bd69002e..d0c784012e887e5e5fa1d44398705779099b5c4a 100644 (file)
@@ -8,6 +8,7 @@
 #include "btree_update_interior.h"
 #include "buckets.h"
 #include "disk_groups.h"
+#include "ec.h"
 #include "inode.h"
 #include "io.h"
 #include "journal_reclaim.h"
@@ -136,6 +137,7 @@ static int bch2_migrate_index_update(struct bch_write_op *op)
        struct btree_iter iter;
        struct migrate_write *m =
                container_of(op, struct migrate_write, op);
+       struct open_bucket *ec_ob = ec_open_bucket(c, &op->open_buckets);
        struct keylist *keys = &op->insert_keys;
        struct bkey_buf _new, _insert;
        int ret = 0;
@@ -253,6 +255,8 @@ static int bch2_migrate_index_update(struct bch_write_op *op)
                if (!ret) {
                        bch2_btree_iter_set_pos(&iter, next_pos);
                        atomic_long_inc(&c->extent_migrate_done);
+                       if (ec_ob)
+                               bch2_ob_add_backpointer(c, ec_ob, &insert->k);
                }
 err:
                if (ret == -EINTR)
index da9c3ea528e76d00eaad3d6acb3eaa737193bcb9..29fae6dbce765a6e32756f73634afb947a726944 100644 (file)
@@ -337,10 +337,11 @@ static void btree_and_journal_iter_prefetch(struct bch_fs *c, struct btree *b,
        bch2_bkey_buf_exit(&tmp, c);
 }
 
-static int bch2_btree_and_journal_walk_recurse(struct bch_fs *c, struct btree *b,
+static int bch2_btree_and_journal_walk_recurse(struct btree_trans *trans, struct btree *b,
                                enum btree_id btree_id,
                                btree_walk_key_fn key_fn)
 {
+       struct bch_fs *c = trans->c;
        struct btree_and_journal_iter iter;
        struct bkey_s_c k;
        struct bkey_buf tmp;
@@ -364,11 +365,11 @@ static int bch2_btree_and_journal_walk_recurse(struct bch_fs *c, struct btree *b
 
                        btree_and_journal_iter_prefetch(c, b, iter);
 
-                       ret = bch2_btree_and_journal_walk_recurse(c, child,
+                       ret = bch2_btree_and_journal_walk_recurse(trans, child,
                                        btree_id, key_fn);
                        six_unlock_read(&child->c.lock);
                } else {
-                       ret = key_fn(c, k);
+                       ret = key_fn(trans, k);
                }
 
                if (ret)
@@ -382,9 +383,10 @@ static int bch2_btree_and_journal_walk_recurse(struct bch_fs *c, struct btree *b
        return ret;
 }
 
-int bch2_btree_and_journal_walk(struct bch_fs *c, enum btree_id btree_id,
+int bch2_btree_and_journal_walk(struct btree_trans *trans, enum btree_id btree_id,
                                btree_walk_key_fn key_fn)
 {
+       struct bch_fs *c = trans->c;
        struct btree *b = c->btree_roots[btree_id].b;
        int ret = 0;
 
@@ -392,7 +394,7 @@ int bch2_btree_and_journal_walk(struct bch_fs *c, enum btree_id btree_id,
                return 0;
 
        six_lock_read(&b->c.lock, NULL, NULL);
-       ret = bch2_btree_and_journal_walk_recurse(c, b, btree_id, key_fn);
+       ret = bch2_btree_and_journal_walk_recurse(trans, b, btree_id, key_fn);
        six_unlock_read(&b->c.lock);
 
        return ret;
index e5565e4f335a535d27e960ab35571b21ca07171d..e45c70b3693f46c020a501cf08fe96d0315279fc 100644 (file)
@@ -45,9 +45,9 @@ void bch2_btree_and_journal_iter_init_node_iter(struct btree_and_journal_iter *,
                                                struct bch_fs *,
                                                struct btree *);
 
-typedef int (*btree_walk_key_fn)(struct bch_fs *c, struct bkey_s_c k);
+typedef int (*btree_walk_key_fn)(struct btree_trans *, struct bkey_s_c);
 
-int bch2_btree_and_journal_walk(struct bch_fs *, enum btree_id, btree_walk_key_fn);
+int bch2_btree_and_journal_walk(struct btree_trans *, enum btree_id, btree_walk_key_fn);
 
 void bch2_journal_keys_free(struct journal_keys *);
 void bch2_journal_entries_free(struct list_head *);
index 4d385c9e9268d1da9f4bffb11e3bc88922de46b2..0ef625d21672798595db8d172d82c75768aa1e68 100644 (file)
@@ -61,10 +61,11 @@ const char *bch2_snapshot_invalid(const struct bch_fs *c, struct bkey_s_c k)
        return NULL;
 }
 
-int bch2_mark_snapshot(struct bch_fs *c,
+int bch2_mark_snapshot(struct btree_trans *trans,
                       struct bkey_s_c old, struct bkey_s_c new,
-                      u64 journal_seq, unsigned flags)
+                      unsigned flags)
 {
+       struct bch_fs *c = trans->c;
        struct snapshot_t *t;
 
        t = genradix_ptr_alloc(&c->snapshots,
@@ -308,7 +309,7 @@ int bch2_fs_snapshots_start(struct bch_fs *c)
                if (BCH_SNAPSHOT_DELETED(bkey_s_c_to_snapshot(k).v))
                        have_deleted = true;
 
-               ret = bch2_mark_snapshot(c, bkey_s_c_null, k, 0, 0);
+               ret = bch2_mark_snapshot(&trans, bkey_s_c_null, k, 0);
                if (ret)
                        break;
        }
@@ -499,7 +500,7 @@ static int bch2_snapshot_node_create(struct btree_trans *trans, u32 parent,
 
                bch2_trans_update(trans, &iter, &n->k_i, 0);
 
-               ret = bch2_mark_snapshot(trans->c, bkey_s_c_null, bkey_i_to_s_c(&n->k_i), 0, 0);
+               ret = bch2_mark_snapshot(trans, bkey_s_c_null, bkey_i_to_s_c(&n->k_i), 0);
                if (ret)
                        break;
 
index b5067dc68fc7790f05e45e79f8e1fb2e4a12c01d..dde755b45392a4713e855905b7cdbac39cbf2a8c 100644 (file)
@@ -12,8 +12,8 @@ const char *bch2_snapshot_invalid(const struct bch_fs *, struct bkey_s_c);
        .val_to_text    = bch2_snapshot_to_text,                \
 }
 
-int bch2_mark_snapshot(struct bch_fs *, struct bkey_s_c,
-                      struct bkey_s_c, u64, unsigned);
+int bch2_mark_snapshot(struct btree_trans *, struct bkey_s_c,
+                      struct bkey_s_c, unsigned);
 
 static inline struct snapshot_t *snapshot_t(struct bch_fs *c, u32 id)
 {
index e0c93cb520c33206b2e3a03a2d259e59ab640761..dc8f641504bea5c0a63ae0789ff4936ebd28191c 100644 (file)
@@ -793,6 +793,9 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
            bch2_fs_fsio_init(c))
                goto err;
 
+       if (c->opts.nochanges)
+               set_bit(JOURNAL_NOCHANGES, &c->journal.flags);
+
        mi = bch2_sb_get_members(c->disk_sb.sb);
        for (i = 0; i < c->sb.nr_devices; i++)
                if (bch2_dev_exists(c->disk_sb.sb, mi, i) &&