Linux block layer
 help / color / mirror / Atom feed
* Re: improve the swap_activate interface
From: Steve French @ 2026-05-13 20:34 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, Chris Li, Kairui Song, Christian Brauner,
	Darrick J . Wong, Jens Axboe, David Sterba, Theodore Ts'o,
	Jaegeuk Kim, Chao Yu, Trond Myklebust, Anna Schumaker,
	Namjae Jeon, Hyunchul Lee, Steve French, Paulo Alcantara,
	Carlos Maiolino, Damien Le Moal, Naohiro Aota, linux-xfs,
	linux-fsdevel, linux-doc, linux-mm, linux-block, linux-btrfs,
	linux-ext4, linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <20260512053625.2950900-1-hch@lst.de>

I just tried this on 7.1-rc3 with the swap patches (full kernel build,
on Ubuntu 25,10) and boot failed with out of memory which I had never
seen before.  Any idea how to workaround this with the swap patch
series, or is there a fix for this in the swap series already?

On Tue, May 12, 2026 at 12:41 AM Christoph Hellwig <hch@lst.de> wrote:
>
> Hi all,
>
> Darrick recently posted iomap support for fuse-iomap, which was trivial
> but a bit ugly, which triggered me into looking how this could be done
> in a cleaner way.  The result of that is this fairly big series that
> reworks how the MM code calls into the file system to activate swap
> files to make it much cleaner and easier to use.
>
> I've tested this with swap devices manually, and using the swap tests
> in xfstests on btrfs, ext3, ext4, f2fs and xfs to exercise the different
> implementation.  Out of those all passed, but f2fs actually notruns all
> tests even in the baseline as it requires special preparation for
> swapfiles which never got wired up in xfstests.
>
> Diffstat:
>  Documentation/filesystems/iomap/operations.rst |    3
>  Documentation/filesystems/locking.rst          |   35 +--
>  Documentation/filesystems/vfs.rst              |   40 ++--
>  block/fops.c                                   |   15 +
>  fs/btrfs/btrfs_inode.h                         |    3
>  fs/btrfs/file.c                                |    4
>  fs/btrfs/inode.c                               |   72 -------
>  fs/ext4/file.c                                 |    6
>  fs/ext4/inode.c                                |   11 -
>  fs/f2fs/data.c                                 |   50 -----
>  fs/f2fs/f2fs.h                                 |    2
>  fs/f2fs/file.c                                 |    4
>  fs/iomap/swapfile.c                            |  165 +++---------------
>  fs/nfs/direct.c                                |    1
>  fs/nfs/file.c                                  |   21 --
>  fs/nfs/nfs4file.c                              |    3
>  fs/ntfs/aops.c                                 |    8
>  fs/ntfs/file.c                                 |    6
>  fs/smb/client/cifsfs.c                         |   18 +
>  fs/smb/client/cifsfs.h                         |    3
>  fs/smb/client/file.c                           |   16 -
>  fs/xfs/xfs_aops.c                              |   48 -----
>  fs/xfs/xfs_file.c                              |   39 ++++
>  fs/zonefs/file.c                               |   30 +--
>  include/linux/fs.h                             |   11 -
>  include/linux/iomap.h                          |    5
>  include/linux/nfs_fs.h                         |    3
>  include/linux/swap.h                           |  129 +-------------
>  mm/page_io.c                                   |   45 ----
>  mm/swap.h                                      |   92 ++++++++++
>  mm/swapfile.c                                  |  227 ++++++++++++++-----------
>  31 files changed, 471 insertions(+), 644 deletions(-)
>


-- 
Thanks,

Steve

^ permalink raw reply

* [PATCH 7.2 0/2] ublk: optimize ublk_rq_has_data()
From: Caleb Sander Mateos @ 2026-05-13 21:18 UTC (permalink / raw)
  To: Ming Lei, Jens Axboe; +Cc: linux-block, linux-kernel, Caleb Sander Mateos

ublk_rq_has_data() currently uses bio_has_data(), which involves 2
indirections and several branches. Introduce a blk_rq_has_data()
analogue for struct request and use it instead to save an indirection
and NULL check.

Caleb Sander Mateos (2):
  blk-mq: introduce blk_rq_has_data()
  ublk: optimize ublk_rq_has_data()

 drivers/block/ublk_drv.c | 21 ++++++++-------------
 include/linux/blk-mq.h   |  9 +++++++++
 2 files changed, 17 insertions(+), 13 deletions(-)

-- 
2.54.0


^ permalink raw reply

* [PATCH 7.2 2/2] ublk: optimize ublk_rq_has_data()
From: Caleb Sander Mateos @ 2026-05-13 21:18 UTC (permalink / raw)
  To: Ming Lei, Jens Axboe; +Cc: linux-block, linux-kernel, Caleb Sander Mateos
In-Reply-To: <20260513211846.1956810-1-csander@purestorage.com>

ublk_rq_has_data() currently uses bio_has_data(), which involves 2
indirections and several branches. Use blk_rq_has_data() instead to save
an indirection and NULL check.

Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
---
 drivers/block/ublk_drv.c | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 8e5f3738c203..4d7efc12247c 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -1170,15 +1170,10 @@ static inline struct ublk_queue *ublk_get_queue(struct ublk_device *dev,
 		int qid)
 {
 	return dev->queues[qid];
 }
 
-static inline bool ublk_rq_has_data(const struct request *rq)
-{
-	return bio_has_data(rq->bio);
-}
-
 static inline struct ublksrv_io_desc *
 ublk_queue_cmd_buf(struct ublk_device *ub, int q_id)
 {
 	return ublk_get_queue(ub, q_id)->io_cmd_buf;
 }
