summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/bcachefs/acl.c18
-rw-r--r--fs/bcachefs/alloc_background.c2
-rw-r--r--fs/bcachefs/btree_cache.c11
-rw-r--r--fs/bcachefs/btree_cache.h4
-rw-r--r--fs/bcachefs/btree_iter.c12
-rw-r--r--fs/bcachefs/dirent.c18
-rw-r--r--fs/bcachefs/fs-common.c4
-rw-r--r--fs/bcachefs/fs-io.c4
-rw-r--r--fs/bcachefs/inode.c2
-rw-r--r--fs/bcachefs/io.c6
-rw-r--r--fs/bcachefs/move.c2
-rw-r--r--fs/bcachefs/reflink.c5
-rw-r--r--fs/bcachefs/str_hash.h2
-rw-r--r--fs/bcachefs/xattr.c8
14 files changed, 71 insertions, 27 deletions
diff --git a/fs/bcachefs/acl.c b/fs/bcachefs/acl.c
index 1642518d3233..d3e2e24758ba 100644
--- a/fs/bcachefs/acl.c
+++ b/fs/bcachefs/acl.c
@@ -222,6 +222,8 @@ struct posix_acl *bch2_get_acl(struct mnt_idmap *idmap,
struct btree_iter *iter;
struct bkey_s_c_xattr xattr;
struct posix_acl *acl = NULL;
+ struct bkey_s_c k;
+ int ret;
bch2_trans_init(&trans, c, 0, 0);
retry:
@@ -240,7 +242,14 @@ retry:
goto out;
}
- xattr = bkey_s_c_to_xattr(bch2_btree_iter_peek_slot(iter));
+ k = bch2_btree_iter_peek_slot(iter);
+ ret = bkey_err(k);
+ if (ret) {
+ acl = ERR_PTR(ret);
+ goto out;
+ }
+
+ xattr = bkey_s_c_to_xattr(k);
acl = bch2_acl_from_disk(xattr_val(xattr.v),
le16_to_cpu(xattr.v->x_val_len));
@@ -358,6 +367,7 @@ int bch2_acl_chmod(struct btree_trans *trans,
struct bkey_s_c_xattr xattr;
struct bkey_i_xattr *new;
struct posix_acl *acl;
+ struct bkey_s_c k;
int ret;
iter = bch2_hash_lookup(trans, bch2_xattr_hash_desc,
@@ -368,7 +378,11 @@ int bch2_acl_chmod(struct btree_trans *trans,
if (ret)
return ret == -ENOENT ? 0 : ret;
- xattr = bkey_s_c_to_xattr(bch2_btree_iter_peek_slot(iter));
+ k = bch2_btree_iter_peek_slot(iter);
+ xattr = bkey_s_c_to_xattr(k);
+ if (ret)
+ goto err;
+
acl = bch2_acl_from_disk(xattr_val(xattr.v),
le16_to_cpu(xattr.v->x_val_len));
ret = PTR_ERR_OR_ZERO(acl);
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
index 26aca7d3977b..932a8176dff7 100644
--- a/fs/bcachefs/alloc_background.c
+++ b/fs/bcachefs/alloc_background.c
@@ -374,7 +374,7 @@ int bch2_alloc_write(struct bch_fs *c, unsigned flags)
percpu_ref_put(&ca->ref);
goto err;
}
- bch2_btree_iter_next_slot(iter);
+ bch2_btree_iter_advance(iter);
}
}
err:
diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c
index 818b8df063da..252801dee028 100644
--- a/fs/bcachefs/btree_cache.c
+++ b/fs/bcachefs/btree_cache.c
@@ -973,9 +973,9 @@ out:
return b;
}
-void bch2_btree_node_prefetch(struct bch_fs *c, struct btree_iter *iter,
- const struct bkey_i *k,
- enum btree_id btree_id, unsigned level)
+int bch2_btree_node_prefetch(struct bch_fs *c, struct btree_iter *iter,
+ const struct bkey_i *k,
+ enum btree_id btree_id, unsigned level)
{
struct btree_cache *bc = &c->btree_cache;
struct btree *b;
@@ -985,9 +985,10 @@ void bch2_btree_node_prefetch(struct bch_fs *c, struct btree_iter *iter,
b = btree_cache_find(bc, k);
if (b)
- return;
+ return 0;
- bch2_btree_node_fill(c, iter, k, btree_id, level, SIX_LOCK_read, false);
+ b = bch2_btree_node_fill(c, iter, k, btree_id, level, SIX_LOCK_read, false);
+ return PTR_ERR_OR_ZERO(b);
}
void bch2_btree_node_evict(struct bch_fs *c, const struct bkey_i *k)
diff --git a/fs/bcachefs/btree_cache.h b/fs/bcachefs/btree_cache.h
index 6e9f08597d94..eb57dc3c70b7 100644
--- a/fs/bcachefs/btree_cache.h
+++ b/fs/bcachefs/btree_cache.h
@@ -27,8 +27,8 @@ struct btree *bch2_btree_node_get(struct btree_trans *, struct btree_iter *,
struct btree *bch2_btree_node_get_noiter(struct bch_fs *, const struct bkey_i *,
enum btree_id, unsigned, bool);
-void bch2_btree_node_prefetch(struct bch_fs *, struct btree_iter *,
- const struct bkey_i *, enum btree_id, unsigned);
+int bch2_btree_node_prefetch(struct bch_fs *, struct btree_iter *,
+ const struct bkey_i *, enum btree_id, unsigned);
void bch2_btree_node_evict(struct bch_fs *, const struct bkey_i *);
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index 2a649166c042..89de6a8a8a9e 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -1142,7 +1142,7 @@ static inline int btree_iter_lock_root(struct btree_iter *iter,
}
noinline
-static void btree_iter_prefetch(struct btree_iter *iter)
+static int btree_iter_prefetch(struct btree_iter *iter)
{
struct bch_fs *c = iter->trans->c;
struct btree_iter_level *l = &iter->l[iter->level];
@@ -1153,10 +1153,11 @@ static void btree_iter_prefetch(struct btree_iter *iter)
? (iter->level > 1 ? 0 : 2)
: (iter->level > 1 ? 1 : 16);
bool was_locked = btree_node_locked(iter, iter->level);
+ int ret = 0;
bch2_bkey_buf_init(&tmp);
- while (nr) {
+ while (nr && !ret) {
if (!bch2_btree_node_relock(iter, iter->level))
break;
@@ -1166,14 +1167,15 @@ static void btree_iter_prefetch(struct btree_iter *iter)
break;
bch2_bkey_buf_unpack(&tmp, c, l->b, k);
- bch2_btree_node_prefetch(c, iter, tmp.k, iter->btree_id,
- iter->level - 1);
+ ret = bch2_btree_node_prefetch(c, iter, tmp.k, iter->btree_id,
+ iter->level - 1);
}
if (!was_locked)
btree_node_unlock(iter, iter->level);
bch2_bkey_buf_exit(&tmp, c);
+ return ret;
}
static noinline void btree_node_mem_ptr_set(struct btree_iter *iter,
@@ -1228,7 +1230,7 @@ static __always_inline int btree_iter_down(struct btree_iter *iter,
btree_node_mem_ptr_set(iter, level + 1, b);
if (iter->flags & BTREE_ITER_PREFETCH)
- btree_iter_prefetch(iter);
+ ret = btree_iter_prefetch(iter);
if (btree_node_read_locked(iter, level + 1))
btree_node_unlock(iter, level + 1);
diff --git a/fs/bcachefs/dirent.c b/fs/bcachefs/dirent.c
index a95165b8eddf..02b29681f695 100644
--- a/fs/bcachefs/dirent.c
+++ b/fs/bcachefs/dirent.c
@@ -210,6 +210,9 @@ int bch2_dirent_rename(struct btree_trans *trans,
goto out;
old_dst = bch2_btree_iter_peek_slot(dst_iter);
+ ret = bkey_err(old_dst);
+ if (ret)
+ goto out;
if (mode != BCH_RENAME)
*dst_inum = le64_to_cpu(bkey_s_c_to_dirent(old_dst).v->d_inum);
@@ -225,6 +228,10 @@ int bch2_dirent_rename(struct btree_trans *trans,
goto out;
old_src = bch2_btree_iter_peek_slot(src_iter);
+ ret = bkey_err(old_src);
+ if (ret)
+ goto out;
+
*src_inum = le64_to_cpu(bkey_s_c_to_dirent(old_src).v->d_inum);
/* Create new dst key: */
@@ -329,20 +336,25 @@ u64 bch2_dirent_lookup(struct bch_fs *c, u64 dir_inum,
struct btree_iter *iter;
struct bkey_s_c k;
u64 inum = 0;
+ int ret = 0;
bch2_trans_init(&trans, c, 0, 0);
iter = __bch2_dirent_lookup_trans(&trans, dir_inum,
hash_info, name, 0);
- if (IS_ERR(iter)) {
- BUG_ON(PTR_ERR(iter) == -EINTR);
+ ret = PTR_ERR_OR_ZERO(iter);
+ if (ret)
goto out;
- }
k = bch2_btree_iter_peek_slot(iter);
+ ret = bkey_err(k);
+ if (ret)
+ goto out;
+
inum = le64_to_cpu(bkey_s_c_to_dirent(k).v->d_inum);
bch2_trans_iter_put(&trans, iter);
out:
+ BUG_ON(ret == -EINTR);
bch2_trans_exit(&trans);
return inum;
}
diff --git a/fs/bcachefs/fs-common.c b/fs/bcachefs/fs-common.c
index 60c54438074e..2189a11ccad8 100644
--- a/fs/bcachefs/fs-common.c
+++ b/fs/bcachefs/fs-common.c
@@ -168,6 +168,10 @@ int bch2_unlink_trans(struct btree_trans *trans,
goto err;
k = bch2_btree_iter_peek_slot(dirent_iter);
+ ret = bkey_err(k);
+ if (ret)
+ goto err;
+
inum = le64_to_cpu(bkey_s_c_to_dirent(k).v->d_inum);
inode_iter = bch2_inode_peek(trans, inode_u, inum, BTREE_ITER_INTENT);
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index 4af8cd018e3a..1a06f77101ab 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -2668,13 +2668,13 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
/* already reserved */
if (k.k->type == KEY_TYPE_reservation &&
bkey_s_c_to_reservation(k).v->nr_replicas >= replicas) {
- bch2_btree_iter_next_slot(iter);
+ bch2_btree_iter_advance(iter);
continue;
}
if (bkey_extent_is_data(k.k) &&
!(mode & FALLOC_FL_ZERO_RANGE)) {
- bch2_btree_iter_next_slot(iter);
+ bch2_btree_iter_advance(iter);
continue;
}
diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c
index 8c6627907431..102bd3c9d30f 100644
--- a/fs/bcachefs/inode.c
+++ b/fs/bcachefs/inode.c
@@ -519,7 +519,7 @@ again:
if (k.k->p.snapshot == snapshot &&
k.k->type != KEY_TYPE_inode &&
!bch2_btree_key_cache_find(c, BTREE_ID_inodes, SPOS(0, pos, snapshot))) {
- bch2_btree_iter_next(iter);
+ bch2_btree_iter_advance(iter);
continue;
}
diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c
index f80b3ce4c7d7..5ff8fea80fba 100644
--- a/fs/bcachefs/io.c
+++ b/fs/bcachefs/io.c
@@ -245,8 +245,12 @@ int bch2_sum_sector_overwrites(struct btree_trans *trans,
* writing to, because i_size could be up to one block
* less:
*/
- if (!bkey_cmp(old.k->p, new->k.p))
+ if (!bkey_cmp(old.k->p, new->k.p)) {
old = bch2_btree_iter_next(iter);
+ ret = bkey_err(old);
+ if (ret)
+ break;
+ }
if (old.k && !bkey_err(old) &&
old.k->p.inode == extent_iter->pos.inode &&
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c
index 3069f32efddd..7dea6637ae58 100644
--- a/fs/bcachefs/move.c
+++ b/fs/bcachefs/move.c
@@ -190,7 +190,7 @@ nomatch:
}
atomic_long_inc(&c->extent_migrate_raced);
trace_move_race(&new->k);
- bch2_btree_iter_next_slot(iter);
+ bch2_btree_iter_advance(iter);
goto next;
}
out:
diff --git a/fs/bcachefs/reflink.c b/fs/bcachefs/reflink.c
index ebf391245470..8b168246ca38 100644
--- a/fs/bcachefs/reflink.c
+++ b/fs/bcachefs/reflink.c
@@ -192,8 +192,9 @@ static struct bkey_s_c get_next_src(struct btree_iter *iter, struct bpos end)
return k;
}
- bch2_btree_iter_set_pos(iter, end);
- return bkey_s_c_null;
+ if (bkey_cmp(iter->pos, end) >= 0)
+ bch2_btree_iter_set_pos(iter, end);
+ return ret ? bkey_s_c_err(ret) : bkey_s_c_null;
}
s64 bch2_remap_range(struct bch_fs *c,
diff --git a/fs/bcachefs/str_hash.h b/fs/bcachefs/str_hash.h
index 2ff8e5bd2744..236023494191 100644
--- a/fs/bcachefs/str_hash.h
+++ b/fs/bcachefs/str_hash.h
@@ -209,7 +209,7 @@ int bch2_hash_needs_whiteout(struct btree_trans *trans,
iter = bch2_trans_copy_iter(trans, start);
- bch2_btree_iter_next_slot(iter);
+ bch2_btree_iter_advance(iter);
for_each_btree_key_continue(iter, BTREE_ITER_SLOTS, k, ret) {
if (k.k->type != desc.key_type &&
diff --git a/fs/bcachefs/xattr.c b/fs/bcachefs/xattr.c
index d7160e8cdc07..bf4164f98743 100644
--- a/fs/bcachefs/xattr.c
+++ b/fs/bcachefs/xattr.c
@@ -124,6 +124,7 @@ static int bch2_xattr_get_trans(struct btree_trans *trans, struct bch_inode_info
struct bch_hash_info hash = bch2_hash_info_init(trans->c, &inode->ei_inode);
struct btree_iter *iter;
struct bkey_s_c_xattr xattr;
+ struct bkey_s_c k;
int ret;
iter = bch2_hash_lookup(trans, bch2_xattr_hash_desc, &hash,
@@ -134,7 +135,12 @@ static int bch2_xattr_get_trans(struct btree_trans *trans, struct bch_inode_info
if (ret)
goto err;
- xattr = bkey_s_c_to_xattr(bch2_btree_iter_peek_slot(iter));
+ k = bch2_btree_iter_peek_slot(iter);
+ ret = bkey_err(k);
+ if (ret)
+ goto err;
+
+ xattr = bkey_s_c_to_xattr(k);
ret = le16_to_cpu(xattr.v->x_val_len);
if (buffer) {
if (ret > size)