]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/btree_gc.c
Update upstream source from tag 'v1.6.3'
[bcachefs-tools-debian] / libbcachefs / btree_gc.c
index ea1d0ed70f5022e2793d9d4c01b075c6568a112b..6c52f116098f7d24723771d79e5374880d743a56 100644 (file)
 #define DROP_THIS_NODE         10
 #define DROP_PREV_NODE         11
 
+static struct bkey_s unsafe_bkey_s_c_to_s(struct bkey_s_c k)
+{
+       return (struct bkey_s) {{{
+               (struct bkey *) k.k,
+               (struct bch_val *) k.v
+       }}};
+}
+
 static bool should_restart_for_topology_repair(struct bch_fs *c)
 {
        return c->opts.fix_errors != FSCK_FIX_no &&
@@ -381,7 +389,8 @@ again:
        have_child = dropped_children = false;
        bch2_bkey_buf_init(&prev_k);
        bch2_bkey_buf_init(&cur_k);
-       bch2_btree_and_journal_iter_init_node_iter(&iter, c, b);
+       bch2_btree_and_journal_iter_init_node_iter(trans, &iter, b);
+       iter.prefetch = true;
 
        while ((k = bch2_btree_and_journal_iter_peek(&iter)).k) {
                BUG_ON(bpos_lt(k.k->p, b->data->min_key));
@@ -398,7 +407,7 @@ again:
                printbuf_reset(&buf);
                bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(cur_k.k));
 
-               if (mustfix_fsck_err_on(ret == -EIO, c,
+               if (mustfix_fsck_err_on(bch2_err_matches(ret, EIO), c,
                                btree_node_unreadable,
                                "Topology repair: unreadable btree node at btree %s level %u:\n"
                                "  %s",
@@ -470,7 +479,8 @@ again:
                goto err;
 
        bch2_btree_and_journal_iter_exit(&iter);
-       bch2_btree_and_journal_iter_init_node_iter(&iter, c, b);
+       bch2_btree_and_journal_iter_init_node_iter(trans, &iter, b);
+       iter.prefetch = true;
 
        while ((k = bch2_btree_and_journal_iter_peek(&iter)).k) {
                bch2_bkey_buf_reassemble(&cur_k, c, k);
@@ -589,7 +599,7 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
                              "bucket %u:%zu data type %s ptr gen %u missing in alloc btree\n"
                              "while marking %s",
                              p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
-                             bch2_data_types[ptr_data_type(k->k, &p.ptr)],
+                             bch2_data_type_str(ptr_data_type(k->k, &p.ptr)),
                              p.ptr.gen,
                              (printbuf_reset(&buf),
                               bch2_bkey_val_to_text(&buf, c, *k), buf.buf)))) {
@@ -607,7 +617,7 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
                              "bucket %u:%zu data type %s ptr gen in the future: %u > %u\n"
                              "while marking %s",
                              p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
-                             bch2_data_types[ptr_data_type(k->k, &p.ptr)],
+                             bch2_data_type_str(ptr_data_type(k->k, &p.ptr)),
                              p.ptr.gen, g->gen,
                              (printbuf_reset(&buf),
                               bch2_bkey_val_to_text(&buf, c, *k), buf.buf)))) {
@@ -629,7 +639,7 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
                              "bucket %u:%zu gen %u data type %s: ptr gen %u too stale\n"
                              "while marking %s",
                              p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr), g->gen,
-                             bch2_data_types[ptr_data_type(k->k, &p.ptr)],
+                             bch2_data_type_str(ptr_data_type(k->k, &p.ptr)),
                              p.ptr.gen,
                              (printbuf_reset(&buf),
                               bch2_bkey_val_to_text(&buf, c, *k), buf.buf))))
@@ -641,7 +651,7 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
                              "bucket %u:%zu data type %s stale dirty ptr: %u < %u\n"
                              "while marking %s",
                              p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
-                             bch2_data_types[ptr_data_type(k->k, &p.ptr)],
+                             bch2_data_type_str(ptr_data_type(k->k, &p.ptr)),
                              p.ptr.gen, g->gen,
                              (printbuf_reset(&buf),
                               bch2_bkey_val_to_text(&buf, c, *k), buf.buf))))
