]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/fsck.c
Update bcachefs sources to 6a20aede29 bcachefs: Fix quotas + snapshots
[bcachefs-tools-debian] / libbcachefs / fsck.c
index 6319f2f7b16f067f17995365a2d69f7fa91f031d..eb3609aa45933afcca1d37b3e3554b15540ba99e 100644 (file)
@@ -72,26 +72,14 @@ static s64 bch2_count_subdirs(struct btree_trans *trans, u64 inum,
 static int __snapshot_lookup_subvol(struct btree_trans *trans, u32 snapshot,
                                    u32 *subvol)
 {
-       struct btree_iter iter;
-       struct bkey_s_c k;
-       int ret;
-
-       bch2_trans_iter_init(trans, &iter, BTREE_ID_snapshots,
-                            POS(0, snapshot), 0);
-       k = bch2_btree_iter_peek_slot(&iter);
-       ret = bkey_err(k);
-       if (ret)
-               goto err;
-
-       if (k.k->type != KEY_TYPE_snapshot) {
+       struct bch_snapshot s;
+       int ret = bch2_bkey_get_val_typed(trans, BTREE_ID_snapshots,
+                                         POS(0, snapshot), 0,
+                                         snapshot, &s);
+       if (!ret)
+               *subvol = le32_to_cpu(s.subvol);
+       else if (ret == -ENOENT)
                bch_err(trans->c, "snapshot %u not fonud", snapshot);
-               ret = -ENOENT;
-               goto err;
-       }
-
-       *subvol = le32_to_cpu(bkey_s_c_to_snapshot(k).v->subvol);
-err:
-       bch2_trans_iter_exit(trans, &iter);
        return ret;
 
 }
@@ -152,9 +140,8 @@ static int __lookup_inode(struct btree_trans *trans, u64 inode_nr,
        struct bkey_s_c k;
        int ret;
 
-       bch2_trans_iter_init(trans, &iter, BTREE_ID_inodes,
-                            SPOS(0, inode_nr, *snapshot), 0);
-       k = bch2_btree_iter_peek_slot(&iter);
+       k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes,
+                              SPOS(0, inode_nr, *snapshot), 0);
        ret = bkey_err(k);
        if (ret)
                goto err;
@@ -259,10 +246,8 @@ static int fsck_inode_rm(struct btree_trans *trans, u64 inum, u32 snapshot)
 retry:
        bch2_trans_begin(trans);
 
-       bch2_trans_iter_init(trans, &iter, BTREE_ID_inodes,
-                            SPOS(0, inum, snapshot), BTREE_ITER_INTENT);
-       k = bch2_btree_iter_peek_slot(&iter);
-
+       k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes,
+                              SPOS(0, inum, snapshot), BTREE_ITER_INTENT);
        ret = bkey_err(k);
        if (ret)
                goto err;
@@ -453,22 +438,14 @@ static int remove_backpointer(struct btree_trans *trans,
                              struct bch_inode_unpacked *inode)
 {
        struct btree_iter iter;
-       struct bkey_s_c k;
+       struct bkey_s_c_dirent d;
        int ret;
 
-       bch2_trans_iter_init(trans, &iter, BTREE_ID_dirents,
-                            POS(inode->bi_dir, inode->bi_dir_offset), 0);
-       k = bch2_btree_iter_peek_slot(&iter);
-       ret = bkey_err(k);
-       if (ret)
-               goto out;
-       if (k.k->type != KEY_TYPE_dirent) {
-               ret = -ENOENT;
-               goto out;
-       }
-
-       ret = __remove_dirent(trans, k.k->p);
-out:
+       d = bch2_bkey_get_iter_typed(trans, &iter, BTREE_ID_dirents,
+                                    POS(inode->bi_dir, inode->bi_dir_offset), 0,
+                                    dirent);
+       ret =   bkey_err(d) ?:
+               __remove_dirent(trans, d.k->p);
        bch2_trans_iter_exit(trans, &iter);
        return ret;
 }
