[PATCH 3/3] nvmet: allow bdev in buffered_io mode

Chaitanya Kulkarni chaitanyak at nvidia.com
Tue Jan 18 23:20:38 PST 2022


From: Chaitanya Kulkarni <kch at nvidia.com>

Allow block device to be configured in the buffered I/O mode by using
the file backend. In this way now we can use cache for the block
device namespace which shows significant performance improvement.

We update the block device ns enable function and return early when
buffered_io flag is set, when revalidating the file backed namespace
open block device handle and consider block device size, use
previously exported block device API to set the namespace size and
blksize_shift value, and call nvmet_bdev_ns_disable() when disabling
file backed namespace. 

Signed-off-by: Chaitanya Kulkarni <kch at nvidia.com>
---
 drivers/nvme/target/io-cmd-bdev.c |  8 ++++++++
 drivers/nvme/target/io-cmd-file.c | 17 ++++++++++++++++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c
index 58907304587e..5e5eb49a0255 100644
--- a/drivers/nvme/target/io-cmd-bdev.c
+++ b/drivers/nvme/target/io-cmd-bdev.c
@@ -96,6 +96,14 @@ int nvmet_bdev_ns_enable(struct nvmet_ns *ns)
 {
 	int ret;
 
+	/*
+	 * When buffered_io namespace attribute is enabled that means user want
+	 * this block device to be used as a file, so block device can take
+	 * an advantage of cache.
+	 */
+	if (ns->buffered_io)
+		return -ENOTBLK;
+
 	ret = nvmet_bdev_ns_open(ns);
 	if (ret)
 		return ret;
diff --git a/drivers/nvme/target/io-cmd-file.c b/drivers/nvme/target/io-cmd-file.c
index 7aa4cdcb80ce..067c45b23bba 100644
--- a/drivers/nvme/target/io-cmd-file.c
+++ b/drivers/nvme/target/io-cmd-file.c
@@ -22,12 +22,25 @@ int nvmet_file_ns_revalidate(struct nvmet_ns *ns)
 	ret = vfs_getattr(&ns->file->f_path, &stat, STATX_SIZE,
 			  AT_STATX_FORCE_SYNC);
 	if (!ret)
-		ns->size = stat.size;
+		ns->size = ns->bdev ? bdev_nr_bytes(ns->bdev) : stat.size;
+
 	return ret;
 }
 
 static int nvmet_file_ns_set_blkshift(struct nvmet_ns *ns)
 {
+	struct kstat stat;
+	int ret;
+
+	ret = vfs_getattr(&ns->file->f_path, &stat, STATX_MODE,
+			  AT_STATX_FORCE_SYNC);
+	if (ret)
+		return ret;
+
+	/* nvmet_bdev_ns_open() sets size & blksize_shift values for ns->bdev */
+	if (S_ISBLK(stat.mode) && ns->buffered_io)
+		return nvmet_bdev_ns_open(ns);
+
 	/*
 	 * i_blkbits can be greater than the universally accepted upper bound,
 	 * so make sure we export a sane namespace lba_shift.
@@ -45,6 +58,8 @@ void nvmet_file_ns_disable(struct nvmet_ns *ns)
 		ns->bvec_pool = NULL;
 		kmem_cache_destroy(ns->bvec_cache);
 		ns->bvec_cache = NULL;
+		/* if block device is configured with buffered_io */
+		nvmet_bdev_ns_disable(ns);
 		fput(ns->file);
 		ns->file = NULL;
 	}
-- 
2.29.0




More information about the Linux-nvme mailing list