Commit 50dc0f69 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Require all btree iterators to be freed

We keep running into occasional bugs with btree transaction iterators
overflowing - this will make those bugs more visible.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 8d956c2f
...@@ -241,12 +241,12 @@ struct posix_acl *bch2_get_acl(struct mnt_idmap *idmap, ...@@ -241,12 +241,12 @@ struct posix_acl *bch2_get_acl(struct mnt_idmap *idmap,
} }
xattr = bkey_s_c_to_xattr(bch2_btree_iter_peek_slot(iter)); xattr = bkey_s_c_to_xattr(bch2_btree_iter_peek_slot(iter));
acl = bch2_acl_from_disk(xattr_val(xattr.v), acl = bch2_acl_from_disk(xattr_val(xattr.v),
le16_to_cpu(xattr.v->x_val_len)); le16_to_cpu(xattr.v->x_val_len));
if (!IS_ERR(acl)) if (!IS_ERR(acl))
set_cached_acl(&inode->v, type, acl); set_cached_acl(&inode->v, type, acl);
bch2_trans_iter_put(&trans, iter);
out: out:
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return acl; return acl;
...@@ -313,7 +313,7 @@ int bch2_set_acl(struct mnt_idmap *idmap, ...@@ -313,7 +313,7 @@ int bch2_set_acl(struct mnt_idmap *idmap,
if (type == ACL_TYPE_ACCESS) { if (type == ACL_TYPE_ACCESS) {
ret = posix_acl_update_mode(idmap, &inode->v, &mode, &acl); ret = posix_acl_update_mode(idmap, &inode->v, &mode, &acl);
if (ret) if (ret)
goto err; goto btree_err;
} }
hash_info = bch2_hash_info_init(c, &inode_u); hash_info = bch2_hash_info_init(c, &inode_u);
...@@ -330,6 +330,8 @@ int bch2_set_acl(struct mnt_idmap *idmap, ...@@ -330,6 +330,8 @@ int bch2_set_acl(struct mnt_idmap *idmap,
&inode->ei_journal_seq, &inode->ei_journal_seq,
BTREE_INSERT_NOUNLOCK); BTREE_INSERT_NOUNLOCK);
btree_err: btree_err:
bch2_trans_iter_put(&trans, inode_iter);
if (ret == -EINTR) if (ret == -EINTR)
goto retry; goto retry;
if (unlikely(ret)) if (unlikely(ret))
...@@ -356,21 +358,22 @@ int bch2_acl_chmod(struct btree_trans *trans, ...@@ -356,21 +358,22 @@ int bch2_acl_chmod(struct btree_trans *trans,
struct bkey_s_c_xattr xattr; struct bkey_s_c_xattr xattr;
struct bkey_i_xattr *new; struct bkey_i_xattr *new;
struct posix_acl *acl; struct posix_acl *acl;
int ret = 0; int ret;
iter = bch2_hash_lookup(trans, bch2_xattr_hash_desc, iter = bch2_hash_lookup(trans, bch2_xattr_hash_desc,
&hash_info, inode->bi_inum, &hash_info, inode->bi_inum,
&X_SEARCH(KEY_TYPE_XATTR_INDEX_POSIX_ACL_ACCESS, "", 0), &X_SEARCH(KEY_TYPE_XATTR_INDEX_POSIX_ACL_ACCESS, "", 0),
BTREE_ITER_INTENT); BTREE_ITER_INTENT);
if (IS_ERR(iter)) ret = PTR_ERR_OR_ZERO(iter);
return PTR_ERR(iter) != -ENOENT ? PTR_ERR(iter) : 0; if (ret)
return ret == -ENOENT ? 0 : ret;
xattr = bkey_s_c_to_xattr(bch2_btree_iter_peek_slot(iter)); xattr = bkey_s_c_to_xattr(bch2_btree_iter_peek_slot(iter));
acl = bch2_acl_from_disk(xattr_val(xattr.v), acl = bch2_acl_from_disk(xattr_val(xattr.v),
le16_to_cpu(xattr.v->x_val_len)); le16_to_cpu(xattr.v->x_val_len));
if (IS_ERR_OR_NULL(acl)) ret = PTR_ERR_OR_ZERO(acl);
return PTR_ERR(acl); if (ret || !acl)
goto err;
ret = __posix_acl_chmod(&acl, GFP_KERNEL, mode); ret = __posix_acl_chmod(&acl, GFP_KERNEL, mode);
if (ret) if (ret)
...@@ -387,6 +390,7 @@ int bch2_acl_chmod(struct btree_trans *trans, ...@@ -387,6 +390,7 @@ int bch2_acl_chmod(struct btree_trans *trans,
*new_acl = acl; *new_acl = acl;
acl = NULL; acl = NULL;
err: err:
bch2_trans_iter_put(trans, iter);
kfree(acl); kfree(acl);
return ret; return ret;
} }
......
...@@ -385,7 +385,6 @@ int bch2_alloc_write(struct bch_fs *c, unsigned flags) ...@@ -385,7 +385,6 @@ int bch2_alloc_write(struct bch_fs *c, unsigned flags)
int ret = 0; int ret = 0;
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0); bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
iter = bch2_trans_get_iter(&trans, BTREE_ID_alloc, POS_MIN, iter = bch2_trans_get_iter(&trans, BTREE_ID_alloc, POS_MIN,
BTREE_ITER_SLOTS|BTREE_ITER_INTENT); BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
...@@ -405,6 +404,7 @@ int bch2_alloc_write(struct bch_fs *c, unsigned flags) ...@@ -405,6 +404,7 @@ int bch2_alloc_write(struct bch_fs *c, unsigned flags)
} }
} }
err: err:
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return ret; return ret;
} }
...@@ -926,7 +926,6 @@ static int bch2_invalidate_buckets(struct bch_fs *c, struct bch_dev *ca) ...@@ -926,7 +926,6 @@ static int bch2_invalidate_buckets(struct bch_fs *c, struct bch_dev *ca)
int ret = 0; int ret = 0;
bch2_trans_init(&trans, c, 0, 0); bch2_trans_init(&trans, c, 0, 0);
iter = bch2_trans_get_iter(&trans, BTREE_ID_alloc, iter = bch2_trans_get_iter(&trans, BTREE_ID_alloc,
POS(ca->dev_idx, 0), POS(ca->dev_idx, 0),
BTREE_ITER_CACHED| BTREE_ITER_CACHED|
...@@ -942,6 +941,7 @@ static int bch2_invalidate_buckets(struct bch_fs *c, struct bch_dev *ca) ...@@ -942,6 +941,7 @@ static int bch2_invalidate_buckets(struct bch_fs *c, struct bch_dev *ca)
(!fifo_empty(&ca->free_inc) (!fifo_empty(&ca->free_inc)
? BTREE_INSERT_NOWAIT : 0)); ? BTREE_INSERT_NOWAIT : 0));
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
/* If we used NOWAIT, don't return the error: */ /* If we used NOWAIT, don't return the error: */
......
...@@ -456,6 +456,8 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id, ...@@ -456,6 +456,8 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
bch2_trans_cond_resched(&trans); bch2_trans_cond_resched(&trans);
} }
bch2_trans_iter_put(&trans, iter);
ret = bch2_trans_exit(&trans) ?: ret; ret = bch2_trans_exit(&trans) ?: ret;
if (ret) if (ret)
return ret; return ret;
...@@ -1212,6 +1214,7 @@ static int bch2_gc_btree_gens(struct bch_fs *c, enum btree_id btree_id) ...@@ -1212,6 +1214,7 @@ static int bch2_gc_btree_gens(struct bch_fs *c, enum btree_id btree_id)
bch2_btree_iter_next(iter); bch2_btree_iter_next(iter);
} }
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&sk, c); bch2_bkey_buf_exit(&sk, c);
...@@ -1509,6 +1512,7 @@ static int bch2_coalesce_btree(struct bch_fs *c, enum btree_id btree_id) ...@@ -1509,6 +1512,7 @@ static int bch2_coalesce_btree(struct bch_fs *c, enum btree_id btree_id)
struct btree *b; struct btree *b;
bool kthread = (current->flags & PF_KTHREAD) != 0; bool kthread = (current->flags & PF_KTHREAD) != 0;
unsigned i; unsigned i;
int ret = 0;
/* Sliding window of adjacent btree nodes */ /* Sliding window of adjacent btree nodes */
struct btree *merge[GC_MERGE_NODES]; struct btree *merge[GC_MERGE_NODES];
...@@ -1557,8 +1561,8 @@ static int bch2_coalesce_btree(struct bch_fs *c, enum btree_id btree_id) ...@@ -1557,8 +1561,8 @@ static int bch2_coalesce_btree(struct bch_fs *c, enum btree_id btree_id)
lock_seq[0] = merge[0]->c.lock.state.seq; lock_seq[0] = merge[0]->c.lock.state.seq;
if (kthread && kthread_should_stop()) { if (kthread && kthread_should_stop()) {
bch2_trans_exit(&trans); ret = -ESHUTDOWN;
return -ESHUTDOWN; break;
} }
bch2_trans_cond_resched(&trans); bch2_trans_cond_resched(&trans);
...@@ -1573,7 +1577,9 @@ static int bch2_coalesce_btree(struct bch_fs *c, enum btree_id btree_id) ...@@ -1573,7 +1577,9 @@ static int bch2_coalesce_btree(struct bch_fs *c, enum btree_id btree_id)
memset(merge + 1, 0, memset(merge + 1, 0,
(GC_MERGE_NODES - 1) * sizeof(merge[0])); (GC_MERGE_NODES - 1) * sizeof(merge[0]));
} }
return bch2_trans_exit(&trans); bch2_trans_iter_put(&trans, iter);
return bch2_trans_exit(&trans) ?: ret;
} }
/** /**
......
...@@ -1208,6 +1208,7 @@ static void bch2_btree_node_write_error(struct bch_fs *c, ...@@ -1208,6 +1208,7 @@ static void bch2_btree_node_write_error(struct bch_fs *c,
if (ret) if (ret)
goto err; goto err;
out: out:
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&k, c); bch2_bkey_buf_exit(&k, c);
bio_put(&wbio->wbio.bio); bio_put(&wbio->wbio.bio);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "btree_locking.h" #include "btree_locking.h"
#include "btree_update.h" #include "btree_update.h"
#include "debug.h" #include "debug.h"
#include "error.h"
#include "extents.h" #include "extents.h"
#include "journal.h" #include "journal.h"
#include "trace.h" #include "trace.h"
...@@ -2116,6 +2117,7 @@ struct btree_iter *bch2_trans_get_node_iter(struct btree_trans *trans, ...@@ -2116,6 +2117,7 @@ struct btree_iter *bch2_trans_get_node_iter(struct btree_trans *trans,
for (i = 0; i < ARRAY_SIZE(iter->l); i++) for (i = 0; i < ARRAY_SIZE(iter->l); i++)
iter->l[i].b = NULL; iter->l[i].b = NULL;
iter->l[iter->level].b = BTREE_ITER_NO_NODE_INIT; iter->l[iter->level].b = BTREE_ITER_NO_NODE_INIT;
iter->ip_allocated = _RET_IP_;
return iter; return iter;
} }
...@@ -2224,6 +2226,8 @@ void bch2_trans_reset(struct btree_trans *trans, unsigned flags) ...@@ -2224,6 +2226,8 @@ void bch2_trans_reset(struct btree_trans *trans, unsigned flags)
(void *) &trans->fs_usage_deltas->memset_start); (void *) &trans->fs_usage_deltas->memset_start);
} }
bch2_trans_cond_resched(trans);
if (!(flags & TRANS_RESET_NOTRAVERSE)) if (!(flags & TRANS_RESET_NOTRAVERSE))
bch2_btree_iter_traverse_all(trans); bch2_btree_iter_traverse_all(trans);
} }
...@@ -2290,6 +2294,19 @@ int bch2_trans_exit(struct btree_trans *trans) ...@@ -2290,6 +2294,19 @@ int bch2_trans_exit(struct btree_trans *trans)
bch2_trans_unlock(trans); bch2_trans_unlock(trans);
#ifdef CONFIG_BCACHEFS_DEBUG #ifdef CONFIG_BCACHEFS_DEBUG
if (trans->iters_live) {
struct btree_iter *iter;
bch_err(c, "btree iterators leaked!");
trans_for_each_iter(trans, iter)
if (btree_iter_live(trans, iter))
printk(KERN_ERR " btree %s allocated at %pS\n",
bch2_btree_ids[iter->btree_id],
(void *) iter->ip_allocated);
/* Be noisy about this: */
bch2_fatal_error(c);
}
mutex_lock(&trans->c->btree_trans_lock); mutex_lock(&trans->c->btree_trans_lock);
list_del(&trans->list); list_del(&trans->list);
mutex_unlock(&trans->c->btree_trans_lock); mutex_unlock(&trans->c->btree_trans_lock);
......
...@@ -242,6 +242,8 @@ static ssize_t bch2_read_btree(struct file *file, char __user *buf, ...@@ -242,6 +242,8 @@ static ssize_t bch2_read_btree(struct file *file, char __user *buf,
if (!i->size) if (!i->size)
break; break;
} }
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return err < 0 ? err : i->ret; return err < 0 ? err : i->ret;
...@@ -294,6 +296,8 @@ static ssize_t bch2_read_btree_formats(struct file *file, char __user *buf, ...@@ -294,6 +296,8 @@ static ssize_t bch2_read_btree_formats(struct file *file, char __user *buf,
if (!i->size) if (!i->size)
break; break;
} }
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return err < 0 ? err : i->ret; return err < 0 ? err : i->ret;
......
...@@ -321,6 +321,7 @@ u64 bch2_dirent_lookup(struct bch_fs *c, u64 dir_inum, ...@@ -321,6 +321,7 @@ u64 bch2_dirent_lookup(struct bch_fs *c, u64 dir_inum,
k = bch2_btree_iter_peek_slot(iter); k = bch2_btree_iter_peek_slot(iter);
inum = le64_to_cpu(bkey_s_c_to_dirent(k).v->d_inum); inum = le64_to_cpu(bkey_s_c_to_dirent(k).v->d_inum);
bch2_trans_iter_put(&trans, iter);
out: out:
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return inum; return inum;
...@@ -379,6 +380,8 @@ int bch2_readdir(struct bch_fs *c, u64 inum, struct dir_context *ctx) ...@@ -379,6 +380,8 @@ int bch2_readdir(struct bch_fs *c, u64 inum, struct dir_context *ctx)
break; break;
ctx->pos = dirent.k->p.offset + 1; ctx->pos = dirent.k->p.offset + 1;
} }
bch2_trans_iter_put(&trans, iter);
ret = bch2_trans_exit(&trans) ?: ret; ret = bch2_trans_exit(&trans) ?: ret;
return ret; return ret;
......
...@@ -873,6 +873,7 @@ static int ec_stripe_update_ptrs(struct bch_fs *c, ...@@ -873,6 +873,7 @@ static int ec_stripe_update_ptrs(struct bch_fs *c,
if (ret) if (ret)
break; break;
} }
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&sk, c); bch2_bkey_buf_exit(&sk, c);
...@@ -1663,12 +1664,13 @@ int bch2_ec_mem_alloc(struct bch_fs *c, bool gc) ...@@ -1663,12 +1664,13 @@ int bch2_ec_mem_alloc(struct bch_fs *c, bool gc)
int ret = 0; int ret = 0;
bch2_trans_init(&trans, c, 0, 0); bch2_trans_init(&trans, c, 0, 0);
iter = bch2_trans_get_iter(&trans, BTREE_ID_stripes, POS(0, U64_MAX), 0); iter = bch2_trans_get_iter(&trans, BTREE_ID_stripes, POS(0, U64_MAX), 0);
k = bch2_btree_iter_prev(iter); k = bch2_btree_iter_prev(iter);
if (!IS_ERR_OR_NULL(k.k)) if (!IS_ERR_OR_NULL(k.k))
idx = k.k->p.offset + 1; idx = k.k->p.offset + 1;
bch2_trans_iter_put(&trans, iter);
ret = bch2_trans_exit(&trans); ret = bch2_trans_exit(&trans);
if (ret) if (ret)
return ret; return ret;
......
...@@ -687,6 +687,8 @@ bool bch2_check_range_allocated(struct bch_fs *c, struct bpos pos, u64 size, ...@@ -687,6 +687,8 @@ bool bch2_check_range_allocated(struct bch_fs *c, struct bpos pos, u64 size,
break; break;
} }
} }
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return ret; return ret;
......
...@@ -866,7 +866,6 @@ void bch2_readahead(struct readahead_control *ractl) ...@@ -866,7 +866,6 @@ void bch2_readahead(struct readahead_control *ractl)
BUG_ON(ret); BUG_ON(ret);
bch2_trans_init(&trans, c, 0, 0); bch2_trans_init(&trans, c, 0, 0);
iter = bch2_trans_get_iter(&trans, BTREE_ID_extents, POS_MIN, iter = bch2_trans_get_iter(&trans, BTREE_ID_extents, POS_MIN,
BTREE_ITER_SLOTS); BTREE_ITER_SLOTS);
...@@ -895,6 +894,7 @@ void bch2_readahead(struct readahead_control *ractl) ...@@ -895,6 +894,7 @@ void bch2_readahead(struct readahead_control *ractl)
bch2_pagecache_add_put(&inode->ei_pagecache_lock); bch2_pagecache_add_put(&inode->ei_pagecache_lock);
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
kfree(readpages_iter.pages); kfree(readpages_iter.pages);
} }
...@@ -918,6 +918,7 @@ static void __bchfs_readpage(struct bch_fs *c, struct bch_read_bio *rbio, ...@@ -918,6 +918,7 @@ static void __bchfs_readpage(struct bch_fs *c, struct bch_read_bio *rbio,
bchfs_read(&trans, iter, rbio, inum, NULL); bchfs_read(&trans, iter, rbio, inum, NULL);
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
} }
...@@ -2155,6 +2156,7 @@ static inline int range_has_data(struct bch_fs *c, ...@@ -2155,6 +2156,7 @@ static inline int range_has_data(struct bch_fs *c,
break; break;
} }
} }
bch2_trans_iter_put(&trans, iter);
return bch2_trans_exit(&trans) ?: ret; return bch2_trans_exit(&trans) ?: ret;
} }
...@@ -2325,6 +2327,7 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr) ...@@ -2325,6 +2327,7 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
bch2_trans_init(&trans, c, 0, 0); bch2_trans_init(&trans, c, 0, 0);
iter = bch2_inode_peek(&trans, &inode_u, inode->v.i_ino, 0); iter = bch2_inode_peek(&trans, &inode_u, inode->v.i_ino, 0);
ret = PTR_ERR_OR_ZERO(iter); ret = PTR_ERR_OR_ZERO(iter);
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
if (ret) if (ret)
...@@ -2459,14 +2462,11 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode, ...@@ -2459,14 +2462,11 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
struct btree_iter *src, *dst, *del; struct btree_iter *src, *dst, *del;
loff_t shift, new_size; loff_t shift, new_size;
u64 src_start; u64 src_start;
int ret; int ret = 0;
if ((offset | len) & (block_bytes(c) - 1)) if ((offset | len) & (block_bytes(c) - 1))
return -EINVAL; return -EINVAL;
bch2_bkey_buf_init(&copy);
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 256);
/* /*
* 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
* btree, and the btree consistent with i_size - we don't need outside * btree, and the btree consistent with i_size - we don't need outside
...@@ -2522,13 +2522,15 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode, ...@@ -2522,13 +2522,15 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
goto err; goto err;
} }
bch2_bkey_buf_init(&copy);
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 256);
src = bch2_trans_get_iter(&trans, BTREE_ID_extents, src = bch2_trans_get_iter(&trans, BTREE_ID_extents,
POS(inode->v.i_ino, src_start >> 9), POS(inode->v.i_ino, src_start >> 9),
BTREE_ITER_INTENT); BTREE_ITER_INTENT);
dst = bch2_trans_copy_iter(&trans, src); dst = bch2_trans_copy_iter(&trans, src);
del = bch2_trans_copy_iter(&trans, src); del = bch2_trans_copy_iter(&trans, src);
while (1) { while (ret == 0 || ret == -EINTR) {
struct disk_reservation disk_res = struct disk_reservation disk_res =
bch2_disk_reservation_init(c, 0); bch2_disk_reservation_init(c, 0);
struct bkey_i delete; struct bkey_i delete;
...@@ -2542,7 +2544,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode, ...@@ -2542,7 +2544,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
? bch2_btree_iter_peek_prev(src) ? bch2_btree_iter_peek_prev(src)
: bch2_btree_iter_peek(src); : bch2_btree_iter_peek(src);
if ((ret = bkey_err(k))) if ((ret = bkey_err(k)))
goto bkey_err; continue;
if (!k.k || k.k->p.inode != inode->v.i_ino) if (!k.k || k.k->p.inode != inode->v.i_ino)
break; break;
...@@ -2562,7 +2564,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode, ...@@ -2562,7 +2564,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
ret = bch2_extent_atomic_end(dst, copy.k, &atomic_end); ret = bch2_extent_atomic_end(dst, copy.k, &atomic_end);
if (ret) if (ret)
goto bkey_err; continue;
if (bkey_cmp(atomic_end, copy.k->k.p)) { if (bkey_cmp(atomic_end, copy.k->k.p)) {
if (insert) { if (insert) {
...@@ -2605,18 +2607,18 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode, ...@@ -2605,18 +2607,18 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
&inode->ei_journal_seq, &inode->ei_journal_seq,
BTREE_INSERT_NOFAIL); BTREE_INSERT_NOFAIL);
bch2_disk_reservation_put(c, &disk_res); bch2_disk_reservation_put(c, &disk_res);
bkey_err:
if (!ret) if (!ret)
bch2_btree_iter_set_pos(src, next_pos); bch2_btree_iter_set_pos(src, next_pos);
if (ret == -EINTR)
ret = 0;
if (ret)
goto err;
bch2_trans_cond_resched(&trans);
} }
bch2_trans_unlock(&trans); bch2_trans_iter_put(&trans, del);
bch2_trans_iter_put(&trans, dst);
bch2_trans_iter_put(&trans, src);
bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&copy, c);
if (ret)
goto err;
if (!insert) { if (!insert) {
i_size_write(&inode->v, new_size); i_size_write(&inode->v, new_size);
...@@ -2626,8 +2628,6 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode, ...@@ -2626,8 +2628,6 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
mutex_unlock(&inode->ei_update_lock); mutex_unlock(&inode->ei_update_lock);
} }
err: err:
bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&copy, c);
bch2_pagecache_block_put(&inode->ei_pagecache_lock); bch2_pagecache_block_put(&inode->ei_pagecache_lock);
inode_unlock(&inode->v); inode_unlock(&inode->v);
return ret; return ret;
...@@ -2682,7 +2682,7 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode, ...@@ -2682,7 +2682,7 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode,
BTREE_ITER_SLOTS|BTREE_ITER_INTENT); BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
end_pos = POS(inode->v.i_ino, block_end >> 9); end_pos = POS(inode->v.i_ino, block_end >> 9);
while (bkey_cmp(iter->pos, end_pos) < 0) { while (!ret && bkey_cmp(iter->pos, end_pos) < 0) {
s64 i_sectors_delta = 0; s64 i_sectors_delta = 0;
struct disk_reservation disk_res = { 0 }; struct disk_reservation disk_res = { 0 };
struct quota_res quota_res = { 0 }; struct quota_res quota_res = { 0 };
...@@ -2746,9 +2746,11 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode, ...@@ -2746,9 +2746,11 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode,
bch2_disk_reservation_put(c, &disk_res); bch2_disk_reservation_put(c, &disk_res);
if (ret == -EINTR) if (ret == -EINTR)
ret = 0; ret = 0;
if (ret)
goto err;
} }
bch2_trans_iter_put(&trans, iter);
if (ret)
goto err;
/* /*
* Do we need to extend the file? * Do we need to extend the file?
...@@ -2770,6 +2772,7 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode, ...@@ -2770,6 +2772,7 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode,
ret = PTR_ERR_OR_ZERO(inode_iter); ret = PTR_ERR_OR_ZERO(inode_iter);
} while (ret == -EINTR); } while (ret == -EINTR);
bch2_trans_iter_put(&trans, inode_iter);
bch2_trans_unlock(&trans); bch2_trans_unlock(&trans);
if (ret) if (ret)
...@@ -3015,6 +3018,7 @@ static loff_t bch2_seek_data(struct file *file, u64 offset) ...@@ -3015,6 +3018,7 @@ static loff_t bch2_seek_data(struct file *file, u64 offset)
} else if (k.k->p.offset >> 9 > isize) } else if (k.k->p.offset >> 9 > isize)
break; break;
} }
bch2_trans_iter_put(&trans, iter);
ret = bch2_trans_exit(&trans) ?: ret; ret = bch2_trans_exit(&trans) ?: ret;
if (ret) if (ret)
...@@ -3118,6 +3122,7 @@ static loff_t bch2_seek_hole(struct file *file, u64 offset) ...@@ -3118,6 +3122,7 @@ static loff_t bch2_seek_hole(struct file *file, u64 offset)
offset = max(offset, bkey_start_offset(k.k) << 9); offset = max(offset, bkey_start_offset(k.k) << 9);
} }
} }
bch2_trans_iter_put(&trans, iter);
ret = bch2_trans_exit(&trans) ?: ret; ret = bch2_trans_exit(&trans) ?: ret;
if (ret) if (ret)
......
...@@ -734,6 +734,8 @@ static int bch2_setattr_nonsize(struct mnt_idmap *idmap, ...@@ -734,6 +734,8 @@ static int bch2_setattr_nonsize(struct mnt_idmap *idmap,
BTREE_INSERT_NOUNLOCK| BTREE_INSERT_NOUNLOCK|
BTREE_INSERT_NOFAIL); BTREE_INSERT_NOFAIL);
btree_err: btree_err:
bch2_trans_iter_put(&trans, inode_iter);
if (ret == -EINTR) if (ret == -EINTR)
goto retry; goto retry;
if (unlikely(ret)) if (unlikely(ret))
...@@ -961,6 +963,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info, ...@@ -961,6 +963,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
ret = bch2_fill_extent(c, info, bkey_i_to_s_c(prev.k), ret = bch2_fill_extent(c, info, bkey_i_to_s_c(prev.k),
FIEMAP_EXTENT_LAST); FIEMAP_EXTENT_LAST);
bch2_trans_iter_put(&trans, iter);
ret = bch2_trans_exit(&trans) ?: ret; ret = bch2_trans_exit(&trans) ?: ret;
bch2_bkey_buf_exit(&cur, c); bch2_bkey_buf_exit(&cur, c);
bch2_bkey_buf_exit(&prev, c); bch2_bkey_buf_exit(&prev, c);
......
...@@ -1485,11 +1485,12 @@ int bch2_fsck_walk_inodes_only(struct bch_fs *c) ...@@ -1485,11 +1485,12 @@ int bch2_fsck_walk_inodes_only(struct bch_fs *c)
BCH_INODE_I_SECTORS_DIRTY| BCH_INODE_I_SECTORS_DIRTY|
BCH_INODE_UNLINKED)) { BCH_INODE_UNLINKED)) {
ret = check_inode(&trans, NULL, iter, inode, NULL); ret = check_inode(&trans, NULL, iter, inode, NULL);
BUG_ON(ret == -EINTR);
if (ret) if (ret)
break; break;
} }
} }
bch2_trans_iter_put(&trans, iter);
BUG_ON(ret == -EINTR); BUG_ON(ret == -EINTR);
return bch2_trans_exit(&trans) ?: ret; return bch2_trans_exit(&trans) ?: ret;
......
...@@ -620,6 +620,7 @@ int bch2_inode_rm(struct bch_fs *c, u64 inode_nr, bool cached) ...@@ -620,6 +620,7 @@ int bch2_inode_rm(struct bch_fs *c, u64 inode_nr, bool cached)
ret = bch2_trans_commit(&trans, NULL, NULL, ret = bch2_trans_commit(&trans, NULL, NULL,
BTREE_INSERT_NOFAIL); BTREE_INSERT_NOFAIL);
bch2_trans_iter_put(&trans, iter);
err: err:
if (ret == -EINTR) if (ret == -EINTR)
goto retry; goto retry;
......
...@@ -414,6 +414,8 @@ int bch2_fpunch(struct bch_fs *c, u64 inum, u64 start, u64 end, ...@@ -414,6 +414,8 @@ int bch2_fpunch(struct bch_fs *c, u64 inum, u64 start, u64 end,
ret = bch2_fpunch_at(&trans, iter, POS(inum, end), ret = bch2_fpunch_at(&trans, iter, POS(inum, end),
journal_seq, i_sectors_delta); journal_seq, i_sectors_delta);
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
if (ret == -EINTR) if (ret == -EINTR)
...@@ -460,6 +462,7 @@ int bch2_write_index_default(struct bch_write_op *op) ...@@ -460,6 +462,7 @@ int bch2_write_index_default(struct bch_write_op *op)
bch2_keylist_pop_front(keys); bch2_keylist_pop_front(keys);
} while (!bch2_keylist_empty(keys)); } while (!bch2_keylist_empty(keys));
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&sk, c); bch2_bkey_buf_exit(&sk, c);
...@@ -1659,6 +1662,7 @@ static void bch2_read_retry_nodecode(struct bch_fs *c, struct bch_read_bio *rbio ...@@ -1659,6 +1662,7 @@ static void bch2_read_retry_nodecode(struct bch_fs *c, struct bch_read_bio *rbio
goto err; goto err;
out: out:
bch2_rbio_done(rbio); bch2_rbio_done(rbio);
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&sk, c); bch2_bkey_buf_exit(&sk, c);
return; return;
...@@ -2259,7 +2263,7 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio, ...@@ -2259,7 +2263,7 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
k = bch2_btree_iter_peek_slot(iter); k = bch2_btree_iter_peek_slot(iter);
ret = bkey_err(k); ret = bkey_err(k);
if (ret) if (ret)
goto err; break;
offset_into_extent = iter->pos.offset - offset_into_extent = iter->pos.offset -
bkey_start_offset(k.k); bkey_start_offset(k.k);
...@@ -2270,7 +2274,7 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio, ...@@ -2270,7 +2274,7 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
ret = bch2_read_indirect_extent(&trans, &data_btree, ret = bch2_read_indirect_extent(&trans, &data_btree,
&offset_into_extent, &sk); &offset_into_extent, &sk);
if (ret) if (ret)
goto err; break;
k = bkey_i_to_s_c(sk.k); k = bkey_i_to_s_c(sk.k);
...@@ -2295,12 +2299,8 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio, ...@@ -2295,12 +2299,8 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
ret = __bch2_read_extent(&trans, rbio, bvec_iter, iter->pos, ret = __bch2_read_extent(&trans, rbio, bvec_iter, iter->pos,
data_btree, k, data_btree, k,
offset_into_extent, failed, flags); offset_into_extent, failed, flags);
switch (ret) { if (ret)
case READ_RETRY: break;
goto retry;
case READ_ERR:
goto err;
};
if (flags & BCH_READ_LAST_FRAGMENT) if (flags & BCH_READ_LAST_FRAGMENT)
break; break;
...@@ -2308,19 +2308,19 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio, ...@@ -2308,19 +2308,19 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
swap(bvec_iter.bi_size, bytes); swap(bvec_iter.bi_size, bytes);
bio_advance_iter(&rbio->bio, &bvec_iter, bytes); bio_advance_iter(&rbio->bio, &bvec_iter, bytes);
} }
out: bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&sk, c); if (ret == -EINTR || ret == READ_RETRY || ret == READ_RETRY_AVOID)
return;
err:
if (ret == -EINTR)
goto retry; goto retry;
bch_err_inum_ratelimited(c, inode, if (ret) {
"read error %i from btree lookup", ret); bch_err_inum_ratelimited(c, inode,
rbio->bio.bi_status = BLK_STS_IOERR; "read error %i from btree lookup", ret);
bch2_rbio_done(rbio); rbio->bio.bi_status = BLK_STS_IOERR;
goto out; bch2_rbio_done(rbio);
}
bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&sk, c);
} }
void bch2_fs_io_exit(struct bch_fs *c) void bch2_fs_io_exit(struct bch_fs *c)
......
...@@ -88,6 +88,7 @@ static int __bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags ...@@ -88,6 +88,7 @@ static int __bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags
if (ret) if (ret)
break; break;
} }
bch2_trans_iter_put(&trans, iter);
ret = bch2_trans_exit(&trans) ?: ret; ret = bch2_trans_exit(&trans) ?: ret;
bch2_bkey_buf_exit(&sk, c); bch2_bkey_buf_exit(&sk, c);
...@@ -135,20 +136,24 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags) ...@@ -135,20 +136,24 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
dev_idx, flags, true); dev_idx, flags, true);
if (ret) { if (ret) {
bch_err(c, "Cannot drop device without losing data"); bch_err(c, "Cannot drop device without losing data");
goto err; break;
} }
ret = bch2_btree_node_update_key(c, iter, b, k.k); ret = bch2_btree_node_update_key(c, iter, b, k.k);
if (ret == -EINTR) { if (ret == -EINTR) {
b = bch2_btree_iter_peek_node(iter); b = bch2_btree_iter_peek_node(iter);
ret = 0;
goto retry; goto retry;
} }
if (ret) { if (ret) {
bch_err(c, "Error updating btree node key: %i", ret); bch_err(c, "Error updating btree node key: %i", ret);
goto err; break;
} }
} }
bch2_trans_iter_free(&trans, iter); bch2_trans_iter_free(&trans, iter);
if (ret)
goto err;
} }
/* flush relevant btree updates */ /* flush relevant btree updates */
......
...@@ -195,6 +195,7 @@ static int bch2_migrate_index_update(struct bch_write_op *op) ...@@ -195,6 +195,7 @@ static int bch2_migrate_index_update(struct bch_write_op *op)
goto next; goto next;
} }
out: out:
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&_insert, c); bch2_bkey_buf_exit(&_insert, c);
bch2_bkey_buf_exit(&_new, c); bch2_bkey_buf_exit(&_new, c);
...@@ -641,6 +642,8 @@ static int __bch2_move_data(struct bch_fs *c, ...@@ -641,6 +642,8 @@ static int __bch2_move_data(struct bch_fs *c,
bch2_trans_cond_resched(&trans); bch2_trans_cond_resched(&trans);
} }
out: out:
bch2_trans_iter_put(&trans, iter);
ret = bch2_trans_exit(&trans) ?: ret; ret = bch2_trans_exit(&trans) ?: ret;
bch2_bkey_buf_exit(&sk, c); bch2_bkey_buf_exit(&sk, c);
......
...@@ -372,6 +372,7 @@ static int bch2_quota_init_type(struct bch_fs *c, enum quota_types type) ...@@ -372,6 +372,7 @@ static int bch2_quota_init_type(struct bch_fs *c, enum quota_types type)
if (ret) if (ret)
break; break;
} }
bch2_trans_iter_put(&trans, iter);
return bch2_trans_exit(&trans) ?: ret; return bch2_trans_exit(&trans) ?: ret;
} }
...@@ -449,6 +450,8 @@ int bch2_fs_quota_read(struct bch_fs *c) ...@@ -449,6 +450,8 @@ int bch2_fs_quota_read(struct bch_fs *c)
KEY_TYPE_QUOTA_NOCHECK); KEY_TYPE_QUOTA_NOCHECK);
} }
} }
bch2_trans_iter_put(&trans, iter);
return bch2_trans_exit(&trans) ?: ret; return bch2_trans_exit(&trans) ?: ret;
} }
...@@ -739,7 +742,9 @@ static int bch2_set_quota_trans(struct btree_trans *trans, ...@@ -739,7 +742,9 @@ static int bch2_set_quota_trans(struct btree_trans *trans,
if (qdq->d_fieldmask & QC_INO_HARD) if (qdq->d_fieldmask & QC_INO_HARD)
new_quota->v.c[Q_INO].hardlimit = cpu_to_le64(qdq->d_ino_hardlimit); new_quota->v.c[Q_INO].hardlimit = cpu_to_le64(qdq->d_ino_hardlimit);
return bch2_trans_update(trans, iter, &new_quota->k_i, 0); ret = bch2_trans_update(trans, iter, &new_quota->k_i, 0);
bch2_trans_iter_put(trans, iter);
return ret;
} }
static int bch2_set_quota(struct super_block *sb, struct kqid qid, static int bch2_set_quota(struct super_block *sb, struct kqid qid,
......
...@@ -223,20 +223,18 @@ s64 bch2_remap_range(struct bch_fs *c, ...@@ -223,20 +223,18 @@ s64 bch2_remap_range(struct bch_fs *c,
dst_iter = bch2_trans_get_iter(&trans, BTREE_ID_extents, dst_start, dst_iter = bch2_trans_get_iter(&trans, BTREE_ID_extents, dst_start,
BTREE_ITER_INTENT); BTREE_ITER_INTENT);
while (1) { while (ret == 0 || ret == -EINTR) {
bch2_trans_begin(&trans); bch2_trans_begin(&trans);
trans.mem_top = 0;
if (fatal_signal_pending(current)) { if (fatal_signal_pending(current)) {
ret = -EINTR; ret = -EINTR;
goto err; break;
} }
src_k = get_next_src(src_iter, src_end); src_k = get_next_src(src_iter, src_end);
ret = bkey_err(src_k); ret = bkey_err(src_k);
if (ret) if (ret)
goto btree_err; continue;
src_done = bpos_min(src_iter->pos, src_end).offset - src_done = bpos_min(src_iter->pos, src_end).offset -
src_start.offset; src_start.offset;
...@@ -245,8 +243,6 @@ s64 bch2_remap_range(struct bch_fs *c, ...@@ -245,8 +243,6 @@ s64 bch2_remap_range(struct bch_fs *c,
if (bkey_cmp(dst_iter->pos, dst_want) < 0) { if (bkey_cmp(dst_iter->pos, dst_want) < 0) {
ret = bch2_fpunch_at(&trans, dst_iter, dst_want, ret = bch2_fpunch_at(&trans, dst_iter, dst_want,
journal_seq, i_sectors_delta); journal_seq, i_sectors_delta);
if (ret)
goto btree_err;
continue; continue;
} }
...@@ -265,7 +261,7 @@ s64 bch2_remap_range(struct bch_fs *c, ...@@ -265,7 +261,7 @@ s64 bch2_remap_range(struct bch_fs *c,
ret = bch2_make_extent_indirect(&trans, src_iter, ret = bch2_make_extent_indirect(&trans, src_iter,
new_src.k); new_src.k);
if (ret) if (ret)
goto btree_err; continue;
BUG_ON(src_k.k->type != KEY_TYPE_reflink_p); BUG_ON(src_k.k->type != KEY_TYPE_reflink_p);
} }
...@@ -294,20 +290,16 @@ s64 bch2_remap_range(struct bch_fs *c, ...@@ -294,20 +290,16 @@ s64 bch2_remap_range(struct bch_fs *c,
NULL, journal_seq, NULL, journal_seq,
new_i_size, i_sectors_delta); new_i_size, i_sectors_delta);
if (ret) if (ret)
goto btree_err; continue;
dst_done = dst_iter->pos.offset - dst_start.offset; dst_done = dst_iter->pos.offset - dst_start.offset;
src_want = POS(src_start.inode, src_start.offset + dst_done); src_want = POS(src_start.inode, src_start.offset + dst_done);
bch2_btree_iter_set_pos(src_iter, src_want); bch2_btree_iter_set_pos(src_iter, src_want);
btree_err:
if (ret == -EINTR)
ret = 0;
if (ret)
goto err;
} }
bch2_trans_iter_put(&trans, dst_iter);
bch2_trans_iter_put(&trans, src_iter);
BUG_ON(bkey_cmp(dst_iter->pos, dst_end)); BUG_ON(!ret && bkey_cmp(dst_iter->pos, dst_end));
err:
BUG_ON(bkey_cmp(dst_iter->pos, dst_end) > 0); BUG_ON(bkey_cmp(dst_iter->pos, dst_end) > 0);
dst_done = dst_iter->pos.offset - dst_start.offset; dst_done = dst_iter->pos.offset - dst_start.offset;
...@@ -329,6 +321,8 @@ s64 bch2_remap_range(struct bch_fs *c, ...@@ -329,6 +321,8 @@ s64 bch2_remap_range(struct bch_fs *c,
ret2 = bch2_inode_write(&trans, inode_iter, &inode_u) ?: ret2 = bch2_inode_write(&trans, inode_iter, &inode_u) ?:
bch2_trans_commit(&trans, NULL, journal_seq, 0); bch2_trans_commit(&trans, NULL, journal_seq, 0);
} }
bch2_trans_iter_put(&trans, inode_iter);
} while (ret2 == -EINTR); } while (ret2 == -EINTR);
ret = bch2_trans_exit(&trans) ?: ret; ret = bch2_trans_exit(&trans) ?: ret;
......
...@@ -67,6 +67,7 @@ static int test_delete(struct bch_fs *c, u64 nr) ...@@ -67,6 +67,7 @@ static int test_delete(struct bch_fs *c, u64 nr)
goto err; goto err;
} }
err: err:
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return ret; return ret;
} }
...@@ -106,6 +107,7 @@ static int test_delete_written(struct bch_fs *c, u64 nr) ...@@ -106,6 +107,7 @@ static int test_delete_written(struct bch_fs *c, u64 nr)
goto err; goto err;
} }
err: err:
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return ret; return ret;
} }
...@@ -113,7 +115,7 @@ static int test_delete_written(struct bch_fs *c, u64 nr) ...@@ -113,7 +115,7 @@ static int test_delete_written(struct bch_fs *c, u64 nr)
static int test_iterate(struct bch_fs *c, u64 nr) static int test_iterate(struct bch_fs *c, u64 nr)
{ {
struct btree_trans trans; struct btree_trans trans;
struct btree_iter *iter; struct btree_iter *iter = NULL;
struct bkey_s_c k; struct bkey_s_c k;
u64 i; u64 i;
int ret = 0; int ret = 0;
...@@ -159,6 +161,7 @@ static int test_iterate(struct bch_fs *c, u64 nr) ...@@ -159,6 +161,7 @@ static int test_iterate(struct bch_fs *c, u64 nr)
BUG_ON(i); BUG_ON(i);
err: err:
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return ret; return ret;
} }
...@@ -166,7 +169,7 @@ static int test_iterate(struct bch_fs *c, u64 nr) ...@@ -166,7 +169,7 @@ static int test_iterate(struct bch_fs *c, u64 nr)
static int test_iterate_extents(struct bch_fs *c, u64 nr) static int test_iterate_extents(struct bch_fs *c, u64 nr)
{ {
struct btree_trans trans; struct btree_trans trans;
struct btree_iter *iter; struct btree_iter *iter = NULL;
struct bkey_s_c k; struct bkey_s_c k;
u64 i; u64 i;
int ret = 0; int ret = 0;
...@@ -213,6 +216,7 @@ static int test_iterate_extents(struct bch_fs *c, u64 nr) ...@@ -213,6 +216,7 @@ static int test_iterate_extents(struct bch_fs *c, u64 nr)
BUG_ON(i); BUG_ON(i);
err: err:
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return ret; return ret;
} }
...@@ -257,7 +261,7 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr) ...@@ -257,7 +261,7 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr)
BUG_ON(k.k->p.offset != i); BUG_ON(k.k->p.offset != i);
i += 2; i += 2;
} }
bch2_trans_iter_free(&trans, iter); bch2_trans_iter_put(&trans, iter);
BUG_ON(i != nr * 2); BUG_ON(i != nr * 2);
...@@ -274,6 +278,7 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr) ...@@ -274,6 +278,7 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr)
if (i == nr * 2) if (i == nr * 2)
break; break;
} }
bch2_trans_iter_put(&trans, iter);
err: err:
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return ret; return ret;
...@@ -318,7 +323,7 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr) ...@@ -318,7 +323,7 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
BUG_ON(k.k->size != 8); BUG_ON(k.k->size != 8);
i += 16; i += 16;
} }
bch2_trans_iter_free(&trans, iter); bch2_trans_iter_put(&trans, iter);
BUG_ON(i != nr); BUG_ON(i != nr);
...@@ -337,6 +342,7 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr) ...@@ -337,6 +342,7 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
if (i == nr) if (i == nr)
break; break;
} }
bch2_trans_iter_put(&trans, iter);
err: err:
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return 0; return 0;
...@@ -362,6 +368,8 @@ static int test_peek_end(struct bch_fs *c, u64 nr) ...@@ -362,6 +368,8 @@ static int test_peek_end(struct bch_fs *c, u64 nr)
k = bch2_btree_iter_peek(iter); k = bch2_btree_iter_peek(iter);
BUG_ON(k.k); BUG_ON(k.k);
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return 0; return 0;
} }
...@@ -382,6 +390,8 @@ static int test_peek_end_extents(struct bch_fs *c, u64 nr) ...@@ -382,6 +390,8 @@ static int test_peek_end_extents(struct bch_fs *c, u64 nr)
k = bch2_btree_iter_peek(iter); k = bch2_btree_iter_peek(iter);
BUG_ON(k.k); BUG_ON(k.k);
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return 0; return 0;
} }
...@@ -508,7 +518,7 @@ static int rand_lookup(struct bch_fs *c, u64 nr) ...@@ -508,7 +518,7 @@ static int rand_lookup(struct bch_fs *c, u64 nr)
} }
} }
bch2_trans_iter_free(&trans, iter); bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return ret; return ret;
} }
...@@ -549,7 +559,7 @@ static int rand_mixed(struct bch_fs *c, u64 nr) ...@@ -549,7 +559,7 @@ static int rand_mixed(struct bch_fs *c, u64 nr)
} }
} }
bch2_trans_iter_free(&trans, iter); bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return ret; return ret;
} }
...@@ -630,6 +640,8 @@ static int seq_insert(struct bch_fs *c, u64 nr) ...@@ -630,6 +640,8 @@ static int seq_insert(struct bch_fs *c, u64 nr)
if (++i == nr) if (++i == nr)
break; break;
} }
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return ret; return ret;
} }
...@@ -645,6 +657,8 @@ static int seq_lookup(struct bch_fs *c, u64 nr) ...@@ -645,6 +657,8 @@ static int seq_lookup(struct bch_fs *c, u64 nr)
for_each_btree_key(&trans, iter, BTREE_ID_xattrs, POS_MIN, 0, k, ret) for_each_btree_key(&trans, iter, BTREE_ID_xattrs, POS_MIN, 0, k, ret)
; ;
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return ret; return ret;
} }
...@@ -671,6 +685,8 @@ static int seq_overwrite(struct bch_fs *c, u64 nr) ...@@ -671,6 +685,8 @@ static int seq_overwrite(struct bch_fs *c, u64 nr)
break; break;
} }
} }
bch2_trans_iter_put(&trans, iter);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return ret; return ret;
} }
......
...@@ -133,12 +133,9 @@ int bch2_xattr_get(struct bch_fs *c, struct bch_inode_info *inode, ...@@ -133,12 +133,9 @@ int bch2_xattr_get(struct bch_fs *c, struct bch_inode_info *inode,
inode->v.i_ino, inode->v.i_ino,
&X_SEARCH(type, name, strlen(name)), &X_SEARCH(type, name, strlen(name)),
0); 0);
if (IS_ERR(iter)) { ret = PTR_ERR_OR_ZERO(iter);
bch2_trans_exit(&trans); if (ret)
BUG_ON(PTR_ERR(iter) == -EINTR); goto err;
return PTR_ERR(iter) == -ENOENT ? -ENODATA : PTR_ERR(iter);
}
xattr = bkey_s_c_to_xattr(bch2_btree_iter_peek_slot(iter)); xattr = bkey_s_c_to_xattr(bch2_btree_iter_peek_slot(iter));
ret = le16_to_cpu(xattr.v->x_val_len); ret = le16_to_cpu(xattr.v->x_val_len);
...@@ -148,9 +145,12 @@ int bch2_xattr_get(struct bch_fs *c, struct bch_inode_info *inode, ...@@ -148,9 +145,12 @@ int bch2_xattr_get(struct bch_fs *c, struct bch_inode_info *inode,
else else
memcpy(buffer, xattr_val(xattr.v), ret); memcpy(buffer, xattr_val(xattr.v), ret);
} }
bch2_trans_iter_put(&trans, iter);
err:
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return ret;
BUG_ON(ret == -EINTR);
return ret == -ENOENT ? -ENODATA : ret;
} }
int bch2_xattr_set(struct btree_trans *trans, u64 inum, int bch2_xattr_set(struct btree_trans *trans, u64 inum,
...@@ -294,6 +294,8 @@ ssize_t bch2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size) ...@@ -294,6 +294,8 @@ ssize_t bch2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
if (ret) if (ret)
break; break;
} }
bch2_trans_iter_put(&trans, iter);
ret = bch2_trans_exit(&trans) ?: ret; ret = bch2_trans_exit(&trans) ?: ret;
if (ret) if (ret)
......
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