@@ -1387,16 +1382,16 @@ static size_t ublk_copy_user_integrity(const struct request *req,
 }
 #endif /* #ifdef CONFIG_BLK_DEV_INTEGRITY */
 
 static inline bool ublk_need_map_req(const struct request *req)
 {
-	return ublk_rq_has_data(req) && req_op(req) == REQ_OP_WRITE;
+	return blk_rq_has_data(req) && req_op(req) == REQ_OP_WRITE;
 }
 
 static inline bool ublk_need_unmap_req(const struct request *req)
 {
-	return ublk_rq_has_data(req) &&
+	return blk_rq_has_data(req) &&
 	       (req_op(req) == REQ_OP_READ || req_op(req) == REQ_OP_DRV_IN);
 }
 
 static unsigned int ublk_map_io(const struct ublk_queue *ubq,
 				const struct request *req,
@@ -1506,11 +1501,11 @@ static blk_status_t ublk_setup_iod(struct ublk_queue *ubq, struct request *req)
 	iod->op_flags = ublk_op | ublk_req_build_flags(req);
 	iod->nr_sectors = blk_rq_sectors(req);
 	iod->start_sector = blk_rq_pos(req);
 
 	/* Try shmem zero-copy match before setting addr */
-	if (ublk_support_shmem_zc(ubq) && ublk_rq_has_data(req)) {
+	if (ublk_support_shmem_zc(ubq) && blk_rq_has_data(req)) {
 		u32 buf_idx, buf_off;
 
 		if (ublk_try_buf_match(ubq->dev, req,
 					  &buf_idx, &buf_off)) {
 			iod->op_flags |= UBLK_IO_F_SHMEM_ZC;
@@ -1796,11 +1791,11 @@ static void ublk_dispatch_req(struct ublk_queue *ubq, struct request *req)
 	}
 
 	if (!ublk_start_io(ubq, req, io))
 		return;
 
-	if (ublk_support_auto_buf_reg(ubq) && ublk_rq_has_data(req)) {
+	if (ublk_support_auto_buf_reg(ubq) && blk_rq_has_data(req)) {
 		ublk_auto_buf_dispatch(ubq, req, io, io->cmd, issue_flags);
 	} else {
 		ublk_init_req_ref(ubq, io);
 		ublk_complete_io_cmd(io, req, UBLK_IO_RES_OK, issue_flags);
 	}
@@ -1817,11 +1812,11 @@ static bool __ublk_batch_prep_dispatch(struct ublk_queue *ubq,
 	struct io_uring_cmd *cmd = data->cmd;
 
 	if (!ublk_start_io(ubq, req, io))
 		return false;
 
-	if (ublk_support_auto_buf_reg(ubq) && ublk_rq_has_data(req)) {
+	if (ublk_support_auto_buf_reg(ubq) && blk_rq_has_data(req)) {
 		res = ublk_auto_buf_register(ubq, req, io, cmd,
 				data->issue_flags);
 
 		if (res == AUTO_BUF_REG_FAIL)
 			return false;
@@ -3198,11 +3193,11 @@ ublk_daemon_register_io_buf(struct io_uring_cmd *cmd,
 	new_registered_buffers = io->task_registered_buffers + 1;
 	if (unlikely(new_registered_buffers >= UBLK_REFCOUNT_INIT))
 		return ublk_register_io_buf(cmd, ub, q_id, tag, io, index,
 					    issue_flags);
 
-	if (!ublk_dev_support_zero_copy(ub) || !ublk_rq_has_data(req))
+	if (!ublk_dev_support_zero_copy(ub) || !blk_rq_has_data(req))
 		return -EINVAL;
 
 	ret = io_buffer_register_bvec(cmd, req, ublk_io_release, index,
 				      issue_flags);
 	if (ret)
@@ -3481,11 +3476,11 @@ static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub,
 		return NULL;
 
 	if (unlikely(!blk_mq_request_started(req) || req->tag != tag))
 		goto fail_put;
 
-	if (!ublk_rq_has_data(req))
+	if (!blk_rq_has_data(req))
 		goto fail_put;
 
 	return req;
 fail_put:
 	ublk_put_req_ref(io, req);
@@ -4054,11 +4049,11 @@ ublk_user_copy(struct kiocb *iocb, struct iov_iter *iter, int dir)
 		/* On daemon, io can't be completed concurrently, so skip ref */
 		if (!(io->flags & UBLK_IO_FLAG_OWNED_BY_SRV))
 			return -EINVAL;
 
 		req = io->req;
-		if (!ublk_rq_has_data(req))
+		if (!blk_rq_has_data(req))
 			return -EINVAL;
 	} else {
 		req = __ublk_check_and_get_req(ub, q_id, tag, io);
 		if (!req)
 			return -EINVAL;
-- 
2.54.0


^ permalink raw reply related

* [PATCH 7.2 1/2] blk-mq: introduce blk_rq_has_data()
From: Caleb Sander Mateos @ 2026-05-13 21:18 UTC (permalink / raw)
  To: Ming Lei, Jens Axboe; +Cc: linux-block, linux-kernel, Caleb Sander Mateos
In-Reply-To: <20260513211846.1956810-1-csander@purestorage.com>

Add blk_rq_has_data(), an analogue of bio_has_data() for struct request.
This skips one dereference relative to bio_has_data(rq->bio).

Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
---
 include/linux/blk-mq.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index 18a2388ba581..4349aefdbc87 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -1102,10 +1102,11 @@ struct req_iterator {
 		 bio_iter_last(bvec, _iter.iter))
 
 /*
  * blk_rq_pos()			: the current sector
  * blk_rq_bytes()		: bytes left in the entire request
+ * blk_rq_has_data()		: whether the request carries data
  * blk_rq_cur_bytes()		: bytes left in the current segment
  * blk_rq_sectors()		: sectors left in the entire request
  * blk_rq_cur_sectors()		: sectors left in the current segment
  * blk_rq_stats_sectors()	: sectors of the entire request used for stats
  */
@@ -1117,10 +1118,18 @@ static inline sector_t blk_rq_pos(const struct request *rq)
 static inline unsigned int blk_rq_bytes(const struct request *rq)
 {
 	return rq->__data_len;
 }
 
+static inline bool blk_rq_has_data(const struct request *rq)
+{
+	return blk_rq_bytes(rq) &&
+	       req_op(rq) != REQ_OP_DISCARD &&
+	       req_op(rq) != REQ_OP_SECURE_ERASE &&
+	       req_op(rq) != REQ_OP_WRITE_ZEROES;
+}
+
 static inline int blk_rq_cur_bytes(const struct request *rq)
 {
 	if (!rq->bio)
 		return 0;
 	if (!bio_has_data(rq->bio))	/* dataless requests such as discard */
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH v4 02/12] block/bdev: Annotate the blk_holder_ops callback functions
From: Bart Van Assche @ 2026-05-13 22:13 UTC (permalink / raw)
  To: Nathan Chancellor, Marco Elver
  Cc: Peter Zijlstra, Jens Axboe, linux-block, Christoph Hellwig
In-Reply-To: <20260513133614.GA703152@ax162>

On 5/13/26 6:36 AM, Nathan Chancellor wrote:
> While doing a dynamic check is more expensive than a version check, I
> would not worry much about that overhead if the check is worthwhile or
> valuable. In this case, I tend to agree with you that it would just be
> better to bump the minimum version of Clang required for context
> analysis because of the improvements (other than the function pointer
> support) that you have landed in main since release/22.x. While I am
> always sad to see support for older compilers dropped, I don't think
> clang-22 is widespread enough for that to really matter. On the other
> hand, I do worry that if we do not have a wide enough window of
> supported compilers for developers / maintainers to use, we won't be
> able to uncover potential problems to address in the compiler (I feel
> like getting __counted_by deployed was particular painful for this
> reason), if that makes sense.

It seems to me that increasing the required Clang version is the least
controversial approach. If nobody objects I will start testing the patch
below.

Thanks,

Bart.

Subject: [PATCH] lib/Kconfig.debug: Require Clang 23 for context analysis

Context annotations for function pointers will be supported by Clang 23
but are not supported by Clang 22. Bump the minimum required Clang
version in preparation of annotating the blk_holder_ops function pointer
members.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
  lib/Kconfig.debug | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 8ff5adcfe1e0..5b5d1d183618 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -630,7 +630,7 @@ config DEBUG_FORCE_WEAK_PER_CPU

  config WARN_CONTEXT_ANALYSIS
  	bool "Compiler context-analysis warnings"
-	depends on CC_IS_CLANG && CLANG_VERSION >= 220100
+	depends on CC_IS_CLANG && CLANG_VERSION >= 230000
  	# Branch profiling re-defines "if", which messes with the compiler's
  	# ability to analyze __cond_acquires(..), resulting in false positives.
  	depends on !TRACE_BRANCH_PROFILING
@@ -641,7 +641,7 @@ config WARN_CONTEXT_ANALYSIS
  	  and releasing user-definable "context locks".

  	  Clang's name of the feature is "Thread Safety Analysis". Requires
-	  Clang 22.1.0 or later.
+	  Clang 23.0 or later.

  	  Produces warnings by default. Select CONFIG_WERROR if you wish to
  	  turn these warnings into errors.




^ permalink raw reply related

* Re: [PATCH v2 1/8] dt-bindings: mmc: Document support for nvmem-layout
From: Rob Herring @ 2026-05-13 22:42 UTC (permalink / raw)
  To: Loic Poulain
  Cc: Ulf Hansson, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Konrad Dybcio, Jens Axboe, Johannes Berg, Jeff Johnson,
	Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
	Balakrishna Godavarthi, Rocky Liao, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Srinivas Kandagatla,
	Andrew Lunn, Heiner Kallweit, Russell King, Saravana Kannan,
	linux-mmc, devicetree, linux-kernel, linux-arm-msm, linux-block,
	linux-wireless, ath10k, linux-bluetooth, netdev, daniel
In-Reply-To: <20260507-block-as-nvmem-v2-1-bf17edd5134e@oss.qualcomm.com>

On Thu, May 07, 2026 at 05:24:36PM +0200, Loic Poulain wrote:
> Add support for an nvmem-layout subnode under an eMMC hardware
> partition. This allows the partition to be exposed as an NVMEM
> provider and its internal layout to be described. For example,
> an eMMC boot partition can be used to store device-specific
> information such as a WiFi MAC address.
> 
> Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
>  .../devicetree/bindings/mmc/mmc-card.yaml          | 24 ++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/mmc-card.yaml b/Documentation/devicetree/bindings/mmc/mmc-card.yaml
> index a61d6c96df759102f9c1fbfd548b026a77921cae..b21426a49cf1d9aae5b4e8e447b5be11b08c96bf 100644
> --- a/Documentation/devicetree/bindings/mmc/mmc-card.yaml
> +++ b/Documentation/devicetree/bindings/mmc/mmc-card.yaml
> @@ -40,6 +40,9 @@ patternProperties:
>          contains:
>            const: fixed-partitions
>  
> +      nvmem-layout:
> +        $ref: /schemas/nvmem/layouts/nvmem-layout.yaml
> +
>  required:
>    - compatible
>    - reg
> @@ -86,6 +89,27 @@ examples:
>                      read-only;
>                  };
>              };
> +
> +            partitions-boot2 {

Shouldn't this have a 'fixed-partitions' compatible? I'm not sure if 
it's an oversight in the schema that 'compatible' is not required here. 
It would be odd that compatible is optional, but if it is present, it 
must contain 'fixed-partitions' compatible. A follow-up to fix that 
would be great.

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>

Rob

^ permalink raw reply

* Re: [PATCH v4 02/12] block/bdev: Annotate the blk_holder_ops callback functions
From: Marco Elver @ 2026-05-13 23:06 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Nathan Chancellor, Peter Zijlstra, Jens Axboe, linux-block,
	Christoph Hellwig
In-Reply-To: <e6dbe36b-7bd3-4848-91e1-9c84d421e1ee@acm.org>

On Thu, 14 May 2026 at 00:14, Bart Van Assche <bvanassche@acm.org> wrote:
>
> On 5/13/26 6:36 AM, Nathan Chancellor wrote:
> > While doing a dynamic check is more expensive than a version check, I
> > would not worry much about that overhead if the check is worthwhile or
> > valuable. In this case, I tend to agree with you that it would just be
> > better to bump the minimum version of Clang required for context
> > analysis because of the improvements (other than the function pointer
> > support) that you have landed in main since release/22.x. While I am
> > always sad to see support for older compilers dropped, I don't think
> > clang-22 is widespread enough for that to really matter. On the other
> > hand, I do worry that if we do not have a wide enough window of
> > supported compilers for developers / maintainers to use, we won't be
> > able to uncover potential problems to address in the compiler (I feel
> > like getting __counted_by deployed was particular painful for this
> > reason), if that makes sense.
>
> It seems to me that increasing the required Clang version is the least
> controversial approach. If nobody objects I will start testing the patch
> below.

My patch which is more complete is still floating around:
https://lore.kernel.org/all/acqELlVC6vEeEF-W@elver.google.com/

Peter is probably still waiting for Debian to upgrade the clang dev version.

Thanks,
-- Marco

^ permalink raw reply

* Re: [PATCH v13 5/8] blk-mq: use hk cpus only when isolcpus=io_queue is enabled
From: Aaron Tomlin @ 2026-05-13 23:30 UTC (permalink / raw)
  To: Daniel Wagner
  Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
	martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
	shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
	sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
	jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
	akpm, maz, ruanjinjie, bigeasy, yphbchou0911, wagi, frederic,
	longman, chenridong, hare, kch, ming.lei, tom.leiming, steve,
	sean, chjohnst, neelx, mproche, nick.lange, marco.crivellari,
	rishil1999, linux-block, linux-kernel
In-Reply-To: <3af2cd18-1221-4ff6-aa7f-6dab74460eab@nitrogen.local>

[-- Attachment #1: Type: text/plain, Size: 1690 bytes --]

On Wed, May 13, 2026 at 11:42:46AM +0200, Daniel Wagner wrote:
> On Tue, May 12, 2026 at 08:55:06PM -0400, Aaron Tomlin wrote:
> > +static void blk_mq_map_fallback(struct blk_mq_queue_map *qmap)
> > +{
> > +	unsigned int cpu;
> > +
> > +	/*
> > +	 * Map all CPUs to the first hctx of this specific map to ensure
> > +	 * at least one online CPU is serving it, respecting the map's
> > +	 * boundaries so secondary maps do not route into the default map.
> > +	 */
> > +	for_each_possible_cpu(cpu)
> > +		qmap->mq_map[cpu] = qmap->queue_offset;
> > +}
> 
> I think this should also check if the CPU is online. The fallback should
> ensure the system will boot.

Thanks for the review Daniel.

While I completely agree with the goal of ensuring a safe boot, I suspect
that we actually must iterate over for_each_possible_cpu(cpu) here to
prevent map boundary violations during CPU hotplug events.

If we restrict this loop to for_each_online_cpu(), any currently offline
CPU would be left with a default array value of 0 in qmap->mq_map[cpu].

For secondary queue maps (e.g., read or poll queues where
qmap->queue_offset > 0), leaving an offline CPU mapped to 0 is highly
dangerous. If that CPU comes online, it could silently route its I/O into
the primary/default hardware queue map before the hotplug state machine has
a chance to recalculate the mappings, no?

By mapping all possible CPUs to qmap->queue_offset, we guarantee that
unassigned or temporarily offline CPUs remain safely fenced within the
correct map boundaries, which I believe perfectly mirrors the safety
guarantee of the original fallback logic.


Kind regards,
-- 
Aaron Tomlin

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v4 02/12] block/bdev: Annotate the blk_holder_ops callback functions
From: Bart Van Assche @ 2026-05-14  0:31 UTC (permalink / raw)
  To: Marco Elver
  Cc: Nathan Chancellor, Peter Zijlstra, Jens Axboe, linux-block,
	Christoph Hellwig
In-Reply-To: <CANpmjNP7JQq5X6bheX58bi2A5XaChkGSXs6+uQK2kiwQeXBvdg@mail.gmail.com>

On 5/13/26 4:06 PM, Marco Elver wrote:
> My patch which is more complete is still floating around:
> https://lore.kernel.org/all/acqELlVC6vEeEF-W@elver.google.com/
> 
> Peter is probably still waiting for Debian to upgrade the clang dev version.

How about reposting that patch? I hope that Peter won't wait with
queuing that patch until Debian has upgraded Clang.

Thanks,

Bart.

^ permalink raw reply

* Re: [PATCH 7.2 1/2] blk-mq: introduce blk_rq_has_data()
From: Ming Lei @ 2026-05-14  9:35 UTC (permalink / raw)
  To: Caleb Sander Mateos; +Cc: Jens Axboe, linux-block, linux-kernel
In-Reply-To: <20260513211846.1956810-2-csander@purestorage.com>

On Wed, May 13, 2026 at 03:18:45PM -0600, Caleb Sander Mateos wrote:
> Add blk_rq_has_data(), an analogue of bio_has_data() for struct request.
> This skips one dereference relative to bio_has_data(rq->bio).
> 
> Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>

Reviewed-by: Ming Lei <tom.leiming@gmail.com>

Thanks,
Ming

^ permalink raw reply

* Re: [PATCH blktests 1/3] check: add --cmd-trace option
From: Shin'ichiro Kawasaki @ 2026-05-14  9:36 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-block, Daniel Wagner, John Meneghini
In-Reply-To: <10bc69b1-762f-40a1-94b0-9ce6580b17e1@acm.org>

On May 13, 2026 / 10:08, Bart Van Assche wrote:
> On 5/13/26 4:23 AM, Shin'ichiro Kawasaki wrote:
> > diff --git a/check b/check
> > index c166fae..a68049b 100755
> > --- a/check
> > +++ b/check
> > @@ -458,7 +458,17 @@ _call_test() {
> >   		TIMEFORMAT="%Rs"
> >   		pushd . >/dev/null || return
> > +		if ((CMD_TRACE)); then
> > +			exec 8>"${seqres}.cmdtrace"
> > +			export BASH_XTRACEFD=8
> > +			set -x
> > +		fi
> 
> Hmm ... my experience is that set -x breaks most tests.

I ran whole blktests in my test environment with this series and the --cmd-trace
option, and observed no new failure. If the bash xtrace feature does not work in
any environment, I would like to understand the condition.


^ permalink raw reply

* Re: [PATCH 7.2 2/2] ublk: optimize ublk_rq_has_data()
From: Ming Lei @ 2026-05-14  9:36 UTC (permalink / raw)
  To: Caleb Sander Mateos; +Cc: Jens Axboe, linux-block, linux-kernel
In-Reply-To: <20260513211846.1956810-3-csander@purestorage.com>

On Wed, May 13, 2026 at 03:18:46PM -0600, Caleb Sander Mateos wrote:
> ublk_rq_has_data() currently uses bio_has_data(), which involves 2
> indirections and several branches. Use blk_rq_has_data() instead to save
> an indirection and NULL check.
> 
> Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>

Reviewed-by: Ming Lei <tom.leiming@gmail.com>


Thanks,
Ming

^ permalink raw reply

* Re: [PATCH blktests 2/3] common/rc: add _echo() function to trace sysfs attribute writes
From: Shin'ichiro Kawasaki @ 2026-05-14  9:41 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: Daniel Wagner, linux-block, Daniel Wagner, John Meneghini
In-Reply-To: <3ef4e2a4-c0ec-4040-a4c7-3687ed7e2d93@acm.org>

On May 13, 2026 / 10:07, Bart Van Assche wrote:
> On 5/13/26 7:05 AM, Daniel Wagner wrote:
> > On Wed, May 13, 2026 at 08:23:25PM +0900, Shin'ichiro Kawasaki wrote:
> > > +# Echo a value to a file. This wrapper is used to trace sysfs attribute writes
> > > +# when the --cmd-trace option is enabled.
> > > +_echo() {
> > > +	echo "$1" > "$2"
> > > +}
> > 
> > Stupid question, can't we override the echo function, something like this:
> > 
> > echo() {
> >      builtin echo "$@"
> >      builtin echo "$@" >> "/tmp/debug_log.txt"
> > }
> 
> How can this work since the sysfs/debugfs/configfs attribute is not an
> argument of the echo command?

I guess Daniel's idea was to do as follows:

echo() {
     builtin echo "$@"
     builtin echo "$@" >> "${seqres}.cmdtrace"
}

This can capture both the value and the filename in the .cmdtrace file.

Said that, this will not work when printf is used to write to
sysfs/debugfs/configfs attributes. So, I'm tempted to Bart's idea to
rename _echo() to _set_attr().


^ permalink raw reply

* Re: [PATCH blktests 2/3] common/rc: add _echo() function to trace sysfs attribute writes
From: Shin'ichiro Kawasaki @ 2026-05-14  9:45 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-block, Daniel Wagner, John Meneghini
In-Reply-To: <472b55a1-cef3-4473-b8b2-08b501efcd77@acm.org>

On May 13, 2026 / 10:17, Bart Van Assche wrote:
> On 5/13/26 4:23 AM, Shin'ichiro Kawasaki wrote:
> > +# Echo a value to a file. This wrapper is used to trace sysfs attribute writes
> 
> Echo -> Write
> file -> sysfs/debugfs/configfs attribute
> sysfs -> sysfs/debugfs/configfs

Thanks, these descriptions are more accurate.

> > +# when the --cmd-trace option is enabled.
> > +_echo() {
> > +	echo "$1" > "$2"
> > +}
> 
> If this is only used to write into sysfs/debugfs/configfs, there are
> probably better names for this function than _echo, e.g. _set_attr(),
> _write_attr() or _write_sys_attr().

Agreed, _set_attr() sounds good to me.

> 
> Should "echo" or "echo -n" be used in the above shell function?

I couldn't catch the comment above. The current patch uses "echo", and it's
working.


^ permalink raw reply

* [PATCH v3] block/blk-iolatency: Add the processing flow of the chained bio in the QoS and define the related types to solve the problem of incorrect inflight processing in the QoS. The usage of the done_split_bio abstract function in the blk-iolatency project.
From: Li kunyu @ 2026-05-14  9:59 UTC (permalink / raw)
  To: axboe, tj, josef; +Cc: linux-block, linux-kernel, Li kunyu
In-Reply-To: <20260506024244.2741-1-likunyu10@163.com>

Signed-off-by: Li kunyu <likunyu10@163.com>
---
v2: Fix the use of 'split' in the 'bio_set_flag' function to 'bio'
v3: Fix the missing implementation of the '__rq_qos_done_split_bio' function

 block/bio.c               |  2 ++
 block/blk-iolatency.c     | 34 ++++++++++++++++++++++++++++++++++
 block/blk-merge.c         |  7 ++++++-
 block/blk-rq-qos.c        |  9 +++++++++
 block/blk-rq-qos.h        | 11 +++++++++++
 include/linux/blk_types.h |  2 ++
 6 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/block/bio.c b/block/bio.c
index b8972dba68a0..7740701afc7f 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1733,6 +1733,8 @@ static inline bool bio_remaining_done(struct bio *bio)
 		return true;
 	}
 
+	rq_qos_done_split_bio(bio);
+
 	return false;
 }
 
diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c
index 53e8dd2dfa8a..ba5870bf14c5 100644
--- a/block/blk-iolatency.c
+++ b/block/blk-iolatency.c
@@ -632,6 +632,39 @@ static void blkcg_iolatency_done_bio(struct rq_qos *rqos, struct bio *bio)
 	}
 }
 
+static void blkcg_iolatency_done_split_bio(struct rq_qos *rqos, struct bio *bio)
+{
+	struct blkcg_gq *blkg;
+	struct rq_wait *rqw;
+	struct iolatency_grp *iolat;
+	int inflight = 0;
+
+	blkg = bio->bi_blkg;
+	if (!blkg || !bio_flagged(bio, BIO_QOS_CHAIN_CHILD))
+		return;
+
+	iolat = blkg_to_lat(bio->bi_blkg);
+	if (!iolat)
+		return;
+
+	if (!iolat->blkiolat->enabled)
+		return;
+
+	while (blkg && blkg->parent) {
+		iolat = blkg_to_lat(blkg);
+		if (!iolat) {
+			blkg = blkg->parent;
+			continue;
+		}
+		rqw = &iolat->rq_wait;
+
+		inflight = atomic_dec_return(&rqw->inflight);
+		WARN_ON_ONCE(inflight < 0);
+
+		blkg = blkg->parent;
+	}
+}
+
 static void blkcg_iolatency_exit(struct rq_qos *rqos)
 {
 	struct blk_iolatency *blkiolat = BLKIOLATENCY(rqos);
@@ -645,6 +678,7 @@ static void blkcg_iolatency_exit(struct rq_qos *rqos)
 static const struct rq_qos_ops blkcg_iolatency_ops = {
 	.throttle = blkcg_iolatency_throttle,
 	.done_bio = blkcg_iolatency_done_bio,
+	.done_split_bio = blkcg_iolatency_done_split_bio,
 	.exit = blkcg_iolatency_exit,
 };
 
diff --git a/block/blk-merge.c b/block/blk-merge.c
index fcf09325b22e..84373e3e1bbe 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -151,8 +151,13 @@ static struct bio *bio_submit_split(struct bio *bio, int split_sectors)
 	if (split_sectors) {
 		bio = bio_submit_split_bioset(bio, split_sectors,
 				&bio->bi_bdev->bd_disk->bio_split);
-		if (bio)
+		if (bio) {
 			bio->bi_opf |= REQ_NOMERGE;
+			/* Fix the issue where the inflight statistics
+			 * of the chained bio in the QoS are incorrect.
+			 */
+			bio_set_flag(bio, BIO_QOS_CHAIN_CHILD);
+		}
 	}
 
 	return bio;
diff --git a/block/blk-rq-qos.c b/block/blk-rq-qos.c
index 85cf74402a09..41ee04defca7 100644
--- a/block/blk-rq-qos.c
+++ b/block/blk-rq-qos.c
@@ -95,6 +95,15 @@ void __rq_qos_done_bio(struct rq_qos *rqos, struct bio *bio)
 	} while (rqos);
 }
 
+void __rq_qos_done_split_bio(struct rq_qos *rqos, struct bio *bio)
+{
+	do {
+		if (rqos->ops->done_split_bio)
+			rqos->ops->done_split_bio(rqos, bio);
+		rqos = rqos->next;
+	} while (rqos);
+}
+
 void __rq_qos_queue_depth_changed(struct rq_qos *rqos)
 {
 	do {
diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h
index a747a504fe42..496a27b9d412 100644
--- a/block/blk-rq-qos.h
+++ b/block/blk-rq-qos.h
@@ -45,6 +45,7 @@ struct rq_qos_ops {
 	void (*cleanup)(struct rq_qos *, struct bio *);
 	void (*queue_depth_changed)(struct rq_qos *);
 	void (*exit)(struct rq_qos *);
+	void (*done_split_bio)(struct rq_qos *, struct bio *);
 	const struct blk_mq_debugfs_attr *debugfs_attrs;
 };
 
@@ -108,6 +109,7 @@ void __rq_qos_throttle(struct rq_qos *rqos, struct bio *bio);
 void __rq_qos_track(struct rq_qos *rqos, struct request *rq, struct bio *bio);
 void __rq_qos_merge(struct rq_qos *rqos, struct request *rq, struct bio *bio);
 void __rq_qos_done_bio(struct rq_qos *rqos, struct bio *bio);
+void __rq_qos_done_split_bio(struct rq_qos *rqos, struct bio *bio);
 void __rq_qos_queue_depth_changed(struct rq_qos *rqos);
 
 static inline void rq_qos_cleanup(struct request_queue *q, struct bio *bio)
@@ -157,6 +159,15 @@ static inline void rq_qos_done_bio(struct bio *bio)
 		__rq_qos_done_bio(q->rq_qos, bio);
 }
 
+static inline void rq_qos_done_split_bio(struct bio *bio)
+{
+	if (bio->bi_bdev && bio_flagged(bio, BIO_QOS_CHAIN_CHILD)) {
+		struct request_queue *q = bdev_get_queue(bio->bi_bdev);
+		if (q->rq_qos)
+			__rq_qos_done_split_bio(q->rq_qos, bio);
+	}
+}
+
 static inline void rq_qos_throttle(struct request_queue *q, struct bio *bio)
 {
 	if (test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags) && q->rq_qos) {
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 8808ee76e73c..63fee89ecc14 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -322,6 +322,8 @@ enum {
 	BIO_REMAPPED,
 	BIO_ZONE_WRITE_PLUGGING, /* bio handled through zone write plugging */
 	BIO_EMULATES_ZONE_APPEND, /* bio emulates a zone append operation */
+	BIO_QOS_CHAIN_CHILD,    /* chained bio child, used for segmenting out
+				* the bio */
 	BIO_FLAG_LAST
 };
 
-- 
2.47.3


^ permalink raw reply related

* Re: [PATCH blktests 2/3] common/rc: add _echo() function to trace sysfs attribute writes
From: Daniel Wagner @ 2026-05-14 10:36 UTC (permalink / raw)
  To: Shin'ichiro Kawasaki
  Cc: Bart Van Assche, linux-block, Daniel Wagner, John Meneghini
In-Reply-To: <agWXr9Yntf4OiQ9e@shinmob>

On Thu, May 14, 2026 at 06:41:39PM +0900, Shin'ichiro Kawasaki wrote:
> Said that, this will not work when printf is used to write to
> sysfs/debugfs/configfs attributes. So, I'm tempted to Bart's idea to
> rename _echo() to _set_attr().

Indeed, my idea was to avoid prefixing all the echo with a _. Since this
doesn't work, Bart's idea to introduce explicit setters sounds like the
way to go. 

^ permalink raw reply

* Re: [PATCH v13 5/8] blk-mq: use hk cpus only when isolcpus=io_queue is enabled
From: Daniel Wagner @ 2026-05-14 10:42 UTC (permalink / raw)
  To: Aaron Tomlin
  Cc: Daniel Wagner, axboe, kbusch, hch, sagi, mst, aacraid,
	James.Bottomley, martin.petersen, liyihang9, kashyap.desai,
	sumit.saxena, shivasharan.srikanteshwara, chandrakanth.patil,
	sathya.prakash, sreekanth.reddy, suganath-prabu.subramani,
	ranjan.kumar, jinpu.wang, tglx, mingo, peterz, juri.lelli,
	vincent.guittot, akpm, maz, ruanjinjie, bigeasy, yphbchou0911,
	wagi, frederic, longman, chenridong, hare, kch, ming.lei,
	tom.leiming, steve, sean, chjohnst, neelx, mproche, nick.lange,
	marco.crivellari, rishil1999, linux-block, linux-kernel
In-Reply-To: <bovevvg2n77nzdrvjkayca2piibjl4noykv24wthex7em4u5lo@beqyhu2xertk>

On Wed, May 13, 2026 at 07:30:44PM -0400, Aaron Tomlin wrote:
> > I think this should also check if the CPU is online. The fallback should
> > ensure the system will boot.
> 
> While I completely agree with the goal of ensuring a safe boot, I suspect
> that we actually must iterate over for_each_possible_cpu(cpu) here to
> prevent map boundary violations during CPU hotplug events.

I have to check this version of the patch what is happening in detail.
Originally the idea was that the fallback should only be taken if it's
not possible to create a valid mapping due to $reason. In this case the
system should still boot and issue a warning. This is also what the
comments says in the function, pick one online CPU and map all hctx to
it. Don't bother to be smart.

^ permalink raw reply

* Re: [PATCH 09/12] swap: push down setting sis->bdev into ->swap_activate
From: Darrick J. Wong @ 2026-05-14 14:37 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: Christoph Hellwig, Andrew Morton, Chris Li, Kairui Song,
	Christian Brauner, Jens Axboe, David Sterba, Theodore Ts'o,
	Jaegeuk Kim, Chao Yu, Trond Myklebust, Anna Schumaker,
	Namjae Jeon, Hyunchul Lee, Steve French, Paulo Alcantara,
	Carlos Maiolino, Naohiro Aota, linux-xfs, linux-fsdevel,
	linux-doc, linux-mm, linux-block, linux-btrfs, linux-ext4,
	linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <b37ca8a7-289e-45a0-8cbd-eb14d7453b97@kernel.org>

On Wed, May 13, 2026 at 04:58:37PM +0900, Damien Le Moal wrote:
> On 5/13/26 16:46, Christoph Hellwig wrote:
> > On Wed, May 13, 2026 at 04:44:53PM +0900, Damien Le Moal wrote:
> >> Hmmm... With zonefs, swap files can be created on top of conventional zone
> >> files. So enforcing "no swap on zoned device" here would break that.
> > 
> > We can check that none of the extents fall onto sequential zones instead
> > of just devices.
> > 
> > I still wonder why you bother with swap to zonefs at all, though.
> 
> Yeah. I do not think anyone actually use that... But since it is there from the
> start, kind of stuck with it now.

Ahh, right, I forgot that zoned devices can have conventional zones
where swap would actually work.  Question withdrawn.

--D

^ permalink raw reply

* Re: [PATCH blktests 2/3] common/rc: add _echo() function to trace sysfs attribute writes
From: Bart Van Assche @ 2026-05-14 15:58 UTC (permalink / raw)
  To: Shin'ichiro Kawasaki; +Cc: linux-block, Daniel Wagner, John Meneghini
In-Reply-To: <agWZZkwOhiSoAvh6@shinmob>

On 5/14/26 2:45 AM, Shin'ichiro Kawasaki wrote:
> On May 13, 2026 / 10:17, Bart Van Assche wrote:
>> Should "echo" or "echo -n" be used in the above shell function?
> 
> I couldn't catch the comment above. The current patch uses "echo", and it's
> working.

We will have to switch to "echo -n" if any code is ever added to
blktests that writes into binary sysfs/debugfs/configfs attributes.

Thanks,

Bart.

^ permalink raw reply

* Re: [PATCH blktests 1/3] check: add --cmd-trace option
From: Bart Van Assche @ 2026-05-14 16:12 UTC (permalink / raw)
  To: Shin'ichiro Kawasaki; +Cc: linux-block, Daniel Wagner, John Meneghini
In-Reply-To: <agWWgSBS2v0sSlUl@shinmob>

On 5/14/26 2:36 AM, Shin'ichiro Kawasaki wrote:
> On May 13, 2026 / 10:08, Bart Van Assche wrote:
>> On 5/13/26 4:23 AM, Shin'ichiro Kawasaki wrote:
>>> diff --git a/check b/check
>>> index c166fae..a68049b 100755
>>> --- a/check
>>> +++ b/check
>>> @@ -458,7 +458,17 @@ _call_test() {
>>>    		TIMEFORMAT="%Rs"
>>>    		pushd . >/dev/null || return
>>> +		if ((CMD_TRACE)); then
>>> +			exec 8>"${seqres}.cmdtrace"
>>> +			export BASH_XTRACEFD=8
>>> +			set -x
>>> +		fi
>>
>> Hmm ... my experience is that set -x breaks most tests.
> 
> I ran whole blktests in my test environment with this series and the --cmd-trace
> option, and observed no new failure. If the bash xtrace feature does not work in
> any environment, I would like to understand the condition.

I should have added in my email "without setting BASH_XTRACEFD". If
BASH_XTRACEFD I think that "set -x" should be fine.

Thanks,

Bart.



^ permalink raw reply

* Re: [RFC PATCH v2] virtio_blk: add fua write support
From: Stefan Hajnoczi @ 2026-05-14 18:22 UTC (permalink / raw)
  To: Sana Sharma; +Cc: afaria, linux-block
In-Reply-To: <20260512191808.45334-2-sansshar@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 1444 bytes --]

On Tue, May 12, 2026 at 03:18:09PM -0400, Sana Sharma wrote:
> Continuing the work of Alberto Faria <afaria@redhat.com>
> this patch addresses the remaining feedback regarding removing
> VIRTIO_BLK_F_OUT_FUA from features_legacy[]
> 
> Link: https://lore.kernel.org/linux-block/20250508001951.421467-1-afaria@redhat.com/
> Originally-by: Alberto Faria <afaria@redhat.com>
> Signed-off-by: Alberto Faria <afaria@redhat.com>
> Signed-off-by: Sana Sharma <sansshar@redhat.com>
> 
> 
> ---
>  drivers/block/virtio_blk.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Thanks, Sana!

Please squash your change into Alberto's commit, rebase against the
latest linux.git/master, test against a patched QEMU, and resend the
entire series once the VIRTIO spec change has been merged (the vote is
currently ongoing).

> 
> diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
> index 5a6aa3dfb18a..aee2d503d6ef 100644
> --- a/drivers/block/virtio_blk.c
> +++ b/drivers/block/virtio_blk.c
> @@ -1665,7 +1665,7 @@ static unsigned int features_legacy[] = {
>  	VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
>  	VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE,
>  	VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES,
> -	VIRTIO_BLK_F_SECURE_ERASE, VIRTIO_BLK_F_OUT_FUA,
> +	VIRTIO_BLK_F_SECURE_ERASE,
>  }
>  ;
>  static unsigned int features[] = {
> -- 
> 2.54.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH 6/8] iomap: use bio_complete_in_task for buffered read errors
From: Tal Zussman @ 2026-05-14 18:30 UTC (permalink / raw)
  To: Christoph Hellwig, Jens Axboe, Matthew Wilcox (Oracle),
	Christian Brauner, Darrick J. Wong, Carlos Maiolino, Al Viro,
	Jan Kara
  Cc: Dave Chinner, Bart Van Assche, Gao Xiang, linux-block,
	linux-kernel, linux-xfs, linux-fsdevel, linux-mm
In-Reply-To: <20260409160243.1008358-7-hch@lst.de>

On 4/9/26 12:02 PM, Christoph Hellwig wrote:
> Replace out own hand-crafted complete in task context scheme with the
> generic block code.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   fs/iomap/bio.c | 44 +-------------------------------------------
>   1 file changed, 1 insertion(+), 43 deletions(-)
> 
> diff --git a/fs/iomap/bio.c b/fs/iomap/bio.c
> index 4504f4633f17..5b9b91198ec8 100644
> --- a/fs/iomap/bio.c
> +++ b/fs/iomap/bio.c
> @@ -9,9 +9,6 @@
>   #include "internal.h"
>   #include "trace.h"
>   
> -static DEFINE_SPINLOCK(failed_read_lock);
> -static struct bio_list failed_read_list = BIO_EMPTY_LIST;
> -
>   static u32 __iomap_read_end_io(struct bio *bio, int error)
>   {
>   	struct folio_iter fi;
> @@ -27,49 +24,10 @@ static u32 __iomap_read_end_io(struct bio *bio, int error)
>   	return folio_count;
>   }
>   
> -static void
> -iomap_fail_reads(
> -	struct work_struct	*work)
> -{
> -	struct bio		*bio;
> -	struct bio_list		tmp = BIO_EMPTY_LIST;
> -	unsigned long		flags;
> -
> -	spin_lock_irqsave(&failed_read_lock, flags);
> -	bio_list_merge_init(&tmp, &failed_read_list);
> -	spin_unlock_irqrestore(&failed_read_lock, flags);
> -
> -	while ((bio = bio_list_pop(&tmp)) != NULL) {
> -		__iomap_read_end_io(bio, blk_status_to_errno(bio->bi_status));
> -		cond_resched();
> -	}
> -}
> -
> -static DECLARE_WORK(failed_read_work, iomap_fail_reads);
> -
> -static void iomap_fail_buffered_read(struct bio *bio)
> -{
> -	unsigned long flags;
> -
> -	/*
> -	 * Bounce I/O errors to a workqueue to avoid nested i_lock acquisitions
> -	 * in the fserror code.  The caller no longer owns the bio reference
> -	 * after the spinlock drops.
> -	 */
> -	spin_lock_irqsave(&failed_read_lock, flags);
> -	if (bio_list_empty(&failed_read_list))
> -		WARN_ON_ONCE(!schedule_work(&failed_read_work));
> -	bio_list_add(&failed_read_list, bio);
> -	spin_unlock_irqrestore(&failed_read_lock, flags);
> -}
> -
>   static void iomap_read_end_io(struct bio *bio)
>   {
> -	if (bio->bi_status) {
> -		iomap_fail_buffered_read(bio);
> +	if (bio->bi_status && bio_complete_in_task(bio))
>   		return;
> -	}
> -
>   	__iomap_read_end_io(bio, 0);

I think this should be something like:

	__iomap_read_end_io(bio, blk_status_to_errno(bio->bi_status));

Otherwise the error is never propagated when iomap_read_end_io() is later
called from task context. Maybe worth rearranging slightly to avoid the
blk_status_to_errno() call for non-error I/Os?

I was planning on carrying this and 7/8 in the next version of my series
so that the procedural version has users, but I'll send without for now.

>   }
>   
> -- 
> 2.47.3
> 


^ permalink raw reply

* [PATCH v6 1/4] block: add task-context bio completion infrastructure
From: Tal Zussman @ 2026-05-14 21:51 UTC (permalink / raw)
  To: Jens Axboe, Matthew Wilcox (Oracle), Christian Brauner,
	Darrick J. Wong, Carlos Maiolino, Alexander Viro, Jan Kara,
	Christoph Hellwig
  Cc: Dave Chinner, Bart Van Assche, linux-block, linux-kernel,
	linux-xfs, linux-fsdevel, linux-mm, Gao Xiang, Tal Zussman
In-Reply-To: <20260514-blk-dontcache-v6-0-782e2fa7477b@columbia.edu>

Some bio completion handlers need to run from preemptible task context,
but bio_endio() may be called from IRQ context (e.g., buffer_head
writeback). Callers need a way to ensure their callback eventually runs
from a sleepable context. Add infrastructure for that, in two forms:

  1. BIO_COMPLETE_IN_TASK, a bio flag the submitter sets when it knows
     in advance that its callback needs task context (e.g., dropbehind
     writeback). bio_endio() sees the flag and offloads completion to a
     worker automatically.

  2. bio_complete_in_task(), a helper that completion callbacks can
     invoke from within bi_end_io() when the deferral decision is
     dynamic (e.g., fserror reporting).

Both share a per-CPU batch list drained by a delayed work item on a
WQ_PERCPU workqueue. Producers push the bio onto the local CPU's batch
and schedule the work item, which then dispatches each bio's bi_end_io()
from task context. The delayed work item uses a 1-jiffie delay to allow
batches of completions to accumulate before processing.

Both methods are gated on bio_in_atomic(), which returns true in any
context where a sleeping bi_end_io() is unsafe, including
non-preemptible task context. This logic is copied from commit
c99fab6e80b7 ("erofs: fix atomic context detection when
!CONFIG_DEBUG_LOCK_ALLOC").

Two CPU hotplug callbacks are used to drain remaining bios from the
departing CPU's batch, while maintaining the per-CPU behavior. The
CPUHP_AP_ONLINE_DYN callback disables the per-CPU delayed work while the
CPU is still online, preventing it from running on an unbound worker
later. CPUHP_BP_PREPARE_DYN then drains any bios added between disabling
the work item and CPU offline.

Link: https://lore.kernel.org/all/20260409160243.1008358-1-hch@lst.de/
Suggested-by: Matthew Wilcox <willy@infradead.org>
Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Tal Zussman <tz2294@columbia.edu>
---
 block/bio.c               | 147 +++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/bio.h       |  32 ++++++++++
 include/linux/blk_types.h |   1 +
 3 files changed, 179 insertions(+), 1 deletion(-)

diff --git a/block/bio.c b/block/bio.c
index b8972dba68a0..6864ee737400 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -19,6 +19,7 @@
 #include <linux/blk-crypto.h>
 #include <linux/xarray.h>
 #include <linux/kmemleak.h>
+#include <linux/local_lock.h>
 
 #include <trace/events/block.h>
 #include "blk.h"
@@ -1717,6 +1718,79 @@ void bio_check_pages_dirty(struct bio *bio)
 }
 EXPORT_SYMBOL_GPL(bio_check_pages_dirty);
 
+/*
+ * Infrastructure for deferring bio completions to task-context via a per-CPU
+ * workqueue. Triggered either by the BIO_COMPLETE_IN_TASK bio flag (static
+ * decision at submit time) or by calling bio_complete_in_task() from
+ * bi_end_io() (dynamic decision at completion time).
+ */
+
+struct bio_complete_batch {
+	local_lock_t lock;
+	struct bio_list list;
+	struct delayed_work work;
+	int cpu;
+};
+
+static DEFINE_PER_CPU(struct bio_complete_batch, bio_complete_batch) = {
+	.lock = INIT_LOCAL_LOCK(lock),
+};
+static struct workqueue_struct *bio_complete_wq;
+
+static void bio_complete_work_fn(struct work_struct *w)
+{
+	struct delayed_work *dw = to_delayed_work(w);
+	struct bio_complete_batch *batch =
+		container_of(dw, struct bio_complete_batch, work);
+
+	while (1) {
+		struct bio_list list;
+		struct bio *bio;
+
+		local_lock_irq(&bio_complete_batch.lock);
+		list = batch->list;
+		bio_list_init(&batch->list);
+		local_unlock_irq(&bio_complete_batch.lock);
+
+		if (bio_list_empty(&list))
+			break;
+
+		while ((bio = bio_list_pop(&list)))
+			bio->bi_end_io(bio);
+
+		if (need_resched()) {
+			bool is_empty;
+
+			local_lock_irq(&bio_complete_batch.lock);
+			is_empty = bio_list_empty(&batch->list);
+			local_unlock_irq(&bio_complete_batch.lock);
+			if (!is_empty)
+				mod_delayed_work_on(batch->cpu,
+						    bio_complete_wq,
+						    &batch->work, 0);
+			break;
+		}
+	}
+}
+
+void __bio_complete_in_task(struct bio *bio)
+{
+	struct bio_complete_batch *batch;
+	unsigned long flags;
+	bool was_empty;
+
+	local_lock_irqsave(&bio_complete_batch.lock, flags);
+	batch = this_cpu_ptr(&bio_complete_batch);
+	was_empty = bio_list_empty(&batch->list);
+	bio_list_add(&batch->list, bio);
+	local_unlock_irqrestore(&bio_complete_batch.lock, flags);
+
+	if (was_empty)
+		mod_delayed_work_on(batch->cpu, bio_complete_wq,
+				    &batch->work, 1);
+}
+EXPORT_SYMBOL_GPL(__bio_complete_in_task);
+
 static inline bool bio_remaining_done(struct bio *bio)
 {
 	/*
@@ -1791,7 +1865,9 @@ void bio_endio(struct bio *bio)
 	}
 #endif
 
-	if (bio->bi_end_io)
+	if (bio_flagged(bio, BIO_COMPLETE_IN_TASK) && bio_in_atomic())
+		__bio_complete_in_task(bio);
+	else if (bio->bi_end_io)
 		bio->bi_end_io(bio);
 }
 EXPORT_SYMBOL(bio_endio);
@@ -1977,6 +2053,51 @@ int bioset_init(struct bio_set *bs,
 }
 EXPORT_SYMBOL(bioset_init);
 
+static int bio_complete_batch_cpu_online(unsigned int cpu)
+{
+	enable_delayed_work(&per_cpu(bio_complete_batch, cpu).work);
+	return 0;
+}
+
+/*
+ * Disable this CPU's delayed work so that it cannot run on an unbound worker
+ * after the CPU is offlined.
+ */
+static int bio_complete_batch_cpu_down_prep(unsigned int cpu)
+{
+	disable_delayed_work_sync(&per_cpu(bio_complete_batch, cpu).work);
+	return 0;
+}
+
+/*
+ * Drain a dead CPU's deferred bio completions. The CPU is dead and the worker
+ * is canceled so no locking is needed.
+ */
+static int bio_complete_batch_cpu_dead(unsigned int cpu)
+{
+	struct bio_complete_batch *batch =
+		per_cpu_ptr(&bio_complete_batch, cpu);
+	struct bio *bio;
+
+	while ((bio = bio_list_pop(&batch->list)))
+		bio->bi_end_io(bio);
+
+	return 0;
+}
+
+static void __init bio_complete_batch_init(int cpu)
+{
+	struct bio_complete_batch *batch =
+		per_cpu_ptr(&bio_complete_batch, cpu);
+
+	bio_list_init(&batch->list);
+	INIT_DELAYED_WORK(&batch->work, bio_complete_work_fn);
+	batch->cpu = cpu;
+
+	if (!cpu_online(cpu))
+		disable_delayed_work_sync(&batch->work);
+}
+
 static int __init init_bio(void)
 {
 	int i;
@@ -1991,6 +2112,30 @@ static int __init init_bio(void)
 				SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
 	}
 
+	for_each_possible_cpu(i)
+		bio_complete_batch_init(i);
+
+	bio_complete_wq = alloc_workqueue("bio_complete",
+					   WQ_MEM_RECLAIM | WQ_PERCPU, 0);
+	if (!bio_complete_wq)
+		panic("bio: can't allocate bio_complete workqueue\n");
+
+	/*
+	 * bio task-context completion draining on hot-unplugged CPUs:
+	 *
+	 *   1. Stop the per-CPU delayed work while the CPU is still online, so
+	 *      that it cannot run on an unbound worker later.
+	 *   2. Drain leftover bios added between worker disabling and CPU
+	 *      offlining.
+	 */
+	cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
+				  "block/bio:complete:online",
+				  bio_complete_batch_cpu_online,
+				  bio_complete_batch_cpu_down_prep);
+	cpuhp_setup_state_nocalls(CPUHP_BP_PREPARE_DYN,
+				  "block/bio:complete:dead",
+				  NULL, bio_complete_batch_cpu_dead);
+
 	cpuhp_setup_state_multi(CPUHP_BIO_DEAD, "block/bio:dead", NULL,
 					bio_cpu_dead);
 
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 97d747320b35..c0214d6c28d6 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -369,6 +369,38 @@ static inline struct bio *bio_alloc(struct block_device *bdev,
 
 void submit_bio(struct bio *bio);
 
+/**
+ * bio_in_atomic - check if the current context is unsafe for bio completion
+ *
+ * Return: %true in atomic contexts (e.g. hard/soft IRQ, preempt-disabled);
+ * %false when a bio can be safely completed in the current context.
+ */
+static inline bool bio_in_atomic(void)
+{
+	if (IS_ENABLED(CONFIG_PREEMPTION) && rcu_preempt_depth())
+		return true;
+	if (!IS_ENABLED(CONFIG_PREEMPT_COUNT))
+		return true;
+	return !preemptible();
+}
+
+void __bio_complete_in_task(struct bio *bio);
+
+/**
+ * bio_complete_in_task - ensure a bio is completed in preemptible task context
+ * @bio: bio to complete
+ *
+ * If called from non-task context, offload the bio completion to a worker
+ * thread and return %true. Else return %false and do nothing.
+ */
+static inline bool bio_complete_in_task(struct bio *bio)
+{
+	if (!bio_in_atomic())
+		return false;
+	__bio_complete_in_task(bio);
+	return true;
+}
+
 extern void bio_endio(struct bio *);
 
 static inline void bio_io_error(struct bio *bio)
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 8808ee76e73c..d49d97a050d0 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -322,6 +322,7 @@ enum {
 	BIO_REMAPPED,
 	BIO_ZONE_WRITE_PLUGGING, /* bio handled through zone write plugging */
 	BIO_EMULATES_ZONE_APPEND, /* bio emulates a zone append operation */
+	BIO_COMPLETE_IN_TASK, /* complete bi_end_io() in task context */
 	BIO_FLAG_LAST
 };
 

-- 
2.39.5


^ permalink raw reply related

* [PATCH v6 0/4] block: enable RWF_DONTCACHE for block devices
From: Tal Zussman @ 2026-05-14 21:51 UTC (permalink / raw)
  To: Jens Axboe, Matthew Wilcox (Oracle), Christian Brauner,
	Darrick J. Wong, Carlos Maiolino, Alexander Viro, Jan Kara,
	Christoph Hellwig
  Cc: Dave Chinner, Bart Van Assche, linux-block, linux-kernel,
	linux-xfs, linux-fsdevel, linux-mm, Gao Xiang, Tal Zussman

Add support for using RWF_DONTCACHE with block devices.

Dropbehind pruning needs to be done in non-IRQ context, but block
devices complete writeback in IRQ context. To fix this, we defer
dropbehind invalidation to task context. Add infrastructure that lets
bi_end_io callbacks run from a worker, in two forms:

  1. BIO_COMPLETE_IN_TASK, a bio flag the submitter sets when it knows
     upfront that the callback needs task context, as in the dropbehind
     writeback paths.

  2. bio_complete_in_task(), a helper that callbacks can invoke from
     bi_end_io() when the decision to defer is dynamic, as in iomap
     fserror reporting.

These queue the bio to a per-CPU batch and schedule a delayed work item
to do bio completion.

Patch 1 adds the block layer task-context completion infrastructure,
with both the flag and the procedural helper. This builds on top of
suggestions by Matthew and Christoph: the procedural helper and
bio_in_atomic() come from Christoph's "bio completion in task
enhancements / experiments" series [1].

[Christoph, I put you down as Suggested-by for this patch. Let me know
if you'd like it to be Co-authored-by with your sign-off.]

Patch 2 wires BIO_COMPLETE_IN_TASK into iomap writeback for dropbehind
folios, removes IOMAP_IOEND_DONTCACHE, and removes the DONTCACHE
workqueue deferral from XFS.

Patch 3 sets up DONTCACHE support for buffer-head-based I/O by setting
BIO_COMPLETE_IN_TASK in submit_bh_wbc() for the CONFIG_BUFFER_HEAD
path.

Patch 4 enables RWF_DONTCACHE for block devices based on the previous
support. This support is useful for databases that operate on raw block
devices, among other userspace applications.

I tested this (with CONFIG_BUFFER_HEAD=y) for reads and writes on a
single block device on a VM, so results may be noisy.

Reads were tested on the root partition with a 45GB range (~2x RAM).
Writes were tested on a disabled swap parition (~1GB) in a memcg of size
244MB to force reclaim pressure.

Results:

===== READS (/dev/nvme0n1p2) =====
 sec   normal MB/s  dontcache MB/s
----  ------------  --------------
   1        1098.6          1609.0
   2        1270.3          1506.6
   3        1093.3          1576.5
   4        1141.8          2393.9
   5        1365.3          2793.8
   6        1324.6          2065.9
   7         879.6          1920.7
   8        1434.1          1662.4
   9        1184.9          1857.9
  10        1166.4          1702.8
  11        1161.4          1653.4
  12        1086.9          1555.4
  13        1198.5          1718.9
  14        1111.9          1752.2
----  ------------  --------------
 avg        1173.7          1828.8  (+56%)

==== WRITES (/dev/nvme0n1p3) =====
 sec   normal MB/s  dontcache MB/s
----  ------------  --------------
   1         692.4          9297.7
   2        4810.8          9342.8
   3        5221.7          2955.2
   4         396.7          8488.3
   5        7249.2          9249.3
   6        6695.4          1376.2
   7         122.9          9125.8
   8        5486.5          9414.7
   9        6921.5          8743.5
  10          27.9          8997.8
----  ------------  --------------
 avg        3762.5          7699.1  (+105%)

[1]: https://lore.kernel.org/all/20260409160243.1008358-1-hch@lst.de/

---
Changes in v6:
- Remove RFC tag
- Rebase on v7.1-rc3.
- 1/4: Revert to using a bio_list, per Jens.
- 1/4: Restructure and simplify work function loop.
- 1/4: Expose both the flag and procedural version, in order to allow
  static and dynamic deferral decisions, per conversation with Matthew
  and Christoph at LSFMM.
- 1/4: Use bio_in_atomic() predicate, per Christoph.
- 1/4: Use the CPU hot-unplug protocol from mm/vmstat.c, to take into
  account use of delayed_work.
- 1/4: Mark the workqueue WQ_PERCPU.
- 1/4: Add comments.
- 3/4 and 4/4: Split into two patches, per Christoph.
- 3/4: Drop the cont_write_begin() change. Block devices don't go
  through cont_write_begin(), so it was out of scope and was left over
  from v1.
- Link to v5: https://lore.kernel.org/r/20260408-blk-dontcache-v5-0-0f080c20a96f@columbia.edu

Changes in v5:
- 1/3: Replace local_lock + bio_list with struct llist, per Dave.
- 1/3: Use delayed_work with 1-jiffie delay, per Dave.
- 1/3: Add dedicated workqueue to avoid deadlocks, per Christoph.
- 1/3: Restructure work function as do/while loop and only schedule work
  originally when the list was previously empty, per Jens.
- 2/3: Delete IOMAP_IOEND_DONTCACHE and its NOMERGE entry, per Matthew
  and Christoph.
- Link to v4: https://lore.kernel.org/r/20260325-blk-dontcache-v4-0-c4b56db43f64@columbia.edu

Changes in v4:
- 1/3: Move dropbehind deferral from folio-level to bio-level using
  BIO_COMPLETE_IN_TASK, per Matthew and Jan.
- 1/3: Work function yields on need_resched() to avoid hogging the CPU,
  per Jan.
- 2/3: New patch. Set BIO_COMPLETE_IN_TASK on iomap writeback bios for
  DONTCACHE folios, removing the need for XFS-specific workqueue
  deferral.
- 3/3: Set BIO_COMPLETE_IN_TASK in submit_bh_wbc() for buffer_head
  path.
- 3/3: Update commit message to mention CONFIG_BUFFER_HEAD=n path.
- Link to v3: https://lore.kernel.org/r/20260227-blk-dontcache-v3-0-cd309ccd5868@columbia.edu

Changes in v3:
- 1/2: Convert dropbehind deferral to per-CPU folio_batches protected by
  local_lock using per-CPU work items, to reduce contention, per Jens.
- 1/2: Call folio_end_dropbehind_irq() directly from
  folio_end_writeback(), per Jens.
- 1/2: Add CPU hotplug dead callback to drain the departing CPU's folio
  batch.
- 2/2: Introduce block_write_begin_iocb(), per Christoph.
- 2/2: Dropped R-b due to changes.
- Link to v2: https://lore.kernel.org/r/20260225-blk-dontcache-v2-0-70e7ac4f7108@columbia.edu

Changes in v2:
- Add R-b from Jan Kara for 2/2.
- Add patch to defer dropbehind completion from IRQ context via a work
  item (1/2).
- Add initial performance numbers to cover letter.
- Link to v1: https://lore.kernel.org/r/20260218-blk-dontcache-v1-1-fad6675ef71f@columbia.edu

---
Tal Zussman (4):
      block: add task-context bio completion infrastructure
      iomap: use BIO_COMPLETE_IN_TASK for dropbehind writeback
      buffer: add dropbehind writeback support
      block: enable RWF_DONTCACHE for block devices

 block/bio.c                 | 147 +++++++++++++++++++++++++++++++++++++++++++-
 block/fops.c                |   5 +-
 fs/buffer.c                 |  19 +++++-
 fs/iomap/ioend.c            |   5 +-
 fs/xfs/xfs_aops.c           |   4 --
 include/linux/bio.h         |  32 ++++++++++
 include/linux/blk_types.h   |   1 +
 include/linux/buffer_head.h |   3 +
 include/linux/iomap.h       |   5 +-
 9 files changed, 206 insertions(+), 15 deletions(-)
---
base-commit: 695fee9be55747935d0a7b58f3d1fb83397a8b4f
change-id: 20260218-blk-dontcache-338133dd045e

Best regards,
-- 
Tal Zussman <tz2294@columbia.edu>


^ permalink raw reply

* [PATCH v6 2/4] iomap: use BIO_COMPLETE_IN_TASK for dropbehind writeback
From: Tal Zussman @ 2026-05-14 21:51 UTC (permalink / raw)
  To: Jens Axboe, Matthew Wilcox (Oracle), Christian Brauner,
	Darrick J. Wong, Carlos Maiolino, Alexander Viro, Jan Kara,
	Christoph Hellwig
  Cc: Dave Chinner, Bart Van Assche, linux-block, linux-kernel,
	linux-xfs, linux-fsdevel, linux-mm, Gao Xiang, Tal Zussman
In-Reply-To: <20260514-blk-dontcache-v6-0-782e2fa7477b@columbia.edu>

Set BIO_COMPLETE_IN_TASK on iomap writeback bios when a dropbehind folio
is added. This ensures that bi_end_io runs in task context, where
folio_end_dropbehind() can safely invalidate folios.

With the bio layer now handling task-context deferral generically,
IOMAP_IOEND_DONTCACHE is no longer needed, as XFS no longer needs to
route DONTCACHE ioends through its completion workqueue. Remove the flag
and its NOMERGE entry.

Without the NOMERGE, regular I/Os that get merged with a dropbehind
folio will also have their completion deferred to task context.

Signed-off-by: Tal Zussman <tz2294@columbia.edu>
---
 fs/iomap/ioend.c      | 5 +++--
 fs/xfs/xfs_aops.c     | 4 ----
 include/linux/iomap.h | 5 +----
 3 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/fs/iomap/ioend.c b/fs/iomap/ioend.c
index acf3cf98b23a..892dbfc77ae9 100644
--- a/fs/iomap/ioend.c
+++ b/fs/iomap/ioend.c
@@ -237,8 +237,6 @@ ssize_t iomap_add_to_ioend(struct iomap_writepage_ctx *wpc, struct folio *folio,
 
 	if (wpc->iomap.flags & IOMAP_F_SHARED)
 		ioend_flags |= IOMAP_IOEND_SHARED;
-	if (folio_test_dropbehind(folio))
-		ioend_flags |= IOMAP_IOEND_DONTCACHE;
 	if (pos == wpc->iomap.offset && (wpc->iomap.flags & IOMAP_F_BOUNDARY))
 		ioend_flags |= IOMAP_IOEND_BOUNDARY;
 
@@ -255,6 +253,9 @@ ssize_t iomap_add_to_ioend(struct iomap_writepage_ctx *wpc, struct folio *folio,
 	if (!bio_add_folio(&ioend->io_bio, folio, map_len, poff))
 		goto new_ioend;
 
+	if (folio_test_dropbehind(folio))
+		bio_set_flag(&ioend->io_bio, BIO_COMPLETE_IN_TASK);
+
 	/*
 	 * Clamp io_offset and io_size to the incore EOF so that ondisk
 	 * file size updates in the ioend completion are byte-accurate.
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index f279055fcea0..0dcf78beae8a 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -511,10 +511,6 @@ xfs_ioend_needs_wq_completion(
 	if (ioend->io_flags & (IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_SHARED))
 		return true;
 
-	/* Page cache invalidation cannot be done in irq context. */
-	if (ioend->io_flags & IOMAP_IOEND_DONTCACHE)
-		return true;
-
 	return false;
 }
 
diff --git a/include/linux/iomap.h b/include/linux/iomap.h
index 2c5685adf3a9..fef04e01116f 100644
--- a/include/linux/iomap.h
+++ b/include/linux/iomap.h
@@ -399,16 +399,13 @@ sector_t iomap_bmap(struct address_space *mapping, sector_t bno,
 #define IOMAP_IOEND_BOUNDARY		(1U << 2)
 /* is direct I/O */
 #define IOMAP_IOEND_DIRECT		(1U << 3)
-/* is DONTCACHE I/O */
-#define IOMAP_IOEND_DONTCACHE		(1U << 4)
 
 /*
  * Flags that if set on either ioend prevent the merge of two ioends.
  * (IOMAP_IOEND_BOUNDARY also prevents merges, but only one-way)
  */
 #define IOMAP_IOEND_NOMERGE_FLAGS \
-	(IOMAP_IOEND_SHARED | IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_DIRECT | \
-	 IOMAP_IOEND_DONTCACHE)
+	(IOMAP_IOEND_SHARED | IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_DIRECT)
 
 /*
  * Structure for writeback I/O completions.

-- 
2.39.5


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox