Commit e8cd1ff1 authored by Anthony Iliopoulos's avatar Anthony Iliopoulos Committed by Jens Axboe

nvmet: add ns revalidation support

Add support for detecting capacity changes on nvmet blockdev and file
backed namespaces. This allows for emulating and testing online resizing
of nvme devices and filesystems on top.
Signed-off-by: default avatarAnthony Iliopoulos <ailiop@suse.com>
[chaitanya: Fix comments posted on V1]
Signed-off-by: default avatarChaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
[hch: reuse code a bit more]
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 31fdad7b
...@@ -486,6 +486,11 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req) ...@@ -486,6 +486,11 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req)
if (!ns) if (!ns)
goto done; goto done;
if (ns->bdev)
nvmet_bdev_ns_revalidate(ns);
else
nvmet_file_ns_revalidate(ns);
/* /*
* nuse = ncap = nsze isn't always true, but we have no way to find * nuse = ncap = nsze isn't always true, but we have no way to find
* that out from the underlying device. * that out from the underlying device.
......
...@@ -75,6 +75,11 @@ void nvmet_bdev_ns_disable(struct nvmet_ns *ns) ...@@ -75,6 +75,11 @@ void nvmet_bdev_ns_disable(struct nvmet_ns *ns)
} }
} }
void nvmet_bdev_ns_revalidate(struct nvmet_ns *ns)
{
ns->size = i_size_read(ns->bdev->bd_inode);
}
static u16 blk_to_nvme_status(struct nvmet_req *req, blk_status_t blk_sts) static u16 blk_to_nvme_status(struct nvmet_req *req, blk_status_t blk_sts)
{ {
u16 status = NVME_SC_SUCCESS; u16 status = NVME_SC_SUCCESS;
......
...@@ -13,6 +13,18 @@ ...@@ -13,6 +13,18 @@
#define NVMET_MAX_MPOOL_BVEC 16 #define NVMET_MAX_MPOOL_BVEC 16
#define NVMET_MIN_MPOOL_OBJ 16 #define NVMET_MIN_MPOOL_OBJ 16
int nvmet_file_ns_revalidate(struct nvmet_ns *ns)
{
struct kstat stat;
int ret;
ret = vfs_getattr(&ns->file->f_path, &stat, STATX_SIZE,
AT_STATX_FORCE_SYNC);
if (!ret)
ns->size = stat.size;
return ret;
}
void nvmet_file_ns_disable(struct nvmet_ns *ns) void nvmet_file_ns_disable(struct nvmet_ns *ns)
{ {
if (ns->file) { if (ns->file) {
...@@ -30,7 +42,6 @@ void nvmet_file_ns_disable(struct nvmet_ns *ns) ...@@ -30,7 +42,6 @@ void nvmet_file_ns_disable(struct nvmet_ns *ns)
int nvmet_file_ns_enable(struct nvmet_ns *ns) int nvmet_file_ns_enable(struct nvmet_ns *ns)
{ {
int flags = O_RDWR | O_LARGEFILE; int flags = O_RDWR | O_LARGEFILE;
struct kstat stat;
int ret; int ret;
if (!ns->buffered_io) if (!ns->buffered_io)
...@@ -43,12 +54,10 @@ int nvmet_file_ns_enable(struct nvmet_ns *ns) ...@@ -43,12 +54,10 @@ int nvmet_file_ns_enable(struct nvmet_ns *ns)
return PTR_ERR(ns->file); return PTR_ERR(ns->file);
} }
ret = vfs_getattr(&ns->file->f_path, ret = nvmet_file_ns_revalidate(ns);
&stat, STATX_SIZE, AT_STATX_FORCE_SYNC);
if (ret) if (ret)
goto err; goto err;
ns->size = stat.size;
/* /*
* i_blkbits can be greater than the universally accepted upper bound, * i_blkbits can be greater than the universally accepted upper bound,
* so make sure we export a sane namespace lba_shift. * so make sure we export a sane namespace lba_shift.
......
...@@ -498,6 +498,8 @@ void nvmet_file_ns_disable(struct nvmet_ns *ns); ...@@ -498,6 +498,8 @@ void nvmet_file_ns_disable(struct nvmet_ns *ns);
u16 nvmet_bdev_flush(struct nvmet_req *req); u16 nvmet_bdev_flush(struct nvmet_req *req);
u16 nvmet_file_flush(struct nvmet_req *req); u16 nvmet_file_flush(struct nvmet_req *req);
void nvmet_ns_changed(struct nvmet_subsys *subsys, u32 nsid); void nvmet_ns_changed(struct nvmet_subsys *subsys, u32 nsid);
void nvmet_bdev_ns_revalidate(struct nvmet_ns *ns);
int nvmet_file_ns_revalidate(struct nvmet_ns *ns);
static inline u32 nvmet_rw_len(struct nvmet_req *req) static inline u32 nvmet_rw_len(struct nvmet_req *req)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment