]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to 07c2895cb3 bcachefs: Add a valgrind memcheck hint
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 13 Oct 2021 15:00:02 +0000 (11:00 -0400)
committerKent Overstreet <kent.overstreet@gmail.com>
Wed, 13 Oct 2021 15:00:02 +0000 (11:00 -0400)
13 files changed:
.bcachefs_revision
libbcachefs/btree_iter.c
libbcachefs/btree_update_interior.c
libbcachefs/dirent.c
libbcachefs/fs-common.c
libbcachefs/fsck.c
libbcachefs/migrate.c
libbcachefs/move.c
libbcachefs/subvolume.c
libbcachefs/subvolume.h
libbcachefs/super.c
libbcachefs/util.c
libbcachefs/varint.c

index f8ad12e76001c3cb1614a28ef0903a9fd7451c52..d1622d3d7f9f20b495d76006db145c4f044f7c42 100644 (file)
@@ -1 +1 @@
-4114ced1db465b8f4e7f4d6a78aa11416a9ab5d9
+07c2895cb3372c0e7b406ab13264de80c7ff19eb
index b5484d7702a49277de8f607153cc3f9633481f74..18d2733e6a6582dee32050de392b861a267b3d8f 100644 (file)
@@ -165,11 +165,20 @@ static bool bch2_btree_node_upgrade(struct btree_trans *trans,
 {
        struct btree *b = path->l[level].b;
 
-       EBUG_ON(btree_lock_want(path, level) != BTREE_NODE_INTENT_LOCKED);
-
        if (!is_btree_node(path, level))
                return false;
 
+       switch (btree_lock_want(path, level)) {
+       case BTREE_NODE_UNLOCKED:
+               BUG_ON(btree_node_locked(path, level));
+               return true;
+       case BTREE_NODE_READ_LOCKED:
+               BUG_ON(btree_node_intent_locked(path, level));
+               return bch2_btree_node_relock(trans, path, level);
+       case BTREE_NODE_INTENT_LOCKED:
+               break;
+       }
+
        if (btree_node_intent_locked(path, level))
                return true;
 
@@ -364,7 +373,8 @@ static void bch2_btree_path_verify_locks(struct btree_path *path)
        unsigned l;
 
        if (!path->nodes_locked) {
-               BUG_ON(path->uptodate == BTREE_ITER_UPTODATE);
+               BUG_ON(path->uptodate == BTREE_ITER_UPTODATE &&
+                      btree_path_node(path, path->level));
                return;
        }
 
@@ -1351,7 +1361,8 @@ retry_all:
 
                EBUG_ON(!(trans->paths_allocated & (1ULL << path->idx)));
 
-               if (path->nodes_locked)
+               if (path->nodes_locked ||
+                   !btree_path_node(path, path->level))
                        i++;
        }
 
@@ -1866,13 +1877,14 @@ bch2_btree_iter_traverse(struct btree_iter *iter)
 
 struct btree *bch2_btree_iter_peek_node(struct btree_iter *iter)
 {
+       struct btree_trans *trans = iter->trans;
        struct btree *b = NULL;
        int ret;
 
        EBUG_ON(iter->path->cached);
        bch2_btree_iter_verify(iter);
 
-       ret = bch2_btree_path_traverse(iter->trans, iter->path, iter->flags);
+       ret = bch2_btree_path_traverse(trans, iter->path, iter->flags);
        if (ret)
                goto out;
 
@@ -1884,7 +1896,11 @@ struct btree *bch2_btree_iter_peek_node(struct btree_iter *iter)
 
        bkey_init(&iter->k);
        iter->k.p = iter->pos = b->key.k.p;
+
+       iter->path = btree_path_set_pos(trans, iter->path, b->key.k.p,
+                                       iter->flags & BTREE_ITER_INTENT);
        iter->path->should_be_locked = true;
+       BUG_ON(iter->path->uptodate);
 out:
        bch2_btree_iter_verify_entry_exit(iter);
        bch2_btree_iter_verify(iter);
@@ -1949,7 +1965,11 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
 
        bkey_init(&iter->k);
        iter->k.p = iter->pos = b->key.k.p;
+
+       iter->path = btree_path_set_pos(trans, iter->path, b->key.k.p,
+                                       iter->flags & BTREE_ITER_INTENT);
        iter->path->should_be_locked = true;
+       BUG_ON(iter->path->uptodate);
 out:
        bch2_btree_iter_verify_entry_exit(iter);
        bch2_btree_iter_verify(iter);
index c54e6b46a02625af829272ecc33fc1524c5b57d5..98c05bb032a93c75e366cbed6501a6fbddb80646 100644 (file)
@@ -1945,9 +1945,16 @@ int bch2_btree_node_update_key(struct btree_trans *trans, struct btree_iter *ite
 {
        struct bch_fs *c = trans->c;
        struct btree *new_hash = NULL;
+       struct btree_path *path = iter->path;
        struct closure cl;
        int ret = 0;
 
+       if (!btree_node_intent_locked(path, b->c.level) &&
+           !bch2_btree_path_upgrade(trans, path, b->c.level + 1)) {
+               btree_trans_restart(trans);
+               return -EINTR;
+       }
+
        closure_init_stack(&cl);
 
        /*
@@ -1966,8 +1973,10 @@ int bch2_btree_node_update_key(struct btree_trans *trans, struct btree_iter *ite
                new_hash = bch2_btree_node_mem_alloc(c);
        }
 
+       path->intent_ref++;
        ret = __bch2_btree_node_update_key(trans, iter, b, new_hash,
                                           new_key, skip_triggers);
+       --path->intent_ref;
 
        if (new_hash) {
                mutex_lock(&c->btree_cache.lock);
index 8653a106809df91683ceb25326ea61a7d3102983..c7344ac87fcd894ca6c1c461d29780cb7737401f 100644 (file)
@@ -191,34 +191,15 @@ int __bch2_dirent_read_target(struct btree_trans *trans,
        if (likely(d.v->d_type != DT_SUBVOL)) {
                *inum = le64_to_cpu(d.v->d_inum);
        } else {
-               struct btree_iter iter;
-               struct bkey_s_c k;
-               struct bkey_s_c_subvolume s;
+               struct bch_subvolume s;
                int ret;
 
                *subvol = le64_to_cpu(d.v->d_inum);
-               bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes,
-                                    POS(0, *subvol),
-                                    BTREE_ITER_CACHED);
-               k = bch2_btree_iter_peek_slot(&iter);
-               ret = bkey_err(k);
-               if (ret)
-                       goto err;
-
-               if (k.k->type != KEY_TYPE_subvolume) {
-                       ret = -ENOENT;
-                       goto err;
-               }
 
-               s = bkey_s_c_to_subvolume(k);
-               *snapshot       = le32_to_cpu(s.v->snapshot);
-               *inum           = le64_to_cpu(s.v->inode);
-err:
-               if (ret == -ENOENT && !is_fsck)
-                       bch2_fs_inconsistent(trans->c, "pointer to missing subvolume %u",
-                                            *subvol);
+               ret = bch2_subvolume_get(trans, *subvol, !is_fsck, BTREE_ITER_CACHED, &s);
 
-               bch2_trans_iter_exit(trans, &iter);
+               *snapshot       = le32_to_cpu(s.snapshot);
+               *inum           = le64_to_cpu(s.inode);
        }
 
        return ret;
index 3e8e3c5bf87038db8252608b80a200116ec74080..c49de741e1e3b156bf603b33a8d74eafdb879262 100644 (file)
@@ -67,26 +67,14 @@ int bch2_create_trans(struct btree_trans *trans,
 
                if (!snapshot_src.inum) {
                        /* Inode wasn't specified, just snapshot: */
-                       struct btree_iter subvol_iter;
-                       struct bkey_s_c k;
-
-                       bch2_trans_iter_init(trans, &subvol_iter, BTREE_ID_subvolumes,
-                                            POS(0, snapshot_src.subvol), 0);
-                       k = bch2_btree_iter_peek_slot(&subvol_iter);
-
-                       ret = bkey_err(k);
-                       if (!ret && k.k->type != KEY_TYPE_subvolume) {
-                               bch_err(c, "subvolume %u not found",
-                                       snapshot_src.subvol);
-                               ret = -ENOENT;
-                       }
-
-                       if (!ret)
-                               snapshot_src.inum = le64_to_cpu(bkey_s_c_to_subvolume(k).v->inode);
-                       bch2_trans_iter_exit(trans, &subvol_iter);
+                       struct bch_subvolume s;
 
+                       ret = bch2_subvolume_get(trans, snapshot_src.subvol, true,
+                                                BTREE_ITER_CACHED, &s);
                        if (ret)
                                goto err;
+
+                       snapshot_src.inum = le64_to_cpu(s.inode);
                }
 
                ret = bch2_inode_peek(trans, &inode_iter, new_inode, snapshot_src,
@@ -279,18 +267,33 @@ int bch2_unlink_trans(struct btree_trans *trans,
        if (ret)
                goto err;
 
-       if (deleting_snapshot == 1 && !inode_u->bi_subvol) {
-               ret = -ENOENT;
-               goto err;
-       }
-
        if (deleting_snapshot <= 0 && S_ISDIR(inode_u->bi_mode)) {
                ret = bch2_empty_dir_trans(trans, inum);
                if (ret)
                        goto err;
        }
 
-       if (inode_u->bi_subvol) {
+       if (deleting_snapshot < 0 &&
+           inode_u->bi_subvol) {
+               struct bch_subvolume s;
+
+               ret = bch2_subvolume_get(trans, inode_u->bi_subvol, true,
+                                        BTREE_ITER_CACHED|
+                                        BTREE_ITER_WITH_UPDATES,
+                                        &s);
+               if (ret)
+                       goto err;
+
+               if (BCH_SUBVOLUME_SNAP(&s))
+                       deleting_snapshot = 1;
+       }
+
+       if (deleting_snapshot == 1) {
+               if (!inode_u->bi_subvol) {
+                       ret = -ENOENT;
+                       goto err;
+               }
+
                ret = bch2_subvolume_delete(trans, inode_u->bi_subvol,
                                            deleting_snapshot);
                if (ret)
@@ -309,6 +312,8 @@ int bch2_unlink_trans(struct btree_trans *trans,
                ret = bch2_btree_iter_traverse(&dirent_iter);
                if (ret)
                        goto err;
+       } else {
+               bch2_inode_nlink_dec(inode_u);
        }
 
        if (inode_u->bi_dir             == dirent_iter.pos.inode &&
@@ -319,7 +324,6 @@ int bch2_unlink_trans(struct btree_trans *trans,
 
        dir_u->bi_mtime = dir_u->bi_ctime = inode_u->bi_ctime = now;
        dir_u->bi_nlink -= is_subdir_for_nlink(inode_u);
-       bch2_inode_nlink_dec(inode_u);
 
        ret =   bch2_hash_delete_at(trans, bch2_dirent_hash_desc,
                                    &dir_hash, &dirent_iter,
index 3622fb4d18e22df3290622d2ba82bfa977abcbd4..208bf6df82b5fcf2eefb75b47ff4f96d07487831 100644 (file)
@@ -103,29 +103,14 @@ static int snapshot_lookup_subvol(struct btree_trans *trans, u32 snapshot,
 static int __subvol_lookup(struct btree_trans *trans, u32 subvol,
                           u32 *snapshot, u64 *inum)
 {
-       struct btree_iter iter;
-       struct bkey_s_c k;
+       struct bch_subvolume s;
        int ret;
 
-       bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes,
-                            POS(0, subvol), 0);
-       k = bch2_btree_iter_peek_slot(&iter);
-       ret = bkey_err(k);
-       if (ret)
-               goto err;
+       ret = bch2_subvolume_get(trans, subvol, false, 0, &s);
 
-       if (k.k->type != KEY_TYPE_subvolume) {
-               bch_err(trans->c, "subvolume %u not fonud", subvol);
-               ret = -ENOENT;
-               goto err;
-       }
-
-       *snapshot = le32_to_cpu(bkey_s_c_to_subvolume(k).v->snapshot);
-       *inum = le64_to_cpu(bkey_s_c_to_subvolume(k).v->inode);
-err:
-       bch2_trans_iter_exit(trans, &iter);
+       *snapshot = le32_to_cpu(s.snapshot);
+       *inum = le64_to_cpu(s.inode);
        return ret;
-
 }
 
 static int subvol_lookup(struct btree_trans *trans, u32 subvol,
index 7c764ee4ea09c2182865081f3e560256725e6aa3..9f9eb799337e2ae22197e0d13aa23febae6ac1be 100644 (file)
@@ -51,7 +51,8 @@ static int __bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags
                             BTREE_ITER_PREFETCH|
                             BTREE_ITER_ALL_SNAPSHOTS);
 
-       while ((k = bch2_btree_iter_peek(&iter)).k &&
+       while ((bch2_trans_begin(&trans),
+               (k = bch2_btree_iter_peek(&iter)).k) &&
               !(ret = bkey_err(k))) {
                if (!bch2_bkey_has_device(k, dev_idx)) {
                        bch2_btree_iter_advance(&iter);
@@ -72,8 +73,6 @@ static int __bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags
                 */
                bch2_extent_normalize(c, bkey_i_to_s(sk.k));
 
-               bch2_btree_iter_set_pos(&iter, bkey_start_pos(&sk.k->k));
-
                ret   = bch2_btree_iter_traverse(&iter) ?:
                        bch2_trans_update(&trans, &iter, sk.k,
                                          BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE) ?:
@@ -125,12 +124,14 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
        closure_init_stack(&cl);
 
        for (id = 0; id < BTREE_ID_NR; id++) {
-               for_each_btree_node(&trans, iter, id, POS_MIN,
-                                   BTREE_ITER_PREFETCH, b) {
-retry:
+               bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0,
+                                         BTREE_ITER_PREFETCH);
+
+               while (bch2_trans_begin(&trans),
+                      (b = bch2_btree_iter_peek_node(&iter))) {
                        if (!bch2_bkey_has_device(bkey_i_to_s_c(&b->key),
                                                  dev_idx))
-                               continue;
+                               goto next;
 
                        bch2_bkey_buf_copy(&k, c, &b->key);
 
@@ -143,14 +144,16 @@ retry:
 
                        ret = bch2_btree_node_update_key(&trans, &iter, b, k.k, false);
                        if (ret == -EINTR) {
-                               b = bch2_btree_iter_peek_node(&iter);
                                ret = 0;
-                               goto retry;
+                               continue;
                        }
+
                        if (ret) {
                                bch_err(c, "Error updating btree node key: %i", ret);
                                break;
                        }
+next:
+                       bch2_btree_iter_next_node(&iter);
                }
                bch2_trans_iter_exit(&trans, &iter);
 
index 44a61818d9a44861661d72841ee006d1a1cfa845..0a8fe7085cc05b5f2afa4253623ce091e744ad5f 100644 (file)
@@ -883,9 +883,11 @@ static int bch2_move_btree(struct bch_fs *c,
             id++) {
                stats->btree_id = id;
 
-               for_each_btree_node(&trans, iter, id,
-                                   id == start_btree_id ? start_pos : POS_MIN,
-                                   BTREE_ITER_PREFETCH, b) {
+               bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0,
+                                         BTREE_ITER_PREFETCH);
+
+               while (bch2_trans_begin(&trans),
+                      (b = bch2_btree_iter_peek_node(&iter))) {
                        if (kthread && kthread_should_stop())
                                break;
 
@@ -911,6 +913,7 @@ static int bch2_move_btree(struct bch_fs *c,
                                        b->data->keys.seq, 0) ?: ret;
 next:
                        bch2_trans_cond_resched(&trans);
+                       bch2_btree_iter_next_node(&iter);
                }
                bch2_trans_iter_exit(&trans, &iter);
 
@@ -943,16 +946,9 @@ static enum data_cmd rereplicate_pred(struct bch_fs *c, void *arg,
                                      struct data_opts *data_opts)
 {
        unsigned nr_good = bch2_bkey_durability(c, k);
-       unsigned replicas = 0;
-
-       switch (k.k->type) {
-       case KEY_TYPE_btree_ptr:
-               replicas = c->opts.metadata_replicas;
-               break;
-       case KEY_TYPE_extent:
-               replicas = io_opts->data_replicas;
-               break;
-       }
+       unsigned replicas = bkey_is_btree_ptr(k.k)
+               ? c->opts.metadata_replicas
+               : io_opts->data_replicas;
 
        if (!nr_good || nr_good >= replicas)
                return DATA_SKIP;
index ff3b4d2d86b93ca0025a12fd8acebe7d7ef52a41..d1c111050c35cdf2601e011f504b46175ef58c2d 100644 (file)
@@ -89,23 +89,6 @@ int bch2_mark_snapshot(struct bch_fs *c,
        return 0;
 }
 
-static int subvol_lookup(struct btree_trans *trans, unsigned id, struct bch_subvolume *s)
-{
-       struct btree_iter iter;
-       struct bkey_s_c k;
-       int ret;
-
-       bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes, POS(0, id), 0);
-       k = bch2_btree_iter_peek_slot(&iter);
-       ret = bkey_err(k) ?: k.k->type == KEY_TYPE_subvolume ? 0 : -ENOENT;
-
-       if (!ret)
-               *s = *bkey_s_c_to_subvolume(k).v;
-
-       bch2_trans_iter_exit(trans, &iter);
-       return ret;
-}
-
 static int snapshot_lookup(struct btree_trans *trans, u32 id,
                           struct bch_snapshot *s)
 {
@@ -195,7 +178,7 @@ static int bch2_snapshot_check(struct btree_trans *trans,
        int ret;
 
        id = le32_to_cpu(s.v->subvol);
-       ret = lockrestart_do(trans, subvol_lookup(trans, id, &subvol));
+       ret = lockrestart_do(trans, bch2_subvolume_get(trans, id, 0, false, &subvol));
        if (ret == -ENOENT)
                bch_err(trans->c, "snapshot node %llu has nonexistent subvolume %u",
                        s.k->p.offset, id);
@@ -798,34 +781,44 @@ void bch2_subvolume_to_text(struct printbuf *out, struct bch_fs *c,
               le32_to_cpu(s.v->snapshot));
 }
 
-int bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvol,
-                               u32 *snapid)
+int bch2_subvolume_get(struct btree_trans *trans, unsigned subvol,
+                      bool inconsistent_if_not_found,
+                      int iter_flags,
+                      struct bch_subvolume *s)
 {
        struct btree_iter iter;
        struct bkey_s_c k;
        int ret;
 
-       bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes,
-                            POS(0, subvol),
-                            BTREE_ITER_CACHED|
-                            BTREE_ITER_WITH_UPDATES);
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes, POS(0, subvol),
+                            iter_flags);
        k = bch2_btree_iter_peek_slot(&iter);
-       ret = bkey_err(k);
-       if (ret)
-               goto err;
+       ret = bkey_err(k) ?: k.k->type == KEY_TYPE_subvolume ? 0 : -ENOENT;
 
-       if (k.k->type != KEY_TYPE_subvolume) {
+       if (ret == -ENOENT && inconsistent_if_not_found)
                bch2_fs_inconsistent(trans->c, "missing subvolume %u", subvol);
-               ret = -EIO;
-               goto err;
-       }
+       if (!ret)
+               *s = *bkey_s_c_to_subvolume(k).v;
 
-       *snapid = le32_to_cpu(bkey_s_c_to_subvolume(k).v->snapshot);
-err:
        bch2_trans_iter_exit(trans, &iter);
        return ret;
 }
 
+int bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvol,
+                               u32 *snapid)
+{
+       struct bch_subvolume s;
+       int ret;
+
+       ret = bch2_subvolume_get(trans, subvol, true,
+                                BTREE_ITER_CACHED|
+                                BTREE_ITER_WITH_UPDATES,
+                                &s);
+
+       *snapid = le32_to_cpu(s.snapshot);
+       return ret;
+}
+
 /* XXX: mark snapshot id for deletion, walk btree and delete: */
 int bch2_subvolume_delete(struct btree_trans *trans, u32 subvolid,
                          int deleting_snapshot)
index 0740c7b7f77288fe267a3880f3602c9475159f42..ed02b982ff96f6f0eec46ff217e5ef1f3bbc369e 100644 (file)
@@ -104,6 +104,8 @@ void bch2_subvolume_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c)
        .val_to_text    = bch2_subvolume_to_text,               \
 }
 
+int bch2_subvolume_get(struct btree_trans *, unsigned,
+                      bool, int, struct bch_subvolume *);
 int bch2_subvolume_get_snapshot(struct btree_trans *, u32, u32 *);
 
 int bch2_subvolume_delete(struct btree_trans *, u32, int);
index 1feb7dee2e0c1ca744683cb9158f8596fdcb4f32..bb633e3df6187212380216de4b3bb983229b8e7c 100644 (file)
@@ -1452,15 +1452,18 @@ static int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca)
        bch2_trans_init(&trans, c, 0, 0);
 
        for (i = 0; i < ca->mi.nbuckets; i++) {
-               ret = bch2_btree_key_cache_flush(&trans,
-                               BTREE_ID_alloc, POS(ca->dev_idx, i));
+               ret = lockrestart_do(&trans,
+                       bch2_btree_key_cache_flush(&trans,
+                               BTREE_ID_alloc, POS(ca->dev_idx, i)));
                if (ret)
                        break;
        }
        bch2_trans_exit(&trans);
 
-       if (ret)
+       if (ret) {
+               bch_err(c, "error %i removing dev alloc info", ret);
                return ret;
+       }
 
        return bch2_btree_delete_range(c, BTREE_ID_alloc,
                                       POS(ca->dev_idx, 0),
index 463260c0458575c2492c165087e4e6eb05c3d58f..9f21f68e84d34333474f89dcf4504b715d02c95e 100644 (file)
@@ -887,9 +887,14 @@ void eytzinger0_find_test(void)
  */
 u64 *bch2_acc_percpu_u64s(u64 __percpu *p, unsigned nr)
 {
-       u64 *ret = this_cpu_ptr(p);
+       u64 *ret;
        int cpu;
 
+       /* access to pcpu vars has to be blocked by other locking */
+       preempt_disable();
+       ret = this_cpu_ptr(p);
+       preempt_enable();
+
        for_each_possible_cpu(cpu) {
                u64 *i = per_cpu_ptr(p, cpu);
 
index 752179b26a1eaac8db7c5203eed07face0306db9..a2d6bb7136c7d412d95469ac09b2c063fd0dd86d 100644 (file)
@@ -4,6 +4,10 @@
 #include <linux/string.h>
 #include <asm/unaligned.h>
 
+#ifdef CONFIG_VALGRIND
+#include <valgrind/memcheck.h>
+#endif
+
 #include "varint.h"
 
 /**
@@ -95,6 +99,9 @@ int bch2_varint_encode_fast(u8 *out, u64 v)
  */
 int bch2_varint_decode_fast(const u8 *in, const u8 *end, u64 *out)
 {
+#ifdef CONFIG_VALGRIND
+       VALGRIND_MAKE_MEM_DEFINED(in, 8);
+#endif
        u64 v = get_unaligned_le64(in);
        unsigned bytes = ffz(*in) + 1;