Commit efdb77a2 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: bch2_readdir() -> for_each_btree_key_in_subvolume_upto

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 0215b918
...@@ -552,62 +552,30 @@ static int bch2_dir_emit(struct dir_context *ctx, struct bkey_s_c_dirent d, subv ...@@ -552,62 +552,30 @@ static int bch2_dir_emit(struct dir_context *ctx, struct bkey_s_c_dirent d, subv
int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx) int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
{ {
struct btree_trans *trans = bch2_trans_get(c);
struct btree_iter iter;
struct bkey_s_c k;
subvol_inum target;
u32 snapshot;
struct bkey_buf sk; struct bkey_buf sk;
int ret;
bch2_bkey_buf_init(&sk); bch2_bkey_buf_init(&sk);
retry:
bch2_trans_begin(trans);
ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot); int ret = bch2_trans_run(c,
if (ret) for_each_btree_key_in_subvolume_upto(trans, iter, BTREE_ID_dirents,
goto err; POS(inum.inum, ctx->pos),
POS(inum.inum, U64_MAX),
for_each_btree_key_upto_norestart(trans, iter, BTREE_ID_dirents, inum.subvol, 0, k, ({
SPOS(inum.inum, ctx->pos, snapshot), if (k.k->type != KEY_TYPE_dirent)
POS(inum.inum, U64_MAX), 0, k, ret) { continue;
if (k.k->type != KEY_TYPE_dirent)
continue;
/* dir_emit() can fault and block: */ /* dir_emit() can fault and block: */
bch2_bkey_buf_reassemble(&sk, c, k); bch2_bkey_buf_reassemble(&sk, c, k);
struct bkey_s_c_dirent dirent = bkey_i_to_s_c_dirent(sk.k); struct bkey_s_c_dirent dirent = bkey_i_to_s_c_dirent(sk.k);
ret = bch2_dirent_read_target(trans, inum, dirent, &target); subvol_inum target;
if (ret < 0) int ret2 = bch2_dirent_read_target(trans, inum, dirent, &target);
break; if (ret2 > 0)
if (ret) continue;
continue;
/* ret2 ?: drop_locks_do(trans, bch2_dir_emit(ctx, dirent, target));
* read_target looks up subvolumes, we can overflow paths if the })));
* directory has many subvolumes in it
*
* XXX: btree_trans_too_many_iters() is something we'd like to
* get rid of, and there's no good reason to be using it here
* except that we don't yet have a for_each_btree_key() helper
* that does subvolume_get_snapshot().
*/
ret = drop_locks_do(trans,
bch2_dir_emit(ctx, dirent, target)) ?:
btree_trans_too_many_iters(trans);
if (ret) {
ret = ret < 0 ? ret : 0;
break;
}
}
bch2_trans_iter_exit(trans, &iter);
err:
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
goto retry;
bch2_trans_put(trans);
bch2_bkey_buf_exit(&sk, c); bch2_bkey_buf_exit(&sk, c);
return ret; return ret < 0 ? ret : 0;
} }
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