@@ -656,8 +666,8 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
                                "bucket %u:%zu different types of data in same bucket: %s, %s\n"
                                "while marking %s",
                                p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
-                               bch2_data_types[g->data_type],
-                               bch2_data_types[data_type],
+                               bch2_data_type_str(g->data_type),
+                               bch2_data_type_str(data_type),
                                (printbuf_reset(&buf),
                                 bch2_bkey_val_to_text(&buf, c, *k), buf.buf))) {
                        if (data_type == BCH_DATA_btree) {
@@ -805,9 +815,6 @@ static int bch2_gc_mark_key(struct btree_trans *trans, enum btree_id btree_id,
        struct bch_fs *c = trans->c;
        struct bkey deleted = KEY(0, 0, 0);
        struct bkey_s_c old = (struct bkey_s_c) { &deleted, NULL };
-       unsigned flags =
-               BTREE_TRIGGER_GC|
-               (initial ? BTREE_TRIGGER_NOATOMIC : 0);
        int ret = 0;
 
        deleted.p = k->k->p;
@@ -829,7 +836,7 @@ static int bch2_gc_mark_key(struct btree_trans *trans, enum btree_id btree_id,
        }
 
        ret = commit_do(trans, NULL, NULL, 0,
-                       bch2_mark_key(trans, btree_id, level, old, *k, flags));
+                       bch2_key_trigger(trans, btree_id, level, old, unsafe_bkey_s_c_to_s(*k), BTREE_TRIGGER_GC));
 fsck_err:
 err:
        bch_err_fn(c, ret);
@@ -926,7 +933,7 @@ static int bch2_gc_btree_init_recurse(struct btree_trans *trans, struct btree *b
        struct printbuf buf = PRINTBUF;
        int ret = 0;
 
-       bch2_btree_and_journal_iter_init_node_iter(&iter, c, b);
+       bch2_btree_and_journal_iter_init_node_iter(trans, &iter, b);
        bch2_bkey_buf_init(&prev);
        bch2_bkey_buf_init(&cur);
        bkey_init(&prev.k->k);
@@ -958,7 +965,8 @@ static int bch2_gc_btree_init_recurse(struct btree_trans *trans, struct btree *b
 
        if (b->c.level > target_depth) {
                bch2_btree_and_journal_iter_exit(&iter);
-               bch2_btree_and_journal_iter_init_node_iter(&iter, c, b);
+               bch2_btree_and_journal_iter_init_node_iter(trans, &iter, b);
+               iter.prefetch = true;
 
                while ((k = bch2_btree_and_journal_iter_peek(&iter)).k) {
                        struct btree *child;
@@ -971,7 +979,7 @@ static int bch2_gc_btree_init_recurse(struct btree_trans *trans, struct btree *b
                                                false);
                        ret = PTR_ERR_OR_ZERO(child);
 
-                       if (ret == -EIO) {
+                       if (bch2_err_matches(ret, EIO)) {
                                bch2_topology_error(c);
 
                                if (__fsck_err(c,
@@ -1185,9 +1193,7 @@ static void bch2_gc_free(struct bch_fs *c)
        genradix_free(&c->gc_stripes);
 
        for_each_member_device(c, ca) {
-               kvpfree(rcu_dereference_protected(ca->buckets_gc, 1),
-                       sizeof(struct bucket_array) +
-                       ca->mi.nbuckets * sizeof(struct bucket));
+               kvfree(rcu_dereference_protected(ca->buckets_gc, 1));
                ca->buckets_gc = NULL;
 
                free_percpu(ca->usage_gc);
@@ -1233,11 +1239,11 @@ static int bch2_gc_done(struct bch_fs *c,
 
                for (i = 0; i < BCH_DATA_NR; i++) {
                        copy_dev_field(dev_usage_buckets_wrong,
-                                      d[i].buckets,    "%s buckets", bch2_data_types[i]);
+                                      d[i].buckets,    "%s buckets", bch2_data_type_str(i));
                        copy_dev_field(dev_usage_sectors_wrong,
-                                      d[i].sectors,    "%s sectors", bch2_data_types[i]);
+                                      d[i].sectors,    "%s sectors", bch2_data_type_str(i));
                        copy_dev_field(dev_usage_fragmented_wrong,
-                                      d[i].fragmented, "%s fragmented", bch2_data_types[i]);
+                                      d[i].fragmented, "%s fragmented", bch2_data_type_str(i));
                }
        }
 
@@ -1248,19 +1254,19 @@ static int bch2_gc_done(struct bch_fs *c,
                        bch2_acc_percpu_u64s((u64 __percpu *) c->usage_gc, nr);
 
                copy_fs_field(fs_usage_hidden_wrong,
-                             hidden,           "hidden");
+                             b.hidden,         "hidden");
                copy_fs_field(fs_usage_btree_wrong,
-                             btree,            "btree");
+                             b.btree,          "btree");
 
                if (!metadata_only) {
                        copy_fs_field(fs_usage_data_wrong,
-                                     data,     "data");
+                                     b.data,   "data");
                        copy_fs_field(fs_usage_cached_wrong,
-                                     cached,   "cached");
+                                     b.cached, "cached");
                        copy_fs_field(fs_usage_reserved_wrong,
-                                     reserved, "reserved");
+                                     b.reserved,       "reserved");
                        copy_fs_field(fs_usage_nr_inodes_wrong,
-                                     nr_inodes,"nr_inodes");
+                                     b.nr_inodes,"nr_inodes");
 
                        for (i = 0; i < BCH_REPLICAS_MAX; i++)
                                copy_fs_field(fs_usage_persistent_reserved_wrong,
@@ -1412,8 +1418,8 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
                        ": got %s, should be %s",
                        iter->pos.inode, iter->pos.offset,
                        gc.gen,
-                       bch2_data_types[new.data_type],
-                       bch2_data_types[gc.data_type]))
+                       bch2_data_type_str(new.data_type),
+                       bch2_data_type_str(gc.data_type)))
                new.data_type = gc.data_type;
 
 #define copy_bucket_field(_errtype, _f)                                        \
@@ -1423,7 +1429,7 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
                        ": got %u, should be %u",                       \
                        iter->pos.inode, iter->pos.offset,              \
                        gc.gen,                                         \
-                       bch2_data_types[gc.data_type],                  \
+                       bch2_data_type_str(gc.data_type),               \
                        new._f, gc._f))                                 \
                new._f = gc._f;                                         \
 
