--- /dev/null
+From 59cd968dd1483503378961f7b99218369d6de82f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Nov 2024 07:26:31 +0100
+Subject: block: lift bio_is_zone_append to bio.h
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 0ef2b9e698dbf9ba78f67952a747f35eb7060470 ]
+
+Make bio_is_zone_append globally available, because file systems need
+to use to check for a zone append bio in their end_io handlers to deal
+with the block layer emulation.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Link: https://lore.kernel.org/r/20241104062647.91160-4-hch@lst.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 6c3864e05548 ("btrfs: use bio_is_zone_append() in the completion handler")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk.h | 9 ---------
+ include/linux/bio.h | 17 +++++++++++++++++
+ 2 files changed, 17 insertions(+), 9 deletions(-)
+
+diff --git a/block/blk.h b/block/blk.h
+index 88fab6a81701..1426f9c28197 100644
+--- a/block/blk.h
++++ b/block/blk.h
+@@ -469,11 +469,6 @@ static inline bool bio_zone_write_plugging(struct bio *bio)
+ {
+ return bio_flagged(bio, BIO_ZONE_WRITE_PLUGGING);
+ }
+-static inline bool bio_is_zone_append(struct bio *bio)
+-{
+- return bio_op(bio) == REQ_OP_ZONE_APPEND ||
+- bio_flagged(bio, BIO_EMULATES_ZONE_APPEND);
+-}
+ void blk_zone_write_plug_bio_merged(struct bio *bio);
+ void blk_zone_write_plug_init_request(struct request *rq);
+ static inline void blk_zone_update_request_bio(struct request *rq,
+@@ -522,10 +517,6 @@ static inline bool bio_zone_write_plugging(struct bio *bio)
+ {
+ return false;
+ }
+-static inline bool bio_is_zone_append(struct bio *bio)
+-{
+- return false;
+-}
+ static inline void blk_zone_write_plug_bio_merged(struct bio *bio)
+ {
+ }
+diff --git a/include/linux/bio.h b/include/linux/bio.h
+index faceadb040f9..66b7620a1b53 100644
+--- a/include/linux/bio.h
++++ b/include/linux/bio.h
+@@ -677,6 +677,23 @@ static inline void bio_clear_polled(struct bio *bio)
+ bio->bi_opf &= ~REQ_POLLED;
+ }
+
++/**
++ * bio_is_zone_append - is this a zone append bio?
++ * @bio: bio to check
++ *
++ * Check if @bio is a zone append operation. Core block layer code and end_io
++ * handlers must use this instead of an open coded REQ_OP_ZONE_APPEND check
++ * because the block layer can rewrite REQ_OP_ZONE_APPEND to REQ_OP_WRITE if
++ * it is not natively supported.
++ */
++static inline bool bio_is_zone_append(struct bio *bio)
++{
++ if (!IS_ENABLED(CONFIG_BLK_DEV_ZONED))
++ return false;
++ return bio_op(bio) == REQ_OP_ZONE_APPEND ||
++ bio_flagged(bio, BIO_EMULATES_ZONE_APPEND);
++}
++
+ struct bio *blk_next_bio(struct bio *bio, struct block_device *bdev,
+ unsigned int nr_pages, blk_opf_t opf, gfp_t gfp);
+ struct bio *bio_chain_and_submit(struct bio *prev, struct bio *new);
+--
+2.39.5
+
--- /dev/null
+From b245322ae34aa0807aff76aa2cc400b22b73e55c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Nov 2024 07:26:32 +0100
+Subject: btrfs: use bio_is_zone_append() in the completion handler
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 6c3864e055486fadb5b97793b57688082e14b43b ]
+
+Otherwise it won't catch bios turned into regular writes by the block
+level zone write plugging. The additional test it adds is for emulated
+zone append.
+
+Fixes: 9b1ce7f0c6f8 ("block: Implement zone append emulation")
+CC: stable@vger.kernel.org # 6.12
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/bio.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c
+index 3d2376caedfa..31f96c2d8691 100644
+--- a/fs/btrfs/bio.c
++++ b/fs/btrfs/bio.c
+@@ -355,7 +355,7 @@ static void btrfs_simple_end_io(struct bio *bio)
+ INIT_WORK(&bbio->end_io_work, btrfs_end_bio_work);
+ queue_work(btrfs_end_io_wq(fs_info, bio), &bbio->end_io_work);
+ } else {
+- if (bio_op(bio) == REQ_OP_ZONE_APPEND && !bio->bi_status)
++ if (bio_is_zone_append(bio) && !bio->bi_status)
+ btrfs_record_physical_zoned(bbio);
+ btrfs_bio_end_io(bbio, bbio->bio.bi_status);
+ }
+@@ -398,7 +398,7 @@ static void btrfs_orig_write_end_io(struct bio *bio)
+ else
+ bio->bi_status = BLK_STS_OK;
+
+- if (bio_op(bio) == REQ_OP_ZONE_APPEND && !bio->bi_status)
++ if (bio_is_zone_append(bio) && !bio->bi_status)
+ stripe->physical = bio->bi_iter.bi_sector << SECTOR_SHIFT;
+
+ btrfs_bio_end_io(bbio, bbio->bio.bi_status);
+@@ -412,7 +412,7 @@ static void btrfs_clone_write_end_io(struct bio *bio)
+ if (bio->bi_status) {
+ atomic_inc(&stripe->bioc->error);
+ btrfs_log_dev_io_error(bio, stripe->dev);
+- } else if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
++ } else if (bio_is_zone_append(bio)) {
+ stripe->physical = bio->bi_iter.bi_sector << SECTOR_SHIFT;
+ }
+
+--
+2.39.5
+