struct bch_fs *c = trans->c;
struct bch_fs_usage_online *fs_usage = NULL;
struct btree_insert_entry *i;
+ struct btree_iter *iter;
unsigned mark_flags = trans->flags & BTREE_INSERT_BUCKET_INVALIDATE
? BCH_BUCKET_MARK_BUCKET_INVALIDATE
: 0;
goto out_clear_replicas;
}
+ trans_for_each_iter(trans, iter) {
+ if (iter->nodes_locked != iter->nodes_intent_locked) {
+ BUG_ON(iter->flags & BTREE_ITER_KEEP_UNTIL_COMMIT);
+ BUG_ON(trans->iters_live & (1ULL << iter->idx));
+ __bch2_btree_iter_unlock(iter);
+ }
+ }
+
if (IS_ENABLED(CONFIG_BCACHEFS_DEBUG))
trans_for_each_update(trans, i)
btree_insert_entry_checks(trans, i);
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 *
__bch2_dirent_lookup_trans(struct btree_trans *, u64,
const struct bch_hash_info *,
- const struct qstr *);
+ const struct qstr *, unsigned);
u64 bch2_dirent_lookup(struct bch_fs *, u64, const struct bch_hash_info *,
const struct qstr *);
u64 now = bch2_current_time(trans->c);
int ret;
- dir_iter = bch2_inode_peek(trans, dir_u, dir_inum,
- name ? BTREE_ITER_INTENT : 0);
+ dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, BTREE_ITER_INTENT);
if (IS_ERR(dir_iter))
return PTR_ERR(dir_iter);
return 0;
}
-int bch2_link_trans(struct btree_trans *trans,
- u64 dir_inum,
+int bch2_link_trans(struct btree_trans *trans, u64 dir_inum,
u64 inum, struct bch_inode_unpacked *inode_u,
const struct qstr *name)
{
struct bch_hash_info dir_hash;
u64 now = bch2_current_time(trans->c);
- dir_iter = bch2_inode_peek(trans, &dir_u, dir_inum, 0);
- if (IS_ERR(dir_iter))
- return PTR_ERR(dir_iter);
-
inode_iter = bch2_inode_peek(trans, inode_u, inum, BTREE_ITER_INTENT);
if (IS_ERR(inode_iter))
return PTR_ERR(inode_iter);
- dir_hash = bch2_hash_info_init(trans->c, &dir_u);
-
inode_u->bi_ctime = now;
bch2_inode_nlink_inc(inode_u);
+ dir_iter = bch2_inode_peek(trans, &dir_u, dir_inum, 0);
+ if (IS_ERR(dir_iter))
+ return PTR_ERR(dir_iter);
+
+ /* XXX: shouldn't we be updating mtime/ctime on the directory? */
+
+ dir_hash = bch2_hash_info_init(trans->c, &dir_u);
+ bch2_trans_iter_put(trans, dir_iter);
+
return bch2_dirent_create(trans, dir_inum, &dir_hash,
mode_to_type(inode_u->bi_mode),
name, inum, BCH_HASH_SET_MUST_CREATE) ?:
dir_hash = bch2_hash_info_init(trans->c, dir_u);
- dirent_iter = __bch2_dirent_lookup_trans(trans, dir_inum,
- &dir_hash, name);
+ dirent_iter = __bch2_dirent_lookup_trans(trans, dir_inum, &dir_hash,
+ name, BTREE_ITER_INTENT);
if (IS_ERR(dirent_iter))
return PTR_ERR(dirent_iter);
struct posix_acl *,
struct posix_acl *);
-int bch2_link_trans(struct btree_trans *,
- u64,
+int bch2_link_trans(struct btree_trans *, u64,
u64, struct bch_inode_unpacked *,
const struct qstr *);
static struct bkey_s_c get_next_src(struct btree_iter *iter, struct bpos end)
{
struct bkey_s_c k = bch2_btree_iter_peek(iter);
+ int ret;
- while (1) {
- if (bkey_err(k))
- return k;
-
+ for_each_btree_key_continue(iter, 0, k, ret) {
if (bkey_cmp(iter->pos, end) >= 0)
return bkey_s_c_null;
if (k.k->type == KEY_TYPE_extent ||
k.k->type == KEY_TYPE_reflink_p)
- return k;
-
- k = bch2_btree_iter_next(iter);
+ break;
}
+
+ return k;
}
s64 bch2_remap_range(struct bch_fs *c,