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,
{
struct btree_iter iter;
struct bkey_s_c k;
+ u32 target_subvol, target_snapshot;
+ u64 target_inum;
int ret;
bch2_trans_iter_init(trans, &iter, BTREE_ID_dirents,
if (k.k->type != KEY_TYPE_dirent)
goto out;
- ret = le64_to_cpu(bkey_s_c_to_dirent(k).v->d_inum) == inode->bi_inum;
+ ret = __bch2_dirent_read_target(trans, bkey_s_c_to_dirent(k),
+ &target_subvol,
+ &target_snapshot,
+ &target_inum,
+ true);
+ if (ret)
+ goto out;
+
+ ret = target_inum == inode->bi_inum;
out:
bch2_trans_iter_exit(trans, &iter);
return ret;
snapshot = snapshot_t(c, snapshot)->equiv;
p->nr = 0;
- while (inode->bi_inum != BCACHEFS_ROOT_INO) {
+ while (!(inode->bi_inum == BCACHEFS_ROOT_INO &&
+ inode->bi_subvol == BCACHEFS_ROOT_SUBVOL)) {
+ if (inode->bi_parent_subvol) {
+ u64 inum;
+
+ ret = subvol_lookup(trans, inode->bi_parent_subvol,
+ &snapshot, &inum);
+ if (ret)
+ break;
+ }
+
ret = lockrestart_do(trans,
inode_backpointer_exists(trans, inode, snapshot));
if (ret < 0)
bch2_inode_nlink_get(&u), link->count)) {
bch2_inode_nlink_set(&u, link->count);
- ret = __bch2_trans_do(&trans, NULL, NULL,
- BTREE_INSERT_NOFAIL|
- BTREE_INSERT_LAZY_RW,
- bch2_btree_iter_traverse(&iter) ?:
- bch2_inode_write(&trans, &iter, &u));
+ ret = write_inode(&trans, &u, k.k->p.snapshot);
if (ret)
bch_err(c, "error in fsck: error %i updating inode", ret);
}