bcachefs: check_extent() refactoring
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 16 Jul 2023 18:45:23 +0000 (14:45 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:10:07 +0000 (17:10 -0400)
More prep work for reducing key_visible_in_snapshot() usage - this
rearranges how KEY_TYPE_whitout keys are handled, so that they can be
marked off in inode_warker->inode->seen_this_pos.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fsck.c

index f3e3cf475c2310c7ab96975dab19ae3128e1c0ba..3a3d89bdf1c96692c55ec3a5fb8c1595e847ffa3 100644 (file)
@@ -1345,13 +1345,6 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
                goto out;
        }
 
-       ret = snapshots_seen_update(c, s, iter->btree_id, k.k->p);
-       if (ret)
-               goto err;
-
-       if (k.k->type == KEY_TYPE_whiteout)
-               goto out;
-
        if (inode->last_pos.inode != k.k->p.inode) {
                ret = check_i_sectors(trans, inode);
                if (ret)
@@ -1365,66 +1358,74 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
        if (ret)
                goto err;
 
-       ret = check_overlapping_extents(trans, s, extent_ends, k, iter);
-       if (ret < 0)
-               goto err;
-
-       if (ret)
-               inode->recalculate_sums = true;
-
-       ret = extent_ends_at(extent_ends, s, k);
+       ret = snapshots_seen_update(c, s, iter->btree_id, k.k->p);
        if (ret)
                goto err;
 
-       if (fsck_err_on(!i, c,
-                       "extent in missing inode:\n  %s",
-                       (printbuf_reset(&buf),
-                        bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
-               goto delete;
+       if (k.k->type != KEY_TYPE_whiteout) {
+               if (fsck_err_on(!i, c,
+                               "extent in missing inode:\n  %s",
+                               (printbuf_reset(&buf),
+                                bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
+                       goto delete;
+
+               if (fsck_err_on(i &&
+                               !S_ISREG(i->inode.bi_mode) &&
+                               !S_ISLNK(i->inode.bi_mode), c,
+                               "extent in non regular inode mode %o:\n  %s",
+                               i->inode.bi_mode,
+                               (printbuf_reset(&buf),
+                                bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
+                       goto delete;
 
-       if (!i)
-               goto out;
+               ret = check_overlapping_extents(trans, s, extent_ends, k, iter);
+               if (ret < 0)
+                       goto err;
 
-       if (fsck_err_on(!S_ISREG(i->inode.bi_mode) &&
-                       !S_ISLNK(i->inode.bi_mode), c,
-                       "extent in non regular inode mode %o:\n  %s",
-                       i->inode.bi_mode,
-                       (printbuf_reset(&buf),
-                        bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
-               goto delete;
+               if (ret)
+                       inode->recalculate_sums = true;
+
+               ret = extent_ends_at(extent_ends, s, k);
+               if (ret)
+                       goto err;
+       }
 
        /*
         * Check inodes in reverse order, from oldest snapshots to newest, so
         * that we emit the fewest number of whiteouts necessary:
         */
        for (i = inode->inodes.data + inode->inodes.nr - 1;
-            i >= inode->inodes.data;
+            inode->inodes.data && i >= inode->inodes.data;
             --i) {
                if (i->snapshot > equiv.snapshot ||
                    !key_visible_in_snapshot(c, s, i->snapshot, equiv.snapshot))
                        continue;
 
-               if (fsck_err_on(!(i->inode.bi_flags & BCH_INODE_I_SIZE_DIRTY) &&
-                               k.k->p.offset > round_up(i->inode.bi_size, block_bytes(c)) >> 9 &&
-                               !bkey_extent_is_reservation(k), c,
-                               "extent type past end of inode %llu:%u, i_size %llu\n  %s",
-                               i->inode.bi_inum, i->snapshot, i->inode.bi_size,
-                               (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) {
-                       struct btree_iter iter2;
-
-                       bch2_trans_copy_iter(&iter2, iter);
-                       bch2_btree_iter_set_snapshot(&iter2, i->snapshot);
-                       ret =   bch2_btree_iter_traverse(&iter2) ?:
-                               bch2_btree_delete_at(trans, &iter2,
-                                       BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE);
-                       bch2_trans_iter_exit(trans, &iter2);
-                       if (ret)
-                               goto err;
-
-                       if (i->snapshot != equiv.snapshot) {
-                               ret = snapshots_seen_add(c, s, i->snapshot);
+               if (k.k->type != KEY_TYPE_whiteout) {
+                       if (fsck_err_on(!(i->inode.bi_flags & BCH_INODE_I_SIZE_DIRTY) &&
+                                       k.k->p.offset > round_up(i->inode.bi_size, block_bytes(c)) >> 9 &&
+                                       !bkey_extent_is_reservation(k), c,
+                                       "extent type past end of inode %llu:%u, i_size %llu\n  %s",
+                                       i->inode.bi_inum, i->snapshot, i->inode.bi_size,
+                                       (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) {
+                               struct btree_iter iter2;
+
+                               bch2_trans_copy_iter(&iter2, iter);
+                               bch2_btree_iter_set_snapshot(&iter2, i->snapshot);
+                               ret =   bch2_btree_iter_traverse(&iter2) ?:
+                                       bch2_btree_delete_at(trans, &iter2,
+                                               BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE);
+                               bch2_trans_iter_exit(trans, &iter2);
                                if (ret)
                                        goto err;
+
+                               if (i->snapshot != equiv.snapshot) {
+                                       ret = snapshots_seen_add(c, s, i->snapshot);
+                                       if (ret)
+                                               goto err;
+                               }
+
+                               iter->k.type = KEY_TYPE_whiteout;
                        }
                }
        }