[RFC] nvme: set block size during namespace validation
Minwoo Im
minwoo.im.dev at gmail.com
Wed Dec 23 10:01:36 EST 2020
Let's say we have 2 LBA format for 4096B and 512B LBA size for a
NVMe namespace. Assume that current LBA format is 4096B and in case
we convert namespace to 512B and 4096B back again:
nvme format /dev/nvme0n1 --lbaf=1 --force # 512B
nvme format /dev/nvme0n1 --lbaf=0 --force # 4096B
Then we can see the following errors during the BLKRRPART ioctl from
the nvme-cli format subcommand:
[ 10.771740] blk_update_request: operation not supported error, dev nvme0n1, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
[ 10.780262] Buffer I/O error on dev nvme0n1, logical block 0, async page read
...
Also, we can see the Read commands followed by the Format command due
to BLKRRPART ioctl with Number of LBAs to 0xffff which is under-flowed
because the request for the Read commands are coming with 512B.
kworker/0:1H-56 [000] .... 913.456922: nvme_setup_cmd: nvme0: disk=nvme0n1, qid=1, cmdid=216, nsid=1, flags=0x0, meta=0x0, cmd=(nvme_cmd_read slba=0, len=65535, ctrl=0x0, dsmgmt=0, reftag=0)
ksoftirqd/0-9 [000] .Ns. 916.566351: nvme_complete_rq: nvme0: disk=nvme0n1, qid=1, cmdid=216, res=0x0, retries=0, flags=0x0, status=0x4002
Before we have commit 5ff9f19231a0 ("block: simplify
set_init_blocksize"), block size used to be bumped up to the
4K(PAGE_SIZE) in this example and we have not seen these errors. But
with this patch, we have to make sure that bdev->bd_inode->i_blkbits to
make sure that BLKRRPART ioctl pass proper request length based on the
changed logical block size.
Currently, nvme_setup_rw() does not consider under-flow case when it
fills the cmnd->rw.length:
cmnd->rw.length = cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1);
Maybe we can have some statement to prevent under-flow case here, but
this patch set the blocksize to the block layer when validating
namespace where the logical_block_size of request_queue also is set.
Signed-off-by: Minwoo Im <minwoo.im.dev at gmail.com>
---
drivers/nvme/host/core.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index ce1b61519441..6f2e8eb78e00 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2085,6 +2085,8 @@ static void nvme_update_disk_info(struct gendisk *disk,
}
blk_queue_logical_block_size(disk->queue, bs);
+ set_blocksize(disk->part0, bs);
+
/*
* Linux filesystems assume writing a single physical block is
* an atomic operation. Hence limit the physical block size to the
--
2.17.1
More information about the Linux-nvme
mailing list