From ac77810cb4ffd16976487d787e2f81ba9cb5fd0c Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sun, 19 Mar 2023 12:50:05 -0400 Subject: [PATCH] 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 --- fs/bcachefs/io.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c index 0c2d42eaba56e..ad22557197a66 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; -- 2.30.2