const struct qstr *dst_name, u64 *dst_inum,
enum bch_rename_mode mode)
{
- struct btree_iter *src_iter, *dst_iter;
+ struct btree_iter *src_iter = NULL, *dst_iter = NULL;
struct bkey_s_c old_src, old_dst;
struct bkey_i_dirent *new_src = NULL, *new_dst = NULL;
struct bpos dst_pos =
POS(dst_dir, bch2_dirent_hash(dst_hash, dst_name));
- int ret;
+ int ret = 0;
*src_inum = *dst_inum = 0;
: bch2_hash_lookup(trans, bch2_dirent_hash_desc,
dst_hash, dst_dir, dst_name,
BTREE_ITER_INTENT);
- if (IS_ERR(dst_iter))
- return PTR_ERR(dst_iter);
+ ret = PTR_ERR_OR_ZERO(dst_iter);
+ if (ret)
+ goto out;
+
old_dst = bch2_btree_iter_peek_slot(dst_iter);
if (mode != BCH_RENAME)
src_iter = bch2_hash_lookup(trans, bch2_dirent_hash_desc,
src_hash, src_dir, src_name,
BTREE_ITER_INTENT);
- if (IS_ERR(src_iter))
- return PTR_ERR(src_iter);
+ ret = PTR_ERR_OR_ZERO(src_iter);
+ if (ret)
+ goto out;
+
old_src = bch2_btree_iter_peek_slot(src_iter);
*src_inum = le64_to_cpu(bkey_s_c_to_dirent(old_src).v->d_inum);
/* Create new dst key: */
new_dst = dirent_create_key(trans, 0, dst_name, 0);
- if (IS_ERR(new_dst))
- return PTR_ERR(new_dst);
+ ret = PTR_ERR_OR_ZERO(new_dst);
+ if (ret)
+ goto out;
dirent_copy_target(new_dst, bkey_s_c_to_dirent(old_src));
new_dst->k.p = dst_iter->pos;
/* Create new src key: */
if (mode == BCH_RENAME_EXCHANGE) {
new_src = dirent_create_key(trans, 0, src_name, 0);
- if (IS_ERR(new_src))
- return PTR_ERR(new_src);
+ ret = PTR_ERR_OR_ZERO(new_src);
+ if (ret)
+ goto out;
dirent_copy_target(new_src, bkey_s_c_to_dirent(old_dst));
new_src->k.p = src_iter->pos;
} else {
new_src = bch2_trans_kmalloc(trans, sizeof(struct bkey_i));
- if (IS_ERR(new_src))
- return PTR_ERR(new_src);
+ ret = PTR_ERR_OR_ZERO(new_src);
+ if (ret)
+ goto out;
+
bkey_init(&new_src->k);
new_src->k.p = src_iter->pos;
*/
new_dst->k.p = src_iter->pos;
bch2_trans_update(trans, src_iter,
- &new_dst->k_i);
- return 0;
+ &new_dst->k_i, 0);
+ goto out;
} else {
/* If we're overwriting, we can't insert new_dst
* at a different slot because it has to
ret = bch2_hash_needs_whiteout(trans, bch2_dirent_hash_desc,
src_hash, src_iter);
if (ret < 0)
- return ret;
+ goto out;
if (ret)
new_src->k.type = KEY_TYPE_whiteout;
}
}
- bch2_trans_update(trans, src_iter, &new_src->k_i);
- bch2_trans_update(trans, dst_iter, &new_dst->k_i);
- return 0;
+ bch2_trans_update(trans, src_iter, &new_src->k_i, 0);
+ bch2_trans_update(trans, dst_iter, &new_dst->k_i, 0);
+out:
+ bch2_trans_iter_put(trans, src_iter);
+ bch2_trans_iter_put(trans, dst_iter);
+ return ret;
}
int bch2_dirent_delete_at(struct btree_trans *trans,
hash_info, iter);
}
-int bch2_dirent_delete(struct bch_fs *c, u64 dir_inum,
- const struct bch_hash_info *hash_info,
- const struct qstr *name,
- u64 *journal_seq)
-{
- return bch2_trans_do(c, journal_seq,
- BTREE_INSERT_ATOMIC|
- BTREE_INSERT_NOFAIL,
- bch2_hash_delete(&trans, bch2_dirent_hash_desc, hash_info,
- dir_inum, name));
-}
-
struct btree_iter *
__bch2_dirent_lookup_trans(struct btree_trans *trans, u64 dir_inum,
const struct bch_hash_info *hash_info,
- const struct qstr *name)
+ const struct qstr *name, unsigned flags)
{
return bch2_hash_lookup(trans, bch2_dirent_hash_desc,
- hash_info, dir_inum, name, 0);
+ hash_info, dir_inum, name, flags);
}
u64 bch2_dirent_lookup(struct bch_fs *c, u64 dir_inum,
bch2_trans_init(&trans, c, 0, 0);
- iter = __bch2_dirent_lookup_trans(&trans, dir_inum, hash_info, name);
+ iter = __bch2_dirent_lookup_trans(&trans, dir_inum,
+ hash_info, name, 0);
if (IS_ERR(iter)) {
BUG_ON(PTR_ERR(iter) == -EINTR);
goto out;
struct btree_iter *iter;
struct bkey_s_c k;
struct bkey_s_c_dirent dirent;
- unsigned len;
int ret;
bch2_trans_init(&trans, c, 0, 0);
for_each_btree_key(&trans, iter, BTREE_ID_DIRENTS,
POS(inum, ctx->pos), 0, k, ret) {
+ if (k.k->p.inode > inum)
+ break;
+
if (k.k->type != KEY_TYPE_dirent)
continue;
dirent = bkey_s_c_to_dirent(k);
- if (bkey_cmp(k.k->p, POS(inum, ctx->pos)) < 0)
- continue;
-
- if (k.k->p.inode > inum)
- break;
-
- len = bch2_dirent_name_bytes(dirent);
-
/*
* XXX: dir_emit() can fault and block, while we're holding
* locks
*/
- if (!dir_emit(ctx, dirent.v->d_name, len,
+ ctx->pos = dirent.k->p.offset;
+ if (!dir_emit(ctx, dirent.v->d_name,
+ bch2_dirent_name_bytes(dirent),
le64_to_cpu(dirent.v->d_inum),
dirent.v->d_type))
break;
-
- ctx->pos = k.k->p.offset + 1;
+ ctx->pos = dirent.k->p.offset + 1;
}
ret = bch2_trans_exit(&trans) ?: ret;