mirror of
https://github.com/torvalds/linux.git
synced 2026-05-21 13:27:57 +02:00
bcachefs: Don't rely on snapshot_tree.master_subvol for reattaching
Previously, fsck used the snapshot tree's master subvol for finding the root inode number - but the master subvol might have been deleting, and setting a new one should be a user operation; meaning we can't rely on it existing. Fortunately, for finding the root inode number in a tree of snapshots, finding any associated subvolume works. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
4541408391
commit
b5e4cd0871
|
|
@ -118,6 +118,7 @@
|
|||
x(ENOENT, ENOENT_dev_not_found) \
|
||||
x(ENOENT, ENOENT_dev_idx_not_found) \
|
||||
x(ENOENT, ENOENT_inode_no_backpointer) \
|
||||
x(ENOENT, ENOENT_no_snapshot_tree_subvol) \
|
||||
x(ENOTEMPTY, ENOTEMPTY_dir_not_empty) \
|
||||
x(ENOTEMPTY, ENOTEMPTY_subvol_not_empty) \
|
||||
x(EEXIST, EEXIST_str_hash_set) \
|
||||
|
|
|
|||
|
|
@ -205,6 +205,36 @@ static int __remove_dirent(struct btree_trans *trans, struct bpos pos)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find any subvolume associated with a tree of snapshots
|
||||
* We can't rely on master_subvol - it might have been deleted.
|
||||
*/
|
||||
static int find_snapshot_tree_subvol(struct btree_trans *trans,
|
||||
u32 tree_id, u32 *subvol)
|
||||
{
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
int ret;
|
||||
|
||||
for_each_btree_key_norestart(trans, iter, BTREE_ID_snapshots, POS_MIN, 0, k, ret) {
|
||||
if (k.k->type != KEY_TYPE_snapshot)
|
||||
continue;
|
||||
|
||||
struct bkey_s_c_snapshot s = bkey_s_c_to_snapshot(k);
|
||||
if (le32_to_cpu(s.v->tree) != tree_id)
|
||||
continue;
|
||||
|
||||
if (s.v->subvol) {
|
||||
*subvol = le32_to_cpu(s.v->subvol);
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
ret = -BCH_ERR_ENOENT_no_snapshot_tree_subvol;
|
||||
found:
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get lost+found, create if it doesn't exist: */
|
||||
static int lookup_lostfound(struct btree_trans *trans, u32 snapshot,
|
||||
struct bch_inode_unpacked *lostfound,
|
||||
|
|
@ -223,19 +253,24 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
subvol_inum root_inum = { .subvol = le32_to_cpu(st.master_subvol) };
|
||||
u32 subvolid;
|
||||
ret = find_snapshot_tree_subvol(trans,
|
||||
bch2_snapshot_tree(c, snapshot), &subvolid);
|
||||
bch_err_msg(c, ret, "finding subvol associated with snapshot tree %u",
|
||||
bch2_snapshot_tree(c, snapshot));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
struct bch_subvolume subvol;
|
||||
ret = bch2_subvolume_get(trans, le32_to_cpu(st.master_subvol), false, &subvol);
|
||||
bch_err_msg(c, ret, "looking up root subvol %u for snapshot %u",
|
||||
le32_to_cpu(st.master_subvol), snapshot);
|
||||
ret = bch2_subvolume_get(trans, subvolid, false, &subvol);
|
||||
bch_err_msg(c, ret, "looking up subvol %u for snapshot %u", subvolid, snapshot);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!subvol.inode) {
|
||||
struct btree_iter iter;
|
||||
struct bkey_i_subvolume *subvol = bch2_bkey_get_mut_typed(trans, &iter,
|
||||
BTREE_ID_subvolumes, POS(0, le32_to_cpu(st.master_subvol)),
|
||||
BTREE_ID_subvolumes, POS(0, subvolid),
|
||||
0, subvolume);
|
||||
ret = PTR_ERR_OR_ZERO(subvol);
|
||||
if (ret)
|
||||
|
|
@ -245,13 +280,16 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot,
|
|||
bch2_trans_iter_exit(trans, &iter);
|
||||
}
|
||||
|
||||
root_inum.inum = le64_to_cpu(subvol.inode);
|
||||
subvol_inum root_inum = {
|
||||
.subvol = subvolid,
|
||||
.inum = le64_to_cpu(subvol.inode)
|
||||
};
|
||||
|
||||
struct bch_inode_unpacked root_inode;
|
||||
struct bch_hash_info root_hash_info;
|
||||
ret = lookup_inode(trans, root_inum.inum, snapshot, &root_inode);
|
||||
bch_err_msg(c, ret, "looking up root inode %llu for subvol %u",
|
||||
root_inum.inum, le32_to_cpu(st.master_subvol));
|
||||
root_inum.inum, subvolid);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user