-720f644e63e0f5b24bb69f2ffb70cdc2dd162810
+d9d1235f3c568a47b3547c0b0adad0d7948f18aa
struct bch_sb *sb = ca->disk_sb.sb;
ranges data;
unsigned i;
+ int ret;
darray_init(data);
bch2_trans_init(&trans, c, 0, 0);
- __for_each_btree_node(&trans, iter, i, POS_MIN, 0, 1, 0, b) {
+ __for_each_btree_node(&trans, iter, i, POS_MIN, 0, 1, 0, b, ret) {
struct btree_node_iter iter;
struct bkey u;
struct bkey_s_c k;
}
}
+ if (ret)
+ die("error %s walking btree nodes", strerror(-ret));
+
b = c->btree_roots[i].b;
if (!btree_node_fake(b)) {
ptrs = bch2_bkey_ptrs_c(bkey_i_to_s_c(&b->key));
struct btree_iter iter;
struct btree *b;
char buf[4096];
+ int ret;
bch2_trans_init(&trans, c, 0, 0);
- __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b) {
+ __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b, ret) {
if (bkey_cmp(b->key.k.p, end) > 0)
break;
}
bch2_trans_iter_exit(&trans, &iter);
+ if (ret)
+ die("error %s walking btree nodes", strerror(-ret));
+
bch2_trans_exit(&trans);
}
struct btree_iter iter;
struct btree *b;
char buf[4096];
+ int ret;
bch2_trans_init(&trans, c, 0, 0);
- __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b) {
+ __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b, ret) {
if (bkey_cmp(b->key.k.p, end) > 0)
break;
}
bch2_trans_iter_exit(&trans, &iter);
+ if (ret)
+ die("error %s walking btree nodes", strerror(-ret));
+
bch2_trans_exit(&trans);
}
struct btree_iter iter;
struct btree *b;
char buf[4096];
+ int ret;
bch2_trans_init(&trans, c, 0, 0);
- __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b) {
+ __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b, ret) {
if (bkey_cmp(b->key.k.p, end) > 0)
break;
}
bch2_trans_iter_exit(&trans, &iter);
+ if (ret)
+ die("error %s walking btree nodes", strerror(-ret));
+
bch2_trans_exit(&trans);
}
struct bkey_s_c k;
struct btree *b;
char buf[4096];
+ int ret;
bch2_trans_init(&trans, c, 0, 0);
- __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b) {
+ __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b, ret) {
if (bkey_cmp(b->key.k.p, end) > 0)
break;
}
bch2_trans_iter_exit(&trans, &iter);
+ if (ret)
+ die("error %s walking btree nodes", strerror(-ret));
+
bch2_trans_exit(&trans);
}
gc_pos_set(c, gc_pos_btree(btree_id, POS_MIN, 0));
__for_each_btree_node(&trans, iter, btree_id, POS_MIN,
- 0, depth, BTREE_ITER_PREFETCH, b) {
+ 0, depth, BTREE_ITER_PREFETCH, b, ret) {
bch2_verify_btree_nr_keys(b);
gc_pos_set(c, gc_pos_btree_node(b));
}
bch2_trans_iter_exit(&trans, &iter);
- ret = bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
if (ret)
return ret;
} while (ret);
}
- if (unlikely(ret == -EIO)) {
- trans->error = true;
+ if (unlikely(ret == -EIO))
goto out;
- }
BUG_ON(ret && ret != -EINTR);
ret = bch2_btree_path_traverse(trans, iter->path, iter->flags);
if (ret)
- goto out;
+ goto err;
b = btree_path_node(iter->path, iter->path->level);
if (!b)
bch2_btree_iter_verify(iter);
return b;
+err:
+ b = ERR_PTR(ret);
+ goto out;
}
struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
if (!btree_path_node(path, path->level))
goto out;
- bch2_trans_cond_resched(trans);
+ ret = bch2_trans_cond_resched(trans);
+ if (ret)
+ goto err;
btree_node_unlock(path, path->level);
path->l[path->level].b = BTREE_ITER_NO_NODE_UP;
btree_path_set_dirty(path, BTREE_ITER_NEED_TRAVERSE);
ret = bch2_btree_path_traverse(trans, path, iter->flags);
if (ret)
- goto out;
+ goto err;
/* got to end? */
b = btree_path_node(path, path->level);
bch2_btree_iter_verify(iter);
ret = bch2_btree_path_traverse(trans, path, iter->flags);
- if (ret) {
- b = NULL;
- goto out;
- }
+ if (ret)
+ goto err;
b = path->l[path->level].b;
}
bch2_btree_iter_verify(iter);
return b;
+err:
+ b = ERR_PTR(ret);
+ goto out;
}
/* Iterate across keys (in leaf nodes only) */
#endif
}
-int bch2_trans_exit(struct btree_trans *trans)
+void bch2_trans_exit(struct btree_trans *trans)
__releases(&c->btree_trans_barrier)
{
struct btree_insert_entry *i;
trans->mem = (void *) 0x1;
trans->paths = (void *) 0x1;
-
- return trans->error ? -EIO : 0;
}
static void __maybe_unused
}
}
-#define __for_each_btree_node(_trans, _iter, _btree_id, _start, \
- _locks_want, _depth, _flags, _b) \
+#define __for_each_btree_node(_trans, _iter, _btree_id, _start, \
+ _locks_want, _depth, _flags, _b, _ret) \
for (bch2_trans_node_iter_init((_trans), &(_iter), (_btree_id), \
_start, _locks_want, _depth, _flags), \
_b = bch2_btree_iter_peek_node(&(_iter)); \
- (_b); \
+ !((_ret) = PTR_ERR_OR_ZERO(_b)) && (_b); \
(_b) = bch2_btree_iter_next_node(&(_iter)))
#define for_each_btree_node(_trans, _iter, _btree_id, _start, \
- _flags, _b) \
+ _flags, _b, _ret) \
__for_each_btree_node(_trans, _iter, _btree_id, _start, \
- 0, 0, _flags, _b)
+ 0, 0, _flags, _b, _ret)
static inline struct bkey_s_c __bch2_btree_iter_peek(struct btree_iter *iter,
unsigned flags)
void *bch2_trans_kmalloc(struct btree_trans *, size_t);
void bch2_trans_begin(struct btree_trans *);
void bch2_trans_init(struct btree_trans *, struct bch_fs *, unsigned, size_t);
-int bch2_trans_exit(struct btree_trans *);
+void bch2_trans_exit(struct btree_trans *);
void bch2_btree_trans_to_text(struct printbuf *, struct bch_fs *);
u8 nr_sorted;
u8 nr_updates;
bool used_mempool:1;
- bool error:1;
bool in_traverse_all:1;
bool restarted:1;
/*
#define bch2_trans_do(_c, _disk_res, _journal_seq, _flags, _do) \
({ \
struct btree_trans trans; \
- int _ret, _ret2; \
+ int _ret; \
\
bch2_trans_init(&trans, (_c), 0, 0); \
_ret = __bch2_trans_do(&trans, _disk_res, _journal_seq, _flags, \
_do); \
- _ret2 = bch2_trans_exit(&trans); \
+ bch2_trans_exit(&trans); \
\
- _ret ?: _ret2; \
+ _ret; \
})
#define trans_for_each_update(_trans, _i) \
goto out;
b = bch2_btree_iter_peek_node(iter);
+ ret = PTR_ERR_OR_ZERO(b);
+ if (ret)
+ goto out;
+
if (!b || b->data->keys.seq != seq)
goto out;
bch2_trans_init(&trans, i->c, 0, 0);
- for_each_btree_node(&trans, iter, i->id, i->from, 0, b) {
+ for_each_btree_node(&trans, iter, i->id, i->from, 0, b, err) {
bch2_btree_node_to_text(&PBUF(i->buf), i->c, b);
i->bytes = strlen(i->buf);
err = flush_buf(i);
if (ret == -EINTR)
goto retry;
- ret = bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
return ret;
}
bch2_trans_iter_init(&trans, &iter, BTREE_ID_stripes, POS(0, U64_MAX), 0);
k = bch2_btree_iter_prev(&iter);
- if (!IS_ERR_OR_NULL(k.k))
+ ret = bkey_err(k);
+ if (!ret && k.k)
idx = k.k->p.offset + 1;
bch2_trans_iter_exit(&trans, &iter);
- ret = bch2_trans_exit(&trans);
+ bch2_trans_exit(&trans);
if (ret)
return ret;
if (ret == -EINTR)
goto retry;
- return bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
+ return ret;
}
static int __bch2_truncate_page(struct bch_inode_info *inode,
if (ret == -EINTR)
goto retry;
- ret = bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
if (ret)
return ret;
if (ret == -EINTR)
goto retry;
- ret = bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
if (ret)
return ret;
ret = bch2_fill_extent(c, info, bkey_i_to_s_c(prev.k),
FIEMAP_EXTENT_LAST);
- ret = bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&cur, c);
bch2_bkey_buf_exit(&prev, c);
return ret < 0 ? ret : 0;
BUG_ON(ret == -EINTR);
- return bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
+ return ret;
}
noinline_for_stack
goto retry;
bch2_trans_iter_exit(&trans, &iter);
- return bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
+ return ret;
}
/* Get root directory, create if it doesn't exist: */
kfree(path.entries);
- return bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
+ return ret;
}
struct nlink_table {
struct btree_iter iter;
struct btree *b;
- for_each_btree_node(&trans, iter, i, POS_MIN,
- BTREE_ITER_PREFETCH, b)
- if (test_bit(BCH_FS_STOPPING, &c->flags)) {
- bch2_trans_exit(&trans);
- return;
- }
+ bch2_trans_node_iter_init(&trans, &iter, i, POS_MIN,
+ 0, 0, BTREE_ITER_PREFETCH);
+retry:
+ bch2_trans_begin(&trans);
+
+ b = bch2_btree_iter_peek_node(&iter);
+
+ while (!(ret = PTR_ERR_OR_ZERO(b)) &&
+ b &&
+ !test_bit(BCH_FS_STOPPING, &c->flags))
+ b = bch2_btree_iter_next_node(&iter);
+
+ if (ret == -EINTR)
+ goto retry;
+
bch2_trans_iter_exit(&trans, &iter);
}
- ret = bch2_trans_exit(&trans);
+ bch2_trans_exit(&trans);
if (ret)
return;
}
bch2_trans_iter_exit(&trans, &iter);
- ret = bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&sk, c);
BUG_ON(ret == -EINTR);
for (id = 0; id < BTREE_ID_NR; id++) {
bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0,
BTREE_ITER_PREFETCH);
-
+retry:
+ ret = 0;
while (bch2_trans_begin(&trans),
- (b = bch2_btree_iter_peek_node(&iter))) {
+ (b = bch2_btree_iter_peek_node(&iter)) &&
+ !(ret = PTR_ERR_OR_ZERO(b))) {
if (!bch2_bkey_has_device(bkey_i_to_s_c(&b->key),
dev_idx))
goto next;
next:
bch2_btree_iter_next_node(&iter);
}
+ if (ret == -EINTR)
+ goto retry;
+
bch2_trans_iter_exit(&trans, &iter);
if (ret)
ret = 0;
err:
- ret = bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&k, c);
BUG_ON(ret == -EINTR);
out:
bch2_trans_iter_exit(&trans, &iter);
- ret = bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&sk, c);
return ret;
bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0,
BTREE_ITER_PREFETCH);
-
+retry:
+ ret = 0;
while (bch2_trans_begin(&trans),
- (b = bch2_btree_iter_peek_node(&iter))) {
+ (b = bch2_btree_iter_peek_node(&iter)) &&
+ !(ret = PTR_ERR_OR_ZERO(b))) {
if (kthread && kthread_should_stop())
break;
bch2_trans_cond_resched(&trans);
bch2_btree_iter_next_node(&iter);
}
+ if (ret == -EINTR)
+ goto retry;
+
bch2_trans_iter_exit(&trans, &iter);
if (kthread && kthread_should_stop())
}
bch2_trans_iter_exit(&trans, &iter);
- return bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
+ return ret;
}
void bch2_fs_quota_exit(struct bch_fs *c)
}
bch2_trans_iter_exit(&trans, &iter);
- return bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
+ return ret;
}
/* Enable/disable/delete quotas for an entire filesystem: */
bch2_trans_iter_exit(&trans, &inode_iter);
} while (ret2 == -EINTR);
- ret = bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&new_src, c);
bch2_bkey_buf_exit(&new_dst, c);
}
bch2_trans_iter_exit(&trans, &iter);
- ret = bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
if (ret)
return ret;
if (ret == -EINTR)
goto retry;
- ret = bch2_trans_exit(&trans) ?: ret;
+ bch2_trans_exit(&trans);
if (ret)
return ret;