Linux block layer
 help / color / mirror / Atom feed
* Re: [GIT PULL] Block fixes for 7.1-rc4
From: pr-tracker-bot @ 2026-05-15 20:10 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-block@vger.kernel.org
In-Reply-To: <093dc3c7-5030-4400-9b38-727c41c5f511@kernel.dk>

The pull request you sent on Fri, 15 May 2026 08:20:27 -0600:

> https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux.git tags/block-7.1-20260515

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/d458a240344c4369bf6f3da203f2779515177738

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html

^ permalink raw reply

* Re: improve the swap_activate interface
From: Chris Li @ 2026-05-15 21:40 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, 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>

On Mon, May 11, 2026 at 10:36 PM 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.

My first impression it looks very promising. I will need more time to
take a closer look.

BTW, I just tried it, this series conflicts with Kairui's swap table
phase IV series. Might need to coordinate the merge order with Kairui.

Chris

^ permalink raw reply

* Re: [PATCH 12/12] swap: move swap_info_struct to mm/swap.h
From: Chris Li @ 2026-05-15 21:58 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, 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-13-hch@lst.de>

On Mon, May 11, 2026 at 10:38 PM Christoph Hellwig <hch@lst.de> wrote:
>
> swap_info_struct is now internal to the MM subsystem, so remove it from
> the public header.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Acked-by: Chris Li <chrisl@kernel.org>

Chris

^ permalink raw reply

* Re: [PATCH 11/12] swap: move struct swap_extent to swapfile.c
From: Chris Li @ 2026-05-15 21:58 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, 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-12-hch@lst.de>

On Mon, May 11, 2026 at 10:38 PM Christoph Hellwig <hch@lst.de> wrote:
>
> struct swap_extent is only used inside of mm/swapfile.c, so move it
> there.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Acked-by: Chris Li <chrisl@kernel.org>

Chris

^ permalink raw reply

* Re: [PATCH 10/12] swap: add a swap_activate_fs_ops helper
From: Chris Li @ 2026-05-15 22:00 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, 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-11-hch@lst.de>

On Mon, May 11, 2026 at 10:37 PM Christoph Hellwig <hch@lst.de> wrote:
>
> Add a helper abstracting away the low-level details of enabling
> fs_ops-based swapping.  This prepares for taking swap_info_struct
> private.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Acked-by: Chris Li <chrisl@kernel.org>

Chris

^ permalink raw reply

* Re: [PATCH 09/12] swap: push down setting sis->bdev into ->swap_activate
From: Chris Li @ 2026-05-15 22:12 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, 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-10-hch@lst.de>

On Mon, May 11, 2026 at 10:37 PM Christoph Hellwig <hch@lst.de> wrote:
>
> Only the file operation method knows what block device we'll swap
> to.  So move down setting sis->bdev and the special blockdev flag
> into ->swap_activate.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>


The core swap part of the code looks fine to me, I did not look much
deeper into the fs side.

Ack-by: Chris Li <chrisl@kernel.org>

Chris

^ permalink raw reply

* Re: [PATCH 06/12] swap,block: move the block device swapon code into block/fops.c
From: Chris Li @ 2026-05-15 22:14 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, 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-7-hch@lst.de>

On Mon, May 11, 2026 at 10:37 PM Christoph Hellwig <hch@lst.de> wrote:
>
> Make use of the abstractions we have.  This is a preparation for
> moving more special casing down into block/.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Acked-by: Chris Li <chrisl@kernel.org>

Chris

^ permalink raw reply

* Re: [PATCH 05/12] swap: cleanup setup_swap_extents
From: Chris Li @ 2026-05-15 22:18 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, 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-6-hch@lst.de>

On Mon, May 11, 2026 at 10:37 PM Christoph Hellwig <hch@lst.de> wrote:
>
> Reflow setup_swap_extents so that the flag checking is not conditional on
> a swap_activate method.  This is currently a no-op because the swapoff
> code still checks the presence of a swap_deactivate method, but it
> simplifies adding a new check, and also makes the SWP_ACTIVATED flag
> more consistent.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Acked-by: Chris Li <chrisl@kernel.org>

Chris

^ permalink raw reply

* Re: [PATCH 04/12] swap: restrict to regular files or block devices
From: Chris Li @ 2026-05-15 22:19 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, 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-5-hch@lst.de>

On Mon, May 11, 2026 at 10:37 PM Christoph Hellwig <hch@lst.de> wrote:
>
> Various swap code assumes it runs either on a block device or on a
> regular file.  Make this restriction explicit using checks right
> after opening the file.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Acked-by: Chris Li <chrisl@kernel.org>

Chris

^ permalink raw reply

* Re: [PATCH 03/12] swap,fs: move swapfile operations to struct file_operations
From: Chris Li @ 2026-05-15 22:24 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, 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-4-hch@lst.de>

On Mon, May 11, 2026 at 10:37 PM Christoph Hellwig <hch@lst.de> wrote:
>
> The swap operations have nothing to do with the address_space, which is
> used for pagecache operations.  Move them to struct file_operations
> instead.  This will allow moving the block device special cases into
> block/fops.c subsequently.
>
> Pass struct file first to ->swap_activate as file operations typically
> get the file or iocb as first argument and use swap_activate instead of
> swapfile_activate in all names to be consistent.
>
> Note that while the trivial iomap wrappers are moved to a new file when
> applicable to keep them local to the file operation instances, complex
> implementation are kept in their existing place.  It might be worth to
> move them in follow-on patches if the maintainers desire so.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

That makes sense to me. I ack for the core swap part of the code.

Acked-by: Chris Li <chrisl@kernel.org>

Chris

^ permalink raw reply

* Re: [PATCH 02/12] swap: move boilerplate code into the core swap code
From: Chris Li @ 2026-05-15 22:29 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, 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-3-hch@lst.de>

On Mon, May 11, 2026 at 10:36 PM Christoph Hellwig <hch@lst.de> wrote:
>
> Make the core swap code calculate sis->pages, nr_extents and the span,
> re-set sis->max based on it and don't require passing the current offset
> into the swap file to swap_add_extent as all that can trivially be
> calculated internally.  Also truncate the spans based on the available
> information.
>
> All this removes a lot of boilerplate code in the callers.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Very nice cleanup.

Acked-by: Chris Li <chrisl@kernel.org>

Chris

^ permalink raw reply

* Re: [PATCH 01/12] swap: remove the maxpages variable in sys_swapon
From: Chris Li @ 2026-05-15 22:37 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, 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-2-hch@lst.de>

On Mon, May 11, 2026 at 10:36 PM Christoph Hellwig <hch@lst.de> wrote:
>
> Always use si->max which is updated setup_swap_extents instead of copying
> into and out of maxpages.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Acked-by: Chris Li <chrisl@kernel.org>