@@ -673,10 +650,8 @@ static int __walk_inode(struct btree_trans *trans,
 
        pos.snapshot = bch2_snapshot_equiv(c, pos.snapshot);
 
-       if (pos.inode == w->cur_inum) {
-               w->first_this_inode = false;
+       if (pos.inode == w->cur_inum)
                goto lookup_snapshot;
-       }
 
        w->inodes.nr = 0;
 
@@ -790,7 +765,7 @@ static int hash_redo_key(struct btree_trans *trans,
        if (IS_ERR(delete))
                return PTR_ERR(delete);
 
-       tmp = bch2_bkey_make_mut(trans, k);
+       tmp = bch2_bkey_make_mut_noupdate(trans, k);
        if (IS_ERR(tmp))
                return PTR_ERR(tmp);
 
@@ -862,10 +837,10 @@ bad_hash:
                     (printbuf_reset(&buf),
                      bch2_bkey_val_to_text(&buf, c, hash_k), buf.buf))) {
                ret = hash_redo_key(trans, desc, hash_info, k_iter, hash_k);
-               if (ret) {
+               if (ret && !bch2_err_matches(ret, BCH_ERR_transaction_restart))
                        bch_err(c, "hash_redo_key err %s", bch2_err_str(ret));
+               if (ret)
                        return ret;
-               }
                ret = -BCH_ERR_transaction_restart_nested;
        }
 fsck_err:
@@ -1083,20 +1058,7 @@ static struct bkey_s_c_dirent dirent_get_by_pos(struct btree_trans *trans,
                                                struct btree_iter *iter,
                                                struct bpos pos)
 {
-       struct bkey_s_c k;
-       int ret;
-
-       bch2_trans_iter_init(trans, iter, BTREE_ID_dirents, pos, 0);
-       k = bch2_btree_iter_peek_slot(iter);
-       ret = bkey_err(k);
-       if (!ret && k.k->type != KEY_TYPE_dirent)
-               ret = -ENOENT;
-       if (ret) {
-               bch2_trans_iter_exit(trans, iter);
-               return (struct bkey_s_c_dirent) { .k = ERR_PTR(ret) };
-       }
-
-       return bkey_s_c_to_dirent(k);
+       return bch2_bkey_get_iter_typed(trans, iter, BTREE_ID_dirents, pos, 0, dirent);
 }
 
 static bool inode_points_to_dirent(struct bch_inode_unpacked *inode,
@@ -1124,7 +1086,7 @@ static int inode_backpointer_exists(struct btree_trans *trans,
 
        d = dirent_get_by_pos(trans, &iter,
                        SPOS(inode->bi_dir, inode->bi_dir_offset, snapshot));
-       ret = bkey_err(d.s_c);
+       ret = bkey_err(d);
        if (ret)
                return ret == -ENOENT ? 0 : ret;
 
@@ -1639,6 +1601,10 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
        if (ret < 0)
                goto err;
 
+       if (dir->first_this_inode)
+               *hash_info = bch2_hash_info_init(c, &dir->inodes.data[0].inode);
+       dir->first_this_inode = false;
+
        if (fsck_err_on(ret == INT_MAX, c,
                        "dirent in nonexisting directory:\n%s",
                        (printbuf_reset(&buf),
@@ -1665,11 +1631,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
                goto out;
        }
 
-       if (dir->first_this_inode)
-               *hash_info = bch2_hash_info_init(c, &dir->inodes.data[0].inode);
-
-       ret = hash_check_key(trans, bch2_dirent_hash_desc,
-                            hash_info, iter, k);
+       ret = hash_check_key(trans, bch2_dirent_hash_desc, hash_info, iter, k);
        if (ret < 0)
                goto err;
        if (ret) {
@@ -1822,6 +1784,10 @@ static int check_xattr(struct btree_trans *trans, struct btree_iter *iter,
        if (ret < 0)
                return ret;
 
+       if (inode->first_this_inode)
+               *hash_info = bch2_hash_info_init(c, &inode->inodes.data[0].inode);
+       inode->first_this_inode = false;
+
        if (fsck_err_on(ret == INT_MAX, c,
                        "xattr for missing inode %llu",
                        k.k->p.inode))
@@ -1832,9 +1798,6 @@ static int check_xattr(struct btree_trans *trans, struct btree_iter *iter,
 
        ret = 0;
 
-       if (inode->first_this_inode)
-               *hash_info = bch2_hash_info_init(c, &inode->inodes.data[0].inode);
-
        ret = hash_check_key(trans, bch2_xattr_hash_desc, hash_info, iter, k);
 fsck_err:
        if (ret && !bch2_err_matches(ret, BCH_ERR_transaction_restart))
@@ -2464,7 +2427,8 @@ int bch2_fsck_full(struct bch_fs *c)
 {
        int ret;
 again:
-       ret =   bch2_fs_check_snapshots(c) ?:
+       ret =   bch2_fs_check_snapshot_trees(c);
+               bch2_fs_check_snapshots(c) ?:
                bch2_fs_check_subvols(c) ?:
                bch2_delete_dead_snapshots(c) ?:
                check_inodes(c, true) ?: