diff options
| author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-03-16 00:46:26 -0400 |
|---|---|---|
| committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:09:12 -0400 |
| commit | b9e1adf57988fb4632b86c43fde1551a24299b86 (patch) | |
| tree | 3f6d8942ede2c864a84cb66501bf80d7682c60a7 /fs/bcachefs/fsck.c | |
| parent | 14b393ee768e8339b9c64f82df24e8c081bdbff9 (diff) | |
| download | linux-b9e1adf57988fb4632b86c43fde1551a24299b86.tar.gz linux-b9e1adf57988fb4632b86c43fde1551a24299b86.tar.bz2 linux-b9e1adf57988fb4632b86c43fde1551a24299b86.zip | |
bcachefs: Add support for dirents that point to subvolumes
Dirents currently always point to inodes. Subvolumes add a new type of
dirent, with d_type DT_SUBVOL, that instead points to an entry in the
subvolumes btree, and the subvolume has a pointer to the root inode.
This patch adds bch2_dirent_read_target() to get the inode (and
potentially subvolume) a dirent points to, and changes existing code to
use that instead of reading from d_inum directly.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/fsck.c')
| -rw-r--r-- | fs/bcachefs/fsck.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 62158c0803db..dca4abda2c41 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -723,6 +723,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter, struct bkey_s_c_dirent d; struct bch_inode_unpacked target; u32 target_snapshot; + u32 target_subvol; bool have_target; bool backpointer_exists = true; u64 d_inum; @@ -783,6 +784,10 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter, d = bkey_s_c_to_dirent(k); d_inum = le64_to_cpu(d.v->d_inum); + ret = bch2_dirent_read_target(trans, d, &d_inum); + if (ret && ret != -ENOENT) + return ret; + ret = __lookup_inode(trans, d_inum, &target, &target_snapshot); if (ret && ret != -ENOENT) return ret; @@ -855,7 +860,23 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter, } } - if (fsck_err_on(d.v->d_type != mode_to_type(target.bi_mode), c, + target_subvol = d.v->d_type == DT_SUBVOL + ? le64_to_cpu(d.v->d_inum) : 0; + + if (fsck_err_on(target.bi_subvol != target_subvol, c, + "subvol root %llu has wrong subvol field:\n" + "got %u\n" + "should be %u", + target.bi_inum, + target.bi_subvol, + target_subvol)) { + target.bi_subvol = target_subvol; + + ret = write_inode(trans, &target, target_snapshot); + return ret ?: -EINTR; + } + + if (fsck_err_on(vfs_d_type(d.v->d_type) != mode_to_type(target.bi_mode), c, "incorrect d_type: should be %u:\n%s", mode_to_type(target.bi_mode), (bch2_bkey_val_to_text(&PBUF(buf), c, |
