Re: [PATCH 2/2] btrfs: use bio::remaining for async checksumming synchronization

From: Qu Wenruo

Date: Wed Sep 02 2026 - 18:29:40 EST




在 2026/9/3 07:32, Qu Wenruo 写道:


在 2026/9/3 02:21, Daniel Vacek 写道:
We can use bio::remaining counter to sync the offloaded checksuming.
As a result we can slim down the btrfs_bio structure by 24 bytes
and simplify the code a bit.

$ pahole | diff
-    /* size: 328, cachelines: 6, members: 15 */
+    /* size: 304, cachelines: 5, members: 14 */

Moreover this will allow us enabling async checksumming with encryption
where we need to checksum the bounce bio instead of our regular one
embedded in btrfs_bio. And so we need to extend it's lifetime. This is
the preffered way to do so.

Signed-off-by: Daniel Vacek <neelx@xxxxxxxx>
---
  fs/btrfs/bio.c       | 4 ----
  fs/btrfs/bio.h       | 4 ----
  fs/btrfs/file-item.c | 6 ++----
  3 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c
index 19b4855969f5..771b7d598aee 100644
--- a/fs/btrfs/bio.c
+++ b/fs/btrfs/bio.c
@@ -103,7 +103,6 @@ static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info,
      bbio->can_use_append = orig_bbio->can_use_append;
      bbio->is_scrub = orig_bbio->is_scrub;
      bbio->is_remap = orig_bbio->is_remap;
-    bbio->async_csum = orig_bbio->async_csum;
      atomic_inc(&orig_bbio->pending_ios);
      return bbio;
@@ -114,9 +113,6 @@ void btrfs_bio_end_io(struct btrfs_bio *bbio, blk_status_t status)
      /* Make sure we're already in task context. */
      ASSERT(in_task());
-    if (bbio->async_csum)
-        wait_for_completion(&bbio->csum_done);
-

But what if there is still a running csum calculation at this stage?

Without waiting for the completion, we are going to get incorrect csums.

Forget this. We no longer need to wait because we won't even reach the bio->bi_end_io() until all remaining works (including the csum calculation and mirrored writes) finished.

Reviewed-by: Qu Wenruo <wqu@xxxxxxxx>

Thanks,
Qu

      bbio->bio.bi_status = status;
      if (bbio->bio.bi_pool == &btrfs_clone_bioset) {
          struct btrfs_bio *orig_bbio = bbio->private;
diff --git a/fs/btrfs/bio.h b/fs/btrfs/bio.h
index b7bd377a0162..bbf362b8668b 100644
--- a/fs/btrfs/bio.h
+++ b/fs/btrfs/bio.h
@@ -58,7 +58,6 @@ struct btrfs_bio {
              struct btrfs_ordered_extent *ordered;
              struct btrfs_ordered_sum *sums;
              struct work_struct csum_work;
-            struct completion csum_done;
              struct bvec_iter csum_saved_iter;
              u64 orig_physical;
              u64 orig_logical;
@@ -93,9 +92,6 @@ struct btrfs_bio {
      /* Whether the bio is coming from copy_remapped_data_io(). */
      bool is_remap:1;
-    /* Whether the csum generation for data write is async. */
-    bool async_csum:1;
-
      /* Whether the bio is written using zone append. */
      bool can_use_append:1;
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 5a5cffb18922..50dcd448d936 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -817,9 +817,8 @@ static void csum_one_bio_work(struct work_struct *work)
      struct btrfs_bio *bbio = container_of(work, struct btrfs_bio, csum_work);
      ASSERT(btrfs_op(&bbio->bio) == BTRFS_MAP_WRITE);
-    ASSERT(bbio->async_csum == true);
      csum_one_bio(bbio, &bbio->csum_saved_iter);
-    complete(&bbio->csum_done);
+    bio_endio(&bbio->bio);
  }
  /*
@@ -854,8 +853,7 @@ int btrfs_csum_one_bio(struct btrfs_bio *bbio, bool async)
          csum_one_bio(bbio, &iter);
          return 0;
      }
-    init_completion(&bbio->csum_done);
-    bbio->async_csum = true;
+    bio_inc_remaining(bio);
      bbio->csum_saved_iter = bio->bi_iter;
      INIT_WORK(&bbio->csum_work, csum_one_bio_work);
      schedule_work(&bbio->csum_work);