> ---
>  mm/swapfile.c | 27 +++++++++++----------------
>  1 file changed, 11 insertions(+), 16 deletions(-)
>
> diff --git a/mm/swapfile.c b/mm/swapfile.c
> index 9174f1eeffb0..f7ebd97e28a3 100644
> --- a/mm/swapfile.c
> +++ b/mm/swapfile.c
> @@ -3350,10 +3350,9 @@ static unsigned long read_swap_header(struct swap_info_struct *si,
>  }
>
>  static int setup_swap_clusters_info(struct swap_info_struct *si,
> -                                   union swap_header *swap_header,
> -                                   unsigned long maxpages)
> +                                   union swap_header *swap_header)
>  {
> -       unsigned long nr_clusters = DIV_ROUND_UP(maxpages, SWAPFILE_CLUSTER);
> +       unsigned long nr_clusters = DIV_ROUND_UP(si->max, SWAPFILE_CLUSTER);
>         struct swap_cluster_info *cluster_info;
>         int err = -ENOMEM;
>         unsigned long i;
> @@ -3395,7 +3394,7 @@ static int setup_swap_clusters_info(struct swap_info_struct *si,
>                 if (err)
>                         goto err;
>         }
> -       for (i = maxpages; i < round_up(maxpages, SWAPFILE_CLUSTER); i++) {
> +       for (i = si->max; i < round_up(si->max, SWAPFILE_CLUSTER); i++) {
>                 err = swap_cluster_setup_bad_slot(si, cluster_info, i, true);

Nitpick: I couldn't hlep but notice the si->max does not change
between setup bad slots, so in theory you can cache the si->max value
to a local variable for the loop. In real life, it will make no
difference, so feel free to keep it as is.

Chris

^ permalink raw reply

* [PATCH] blk-cgroup-rwstat: add missing DISCARD counter in blkg_rwstat_total()
From: Tao Cui @ 2026-05-16  4:47 UTC (permalink / raw)
  To: axboe, tj, linux-block; +Cc: Tao Cui

Since commit 636620b66d5d ("blkcg: Track DISCARD statistics and output
them in cgroup io.stat"), blkg_rwstat_add() routes discard IOs into
BLKG_RWSTAT_DISCARD, but blkg_rwstat_total() still only sums READ and
WRITE.  This makes the total inconsistent with the per-type counters
whenever discard IOs are present.

On mixed read/write/discard workloads, the total undercounts the
actual IO activity.  If only discard requests are queued, the total
returns 0 outright.  In BFQ this causes avg_queue_size to be
underestimated and the group to be incorrectly marked empty.

The affected BFQ code paths are all gated by CONFIG_BFQ_CGROUP_DEBUG
and used only for statistics display (bfq.sectors, bfq.avg_queue_size,
bfq.empty_time).  No scheduling decisions depend on these values.

Signed-off-by: Tao Cui <cuitao@kylinos.cn>
---
 block/blk-cgroup-rwstat.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/block/blk-cgroup-rwstat.h b/block/blk-cgroup-rwstat.h
index 703a16fe1404..b7908d877e2b 100644
--- a/block/blk-cgroup-rwstat.h
+++ b/block/blk-cgroup-rwstat.h
@@ -110,7 +110,8 @@ static inline uint64_t blkg_rwstat_total(struct blkg_rwstat *rwstat)
 	struct blkg_rwstat_sample tmp = { };
 
 	blkg_rwstat_read(rwstat, &tmp);
-	return tmp.cnt[BLKG_RWSTAT_READ] + tmp.cnt[BLKG_RWSTAT_WRITE];
+	return tmp.cnt[BLKG_RWSTAT_READ] + tmp.cnt[BLKG_RWSTAT_WRITE] +
+	       tmp.cnt[BLKG_RWSTAT_DISCARD];
 }
 
 /**
-- 
2.43.0


^ permalink raw reply related

* Re: [REGRESSION] block: virtio-blk + LVM raid1 spurious sector-0 read failures on libaio/threads submit since 5ff3f74e145a ("block: simplify direct io validity check")
From: Thorsten Leemhuis @ 2026-05-16  5:09 UTC (permalink / raw)
  To: Vjaceslavs Klimovs, Jens Axboe
  Cc: Keith Busch, Hannes Reinecke, Martin K. Petersen,
	Christoph Hellwig, linux-block, linux-raid, dm-devel,
	linux-kernel, regressions
In-Reply-To: <CAC_j7i1R7oy+nRhxEjCTba=DUgn02w9X+p94DCu0aHv5+5tKnQ@mail.gmail.com>

On 5/15/26 18:52, Vjaceslavs Klimovs wrote:
> Summary
> -------
> On v6.18, starting a libvirt/QEMU guest with virtio-blk backed by an
> LVM "--type raid1" LV (drivers/md/dm-raid.c stacked on
> drivers/md/raid1.c) makes md/raid1 register read failures at LV
> sector 0 within seconds of "virsh start" and mark rimage_0 Faulty
> once max_corrected_read_errors (default 20) is exceeded. Reads
> succeed via the redirect path so guests boot, but every guest disk
> ends up degraded on every VM start. Same workload on legacy
> "--type mirror" (drivers/md/dm-raid1.c) crashes the host: a
> zero-length READ reaches the NVMe controller, is rejected with
> "Invalid Field in Command", and the dm-mirror recovery path oopses.

That sounds somewhat like
https://lore.kernel.org/all/2982107.4sosBPzcNG@electra/

Have you tried latest 7.1-rc? It contains a fix for the problem
mentioned in said thread: f7b24c7b41f23b ("md/raid1,raid10: don't fail
devices for invalid IO errors") [v7.1-rc2]

Ciao, Thorsten

> Symptom on dm-raid raid1 (post --type raid1)
> --------------------------------------------
> Per LV, at virsh start, in host dmesg:
> 
>   kernel: raid1_end_read_request: 95 callbacks suppressed
>   kernel: raid1_read_request: 95 callbacks suppressed
>   kernel: md/raid1:mdX: dm-58: rescheduling sector 0
>   kernel: md/raid1:mdX: redirecting sector 0 to other mirror: dm-58
>   kernel: md/raid1:mdX: dm-58: rescheduling sector 0
>   kernel: md/raid1:mdX: redirecting sector 0 to other mirror: dm-58
>   [... 10 rescheduling/redirecting pairs ...]
>   kernel: md/raid1:mdX: dm-58: Raid device exceeded read_error
> threshold [cur 21:max 20]
>   kernel: md/raid1:mdX: dm-58: Failing raid device
>   kernel: md/raid1:mdX: Disk failure on dm-58, disabling device.
>   kernel: md/raid1:mdX: Operation continuing on 1 devices.
> 
>   dmeventd: WARNING: Device #0 of raid1 array, vg0-iris_boot, has failed.
>   dmeventd: WARNING: Waiting for resynchronization to finish before
> initiating repair on RAID device vg0-iris_boot.
>   dmeventd: Use 'lvconvert --repair vg0/iris_boot' to replace failed device.
> 
> Subsequent "lvs -a":
> 
>   WARNING: RaidLV vg0/iris_boot needs to be refreshed!
>   See character 'r' at position 9 in the RaidLV's attributes and its SubLV(s).
> 
> dmesg | grep nvme is EMPTY on this path. The NVMe driver is not
> involved in producing the error; the failure originates between the
> virtio-blk bio submission and raid1_end_read_request().
> 
> Symptom on legacy dm-mirror (pre-conversion --type mirror)
> ----------------------------------------------------------
> Same workload on drivers/md/dm-raid1.c reaches the NVMe controller
> as a zero-length READ and panics the host through dm-mirror's
> recovery path:
> 
>   kernel: operation not supported error, dev nvme1n1, sector 935446535
> op 0x0:(READ) flags 0x0 phys_seg 0 prio class 2
>   kernel: nvme1n1: I/O Cmd(0x2) @ LBA 935446535, 0 blocks, I/O Error
> (sct 0x0 / sc 0x2)
>   [... 10+ identical bursts at same timestamp ...]
>   dmeventd: Primary mirror device 252:58 read failed.
>   dmeventd: vg0-iris_boot is now in-sync.
>   [kernel oops in dm_mirror recovery path, full trace lost to console flash]
> 
> The "phys_seg 0", "0 blocks", "sct 0x0/sc 0x2" trio (NVMe Generic,
> Invalid Field in Command, NVMe spec 4.1.1.2) is unambiguous: a bio
> with bi_iter.bi_size == 0 and bi_vcnt == 0 left the block layer and
> hit the controller. dm-raid raid1 hides this by retrying on the
> surviving leg, but the upstream-of-md trigger is identical.
> 
> Bisect
> ------
> git bisect, v6.12..v6.18, 16 deterministic GOOD/BAD steps, no skips,
> ~104 minutes:
> 
>   5ff3f74e145adc79b49668adb8de276446acf6be is the first bad commit
>   block: simplify direct io validity check
> 
>   --- a/block/fops.c
>   +++ b/block/fops.c
>   @@ -38,8 +38,8 @@ static blk_opf_t dio_bio_write_op(struct kiocb *iocb)
>    static bool blkdev_dio_invalid(struct block_device *bdev, struct kiocb *iocb,
>                                   struct iov_iter *iter)
>    {
>   -        return iocb->ki_pos & (bdev_logical_block_size(bdev) - 1) ||
>   -                !bdev_iter_is_aligned(bdev, iter);
>   +        return (iocb->ki_pos | iov_iter_count(iter)) &
>   +                        (bdev_logical_block_size(bdev) - 1);
>    }
> 
> The dropped bdev_iter_is_aligned() used to walk the iov_iter and
> reject per-segment misaligned/degenerate vectors at the blkdev fops
> entry point. The replacement only validates ki_pos and total length
> against the logical block size. Cases that now pass that no longer
> get rejected:
> 
>   - iter with iov_iter_count(iter) == 0  (degenerate; total length is
>     "sector-aligned" since 0 % 512 == 0)
>   - iter where total length is sector-aligned but a segment isn't
> 
> The commit message justifies the removal with "The block layer
> checks all the segments for validity later". This is true for the
> io_uring submit path (which enters __blkdev_direct_IO directly and
> does its own validation) but not for the libaio aio_read/write_iter
> or the worker-pool sync read/write_iter paths that enter via
> blkdev_{read,write}_iter() -> blkdev_dio_invalid(). For those paths,
> the segment check has no replacement.
> 
> Reproducing
> ----------------------------------------------------------
> 
> The trigger requires QEMU virtio-blk's specific submission shape AND
> a non-io_uring submit. Userspace libaio alone, userspace
> preadv-in-a-thread alone, and QEMU's raw-driver open probes (which
> qemu-img info exercises identically) are all insufficient. The
> combination that hits the bug is "guest-driven I/O through
> virtio-blk-pci with cache.direct=on and aio in {native, threads}".
> 
> #regzbot introduced: 5ff3f74e145adc79b49668adb8de276446acf6be
> 
> Thanks,
> Vjaceslavs Klimovs
> 


^ permalink raw reply

* [PATCH v2] cgroup/rstat: validate cpu before css_rstat_cpu() access
From: Qing Ming @ 2026-05-16  7:08 UTC (permalink / raw)
  To: Tejun Heo, Josef Bacik, Jens Axboe, Johannes Weiner,
	Michal Koutný, Michal Hocko, Roman Gushchin, Shakeel Butt,
	Muchun Song, Andrew Morton, Alexei Starovoitov, Hao Luo,
	Yosry Ahmed
  Cc: cgroups, linux-block, linux-kernel, linux-mm, bpf, Qing Ming
In-Reply-To: <20260515122952.59209-1-a0yami@mailbox.org>

css_rstat_updated() is exposed as a BPF kfunc and accepts a
caller-provided cpu argument. The function uses cpu for per-cpu rstat
lookups without checking whether it refers to a valid possible CPU.

A BPF iter/cgroup program with CAP_BPF and CAP_PERFMON can pass an
invalid cpu value. On an unfixed UBSCAN_BOUNDS test kernel, cpu ==
0x7fffffff triggers:

  UBSAN: array-index-out-of-bounds in kernel/cgroup/rstat.c:31:9
  index 2147483647 is out of range for type 'long unsigned int [64]'
  Call Trace:
    css_rstat_updated
    bpf_iter_run_prog
    cgroup_iter_seq_show
    bpf_seq_read

Add cpu validation to the BPF-facing css_rstat_updated() kfunc and
move the common implementation to __css_rstat_updated() for in-kernel
callers.

Fixes: a319185be9f5 ("cgroup: bpf: enable bpf programs to integrate with rstat")
Signed-off-by: Qing Ming <a0yami@mailbox.org>
---
v2:
- Split css_rstat_updated() into a BPF-visible wrapper and an internal
  __css_rstat_updated() helper.
- Switch internal callers to __css_rstat_updated().

 block/blk-cgroup.c     |  2 +-
 include/linux/cgroup.h |  1 +
 kernel/cgroup/rstat.c  | 30 ++++++++++++++++++++----------
 mm/memcontrol.c        |  6 +++---
 4 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 554c87bb4a86..bc63bd220865 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -2241,7 +2241,7 @@ void blk_cgroup_bio_start(struct bio *bio)
 	}
 
 	u64_stats_update_end_irqrestore(&bis->sync, flags);
-	css_rstat_updated(&blkcg->css, cpu);
+	__css_rstat_updated(&blkcg->css, cpu);
 	put_cpu();
 }
 
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index f6d037a30fd8..c5648fcf74e2 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -777,6 +777,7 @@ static inline void cgroup_path_from_kernfs_id(u64 id, char *buf, size_t buflen)
 /*
  * cgroup scalable recursive statistics.
  */
+void __css_rstat_updated(struct cgroup_subsys_state *css, int cpu);
 void css_rstat_updated(struct cgroup_subsys_state *css, int cpu);
 void css_rstat_flush(struct cgroup_subsys_state *css);
 
diff --git a/kernel/cgroup/rstat.c b/kernel/cgroup/rstat.c
index 150e5871e66f..ed60ba119c68 100644
--- a/kernel/cgroup/rstat.c
+++ b/kernel/cgroup/rstat.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include "cgroup-internal.h"
 
+#include <linux/cpumask.h>
 #include <linux/sched/cputime.h>
 
 #include <linux/bpf.h>
@@ -53,7 +54,7 @@ static inline struct llist_head *ss_lhead_cpu(struct cgroup_subsys *ss, int cpu)
 }
 
 /**
- * css_rstat_updated - keep track of updated rstat_cpu
+ * __css_rstat_updated - keep track of updated rstat_cpu
  * @css: target cgroup subsystem state
  * @cpu: cpu on which rstat_cpu was updated
  *
@@ -63,20 +64,17 @@ static inline struct llist_head *ss_lhead_cpu(struct cgroup_subsys *ss, int cpu)
  *
  * NOTE: if the user needs the guarantee that the updater either add itself in
  * the lockless list or the concurrent flusher flushes its updated stats, a
- * memory barrier is needed before the call to css_rstat_updated() i.e. a
+ * memory barrier is needed before the call to __css_rstat_updated() i.e. a
  * barrier after updating the per-cpu stats and before calling
- * css_rstat_updated().
+ * __css_rstat_updated().
  */
-__bpf_kfunc void css_rstat_updated(struct cgroup_subsys_state *css, int cpu)
+void __css_rstat_updated(struct cgroup_subsys_state *css, int cpu)
 {
 	struct llist_head *lhead;
 	struct css_rstat_cpu *rstatc;
 	struct llist_node *self;
 
-	/*
-	 * Since bpf programs can call this function, prevent access to
-	 * uninitialized rstat pointers.
-	 */
+	/* Prevent access to uninitialized rstat pointers. */
 	if (!css_uses_rstat(css))
 		return;
 
@@ -125,6 +123,18 @@ __bpf_kfunc void css_rstat_updated(struct cgroup_subsys_state *css, int cpu)
 	llist_add(&rstatc->lnode, lhead);
 }
 
+/*
+ * BPF-facing wrapper for __css_rstat_updated(). Validate the caller-provided
+ * CPU before passing it to the internal rstat updater.
+ */
+__bpf_kfunc void css_rstat_updated(struct cgroup_subsys_state *css, int cpu)
+{
+	if (unlikely(cpu < 0 || cpu >= nr_cpu_ids || !cpu_possible(cpu)))
+		return;
+
+	__css_rstat_updated(css, cpu);
+}
+
 static void __css_process_update_tree(struct cgroup_subsys_state *css, int cpu)
 {
 	/* put @css and all ancestors on the corresponding updated lists */
@@ -170,7 +180,7 @@ static void css_process_update_tree(struct cgroup_subsys *ss, int cpu)
 		 * flusher flush the stats updated by the updater who have
 		 * observed that they are already on the list. The
 		 * corresponding barrier pair for this one should be before
-		 * css_rstat_updated() by the user.
+		 * __css_rstat_updated() by the user.
 		 *
 		 * For now, there aren't any such user, so not adding the
 		 * barrier here but if such a use-case arise, please add
@@ -614,7 +624,7 @@ static void cgroup_base_stat_cputime_account_end(struct cgroup *cgrp,
 						 unsigned long flags)
 {
 	u64_stats_update_end_irqrestore(&rstatbc->bsync, flags);
-	css_rstat_updated(&cgrp->self, smp_processor_id());
+	__css_rstat_updated(&cgrp->self, smp_processor_id());
 	put_cpu_ptr(rstatbc);
 }
 
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index c03d4787d466..749c128b4fad 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -679,7 +679,7 @@ static inline void memcg_rstat_updated(struct mem_cgroup *memcg, long val,
 	if (!val)
 		return;
 
-	css_rstat_updated(&memcg->css, cpu);
+	__css_rstat_updated(&memcg->css, cpu);
 	statc_pcpu = memcg->vmstats_percpu;
 	for (; statc_pcpu; statc_pcpu = statc->parent_pcpu) {
 		statc = this_cpu_ptr(statc_pcpu);
@@ -2796,7 +2796,7 @@ static inline void account_slab_nmi_safe(struct mem_cgroup *memcg,
 		struct mem_cgroup_per_node *pn = memcg->nodeinfo[pgdat->node_id];
 
 		/* preemption is disabled in_nmi(). */
-		css_rstat_updated(&memcg->css, smp_processor_id());
+		__css_rstat_updated(&memcg->css, smp_processor_id());
 		if (idx == NR_SLAB_RECLAIMABLE_B)
 			atomic_add(nr, &pn->slab_reclaimable);
 		else
@@ -3019,7 +3019,7 @@ static inline void account_kmem_nmi_safe(struct mem_cgroup *memcg, int val)
 		mod_memcg_state(memcg, MEMCG_KMEM, val);
 	} else {
 		/* preemption is disabled in_nmi(). */
-		css_rstat_updated(&memcg->css, smp_processor_id());
+		__css_rstat_updated(&memcg->css, smp_processor_id());
 		atomic_add(val, &memcg->kmem_stat);
 	}
 }
-- 
2.53.0


^ permalink raw reply related

* [PATCH blktests v2 0/3] introduce command trace feature
From: Shin'ichiro Kawasaki @ 2026-05-16 12:07 UTC (permalink / raw)
  To: linux-block
  Cc: Daniel Wagner, John Meneghini, Bart Van Assche,
	Shin'ichiro Kawasaki

Some blktests test cases have deep nesting, making their behavior
difficult to understand. For example, the nvme test group has many
helper functions that set sysfs attribute values and call nvme-cli
commands. Understanding these behaviors is essential for debugging test
case failures.

This series adds a new 'command trace' feature to blktests. The first
patch introduces a new --cmd-trace (or -t) option to record commands
executed during test runs. The second and third patches add a new helper
function _set_attr(), which traces both the value and file name of sysfs
attribute writes.

With this series, blktests users can use the option to generate a
.cmdtrace file that records all commands executed during a test case
run. By grepping the .cmdtrace file, users can check writes to sysfs
attributes and nvme-cli command invocations. The example below shows how
nvme targets are set up for the nvme/008 test case with rdma transport.

# NVMET_TRTYPES=rdma NVMET_BLKDEV_TYPES=device ./check --cmd-trace nvme/008
nvme/008 (tr=rdma bd=device) (create an NVMeOF host)         [passed]
    runtime  1.903s  ...  1.890s
# grep -e _set_attr -e "nvme " results/nodev_tr_rdma_bd_device/nvme/008.cmdtrace
+ _set_attr 0 /sys/kernel/config/nvmet/subsystems/blktests-subsystem-1/attr_allow_any_host
+ _set_attr /dev/loop0 /sys/kernel/config/nvmet/subsystems/blktests-subsystem-1/namespaces/1/device_path
+ _set_attr 91fdba0d-f87b-4c25-b80f-db7be1418b9e /sys/kernel/config/nvmet/subsystems/blktests-subsystem-1/namespaces/1/device_uuid
+ _set_attr 1 /sys/kernel/config/nvmet/subsystems/blktests-subsystem-1/namespaces/1/enable
++ _set_attr rdma /sys/kernel/config/nvmet/ports/0/addr_trtype
++ _set_attr 10.0.2.15 /sys/kernel/config/nvmet/ports/0/addr_traddr
++ _set_attr ipv4 /sys/kernel/config/nvmet/ports/0/addr_adrfam
++ _set_attr 4420 /sys/kernel/config/nvmet/ports/0/addr_trsvcid
++ nvme connect --traddr 10.0.2.15 --transport rdma --trsvcid 4420 --nqn blktests-subsystem-1 --hostnqn=nqn.2014-08.org.nvmexpress:uuid:0f01fb42-9f7f-4856-b0b3-51e60b8de349 --hostid=0f01fb42-9f7f-4856-b0b3-51e60b8de349 --output-format=json
+ nvme disconnect --nqn blktests-subsystem-1
+ _set_attr 0 /sys/kernel/config/nvmet/subsystems/blktests-subsystem-1/namespaces/1/enable


Changes from v1:
- 2nd patch: added -n option to the echo command
- 2nd and 3rd patches: renamed _echo() to _set_attr()
- Link to v1: https://lore.kernel.org/linux-block/20260513112326.584256-1-shinichiro.kawasaki@wdc.com/

Shin'ichiro Kawasaki (3):
  check: add --cmd-trace option
  common/rc: add _set_attr() function to trace attribute writes
  common/nvme, nvme/rc: use _set_attr() to trace attribute writes

 check         | 17 ++++++++++++++-
 common/nvme   | 34 ++++++++++++++---------------
 common/rc     |  7 ++++++
 tests/nvme/rc | 60 +++++++++++++++++++++++++--------------------------
 4 files changed, 69 insertions(+), 49 deletions(-)

-- 
2.54.0


^ permalink raw reply

* [PATCH blktests v2 1/3] check: add --cmd-trace option
From: Shin'ichiro Kawasaki @ 2026-05-16 12:07 UTC (permalink / raw)
  To: linux-block
  Cc: Daniel Wagner, John Meneghini, Bart Van Assche,
	Shin'ichiro Kawasaki
In-Reply-To: <20260516120729.113659-1-shinichiro.kawasaki@wdc.com>

Test cases that use helper functions can be difficult to understand due
to deep nesting. To make test execution easier to follow, add a new
--cmd-trace (or -t) option to record the commands executed during test
runs.

The trace is implemented using bash's xtrace feature. Enable xtrace with
`set -x` before each test case and redirect the trace output to a
`.cmdtrace` file in the result directory.

Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
---
 check | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

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
 		{ time "$test_func" >"${seqres}.out" 2>&1; } 2>"${seqres}.runtime"
+		if ((CMD_TRACE)); then
+			set +x
+			unset BASH_XTRACEFD
+			exec 8>&-
+		fi
 		TEST_RUN["exit_status"]=$?
 		popd >/dev/null || return
 		TEST_RUN["runtime"]="$(cat "${seqres}.runtime")"
@@ -1157,7 +1167,7 @@ Miscellaneous:
 
 _check_dependencies
 
-if ! TEMP=$(getopt -o 'do:q::x:c:h' --long 'device-only,quick::,exclude:,output:,config:,help' -n "$0" -- "$@"); then
+if ! TEMP=$(getopt -o 'do:q::x:c:th' --long 'device-only,quick::,exclude:,output:,config:,cmd-trace,help' -n "$0" -- "$@"); then
 	exit 1
 fi
 
@@ -1165,6 +1175,7 @@ eval set -- "$TEMP"
 unset TEMP
 
 LOADED_CONFIG=0
+CMD_TRACE=0
 OPTION_EXCLUDE=()
 while true; do
 	case "$1" in
@@ -1192,6 +1203,10 @@ while true; do
 			LOADED_CONFIG=1
 			shift 2
 			;;
+		'-t'|'--cmd-trace')
+			CMD_TRACE=1
+			shift
+			;;
 		'-h'|'--help')
 			usage out
 			;;
-- 
2.54.0


^ permalink raw reply related

* [PATCH blktests v2 2/3] common/rc: add _set_attr() function to trace attribute writes
From: Shin'ichiro Kawasaki @ 2026-05-16 12:07 UTC (permalink / raw)
  To: linux-block
  Cc: Daniel Wagner, John Meneghini, Bart Van Assche,
	Shin'ichiro Kawasaki
In-Reply-To: <20260516120729.113659-1-shinichiro.kawasaki@wdc.com>

Many test cases write to sysfs/configfs/debugfs attributes, and these
writes are important for understanding test behavior. However, bash's
xtrace feature does not record the target attribute file in commands
like `echo X > Y`; it only records `echo X`.

To capture the write target, introduce `_set_attr()`, which writes its
first argument to the file specified by its second argument. This allows
xtrace to record the complete operation (e.g., `_set_attr X Y` instead
of just `echo X`).

Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
---
 common/rc | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/common/rc b/common/rc
index d2c1d74..7dd5898 100644
--- a/common/rc
+++ b/common/rc
@@ -780,3 +780,10 @@ _min() {
 	done
 	echo "$ret"
 }
+
+# Write a value to a sysfs/debugfs/configfs attribute. This wrapper is used to
+# trace sysfs/debugfs/configfs attribute writes when the --cmd-trace option is
+# enabled.
+_set_attr() {
+	echo -n "$1" > "$2"
+}
-- 
2.54.0


^ permalink raw reply related

* [PATCH blktests v2 3/3] common/nvme, nvme/rc: use _set_attr() to trace attribute writes
From: Shin'ichiro Kawasaki @ 2026-05-16 12:07 UTC (permalink / raw)
  To: linux-block
  Cc: Daniel Wagner, John Meneghini, Bart Van Assche,
	Shin'ichiro Kawasaki
In-Reply-To: <20260516120729.113659-1-shinichiro.kawasaki@wdc.com>

The previous commit introduced the helper function _set_attr(). Use it
in common/nvme and tests/nvme/rc to trace sysfs/configfs/debugfs
attribute writes.

Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
---
 common/nvme   | 34 ++++++++++++++---------------
 tests/nvme/rc | 60 +++++++++++++++++++++++++--------------------------
 2 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/common/nvme b/common/nvme
index 565de59..44f2fe6 100644
--- a/common/nvme
+++ b/common/nvme
@@ -570,18 +570,18 @@ _create_nvmet_port() {
 		traddr=$(_fc_traddr $port)
 		adrfam="fc"
 	fi
-	echo "${trtype}" > "${portcfs}/addr_trtype"
-	echo "${traddr}" > "${portcfs}/addr_traddr"
-	echo "${adrfam}" > "${portcfs}/addr_adrfam"
+	_set_attr "${trtype}" "${portcfs}/addr_trtype"
+	_set_attr "${traddr}" "${portcfs}/addr_traddr"
+	_set_attr "${adrfam}" "${portcfs}/addr_adrfam"
 	if [[ "${adrfam}" != "fc" ]] && \
 	   [[ "${adrfam}" != "loop" ]] ; then
-		echo "${trsvcid}" > "${portcfs}/addr_trsvcid"
+		_set_attr "${trsvcid}" "${portcfs}/addr_trsvcid"
 	fi
 	if [[ "${trtype}" == "tcp" ]] && \
 		   [[ "${tls}" != "none" ]]; then
-		echo "tls1.3" > "${portcfs}/addr_tsas"
+		_set_attr "tls1.3" "${portcfs}/addr_tsas"
 		if [[ "${tls}" != "required" ]]; then
-			echo "not required" > "${portcfs}/addr_treq"
+			_set_attr "not required" "${portcfs}/addr_treq"
 		fi
 	fi
 	echo "${port}"
@@ -601,7 +601,7 @@ _setup_nvmet_port_ana() {
 		fi
 		mkdir "${anaport}"
 	fi
-	echo "${anastate}" > "${anaport}/ana_state"
+	_set_attr "${anastate}" "${anaport}/ana_state"
 }
 
 _remove_nvmet_port() {
@@ -722,19 +722,19 @@ _create_nvmet_ns() {
 	subsys_path="${NVMET_CFS}/subsystems/${subsysnqn}"
 	ns_path="${subsys_path}/namespaces/${nsid}"
 	mkdir "${ns_path}"
-	printf "%s" "${blkdev}" > "${ns_path}/device_path"
+	_set_attr "$(printf "%s" "${blkdev}")" "${ns_path}/device_path"
 	if [[ -f "${ns_path}/resv_enable" && "${resv_enable}" = true ]] ; then
-		printf 1 > "${ns_path}/resv_enable"
+		_set_attr 1 "${ns_path}/resv_enable"
 	fi
 	if [[ -n "${uuid}" ]]; then
-		printf "%s" "${uuid}" > "${ns_path}/device_uuid"
+		_set_attr "$(printf "%s" "${uuid}")" "${ns_path}/device_uuid"
 	else
 		uuid=$(cat "${ns_path}/device_uuid")
 	fi
 	if (( grpid != 1 )); then
-		printf "%d" "${grpid}" > "${ns_path}/ana_grpid"
+		_set_attr "$(printf "%d" "${grpid}")" "${ns_path}/ana_grpid"
 	fi
-	printf 1 > "${ns_path}/enable"
+	_set_attr 1 "${ns_path}/enable"
 	echo "${uuid}"
 }
 
@@ -748,7 +748,7 @@ _setup_nvmet_ns_ana() {
 	if [[ ! -d "${ns_path}" ]]; then
 		return
 	fi
-	echo "${anagrpid}" > "${ns_path}/anagrpid"
+	_set_attr "${anagrpid}" "${ns_path}/anagrpid"
 }
 
 _create_nvmet_subsystem() {
@@ -786,7 +786,7 @@ _create_nvmet_subsystem() {
 
 	cfs_path="${NVMET_CFS}/subsystems/${subsystem}"
 	mkdir -p "${cfs_path}"
-	echo 0 > "${cfs_path}/attr_allow_any_host"
+	_set_attr 0 "${cfs_path}/attr_allow_any_host"
 	if [[ -z "${blkdev}" ]]; then
 		return 0
 	fi
@@ -825,10 +825,10 @@ _create_nvmet_host() {
 	mkdir "${host_path}"
 	_add_nvmet_allow_hosts "${nvmet_subsystem}" "${nvmet_hostnqn}"
 	if [[ "${nvmet_hostkey}" ]] ; then
-		echo "${nvmet_hostkey}" > "${host_path}/dhchap_key"
+		_set_attr "${nvmet_hostkey}" "${host_path}/dhchap_key"
 	fi
 	if [[ "${nvmet_ctrlkey}" ]] ; then
-		echo "${nvmet_ctrlkey}" > "${host_path}/dhchap_ctrl_key"
+		_set_attr "${nvmet_ctrlkey}" "${host_path}/dhchap_ctrl_key"
 	fi
 }
 
@@ -838,7 +838,7 @@ _remove_nvmet_ns() {
 	local subsys_path="${NVMET_CFS}/subsystems/${nvmet_subsystem}"
 	local nvmet_ns_path="${subsys_path}/namespaces/${nsid}"
 
-	echo 0 > "${nvmet_ns_path}/enable"
+	_set_attr 0 "${nvmet_ns_path}/enable"
 	rmdir "${nvmet_ns_path}"
 }
 
diff --git a/tests/nvme/rc b/tests/nvme/rc
index a8f80d8..d6496b3 100644
--- a/tests/nvme/rc
+++ b/tests/nvme/rc
@@ -223,12 +223,12 @@ _create_nvmet_passthru() {
 	local passthru_path="${subsys_path}/passthru"
 
 	mkdir -p "${subsys_path}"
-	echo 0 > "${subsys_path}/attr_allow_any_host"
+	_set_attr 0 "${subsys_path}/attr_allow_any_host"
 
 	_test_dev_nvme_ctrl > "${passthru_path}/device_path"
-	echo 1 > "${passthru_path}/enable"
+	_set_attr 1 "${passthru_path}/enable"
 	if [[ -f "${passthru_path}/clear_ids" ]]; then
-		echo 1 > "${passthru_path}/clear_ids"
+		_set_attr 1 "${passthru_path}/clear_ids"
 	fi
 }
 
@@ -237,7 +237,7 @@ _remove_nvmet_passhtru() {
 	local subsys_path="${NVMET_CFS}/subsystems/${nvmet_subsystem}"
 	local passthru_path="${subsys_path}/passthru"
 
-	echo 0 > "${passthru_path}/enable"
+	_set_attr 0 "${passthru_path}/enable"
 	rm -f "${subsys_path}"/allowed_hosts/*
 	rmdir "${subsys_path}"
 }
@@ -247,8 +247,7 @@ _set_nvmet_hostkey() {
 	local nvmet_hostkey="$2"
 	local cfs_path="${NVMET_CFS}/hosts/${nvmet_hostnqn}"
 
-	echo "${nvmet_hostkey}" > \
-	     "${cfs_path}/dhchap_key"
+	_set_attr "${nvmet_hostkey}" "${cfs_path}/dhchap_key"
 }
 
 _set_nvmet_ctrlkey() {
@@ -256,8 +255,7 @@ _set_nvmet_ctrlkey() {
 	local nvmet_ctrlkey="$2"
 	local cfs_path="${NVMET_CFS}/hosts/${nvmet_hostnqn}"
 
-	echo "${nvmet_ctrlkey}" > \
-	     "${cfs_path}/dhchap_ctrl_key"
+	_set_attr "${nvmet_ctrlkey}" "${cfs_path}/dhchap_ctrl_key"
 }
 
 _set_nvmet_hash() {
@@ -265,8 +263,7 @@ _set_nvmet_hash() {
 	local nvmet_hash="$2"
 	local cfs_path="${NVMET_CFS}/hosts/${nvmet_hostnqn}"
 
-	echo "${nvmet_hash}" > \
-	     "${cfs_path}/dhchap_hash"
+	_set_attr "${nvmet_hash}" "${cfs_path}/dhchap_hash"
 }
 
 _set_nvmet_dhgroup() {
@@ -274,8 +271,7 @@ _set_nvmet_dhgroup() {
 	local nvmet_dhgroup="$2"
 	local cfs_path="${NVMET_CFS}/hosts/${nvmet_hostnqn}"
 
-	echo "${nvmet_dhgroup}" > \
-	     "${cfs_path}/dhchap_dhgroup"
+	_set_attr "${nvmet_dhgroup}" "${cfs_path}/dhchap_dhgroup"
 }
 
 _enable_nvmet_ns() {
@@ -285,7 +281,7 @@ _enable_nvmet_ns() {
 	cfs_path="${NVMET_CFS}/subsystems/${subsysnqn}"
 	ns_path="${cfs_path}/namespaces/${nsid}"
 
-	echo 1 > "${ns_path}/enable"
+	_set_attr 1 "${ns_path}/enable"
 }
 
 _disable_nvmet_ns() {
@@ -295,7 +291,7 @@ _disable_nvmet_ns() {
 	cfs_path="${NVMET_CFS}/subsystems/${subsysnqn}"
 	ns_path="${cfs_path}/namespaces/${nsid}"
 
-	echo 0 > "${ns_path}/enable"
+	_set_attr 0 "${ns_path}/enable"
 }
 
 _set_nvmet_ns_uuid() {
@@ -473,8 +469,10 @@ _nvme_passthru_logging_setup()
 
 _nvme_passthru_logging_cleanup()
 {
-	echo "$ctrl_dev_passthru_logging" > /sys/class/nvme/"$2"/passthru_err_log_enabled
-	echo "$ns_dev_passthru_logging" > /sys/class/nvme/"$2"/"$1"/passthru_err_log_enabled
+	_set_attr "$ctrl_dev_passthru_logging" \
+	      /sys/class/nvme/"$2"/passthru_err_log_enabled
+	_set_attr "$ns_dev_passthru_logging" \
+	      /sys/class/nvme/"$2"/"$1"/passthru_err_log_enabled
 }
 
 _nvme_err_inject_setup()
@@ -495,55 +493,55 @@ _nvme_err_inject_cleanup()
         local a
 
         for a in /sys/kernel/debug/"$1"/fault_inject/*; do
-                echo "${NS_DEV_FAULT_INJECT_SAVE[${a}]}" > "${a}"
+                _set_attr "${NS_DEV_FAULT_INJECT_SAVE[${a}]}" "${a}"
         done
 
         for a in /sys/kernel/debug/"$2"/fault_inject/*; do
-                echo "${CTRL_DEV_FAULT_INJECT_SAVE[${a}]}" > "${a}"
+                _set_attr "${CTRL_DEV_FAULT_INJECT_SAVE[${a}]}" "${a}"
         done
 }
 
 _nvme_enable_err_inject()
 {
-        echo "$2" > /sys/kernel/debug/"$1"/fault_inject/verbose
-        echo "$3" > /sys/kernel/debug/"$1"/fault_inject/probability
-        echo "$4" > /sys/kernel/debug/"$1"/fault_inject/dont_retry
-        echo "$5" > /sys/kernel/debug/"$1"/fault_inject/status
-        echo "$6" > /sys/kernel/debug/"$1"/fault_inject/times
+        _set_attr "$2" /sys/kernel/debug/"$1"/fault_inject/verbose
+        _set_attr "$3" /sys/kernel/debug/"$1"/fault_inject/probability
+        _set_attr "$4" /sys/kernel/debug/"$1"/fault_inject/dont_retry
+        _set_attr "$5" /sys/kernel/debug/"$1"/fault_inject/status
+        _set_attr "$6" /sys/kernel/debug/"$1"/fault_inject/times
 }
 
 _nvme_disable_err_inject()
 {
-        echo 0 > /sys/kernel/debug/"$1"/fault_inject/probability
-        echo 0 > /sys/kernel/debug/"$1"/fault_inject/times
+        _set_attr 0 /sys/kernel/debug/"$1"/fault_inject/probability
+        _set_attr 0 /sys/kernel/debug/"$1"/fault_inject/times
 }
 
 _nvme_enable_passthru_admin_error_logging()
 {
-	echo on > /sys/class/nvme/"$1"/passthru_err_log_enabled
+	_set_attr on /sys/class/nvme/"$1"/passthru_err_log_enabled
 }
 
 _nvme_enable_passthru_io_error_logging()
 {
-	echo on > /sys/class/nvme/"$2"/"$1"/passthru_err_log_enabled
+	_set_attr on /sys/class/nvme/"$2"/"$1"/passthru_err_log_enabled
 }
 
 _nvme_disable_passthru_admin_error_logging()
 {
-	echo off > /sys/class/nvme/"$1"/passthru_err_log_enabled
+	_set_attr off /sys/class/nvme/"$1"/passthru_err_log_enabled
 }
 
 _nvme_disable_passthru_io_error_logging()
 {
-	echo off > /sys/class/nvme/"$2"/"$1"/passthru_err_log_enabled
+	_set_attr off /sys/class/nvme/"$2"/"$1"/passthru_err_log_enabled
 }
 
 _nvme_reset_ctrl() {
-	echo 1 > /sys/class/nvme/"$1"/reset_controller
+	_set_attr 1 /sys/class/nvme/"$1"/reset_controller
 }
 
 _nvme_delete_ctrl() {
-	echo 1 > /sys/class/nvme/"$1"/delete_controller
+	_set_attr 1 /sys/class/nvme/"$1"/delete_controller
 }
 
 # Check whether the version of the fio is greater than or equal to $1.$2.$3
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH blktests 2/3] common/rc: add _echo() function to trace sysfs attribute writes
From: Shin'ichiro Kawasaki @ 2026-05-16 12:11 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-block, Daniel Wagner, John Meneghini
In-Reply-To: <58c5d530-416a-4dce-8aa7-099eb571bddc@acm.org>

On May 14, 2026 / 08:58, Bart Van Assche wrote:
> 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, then "echo -n" is more appropriate. I have reflected it to the v2
series.

^ 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-13  9:42 UTC (permalink / raw)
  To: Aaron Tomlin
  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: <20260513005509.135966-6-atomlin@atomlin.com>

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.

^ permalink raw reply

* Re: remove dead code and export
From: Jens Axboe @ 2026-05-16 19:05 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-block
In-Reply-To: <20260515045547.3790129-1-hch@lst.de>


On Fri, 15 May 2026 06:55:29 +0200, Christoph Hellwig wrote:
> this series removes some minor dead code and dead exports in the block code.
> 
> Diffstat:
>  block/bio.c            |   44 ++++++++++++++++++--------------------------
>  block/blk-core.c       |    2 --
>  block/blk.h            |    2 ++
>  include/linux/bio.h    |    9 +--------
>  include/linux/blkdev.h |    1 -
>  5 files changed, 21 insertions(+), 37 deletions(-)
> 
> [...]

Applied, thanks!

[1/5] block: remove zero_fill_bio_iter
      commit: 64cf531f9900c011afe97a28c8ef464d551cec1b
[2/5] block: remove bio_copy_data_iter
      commit: 8d57b5876d39679c81d479485422e88319f17418
[3/5] block: unexport blk_io_schedule
      commit: 9957d5bbb916d37b277bf298e635d29a71205f99
[4/5] block: unexport blk_status_to_str
      commit: 82aaa55a3162acaad10baced6f87126a4454a0d7
[5/5] block: unexport bio_{set,check}_pages_dirty
      commit: be34ec59ef061a1cc435a3e066ad71ca675c7fcd

Best regards,
-- 
Jens Axboe




^ permalink raw reply

* Re: [PATCH RFC 1/2] nvme: downgrade WARN in nvme_setup_rw to pr_debug
From: Chao S @ 2026-05-17  3:53 UTC (permalink / raw)
  To: Keith Busch
  Cc: linux-nvme, linux-block, hch, sagi, axboe, Sungwoo Kim, Dave Tian,
	Weidong Zhu
In-Reply-To: <afzWCpJSqvjnTgpF@kbusch-mbp>

On Thu, May 07, 2026 at 07:12:26PM +0100, Keith Busch wrote:
> [...] how that was defeated [...]

Hi Keith,

Not the freeze.  The WARN does not depend on q->limits, but on
ns->head->ms (read live at dispatch, set inside the freeze window) and
on REQ_INTEGRITY, never set for EXT_LBAS-non-PI.  capacity==0 only
gates submission (bio_check_eod()), not dispatch: a writeback bio that
passed bio_check_eod() under the old capacity sits on the task plug
holding no q_usage_counter ref, so it does not block the freeze;
blk_finish_plug() flushes it after the update committed head->ms != 0
(dmesg: the capacity-change line prints before the WARN).

So it is reachable -- the host-unaware geometry change you described,
unrelated to your block fix.  The deeper fencing gap is the separate
TP-level issue; v2 does not attempt it, it only stops a
device-reachable, already-safely-rejected dispatch from being a WARN
(a panic under panic_on_warn).

Thanks,
Chao

On Thu, May 7, 2026 at 2:12 PM Keith Busch <kbusch@kernel.org> wrote:
>
> On Sun, Apr 26, 2026 at 08:34:56PM -0400, Chao Shi wrote:
> > In both cases the bio was submitted without REQ_INTEGRITY (because
> > blk_get_integrity() returned NULL at dispatch time, so
> > bio_integrity_action() returned 0 and bio_integrity_prep() was not
> > called), and it reaches nvme_setup_rw() for a namespace where
> > head->ms != 0.  The existing BLK_STS_NOTSUPP return correctly handles
> > this dispatch; the WARN_ON_ONCE is a false positive.
>
> This is what I'm not really following. The cached request holds a
> reference on the queue that prevents the queue freeze from proceeding.
> This driver freezes the queue along with the queue limits update. As I
> mentioned in the other patch, that was supposed to ensure the block
> layer had the updated limits before it could allocate a request, so I
> think we need to understand how that was defeated to get to a real
> solution.

^ permalink raw reply

* Re: [PATCH RFC 1/2] nvme: downgrade WARN in nvme_setup_rw to pr_debug
From: Chao S @ 2026-05-17  3:54 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-nvme, linux-block, kbusch, sagi, axboe, Sungwoo Kim,
	Dave Tian, Weidong Zhu
In-Reply-To: <20260507054809.GA19796@lst.de>

On Thu, May 07, 2026 at 07:48:09AM +0200, Christoph Hellwig wrote:
> What is "semantic mutation of Identify Namespace responses" [...]

The emulated controller returns a mutated Identify Namespace on
rescan (flbas META_EXT, lbaf.ms != 0, dps == 0) -- the host-unaware
geometry change Keith described (out-of-band format on a shared
namespace, or a non-compliant device), learned via rescan/AEN, not
the host's own Format NVM.

> [...] rather theoretical case [...]

Agreed v1 was wrong (1/2 hid the signal, 2/2 unrelated; 2/2 dropped).
Not fuzzer-only though: the out-of-band-format path Keith acknowledged
is real, and the branch is reachable from device data, so under
panic_on_warn this is a device-triggerable panic.  The deeper fencing
fix is the bigger TP-level work; v2 does not attempt it -- it only
adds the missing nvme_setup_rw() case for an unusable (metadata, no
PI, no profile) namespace whose I/O is already rejected, replacing the
assertion with one dev_warn_once().  Worth the bigger fix, or leave it
documented?

Thanks,
Chao

On Thu, May 7, 2026 at 1:48 AM Christoph Hellwig <hch@lst.de> wrote:
>
> On Sun, Apr 26, 2026 at 08:34:56PM -0400, Chao Shi wrote:
> > When an NVMe namespace is configured with embedded metadata (flbas bit 4
> > set, NVME_NS_FLBAS_META_EXT) but no Protection Information (dps=0) and
> > no NVME_NS_METADATA_SUPPORTED, nvme_setup_rw() fires WARN_ON_ONCE on
> > any request that reaches it with REQ_INTEGRITY unset.  The WARN was
> > observed repeatedly during NVMe fuzz testing with a FEMU-based fuzzer
> > that performs semantic mutation of Identify Namespace responses.
>
> What is "semantic mutation of Identify Namespace responses" supposed to
> mean?
>
> > In both cases the bio was submitted without REQ_INTEGRITY (because
> > blk_get_integrity() returned NULL at dispatch time, so
> > bio_integrity_action() returned 0 and bio_integrity_prep() was not
> > called), and it reaches nvme_setup_rw() for a namespace where
> > head->ms != 0.  The existing BLK_STS_NOTSUPP return correctly handles
> > this dispatch; the WARN_ON_ONCE is a false positive.
>
> That means we fail to properaly freeze and quiesce the queue over
> updateѕm which has much worse results than just a WARN_ON.  So if we
> care about this rather theoretical case we'll need to fix that.
>

^ permalink raw reply

* [PATCH v2] nvme: don't WARN on I/O to a namespace revalidated to unusable metadata
From: Chao Shi @ 2026-05-17  5:36 UTC (permalink / raw)
  To: linux-nvme
  Cc: linux-block, hch, kbusch, sagi, axboe, iam, daveti, weizhu,
	Chao Shi

nvme_setup_rw() fires WARN_ON_ONCE(!nvme_ns_has_pi(ns->head)) for a
namespace with head->ms != 0 but no PI and no REQ_INTEGRITY.  This
occurs when Identify Namespace reports flbas META_EXT, lbaf[].ms != 0
and dps == 0: on PCIe nvme_configure_metadata() sets EXT_LBAS without
METADATA_SUPPORTED, nvme_init_integrity() registers no profile, and
capacity is forced to 0.  It is the host-unaware geometry change Keith
described -- an out-of-band format on a shared namespace, or a
non-compliant device seen on rescan -- not the host's own Format NVM,
which freezes first.

The freeze in nvme_update_ns_info_block() is not defeated; the WARN
just does not depend on q->limits.  It depends on ns->head->ms (read
live at dispatch, set inside the freeze window) and on REQ_INTEGRITY,
never set for this geometry.  capacity == 0 only gates submission
(bio_check_eod()), not dispatch: a writeback bio that passed
bio_check_eod() under the old capacity sits on the task plug holding
no q_usage_counter reference and is flushed by blk_finish_plug() after
the update committed head->ms != 0 (dmesg confirms: the capacity-change
line prints before the WARN).

The I/O is already rejected correctly (BLK_STS_NOTSUPP, capacity 0).
The assertion fires on a device-reachable, already-handled condition
-- a panic under panic_on_warn -- and its premise does not hold:
metadata without PI or a registrable profile is a legitimate, unusable
state.  Add that explicit case and emit one dev_warn_once() instead.
Fully fencing already-submitted bios over a revalidation is larger,
TP-level work and is out of scope here.

Tested: built on linux-kcov-debug (6.19.0+, KASAN); boot-tested under
FEMU, 4x dd + 500 rescans, no splat; reject path verified by code
inspection.

Found by FuzzNvme (Syzkaller with FEMU fuzzing framework).

Link: https://lore.kernel.org/linux-nvme/20260427003457.1264511-1-coshi036@gmail.com/
Acked-by: Sungwoo Kim <iam@sung-woo.kim>
Acked-by: Dave Tian <daveti@purdue.edu>
Acked-by: Weidong Zhu <weizhu@fiu.edu>
Signed-off-by: Chao Shi <coshi036@gmail.com>
---
v2: drop 2/2 (faking an integrity profile); supersede 1/2 with an
    explicit unusable-metadata case + one dev_warn_once() instead of
    downgrading the WARN; rewrite the log with the requested mechanism.
RFC v1: https://lore.kernel.org/linux-nvme/20260427003457.1264511-1-coshi036@gmail.com/

 drivers/nvme/host/core.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index d1711ef59fb8..32ccb56c4aaf 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1039,8 +1039,23 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,
 		 * namespace capacity to zero to prevent any I/O.
 		 */
 		if (!blk_integrity_rq(req)) {
-			if (WARN_ON_ONCE(!nvme_ns_has_pi(ns->head)))
+			/*
+			 * A namespace with metadata but neither PI nor a block
+			 * layer integrity profile is unusable: nvme_init_integrity()
+			 * registers no profile, blk_get_integrity() is NULL, no bio
+			 * ever gets REQ_INTEGRITY, and the capacity is forced to 0.
+			 * A bio that passed bio_check_eod() under the old capacity
+			 * and was batched on a plug before the namespace revalidated
+			 * can still be dispatched here afterwards.  Reject it; this
+			 * is the expected terminal handling of I/O to a namespace
+			 * that revalidated to an unusable geometry, not a bug.
+			 */
+			if (!nvme_ns_has_pi(ns->head)) {
+				dev_warn_once(ns->ctrl->device,
+					"%s: I/O to namespace with metadata but no usable integrity profile (ms=%u), rejecting\n",
+					ns->disk->disk_name, ns->head->ms);
 				return BLK_STS_NOTSUPP;
+			}
 			control |= NVME_RW_PRINFO_PRACT;
 			nvme_set_ref_tag(ns, cmnd, req);
 		}
-- 
2.43.0


^ 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