@@ -1486,7 +1492,7 @@ static int bch2_gc_alloc_done(struct bch_fs *c, bool metadata_only)
 static int bch2_gc_alloc_start(struct bch_fs *c, bool metadata_only)
 {
        for_each_member_device(c, ca) {
-               struct bucket_array *buckets = kvpmalloc(sizeof(struct bucket_array) +
+               struct bucket_array *buckets = kvmalloc(sizeof(struct bucket_array) +
                                ca->mi.nbuckets * sizeof(struct bucket),
                                GFP_KERNEL|__GFP_ZERO);
                if (!buckets) {
@@ -1589,7 +1595,7 @@ static int bch2_gc_write_reflink_key(struct btree_trans *trans,
                if (!r->refcount)
                        new->k.type = KEY_TYPE_deleted;
                else
-                       *bkey_refcount(new) = cpu_to_le64(r->refcount);
+                       *bkey_refcount(bkey_i_to_s(new)) = cpu_to_le64(r->refcount);
        }
 fsck_err:
        printbuf_exit(&buf);
@@ -1844,7 +1850,6 @@ static int gc_btree_gens_key(struct btree_trans *trans,
 {
        struct bch_fs *c = trans->c;
        struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
-       const struct bch_extent_ptr *ptr;
        struct bkey_i *u;
        int ret;
 
@@ -1966,7 +1971,7 @@ int bch2_gc_gens(struct bch_fs *c)
 
        c->gc_count++;
 
-       bch2_time_stats_update(&c->times[BCH_TIME_btree_gc], start_time);
+       time_stats_update(&c->times[BCH_TIME_btree_gc], start_time);
        trace_and_count(c, gc_gens_end, c);
 err:
        for_each_member_device(c, ca) {