Commit d69f41d6 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Convert raw uses of bch2_btree_iter_link() to new transactions

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 88c07f73
...@@ -390,7 +390,8 @@ static int bchfs_write_index_update(struct bch_write_op *wop) ...@@ -390,7 +390,8 @@ static int bchfs_write_index_update(struct bch_write_op *wop)
struct bchfs_write_op *op = container_of(wop, struct bchfs_write_op *op = container_of(wop,
struct bchfs_write_op, op); struct bchfs_write_op, op);
struct keylist *keys = &op->op.insert_keys; struct keylist *keys = &op->op.insert_keys;
struct btree_iter extent_iter, inode_iter; struct btree_trans trans;
struct btree_iter *extent_iter, *inode_iter = NULL;
struct bchfs_extent_trans_hook hook; struct bchfs_extent_trans_hook hook;
struct bkey_i *k = bch2_keylist_front(keys); struct bkey_i *k = bch2_keylist_front(keys);
s64 orig_sectors_added = op->sectors_added; s64 orig_sectors_added = op->sectors_added;
...@@ -398,12 +399,13 @@ static int bchfs_write_index_update(struct bch_write_op *wop) ...@@ -398,12 +399,13 @@ static int bchfs_write_index_update(struct bch_write_op *wop)
BUG_ON(k->k.p.inode != op->inode->v.i_ino); BUG_ON(k->k.p.inode != op->inode->v.i_ino);
bch2_btree_iter_init(&extent_iter, wop->c, BTREE_ID_EXTENTS, bch2_trans_init(&trans, wop->c);
extent_iter = bch2_trans_get_iter(&trans,
BTREE_ID_EXTENTS,
bkey_start_pos(&bch2_keylist_front(keys)->k), bkey_start_pos(&bch2_keylist_front(keys)->k),
BTREE_ITER_INTENT); BTREE_ITER_INTENT);
bch2_btree_iter_init(&inode_iter, wop->c, BTREE_ID_INODES, BUG_ON(IS_ERR(extent_iter));
POS(extent_iter.pos.inode, 0),
BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
hook.op = op; hook.op = op;
hook.hook.fn = bchfs_extent_update_hook; hook.hook.fn = bchfs_extent_update_hook;
...@@ -417,23 +419,28 @@ static int bchfs_write_index_update(struct bch_write_op *wop) ...@@ -417,23 +419,28 @@ static int bchfs_write_index_update(struct bch_write_op *wop)
hook.need_inode_update = true; hook.need_inode_update = true;
/* optimization for fewer transaction restarts: */ /* optimization for fewer transaction restarts: */
ret = bch2_btree_iter_traverse(&extent_iter); ret = bch2_btree_iter_traverse(extent_iter);
if (ret) if (ret)
goto err; goto err;
if (hook.need_inode_update) { if (hook.need_inode_update) {
struct bkey_s_c inode; struct bkey_s_c inode;
if (!btree_iter_linked(&inode_iter)) if (!inode_iter) {
bch2_btree_iter_link(&extent_iter, &inode_iter); inode_iter = bch2_trans_get_iter(&trans,
BTREE_ID_INODES,
POS(extent_iter->pos.inode, 0),
BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
BUG_ON(IS_ERR(inode_iter));
}
inode = bch2_btree_iter_peek_slot(&inode_iter); inode = bch2_btree_iter_peek_slot(inode_iter);
if ((ret = btree_iter_err(inode))) if ((ret = btree_iter_err(inode)))
goto err; goto err;
if (WARN_ONCE(inode.k->type != BCH_INODE_FS, if (WARN_ONCE(inode.k->type != BCH_INODE_FS,
"inode %llu not found when updating", "inode %llu not found when updating",
extent_iter.pos.inode)) { extent_iter->pos.inode)) {
ret = -ENOENT; ret = -ENOENT;
break; break;
} }
...@@ -441,7 +448,7 @@ static int bchfs_write_index_update(struct bch_write_op *wop) ...@@ -441,7 +448,7 @@ static int bchfs_write_index_update(struct bch_write_op *wop)
if (WARN_ONCE(bkey_bytes(inode.k) > if (WARN_ONCE(bkey_bytes(inode.k) >
sizeof(hook.inode_p), sizeof(hook.inode_p),
"inode %llu too big (%zu bytes, buf %zu)", "inode %llu too big (%zu bytes, buf %zu)",
extent_iter.pos.inode, extent_iter->pos.inode,
bkey_bytes(inode.k), bkey_bytes(inode.k),
sizeof(hook.inode_p))) { sizeof(hook.inode_p))) {
ret = -ENOENT; ret = -ENOENT;
...@@ -453,7 +460,7 @@ static int bchfs_write_index_update(struct bch_write_op *wop) ...@@ -453,7 +460,7 @@ static int bchfs_write_index_update(struct bch_write_op *wop)
&hook.inode_u); &hook.inode_u);
if (WARN_ONCE(ret, if (WARN_ONCE(ret,
"error %i unpacking inode %llu", "error %i unpacking inode %llu",
ret, extent_iter.pos.inode)) { ret, extent_iter->pos.inode)) {
ret = -ENOENT; ret = -ENOENT;
break; break;
} }
...@@ -463,8 +470,8 @@ static int bchfs_write_index_update(struct bch_write_op *wop) ...@@ -463,8 +470,8 @@ static int bchfs_write_index_update(struct bch_write_op *wop)
BTREE_INSERT_NOFAIL| BTREE_INSERT_NOFAIL|
BTREE_INSERT_ATOMIC| BTREE_INSERT_ATOMIC|
BTREE_INSERT_USE_RESERVE, BTREE_INSERT_USE_RESERVE,
BTREE_INSERT_ENTRY(&extent_iter, k), BTREE_INSERT_ENTRY(extent_iter, k),
BTREE_INSERT_ENTRY_EXTRA_RES(&inode_iter, BTREE_INSERT_ENTRY_EXTRA_RES(inode_iter,
&hook.inode_p.inode.k_i, 2)); &hook.inode_p.inode.k_i, 2));
} else { } else {
ret = bch2_btree_insert_at(wop->c, &wop->res, ret = bch2_btree_insert_at(wop->c, &wop->res,
...@@ -472,10 +479,10 @@ static int bchfs_write_index_update(struct bch_write_op *wop) ...@@ -472,10 +479,10 @@ static int bchfs_write_index_update(struct bch_write_op *wop)
BTREE_INSERT_NOFAIL| BTREE_INSERT_NOFAIL|
BTREE_INSERT_ATOMIC| BTREE_INSERT_ATOMIC|
BTREE_INSERT_USE_RESERVE, BTREE_INSERT_USE_RESERVE,
BTREE_INSERT_ENTRY(&extent_iter, k)); BTREE_INSERT_ENTRY(extent_iter, k));
} }
BUG_ON(bkey_cmp(extent_iter.pos, bkey_start_pos(&k->k))); BUG_ON(bkey_cmp(extent_iter->pos, bkey_start_pos(&k->k)));
if (WARN_ONCE(!ret != !k->k.size, if (WARN_ONCE(!ret != !k->k.size,
"ret %i k->size %u", ret, k->k.size)) "ret %i k->size %u", ret, k->k.size))
...@@ -486,12 +493,11 @@ static int bchfs_write_index_update(struct bch_write_op *wop) ...@@ -486,12 +493,11 @@ static int bchfs_write_index_update(struct bch_write_op *wop)
if (ret) if (ret)
break; break;
BUG_ON(bkey_cmp(extent_iter.pos, k->k.p) < 0); BUG_ON(bkey_cmp(extent_iter->pos, k->k.p) < 0);
bch2_keylist_pop_front(keys); bch2_keylist_pop_front(keys);
} while (!bch2_keylist_empty(keys)); } while (!bch2_keylist_empty(keys));
bch2_btree_iter_unlock(&extent_iter); bch2_trans_exit(&trans);
bch2_btree_iter_unlock(&inode_iter);
if (op->is_dio) { if (op->is_dio) {
struct dio_write *dio = container_of(op, struct dio_write, iop); struct dio_write *dio = container_of(op, struct dio_write, iop);
...@@ -2363,8 +2369,8 @@ static long bch2_fcollapse(struct bch_inode_info *inode, ...@@ -2363,8 +2369,8 @@ static long bch2_fcollapse(struct bch_inode_info *inode,
{ {
struct bch_fs *c = inode->v.i_sb->s_fs_info; struct bch_fs *c = inode->v.i_sb->s_fs_info;
struct address_space *mapping = inode->v.i_mapping; struct address_space *mapping = inode->v.i_mapping;
struct btree_iter src; struct btree_trans trans;
struct btree_iter dst; struct btree_iter *src, *dst;
BKEY_PADDED(k) copy; BKEY_PADDED(k) copy;
struct bkey_s_c k; struct bkey_s_c k;
struct i_sectors_hook i_sectors_hook = i_sectors_hook_init(inode, 0); struct i_sectors_hook i_sectors_hook = i_sectors_hook_init(inode, 0);
...@@ -2374,13 +2380,17 @@ static long bch2_fcollapse(struct bch_inode_info *inode, ...@@ -2374,13 +2380,17 @@ static long bch2_fcollapse(struct bch_inode_info *inode,
if ((offset | len) & (block_bytes(c) - 1)) if ((offset | len) & (block_bytes(c) - 1))
return -EINVAL; return -EINVAL;
bch2_btree_iter_init(&dst, c, BTREE_ID_EXTENTS, bch2_trans_init(&trans, c);
dst = bch2_trans_get_iter(&trans, BTREE_ID_EXTENTS,
POS(inode->v.i_ino, offset >> 9), POS(inode->v.i_ino, offset >> 9),
BTREE_ITER_SLOTS|BTREE_ITER_INTENT); BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
BUG_ON(IS_ERR(dst));
/* position will be set from dst iter's position: */ /* position will be set from dst iter's position: */
bch2_btree_iter_init(&src, c, BTREE_ID_EXTENTS, POS_MIN, src = bch2_trans_get_iter(&trans, BTREE_ID_EXTENTS, POS_MIN,
BTREE_ITER_SLOTS); BTREE_ITER_SLOTS);
bch2_btree_iter_link(&src, &dst); BUG_ON(IS_ERR(src));
/* /*
* We need i_mutex to keep the page cache consistent with the extents * We need i_mutex to keep the page cache consistent with the extents
...@@ -2409,24 +2419,24 @@ static long bch2_fcollapse(struct bch_inode_info *inode, ...@@ -2409,24 +2419,24 @@ static long bch2_fcollapse(struct bch_inode_info *inode,
if (ret) if (ret)
goto err; goto err;
while (bkey_cmp(dst.pos, while (bkey_cmp(dst->pos,
POS(inode->v.i_ino, POS(inode->v.i_ino,
round_up(new_size, PAGE_SIZE) >> 9)) < 0) { round_up(new_size, PAGE_SIZE) >> 9)) < 0) {
struct disk_reservation disk_res; struct disk_reservation disk_res;
bch2_btree_iter_set_pos(&src, bch2_btree_iter_set_pos(src,
POS(dst.pos.inode, dst.pos.offset + (len >> 9))); POS(dst->pos.inode, dst->pos.offset + (len >> 9)));
k = bch2_btree_iter_peek_slot(&src); k = bch2_btree_iter_peek_slot(src);
if ((ret = btree_iter_err(k))) if ((ret = btree_iter_err(k)))
goto btree_iter_err; goto btree_iter_err;
bkey_reassemble(&copy.k, k); bkey_reassemble(&copy.k, k);
bch2_cut_front(src.pos, &copy.k); bch2_cut_front(src->pos, &copy.k);
copy.k.k.p.offset -= len >> 9; copy.k.k.p.offset -= len >> 9;
BUG_ON(bkey_cmp(dst.pos, bkey_start_pos(&copy.k.k))); BUG_ON(bkey_cmp(dst->pos, bkey_start_pos(&copy.k.k)));
ret = bch2_disk_reservation_get(c, &disk_res, copy.k.k.size, ret = bch2_disk_reservation_get(c, &disk_res, copy.k.k.size,
bch2_extent_nr_dirty_ptrs(bkey_i_to_s_c(&copy.k)), bch2_extent_nr_dirty_ptrs(bkey_i_to_s_c(&copy.k)),
...@@ -2437,14 +2447,13 @@ static long bch2_fcollapse(struct bch_inode_info *inode, ...@@ -2437,14 +2447,13 @@ static long bch2_fcollapse(struct bch_inode_info *inode,
&inode->ei_journal_seq, &inode->ei_journal_seq,
BTREE_INSERT_ATOMIC| BTREE_INSERT_ATOMIC|
BTREE_INSERT_NOFAIL, BTREE_INSERT_NOFAIL,
BTREE_INSERT_ENTRY(&dst, &copy.k)); BTREE_INSERT_ENTRY(dst, &copy.k));
bch2_disk_reservation_put(c, &disk_res); bch2_disk_reservation_put(c, &disk_res);
btree_iter_err: btree_iter_err:
if (ret == -EINTR) if (ret == -EINTR)
ret = 0; ret = 0;
if (ret) { if (ret) {
bch2_btree_iter_unlock(&src); bch2_trans_exit(&trans);
bch2_btree_iter_unlock(&dst);
goto err_put_sectors_dirty; goto err_put_sectors_dirty;
} }
/* /*
...@@ -2452,11 +2461,10 @@ static long bch2_fcollapse(struct bch_inode_info *inode, ...@@ -2452,11 +2461,10 @@ static long bch2_fcollapse(struct bch_inode_info *inode,
* pointers... which isn't a _super_ serious problem... * pointers... which isn't a _super_ serious problem...
*/ */
bch2_btree_iter_cond_resched(&src); bch2_btree_iter_cond_resched(src);
} }
bch2_btree_iter_unlock(&src); bch2_trans_exit(&trans);
bch2_btree_iter_unlock(&dst);
ret = bch2_inode_truncate(c, inode->v.i_ino, ret = bch2_inode_truncate(c, inode->v.i_ino,
round_up(new_size, block_bytes(c)) >> 9, round_up(new_size, block_bytes(c)) >> 9,
......
...@@ -127,16 +127,22 @@ static int walk_inode(struct bch_fs *c, struct inode_walker *w, u64 inum) ...@@ -127,16 +127,22 @@ static int walk_inode(struct bch_fs *c, struct inode_walker *w, u64 inum)
struct hash_check { struct hash_check {
struct bch_hash_info info; struct bch_hash_info info;
struct btree_iter chain; struct btree_trans *trans;
struct btree_iter iter;
/* start of current chain of hash collisions: */
struct btree_iter *chain;
/* next offset in current chain of hash collisions: */
u64 next; u64 next;
}; };
static void hash_check_init(const struct bch_hash_desc desc, static void hash_check_init(const struct bch_hash_desc desc,
struct hash_check *h, struct bch_fs *c) struct btree_trans *trans,
struct hash_check *h)
{ {
bch2_btree_iter_init(&h->chain, c, desc.btree_id, POS_MIN, 0); h->trans = trans;
bch2_btree_iter_init(&h->iter, c, desc.btree_id, POS_MIN, 0); h->chain = bch2_trans_get_iter(trans, desc.btree_id, POS_MIN, 0);
h->next = -1;
} }
static void hash_check_set_inode(struct hash_check *h, struct bch_fs *c, static void hash_check_set_inode(struct hash_check *h, struct bch_fs *c,
...@@ -207,6 +213,42 @@ static int fsck_hash_delete_at(const struct bch_hash_desc desc, ...@@ -207,6 +213,42 @@ static int fsck_hash_delete_at(const struct bch_hash_desc desc,
return ret; return ret;
} }
static int hash_check_duplicates(const struct bch_hash_desc desc,
struct hash_check *h, struct bch_fs *c,
struct btree_iter *k_iter, struct bkey_s_c k)
{
struct btree_iter *iter;
struct bkey_s_c k2;
char buf[200];
int ret = 0;
if (!bkey_cmp(h->chain->pos, k_iter->pos))
return 0;
iter = bch2_trans_copy_iter(h->trans, h->chain);
BUG_ON(IS_ERR(iter));
for_each_btree_key_continue(iter, 0, k2) {
if (bkey_cmp(k2.k->p, k.k->p) >= 0)
break;
if (fsck_err_on(k2.k->type == desc.key_type &&
!desc.cmp_bkey(k, k2), c,
"duplicate hash table keys:\n%s",
(bch2_bkey_val_to_text(c, bkey_type(0, desc.btree_id),
buf, sizeof(buf), k), buf))) {
ret = fsck_hash_delete_at(desc, &h->info, k_iter);
if (ret)
return ret;
ret = 1;
break;
}
}
fsck_err:
bch2_trans_iter_free(h->trans, iter);
return ret;
}
static int hash_check_key(const struct bch_hash_desc desc, static int hash_check_key(const struct bch_hash_desc desc,
struct hash_check *h, struct bch_fs *c, struct hash_check *h, struct bch_fs *c,
struct btree_iter *k_iter, struct bkey_s_c k) struct btree_iter *k_iter, struct bkey_s_c k)
...@@ -219,13 +261,8 @@ static int hash_check_key(const struct bch_hash_desc desc, ...@@ -219,13 +261,8 @@ static int hash_check_key(const struct bch_hash_desc desc,
k.k->type != desc.key_type) k.k->type != desc.key_type)
return 0; return 0;
if (k.k->p.offset != h->next) { if (k.k->p.offset != h->next)
if (!btree_iter_linked(&h->chain)) { bch2_btree_iter_copy(h->chain, k_iter);
bch2_btree_iter_link(k_iter, &h->chain);
bch2_btree_iter_link(k_iter, &h->iter);
}
bch2_btree_iter_copy(&h->chain, k_iter);
}
h->next = k.k->p.offset + 1; h->next = k.k->p.offset + 1;
if (k.k->type != desc.key_type) if (k.k->type != desc.key_type)
...@@ -233,11 +270,11 @@ static int hash_check_key(const struct bch_hash_desc desc, ...@@ -233,11 +270,11 @@ static int hash_check_key(const struct bch_hash_desc desc,
hashed = desc.hash_bkey(&h->info, k); hashed = desc.hash_bkey(&h->info, k);
if (fsck_err_on(hashed < h->chain.pos.offset || if (fsck_err_on(hashed < h->chain->pos.offset ||
hashed > k.k->p.offset, c, hashed > k.k->p.offset, c,
"hash table key at wrong offset: %llu, " "hash table key at wrong offset: %llu, "
"hashed to %llu chain starts at %llu\n%s", "hashed to %llu chain starts at %llu\n%s",
k.k->p.offset, hashed, h->chain.pos.offset, k.k->p.offset, hashed, h->chain->pos.offset,
(bch2_bkey_val_to_text(c, bkey_type(0, desc.btree_id), (bch2_bkey_val_to_text(c, bkey_type(0, desc.btree_id),
buf, sizeof(buf), k), buf))) { buf, sizeof(buf), k), buf))) {
ret = hash_redo_key(desc, h, c, k_iter, k, hashed); ret = hash_redo_key(desc, h, c, k_iter, k, hashed);
...@@ -248,25 +285,7 @@ static int hash_check_key(const struct bch_hash_desc desc, ...@@ -248,25 +285,7 @@ static int hash_check_key(const struct bch_hash_desc desc,
return 1; return 1;
} }
if (!bkey_cmp(h->chain.pos, k_iter->pos)) ret = hash_check_duplicates(desc, h, c, k_iter, k);
return 0;
bch2_btree_iter_copy(&h->iter, &h->chain);
while (bkey_cmp(h->iter.pos, k_iter->pos) < 0) {
struct bkey_s_c k2 = bch2_btree_iter_peek(&h->iter);
if (fsck_err_on(k2.k->type == desc.key_type &&
!desc.cmp_bkey(k, k2), c,
"duplicate hash table keys:\n%s",
(bch2_bkey_val_to_text(c, bkey_type(0, desc.btree_id),
buf, sizeof(buf), k), buf))) {
ret = fsck_hash_delete_at(desc, &h->info, &h->iter);
if (ret)
return ret;
return 1;
}
bch2_btree_iter_next(&h->iter);
}
fsck_err: fsck_err:
return ret; return ret;
} }
...@@ -368,7 +387,8 @@ static int check_dirents(struct bch_fs *c) ...@@ -368,7 +387,8 @@ static int check_dirents(struct bch_fs *c)
{ {
struct inode_walker w = inode_walker_init(); struct inode_walker w = inode_walker_init();
struct hash_check h; struct hash_check h;
struct btree_iter iter; struct btree_trans trans;
struct btree_iter *iter;
struct bkey_s_c k; struct bkey_s_c k;
unsigned name_len; unsigned name_len;
char buf[200]; char buf[200];
...@@ -376,10 +396,16 @@ static int check_dirents(struct bch_fs *c) ...@@ -376,10 +396,16 @@ static int check_dirents(struct bch_fs *c)
bch_verbose(c, "checking dirents"); bch_verbose(c, "checking dirents");
hash_check_init(bch2_dirent_hash_desc, &h, c); bch2_trans_init(&trans, c);
for_each_btree_key(&iter, c, BTREE_ID_DIRENTS, BUG_ON(bch2_trans_preload_iters(&trans));
POS(BCACHEFS_ROOT_INO, 0), 0, k) {
iter = bch2_trans_get_iter(&trans, BTREE_ID_DIRENTS,
POS(BCACHEFS_ROOT_INO, 0), 0);
hash_check_init(bch2_dirent_hash_desc, &trans, &h);
for_each_btree_key_continue(iter, 0, k) {
struct bkey_s_c_dirent d; struct bkey_s_c_dirent d;
struct bch_inode_unpacked target; struct bch_inode_unpacked target;
bool have_target; bool have_target;
...@@ -398,7 +424,7 @@ static int check_dirents(struct bch_fs *c) ...@@ -398,7 +424,7 @@ static int check_dirents(struct bch_fs *c)
mode_to_type(w.inode.bi_mode), mode_to_type(w.inode.bi_mode),
(bch2_bkey_val_to_text(c, (enum bkey_type) BTREE_ID_DIRENTS, (bch2_bkey_val_to_text(c, (enum bkey_type) BTREE_ID_DIRENTS,
buf, sizeof(buf), k), buf))) { buf, sizeof(buf), k), buf))) {
ret = bch2_btree_delete_at(&iter, 0); ret = bch2_btree_delete_at(iter, 0);
if (ret) if (ret)
goto err; goto err;
continue; continue;
...@@ -407,7 +433,7 @@ static int check_dirents(struct bch_fs *c) ...@@ -407,7 +433,7 @@ static int check_dirents(struct bch_fs *c)
if (w.first_this_inode && w.have_inode) if (w.first_this_inode && w.have_inode)
hash_check_set_inode(&h, c, &w.inode); hash_check_set_inode(&h, c, &w.inode);
ret = hash_check_key(bch2_dirent_hash_desc, &h, c, &iter, k); ret = hash_check_key(bch2_dirent_hash_desc, &h, c, iter, k);
if (ret > 0) { if (ret > 0) {
ret = 0; ret = 0;
continue; continue;
...@@ -431,7 +457,7 @@ static int check_dirents(struct bch_fs *c) ...@@ -431,7 +457,7 @@ static int check_dirents(struct bch_fs *c)
fsck_err_on(name_len == 2 && fsck_err_on(name_len == 2 &&
!memcmp(d.v->d_name, "..", 2), c, !memcmp(d.v->d_name, "..", 2), c,
".. dirent")) { ".. dirent")) {
ret = remove_dirent(c, &iter, d); ret = remove_dirent(c, iter, d);
if (ret) if (ret)
goto err; goto err;
continue; continue;
...@@ -441,7 +467,7 @@ static int check_dirents(struct bch_fs *c) ...@@ -441,7 +467,7 @@ static int check_dirents(struct bch_fs *c)
"dirent points to own directory:\n%s", "dirent points to own directory:\n%s",
(bch2_bkey_val_to_text(c, (enum bkey_type) BTREE_ID_DIRENTS, (bch2_bkey_val_to_text(c, (enum bkey_type) BTREE_ID_DIRENTS,
buf, sizeof(buf), k), buf))) { buf, sizeof(buf), k), buf))) {
ret = remove_dirent(c, &iter, d); ret = remove_dirent(c, iter, d);
if (ret) if (ret)
goto err; goto err;
continue; continue;
...@@ -458,7 +484,7 @@ static int check_dirents(struct bch_fs *c) ...@@ -458,7 +484,7 @@ static int check_dirents(struct bch_fs *c)
"dirent points to missing inode:\n%s", "dirent points to missing inode:\n%s",
(bch2_bkey_val_to_text(c, (enum bkey_type) BTREE_ID_DIRENTS, (bch2_bkey_val_to_text(c, (enum bkey_type) BTREE_ID_DIRENTS,
buf, sizeof(buf), k), buf))) { buf, sizeof(buf), k), buf))) {
ret = remove_dirent(c, &iter, d); ret = remove_dirent(c, iter, d);
if (ret) if (ret)
goto err; goto err;
continue; continue;
...@@ -484,7 +510,7 @@ static int check_dirents(struct bch_fs *c) ...@@ -484,7 +510,7 @@ static int check_dirents(struct bch_fs *c)
ret = bch2_btree_insert_at(c, NULL, NULL, NULL, ret = bch2_btree_insert_at(c, NULL, NULL, NULL,
BTREE_INSERT_NOFAIL, BTREE_INSERT_NOFAIL,
BTREE_INSERT_ENTRY(&iter, &n->k_i)); BTREE_INSERT_ENTRY(iter, &n->k_i));
kfree(n); kfree(n);
if (ret) if (ret)
goto err; goto err;
...@@ -493,9 +519,7 @@ static int check_dirents(struct bch_fs *c) ...@@ -493,9 +519,7 @@ static int check_dirents(struct bch_fs *c)
} }
err: err:
fsck_err: fsck_err:
bch2_btree_iter_unlock(&h.chain); return bch2_trans_exit(&trans) ?: ret;
bch2_btree_iter_unlock(&h.iter);
return bch2_btree_iter_unlock(&iter) ?: ret;
} }
/* /*
...@@ -506,16 +530,23 @@ static int check_xattrs(struct bch_fs *c) ...@@ -506,16 +530,23 @@ static int check_xattrs(struct bch_fs *c)
{ {
struct inode_walker w = inode_walker_init(); struct inode_walker w = inode_walker_init();
struct hash_check h; struct hash_check h;
struct btree_iter iter; struct btree_trans trans;
struct btree_iter *iter;
struct bkey_s_c k; struct bkey_s_c k;
int ret = 0; int ret = 0;
bch_verbose(c, "checking xattrs"); bch_verbose(c, "checking xattrs");
hash_check_init(bch2_xattr_hash_desc, &h, c); bch2_trans_init(&trans, c);
for_each_btree_key(&iter, c, BTREE_ID_XATTRS, BUG_ON(bch2_trans_preload_iters(&trans));
POS(BCACHEFS_ROOT_INO, 0), 0, k) {
iter = bch2_trans_get_iter(&trans, BTREE_ID_XATTRS,
POS(BCACHEFS_ROOT_INO, 0), 0);
hash_check_init(bch2_xattr_hash_desc, &trans, &h);
for_each_btree_key_continue(iter, 0, k) {
ret = walk_inode(c, &w, k.k->p.inode); ret = walk_inode(c, &w, k.k->p.inode);
if (ret) if (ret)
break; break;
...@@ -523,7 +554,7 @@ static int check_xattrs(struct bch_fs *c) ...@@ -523,7 +554,7 @@ static int check_xattrs(struct bch_fs *c)
if (fsck_err_on(!w.have_inode, c, if (fsck_err_on(!w.have_inode, c,
"xattr for missing inode %llu", "xattr for missing inode %llu",
k.k->p.inode)) { k.k->p.inode)) {
ret = bch2_btree_delete_at(&iter, 0); ret = bch2_btree_delete_at(iter, 0);
if (ret) if (ret)
goto err; goto err;
continue; continue;
...@@ -532,15 +563,13 @@ static int check_xattrs(struct bch_fs *c) ...@@ -532,15 +563,13 @@ static int check_xattrs(struct bch_fs *c)
if (w.first_this_inode && w.have_inode) if (w.first_this_inode && w.have_inode)
hash_check_set_inode(&h, c, &w.inode); hash_check_set_inode(&h, c, &w.inode);
ret = hash_check_key(bch2_xattr_hash_desc, &h, c, &iter, k); ret = hash_check_key(bch2_xattr_hash_desc, &h, c, iter, k);
if (ret) if (ret)
goto fsck_err; goto fsck_err;
} }
err: err:
fsck_err: fsck_err:
bch2_btree_iter_unlock(&h.chain); return bch2_trans_exit(&trans) ?: ret;
bch2_btree_iter_unlock(&h.iter);
return bch2_btree_iter_unlock(&iter) ?: ret;
} }
/* Get root directory, create if it doesn't exist: */ /* Get root directory, create if it doesn't exist: */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment