summaryrefslogtreecommitdiff
path: root/fs/bcachefs/io.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-03-19 19:50:05 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:58 +0300
commitac77810cb4ffd16976487d787e2f81ba9cb5fd0c (patch)
treea71ffe84c50508fe578f2eb9e8b2168b9bc91556 /fs/bcachefs/io.c
parentabab7609de92c973bfa3ad069a622c0a107b6386 (diff)
downloadlinux-ac77810cb4ffd16976487d787e2f81ba9cb5fd0c.tar.xz
bcachefs: Nocow write error path fix
The nocow write error path was iterating over pointers in an extent, aftre we'd dropped btree locks - oops. Fortunately we'd already stashed what we need in nocow_lock_bucket, so use that instead. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/io.c')
-rw-r--r--fs/bcachefs/io.c18
1 files changed, 7 insertions, 11 deletions
diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c
index 0c2d42eaba56..ad22557197a6 100644
--- a/fs/bcachefs/io.c
+++ b/fs/bcachefs/io.c
@@ -1481,7 +1481,7 @@ static void bch2_nocow_write(struct bch_write_op *op)
struct btree_iter iter;
struct bkey_s_c k;
struct bkey_ptrs_c ptrs;
- const struct bch_extent_ptr *ptr, *ptr2;
+ const struct bch_extent_ptr *ptr;
struct {
struct bpos b;
unsigned gen;
@@ -1536,11 +1536,12 @@ retry:
bucket_to_u64(buckets[nr_buckets].b));
prefetch(buckets[nr_buckets].l);
- nr_buckets++;
if (unlikely(!bch2_dev_get_ioref(bch_dev_bkey_exists(c, ptr->dev), WRITE)))
goto err_get_ioref;
+ nr_buckets++;
+
if (ptr->unwritten)
op->flags |= BCH_WRITE_CONVERT_UNWRITTEN;
}
@@ -1631,12 +1632,8 @@ err:
}
return;
err_get_ioref:
- bkey_for_each_ptr(ptrs, ptr2) {
- if (ptr2 == ptr)
- break;
-
- percpu_ref_put(&bch_dev_bkey_exists(c, ptr2->dev)->io_ref);
- }
+ for (i = 0; i < nr_buckets; i++)
+ percpu_ref_put(&bch_dev_bkey_exists(c, buckets[i].b.inode)->io_ref);
/* Fall back to COW path: */
goto out;
@@ -1645,9 +1642,8 @@ err_bucket_stale:
bch2_bucket_nocow_unlock(&c->nocow_locks,
buckets[i].b,
BUCKET_NOCOW_LOCK_UPDATE);
-
- bkey_for_each_ptr(ptrs, ptr2)
- percpu_ref_put(&bch_dev_bkey_exists(c, ptr2->dev)->io_ref);
+ for (i = 0; i < nr_buckets; i++)
+ percpu_ref_put(&bch_dev_bkey_exists(c, buckets[i].b.inode)->io_ref);
/* We can retry this: */
ret = BCH_ERR_transaction_restart;