From: Nilay Shroff <nilay@linux.ibm.com>
To: kbusch@kernel.org, hch@lst.de, sagi@grimberg.me, axboe@kernel.dk,
chaitanyak@nvidia.com
Cc: gjoyce@linux.ibm.com, bvanassche@acm.org, elver@google.com,
linux-nvme@lists.infradead.org,
Nilay Shroff <nilay@linux.ibm.com>
Subject: [PATCH 01/23] nvmet: add context annotation for nvmet_ns::bdev
Date: Mon, 9 Nov 2026 08:58:06 +0530 [thread overview]
Message-ID: <20261109033102.982191-26-nilay@linux.ibm.com> (raw)
In-Reply-To: <20261109033102.982191-25-nilay@linux.ibm.com>
The nvmet_ns::bdev field is protected by nvmet_subsys::lock. Annotate
it with __guarded_by(&subsys->lock) so that the clang context analyzer
can validate accesses to this field.
Some accesses to nvmet_ns::bdev in the I/O hotpath do not require
holding nvmet_subsys::lock, as the namespace reference guarantees that
the namespace remains valid and the field is not modified while I/O is
in flight. However, the clang context analyzer cannot express this
access pattern directly. So introduce nvmet_ns_bdev() as an inline
helper annotated with __context_unsafe() to allow these accesses
without requiring the subsystem lock. Convert the relevant accesses in
the I/O hotpath and other request-processing paths to use this helper.
Additionally, annotate namespace enable, disable, revalidation and
write protect functions with __must_hold() to make their locking
requirements explicit. This includes the block device and P2P memory
namespace operations.
When accessing the same subsystem lock through different expressions,
such as subsys->lock, ctrl->subsys->lock and ns->subsys->lock the clang
context analyzer cannot infer that they refer to the same lock. Use
__assume_ctx_lock() to explicitly assert the corresponding locking
capability at relevant call sites.
Since nvmet_ns_revalidate() requires callers to hold ns->subsys->lock,
acquire req->ns->subsys->lock before invoking it from
nvmet_execute_identify_ns() and nvmet_execute_identify_ns_zns().
Finally, update nvmet_set_feat_write_protect() to acquire
req->ns->subsys->lock instead of subsys->lock. Both expressions refer
to the same lock, but using the former allows the context analyzer to
correctly validate the locking requirement of
nvmet_write_protect_flush_sync().
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/target/admin-cmd.c | 52 ++++++------
drivers/nvme/target/core.c | 27 +++++-
drivers/nvme/target/io-cmd-bdev.c | 22 ++---
drivers/nvme/target/nvmet.h | 136 ++++++++++++++++++------------
drivers/nvme/target/rdma.c | 2 +-
drivers/nvme/target/zns.c | 44 +++++-----
6 files changed, 170 insertions(+), 113 deletions(-)
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index 6732d6d078e3..2d4e21b3ee7d 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -259,15 +259,17 @@ static u16 nvmet_get_smart_log_nsid(struct nvmet_req *req,
return status;
/* we don't have the right data for file backed ns */
- if (!req->ns->bdev)
+ if (!nvmet_ns_bdev(req->ns))
return NVME_SC_SUCCESS;
- host_reads = part_stat_read(req->ns->bdev, ios[READ]);
+ host_reads = part_stat_read(nvmet_ns_bdev(req->ns), ios[READ]);
data_units_read =
- DIV_ROUND_UP(part_stat_read(req->ns->bdev, sectors[READ]), 1000);
- host_writes = part_stat_read(req->ns->bdev, ios[WRITE]);
+ DIV_ROUND_UP(part_stat_read(nvmet_ns_bdev(req->ns),
+ sectors[READ]), 1000);
+ host_writes = part_stat_read(nvmet_ns_bdev(req->ns), ios[WRITE]);
data_units_written =
- DIV_ROUND_UP(part_stat_read(req->ns->bdev, sectors[WRITE]), 1000);
+ DIV_ROUND_UP(part_stat_read(nvmet_ns_bdev(req->ns),
+ sectors[WRITE]), 1000);
put_unaligned_le64(host_reads, &slog->host_reads[0]);
put_unaligned_le64(data_units_read, &slog->data_units_read[0]);
@@ -319,7 +321,7 @@ static void nvmet_execute_get_log_page_rmi(struct nvmet_req *req)
if (status)
goto out;
- if (!req->ns->bdev || !bdev_rot(req->ns->bdev)) {
+ if (!nvmet_ns_bdev(req->ns) || !bdev_rot(nvmet_ns_bdev(req->ns))) {
status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
goto out;
}
@@ -336,7 +338,7 @@ static void nvmet_execute_get_log_page_rmi(struct nvmet_req *req)
}
log->endgid = req->cmd->get_log_page.lsi;
- disk = req->ns->bdev->bd_disk;
+ disk = nvmet_ns_bdev(req->ns)->bd_disk;
if (disk && disk->ia_ranges)
log->numa = cpu_to_le16(disk->ia_ranges->nr_ia_ranges);
else
@@ -537,15 +539,17 @@ static void nvmet_execute_get_log_page_endgrp(struct nvmet_req *req)
goto out;
}
- if (!req->ns->bdev)
+ if (!nvmet_ns_bdev(req->ns))
goto copy;
- host_reads = part_stat_read(req->ns->bdev, ios[READ]);
+ host_reads = part_stat_read(nvmet_ns_bdev(req->ns), ios[READ]);
data_units_read =
- DIV_ROUND_UP(part_stat_read(req->ns->bdev, sectors[READ]), 1000);
- host_writes = part_stat_read(req->ns->bdev, ios[WRITE]);
+ DIV_ROUND_UP(part_stat_read(nvmet_ns_bdev(req->ns),
+ sectors[READ]), 1000);
+ host_writes = part_stat_read(nvmet_ns_bdev(req->ns), ios[WRITE]);
data_units_written =
- DIV_ROUND_UP(part_stat_read(req->ns->bdev, sectors[WRITE]), 1000);
+ DIV_ROUND_UP(part_stat_read(nvmet_ns_bdev(req->ns),
+ sectors[WRITE]), 1000);
put_unaligned_le64(host_reads, &log->hrc[0]);
put_unaligned_le64(data_units_read, &log->dur[0]);
@@ -859,11 +863,10 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req)
goto done;
}
- if (nvmet_ns_revalidate(req->ns)) {
- mutex_lock(&req->ns->subsys->lock);
+ mutex_lock(&req->ns->subsys->lock);
+ if (nvmet_ns_revalidate(req->ns))
nvmet_ns_changed(req->ns->subsys, req->ns->nsid);
- mutex_unlock(&req->ns->subsys->lock);
- }
+ mutex_unlock(&req->ns->subsys->lock);
/*
* nuse = ncap = nsze isn't always true, but we have no way to find
@@ -880,8 +883,8 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req)
break;
}
- if (req->ns->bdev)
- nvmet_bdev_set_limits(req->ns->bdev, id);
+ if (nvmet_ns_bdev(req->ns))
+ nvmet_bdev_set_limits(nvmet_ns_bdev(req->ns), id);
/*
* We just provide a single LBA format that matches what the
@@ -1095,8 +1098,8 @@ static void nvme_execute_identify_ns_nvm(struct nvmet_req *req)
status = NVME_SC_INTERNAL;
goto out;
}
- if (req->ns->bdev)
- nvmet_bdev_set_nvm_limits(req->ns->bdev, id);
+ if (nvmet_ns_bdev(req->ns))
+ nvmet_bdev_set_nvm_limits(nvmet_ns_bdev(req->ns), id);
status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id));
kfree(id);
out:
@@ -1123,14 +1126,14 @@ static void nvmet_execute_id_cs_indep(struct nvmet_req *req)
id->nmic = NVME_NS_NMIC_SHARED;
if (req->ns->readonly)
id->nsattr |= NVME_NS_ATTR_RO;
- if (req->ns->bdev && bdev_rot(req->ns->bdev))
+ if (nvmet_ns_bdev(req->ns) && bdev_rot(nvmet_ns_bdev(req->ns)))
id->nsfeat |= NVME_NS_ROTATIONAL;
/*
* We need flush command to flush the file's metadata,
* so report supporting vwc if backend is file, even
* though buffered_io is disable.
*/
- if (req->ns->bdev && !bdev_write_cache(req->ns->bdev))
+ if (nvmet_ns_bdev(req->ns) && !bdev_write_cache(nvmet_ns_bdev(req->ns)))
id->nsfeat |= NVME_NS_VWC_NOT_PRESENT;
status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id));
@@ -1216,6 +1219,7 @@ static void nvmet_execute_abort(struct nvmet_req *req)
}
static u16 nvmet_write_protect_flush_sync(struct nvmet_req *req)
+ __must_hold(&req->ns->subsys->lock)
{
u16 status;
@@ -1239,7 +1243,7 @@ static u16 nvmet_set_feat_write_protect(struct nvmet_req *req)
if (status)
return status;
- mutex_lock(&subsys->lock);
+ mutex_lock(&req->ns->subsys->lock);
switch (write_protect) {
case NVME_NS_WRITE_PROTECT:
req->ns->readonly = true;
@@ -1257,7 +1261,7 @@ static u16 nvmet_set_feat_write_protect(struct nvmet_req *req)
if (!status)
nvmet_ns_changed(subsys, req->ns->nsid);
- mutex_unlock(&subsys->lock);
+ mutex_unlock(&req->ns->subsys->lock);
return status;
}
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index cc1955bc8c84..c9837263898a 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -484,12 +484,14 @@ void nvmet_put_namespace(struct nvmet_ns *ns)
}
static void nvmet_ns_dev_disable(struct nvmet_ns *ns)
+ __must_hold(&ns->subsys->lock)
{
nvmet_bdev_ns_disable(ns);
nvmet_file_ns_disable(ns);
}
static int nvmet_p2pmem_ns_enable(struct nvmet_ns *ns)
+ __must_hold(&ns->subsys->lock)
{
int ret;
struct pci_dev *p2p_dev;
@@ -535,12 +537,19 @@ static int nvmet_p2pmem_ns_enable(struct nvmet_ns *ns)
static void nvmet_p2pmem_ns_add_p2p(struct nvmet_ctrl *ctrl,
struct nvmet_ns *ns)
+ __must_hold(&ctrl->subsys->lock)
{
struct device *clients[2];
struct pci_dev *p2p_dev;
int ret;
lockdep_assert_held(&ctrl->subsys->lock);
+ /*
+ * Both ctrl->subsys->lock and ns->subsys->lock refers to the same lock.
+ * However there's no way for us to annotate such locking semantics
+ * using clang context annotation. So explicitly assert the capability.
+ */
+ __assume_ctx_lock(&ns->subsys->lock);
if (!ctrl->p2p_client || !ns->use_p2pmem)
return;
@@ -615,8 +624,16 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
if (ret)
goto out_dev_disable;
- list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)
+ list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) {
+ /*
+ * Both subsys->lock and ctrl->subsys->lock refers to the same
+ * lock. However there's no way for us to annotate such locking
+ * semantics using clang context annotation. So explicitly
+ * assert the capability.
+ */
+ __assume_ctx_lock(&ctrl->subsys->lock);
nvmet_p2pmem_ns_add_p2p(ctrl, ns);
+ }
if (ns->pr.enable) {
ret = nvmet_pr_init_ns(ns);
@@ -1576,6 +1593,7 @@ bool nvmet_host_allowed(struct nvmet_subsys *subsys, const char *hostnqn)
static void nvmet_setup_p2p_ns_map(struct nvmet_ctrl *ctrl,
struct device *p2p_client)
+ __must_hold(&ctrl->subsys->lock)
{
struct nvmet_ns *ns;
unsigned long idx;
@@ -1733,6 +1751,13 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args)
if (ret)
goto init_pr_fail;
list_add_tail(&ctrl->subsys_entry, &subsys->ctrls);
+
+ /*
+ * Both subsys->lock and ctrl->subsys->lock refers to the same lock.
+ * However there's no way for us to annotate such locking semantics
+ * using clang context annotation. So explicitly assert the capability.
+ */
+ __assume_ctx_lock(&ctrl->subsys->lock);
nvmet_setup_p2p_ns_map(ctrl, args->p2p_client);
nvmet_debugfs_ctrl_setup(ctrl);
mutex_unlock(&subsys->lock);
diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c
index 72618dced191..7c263cb169a8 100644
--- a/drivers/nvme/target/io-cmd-bdev.c
+++ b/drivers/nvme/target/io-cmd-bdev.c
@@ -73,6 +73,7 @@ void nvmet_bdev_ns_disable(struct nvmet_ns *ns)
}
static void nvmet_bdev_ns_enable_integrity(struct nvmet_ns *ns)
+ __must_hold(&ns->subsys->lock)
{
struct blk_integrity *bi = bdev_get_integrity(ns->bdev);
@@ -206,7 +207,7 @@ static int nvmet_bdev_alloc_bip(struct nvmet_req *req, struct bio *bio,
int rc;
size_t resid, len;
- bi = bdev_get_integrity(req->ns->bdev);
+ bi = bdev_get_integrity(nvmet_ns_bdev(req->ns));
if (unlikely(!bi)) {
pr_err("Unable to locate bio_integrity\n");
return -ENODEV;
@@ -291,11 +292,11 @@ static void nvmet_bdev_execute_rw(struct nvmet_req *req)
if (nvmet_use_inline_bvec(req)) {
bio = &req->b.inline_bio;
- bio_init(bio, req->ns->bdev, req->inline_bvec,
+ bio_init(bio, nvmet_ns_bdev(req->ns), req->inline_bvec,
ARRAY_SIZE(req->inline_bvec), opf);
} else {
- bio = bio_alloc(req->ns->bdev, bio_max_segs(sg_cnt), opf,
- GFP_KERNEL);
+ bio = bio_alloc(nvmet_ns_bdev(req->ns), bio_max_segs(sg_cnt),
+ opf, GFP_KERNEL);
}
bio->bi_iter.bi_sector = sector;
bio->bi_private = req;
@@ -320,8 +321,9 @@ static void nvmet_bdev_execute_rw(struct nvmet_req *req)
}
}
- bio = bio_alloc(req->ns->bdev, bio_max_segs(sg_cnt),
- opf, GFP_KERNEL);
+ bio = bio_alloc(nvmet_ns_bdev(req->ns),
+ bio_max_segs(sg_cnt), opf,
+ GFP_KERNEL);
bio->bi_iter.bi_sector = sector;
bio_chain(bio, prev);
@@ -349,7 +351,7 @@ static void nvmet_bdev_execute_flush(struct nvmet_req *req)
{
struct bio *bio = &req->b.inline_bio;
- if (!bdev_write_cache(req->ns->bdev)) {
+ if (!bdev_write_cache(nvmet_ns_bdev(req->ns))) {
nvmet_req_complete(req, NVME_SC_SUCCESS);
return;
}
@@ -357,7 +359,7 @@ static void nvmet_bdev_execute_flush(struct nvmet_req *req)
if (!nvmet_check_transfer_len(req, 0))
return;
- bio_init(bio, req->ns->bdev, req->inline_bvec,
+ bio_init(bio, nvmet_ns_bdev(req->ns), req->inline_bvec,
ARRAY_SIZE(req->inline_bvec), REQ_OP_WRITE | REQ_PREFLUSH);
bio->bi_private = req;
bio->bi_end_io = nvmet_bio_done;
@@ -392,7 +394,7 @@ static void nvmet_bdev_execute_discard(struct nvmet_req *req)
nr_sects = (sector_t)le32_to_cpu(range.nlb) <<
(ns->blksize_shift - 9);
- __blkdev_issue_discard(ns->bdev,
+ __blkdev_issue_discard(nvmet_ns_bdev(ns),
nvmet_lba_to_sect(ns, range.slba), nr_sects,
GFP_KERNEL, &bio);
}
@@ -442,7 +444,7 @@ static void nvmet_bdev_execute_write_zeroes(struct nvmet_req *req)
nr_sector = (((sector_t)le16_to_cpu(write_zeroes->length) + 1) <<
(req->ns->blksize_shift - 9));
- ret = __blkdev_issue_zeroout(req->ns->bdev, sector, nr_sector,
+ ret = __blkdev_issue_zeroout(nvmet_ns_bdev(req->ns), sector, nr_sector,
GFP_KERNEL, &bio, 0);
if (bio) {
bio->bi_private = req;
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 2c2460ef5e2b..41912877ade3 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -98,10 +98,60 @@ struct nvmet_pr_per_ctrl_ref {
uuid_t hostid;
};
+struct nvmet_subsys {
+ enum nvme_subsys_type type;
+
+ struct mutex lock;
+ struct kref ref;
+
+ struct xarray namespaces;
+ unsigned int nr_namespaces;
+ u32 max_nsid;
+ u16 cntlid_min;
+ u16 cntlid_max;
+
+ struct list_head ctrls;
+
+ struct list_head hosts;
+ bool allow_any_host;
+#ifdef CONFIG_NVME_TARGET_DEBUGFS
+ struct dentry *debugfs_dir;
+#endif
+ u16 max_qid;
+
+ u64 ver;
+ char serial[NVMET_SN_MAX_SIZE];
+ bool subsys_discovered;
+ char *subsysnqn;
+ bool pi_support;
+ bool tbkas;
+
+ struct config_group group;
+
+ struct config_group namespaces_group;
+ struct config_group allowed_hosts_group;
+
+ u16 vendor_id;
+ u16 subsys_vendor_id;
+ char *model_number;
+ u32 ieee_oui;
+ char *firmware_rev;
+
+#ifdef CONFIG_NVME_TARGET_PASSTHRU
+ struct nvmet_passthru *passthru;
+ struct config_group passthru_group;
+#endif /* CONFIG_NVME_TARGET_PASSTHRU */
+
+#ifdef CONFIG_BLK_DEV_ZONED
+ u8 zasl;
+#endif /* CONFIG_BLK_DEV_ZONED */
+};
+
struct nvmet_ns {
struct percpu_ref ref;
struct file *bdev_file;
- struct block_device *bdev;
+ struct block_device *bdev
+ __guarded_by(&subsys->lock);
struct file *file;
bool readonly;
u32 nsid;
@@ -136,12 +186,29 @@ struct nvmet_ns {
#endif
};
+/*
+ * The accessors generated by this macro are annotated with __context_unsafe()
+ * because they are intended for use in I/O hotpaths and request-processing
+ * paths where a namespace reference is held. These paths access namespace
+ * fields that are guaranteed not to change while the reference is held and the
+ * I/O or request processing is in progress.
+ */
+#define NVMET_NS_ACCESSOR(_type, _name) \
+static inline _type nvmet_ns_##_name(struct nvmet_ns *ns) \
+ __context_unsafe(/* access _name after getting ns reference */) \
+{ \
+ return ns->_name; \
+}
+
+NVMET_NS_ACCESSOR(struct block_device *, bdev)
+
static inline struct nvmet_ns *to_nvmet_ns(struct config_item *item)
{
return container_of(to_config_group(item), struct nvmet_ns, group);
}
static inline struct device *nvmet_ns_dev(struct nvmet_ns *ns)
+ __must_hold(&ns->subsys->lock)
{
return ns->bdev ? disk_to_dev(ns->bdev->bd_disk) : NULL;
}
@@ -336,55 +403,6 @@ struct nvmet_passthru {
unsigned int clear_ids;
};
-struct nvmet_subsys {
- enum nvme_subsys_type type;
-
- struct mutex lock;
- struct kref ref;
-
- struct xarray namespaces;
- unsigned int nr_namespaces;
- u32 max_nsid;
- u16 cntlid_min;
- u16 cntlid_max;
-
- struct list_head ctrls;
-
- struct list_head hosts;
- bool allow_any_host;
-#ifdef CONFIG_NVME_TARGET_DEBUGFS
- struct dentry *debugfs_dir;
-#endif
- u16 max_qid;
-
- u64 ver;
- char serial[NVMET_SN_MAX_SIZE];
- bool subsys_discovered;
- char *subsysnqn;
- bool pi_support;
- bool tbkas;
-
- struct config_group group;
-
- struct config_group namespaces_group;
- struct config_group allowed_hosts_group;
-
- u16 vendor_id;
- u16 subsys_vendor_id;
- char *model_number;
- u32 ieee_oui;
- char *firmware_rev;
-
-#ifdef CONFIG_NVME_TARGET_PASSTHRU
- struct nvmet_passthru *passthru;
- struct config_group passthru_group;
-#endif /* CONFIG_NVME_TARGET_PASSTHRU */
-
-#ifdef CONFIG_BLK_DEV_ZONED
- u8 zasl;
-#endif /* CONFIG_BLK_DEV_ZONED */
-};
-
static inline struct nvmet_subsys *to_subsys(struct config_item *item)
{
return container_of(to_config_group(item), struct nvmet_subsys, group);
@@ -737,19 +755,25 @@ extern struct rw_semaphore nvmet_ana_sem;
bool nvmet_host_allowed(struct nvmet_subsys *subsys, const char *hostnqn);
-int nvmet_bdev_ns_enable(struct nvmet_ns *ns);
+int nvmet_bdev_ns_enable(struct nvmet_ns *ns)
+ __must_hold(&ns->subsys->lock);
int nvmet_file_ns_enable(struct nvmet_ns *ns);
-void nvmet_bdev_ns_disable(struct nvmet_ns *ns);
+void nvmet_bdev_ns_disable(struct nvmet_ns *ns)
+ __must_hold(&ns->subsys->lock);
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)
+ __must_hold(&req->ns->subsys->lock);
u16 nvmet_file_flush(struct nvmet_req *req);
void nvmet_ns_changed(struct nvmet_subsys *subsys, u32 nsid);
-void nvmet_bdev_ns_revalidate(struct nvmet_ns *ns);
+void nvmet_bdev_ns_revalidate(struct nvmet_ns *ns)
+ __must_hold(&ns->subsys->lock);
void nvmet_file_ns_revalidate(struct nvmet_ns *ns);
-bool nvmet_ns_revalidate(struct nvmet_ns *ns);
+bool nvmet_ns_revalidate(struct nvmet_ns *ns)
+ __must_hold(&ns->subsys->lock);
u16 blk_to_nvme_status(struct nvmet_req *req, blk_status_t blk_sts);
-bool nvmet_bdev_zns_enable(struct nvmet_ns *ns);
+bool nvmet_bdev_zns_enable(struct nvmet_ns *ns)
+ __must_hold(&ns->subsys->lock);
void nvmet_execute_identify_ctrl_zns(struct nvmet_req *req);
void nvmet_execute_identify_ns_zns(struct nvmet_req *req);
void nvmet_bdev_execute_zone_mgmt_recv(struct nvmet_req *req);
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index f386c388da18..0b351d39340c 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -594,7 +594,7 @@ static void nvmet_rdma_set_sig_attrs(struct nvmet_req *req,
u8 pi_type = req->ns->pi_type;
struct blk_integrity *bi;
- bi = bdev_get_integrity(req->ns->bdev);
+ bi = bdev_get_integrity(nvmet_ns_bdev(req->ns));
memset(sig_attrs, 0, sizeof(*sig_attrs));
diff --git a/drivers/nvme/target/zns.c b/drivers/nvme/target/zns.c
index cea05b4bc740..ce5309453668 100644
--- a/drivers/nvme/target/zns.c
+++ b/drivers/nvme/target/zns.c
@@ -110,30 +110,29 @@ void nvmet_execute_identify_ns_zns(struct nvmet_req *req)
if (status)
goto out;
- if (nvmet_ns_revalidate(req->ns)) {
- mutex_lock(&req->ns->subsys->lock);
+ mutex_lock(&req->ns->subsys->lock);
+ if (nvmet_ns_revalidate(req->ns))
nvmet_ns_changed(req->ns->subsys, req->ns->nsid);
- mutex_unlock(&req->ns->subsys->lock);
- }
+ mutex_unlock(&req->ns->subsys->lock);
- if (!req->ns->bdev || !bdev_is_zoned(req->ns->bdev)) {
+ if (!nvmet_ns_bdev(req->ns) || !bdev_is_zoned(nvmet_ns_bdev(req->ns))) {
status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
req->error_loc = offsetof(struct nvme_identify, nsid);
goto out;
}
- zsze = (bdev_zone_sectors(req->ns->bdev) << 9) >>
+ zsze = (bdev_zone_sectors(nvmet_ns_bdev(req->ns)) << 9) >>
req->ns->blksize_shift;
id_zns->lbafe[0].zsze = cpu_to_le64(zsze);
- mor = bdev_max_open_zones(req->ns->bdev);
+ mor = bdev_max_open_zones(nvmet_ns_bdev(req->ns));
if (!mor)
mor = U32_MAX;
else
mor--;
id_zns->mor = cpu_to_le32(mor);
- mar = bdev_max_active_zones(req->ns->bdev);
+ mar = bdev_max_active_zones(nvmet_ns_bdev(req->ns));
if (!mar)
mar = U32_MAX;
else
@@ -151,7 +150,7 @@ static u16 nvmet_bdev_validate_zone_mgmt_recv(struct nvmet_req *req)
sector_t sect = nvmet_lba_to_sect(req->ns, req->cmd->zmr.slba);
u32 out_bufsize = (le32_to_cpu(req->cmd->zmr.numd) + 1) << 2;
- if (sect >= get_capacity(req->ns->bdev->bd_disk)) {
+ if (sect >= get_capacity(nvmet_ns_bdev(req->ns)->bd_disk)) {
req->error_loc = offsetof(struct nvme_zone_mgmt_recv_cmd, slba);
return NVME_SC_LBA_RANGE | NVME_STATUS_DNR;
}
@@ -247,7 +246,8 @@ static unsigned long nvmet_req_nr_zones_from_slba(struct nvmet_req *req)
{
unsigned int sect = nvmet_lba_to_sect(req->ns, req->cmd->zmr.slba);
- return bdev_nr_zones(req->ns->bdev) - bdev_zone_no(req->ns->bdev, sect);
+ return bdev_nr_zones(nvmet_ns_bdev(req->ns)) -
+ bdev_zone_no(nvmet_ns_bdev(req->ns), sect);
}
static unsigned long get_nr_zones_from_buf(struct nvmet_req *req, u32 bufsize)
@@ -291,8 +291,8 @@ static void nvmet_bdev_zone_zmgmt_recv_work(struct work_struct *w)
goto out;
}
- ret = blkdev_report_zones(req->ns->bdev, start_sect, req_slba_nr_zones,
- nvmet_bdev_report_zone_cb, &rz_data);
+ ret = blkdev_report_zones(nvmet_ns_bdev(req->ns), start_sect,
+ req_slba_nr_zones, nvmet_bdev_report_zone_cb, &rz_data);
if (ret < 0) {
status = NVME_SC_INTERNAL;
goto out;
@@ -415,7 +415,7 @@ static int zmgmt_send_scan_cb(struct blk_zone *z, unsigned i, void *d)
static u16 nvmet_bdev_zone_mgmt_emulate_all(struct nvmet_req *req)
{
- struct block_device *bdev = req->ns->bdev;
+ struct block_device *bdev = nvmet_ns_bdev(req->ns);
unsigned int nr_zones = bdev_nr_zones(bdev);
struct bio *bio = NULL;
sector_t sector = 0;
@@ -471,8 +471,9 @@ static u16 nvmet_bdev_execute_zmgmt_send_all(struct nvmet_req *req)
switch (zsa_req_op(req->cmd->zms.zsa)) {
case REQ_OP_ZONE_RESET:
- ret = blkdev_zone_mgmt(req->ns->bdev, REQ_OP_ZONE_RESET, 0,
- get_capacity(req->ns->bdev->bd_disk));
+ ret = blkdev_zone_mgmt(nvmet_ns_bdev(req->ns),
+ REQ_OP_ZONE_RESET, 0,
+ get_capacity(nvmet_ns_bdev(req->ns)->bd_disk));
if (ret < 0)
return blkdev_zone_mgmt_errno_to_nvme_status(ret);
break;
@@ -494,7 +495,7 @@ static void nvmet_bdev_zmgmt_send_work(struct work_struct *w)
struct nvmet_req *req = container_of(w, struct nvmet_req, z.zmgmt_work);
sector_t sect = nvmet_lba_to_sect(req->ns, req->cmd->zms.slba);
enum req_op op = zsa_req_op(req->cmd->zms.zsa);
- struct block_device *bdev = req->ns->bdev;
+ struct block_device *bdev = nvmet_ns_bdev(req->ns);
sector_t zone_sectors = bdev_zone_sectors(bdev);
u16 status = NVME_SC_SUCCESS;
int ret;
@@ -560,13 +561,14 @@ void nvmet_bdev_execute_zone_append(struct nvmet_req *req)
u32 data_len = nvmet_rw_data_len(req);
struct bio *bio;
int sg_cnt;
+ struct block_device *bdev = nvmet_ns_bdev(req->ns);
/* Request is completed on len mismatch in nvmet_check_transfer_len() */
if (!nvmet_check_transfer_len(req, nvmet_rw_data_len(req)))
return;
if (data_len >
- bdev_max_zone_append_sectors(req->ns->bdev) << SECTOR_SHIFT) {
+ bdev_max_zone_append_sectors(bdev) << SECTOR_SHIFT) {
req->error_loc = offsetof(struct nvme_rw_command, length);
status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
goto out;
@@ -577,13 +579,13 @@ void nvmet_bdev_execute_zone_append(struct nvmet_req *req)
return;
}
- if (sect >= get_capacity(req->ns->bdev->bd_disk)) {
+ if (sect >= get_capacity(bdev->bd_disk)) {
req->error_loc = offsetof(struct nvme_rw_command, slba);
status = NVME_SC_LBA_RANGE | NVME_STATUS_DNR;
goto out;
}
- if (sect & (bdev_zone_sectors(req->ns->bdev) - 1)) {
+ if (sect & (bdev_zone_sectors(bdev) - 1)) {
req->error_loc = offsetof(struct nvme_rw_command, slba);
status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
goto out;
@@ -591,10 +593,10 @@ void nvmet_bdev_execute_zone_append(struct nvmet_req *req)
if (nvmet_use_inline_bvec(req)) {
bio = &req->z.inline_bio;
- bio_init(bio, req->ns->bdev, req->inline_bvec,
+ bio_init(bio, bdev, req->inline_bvec,
ARRAY_SIZE(req->inline_bvec), opf);
} else {
- bio = bio_alloc(req->ns->bdev, req->sg_cnt, opf, GFP_KERNEL);
+ bio = bio_alloc(bdev, req->sg_cnt, opf, GFP_KERNEL);
}
bio->bi_end_io = nvmet_bdev_zone_append_bio_done;
--
2.53.0
next prev parent reply other threads:[~2026-11-09 3:31 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 3:28 [PATCH 00/23] nvmet: add context annotation for params in struct nvmet_ns Nilay Shroff
2026-11-09 3:28 ` Nilay Shroff [this message]
2026-11-09 20:09 ` [PATCH 01/23] nvmet: add context annotation for nvmet_ns::bdev sashiko-bot
2026-11-09 21:46 ` Bart Van Assche
2026-11-10 6:38 ` Nilay Shroff
2026-11-10 17:29 ` Bart Van Assche
2026-11-11 7:25 ` Nilay Shroff
2026-11-11 18:00 ` Bart Van Assche
2026-11-12 9:04 ` Nilay Shroff
2026-11-09 3:28 ` [PATCH 02/23] nvmet: fix nvmet_ns::bdev access using nvmet_subsys::lock Nilay Shroff
2026-11-09 20:15 ` sashiko-bot
2026-11-09 21:47 ` Bart Van Assche
2026-11-10 6:49 ` Nilay Shroff
2026-11-09 3:28 ` [PATCH 03/23] nvmet: add context annotation for nvmet_ns::file Nilay Shroff
2026-11-09 20:20 ` sashiko-bot
2026-11-09 21:53 ` Bart Van Assche
2026-11-10 7:12 ` Nilay Shroff
2026-11-09 3:28 ` [PATCH 04/23] nvmet: add context annotation for nvmet_ns::bdev_file Nilay Shroff
2026-11-09 3:28 ` [PATCH 05/23] nvmet: add context annotation for nvmet_ns::readonly Nilay Shroff
2026-11-09 3:28 ` [PATCH 06/23] nvmet: add context annotation for nvmet_ns::nsid Nilay Shroff
2026-11-09 21:56 ` Bart Van Assche
2026-11-10 8:50 ` Nilay Shroff
2026-11-09 3:28 ` [PATCH 07/23] nvmet: fix nvmet_ns::nsid access using nvmet_subsys::lock Nilay Shroff
2026-11-09 3:28 ` [PATCH 08/23] nvmet: add context annotation for nvmet_ns::blksize_shift Nilay Shroff
2026-11-09 3:28 ` [PATCH 09/23] nvmet: add context annotation for nvmet_ns::size Nilay Shroff
2026-11-09 3:28 ` [PATCH 10/23] nvmet: add context annotation for nvmet_ns::nguid Nilay Shroff
2026-11-09 3:28 ` [PATCH 11/23] nvmet: add context annotation for nvmet_ns::uuid Nilay Shroff
2026-11-09 21:58 ` Bart Van Assche
2026-11-10 9:01 ` Nilay Shroff
2026-11-09 3:28 ` [PATCH 12/23] nvmet: fix nvmet_ns::uuid access using nvmet_subsys::lock Nilay Shroff
2026-11-09 3:28 ` [PATCH 13/23] nvmet: add context annotation for nvmet_ns::buffered_io Nilay Shroff
2026-11-09 3:28 ` [PATCH 14/23] nvmet: fix nvmet_ns::buffered_io access using nvmet_subsys::lock Nilay Shroff
2026-11-09 3:28 ` [PATCH 15/23] nvmet: add context annotation for nvmet_ns::enabled Nilay Shroff
2026-11-09 3:28 ` [PATCH 16/23] nvmet: fix access to nvmet_ns::enable using nvmet_subsys::lock Nilay Shroff
2026-11-09 3:28 ` [PATCH 17/23] nvmet: add context annotation for nvmet_ns::device_path Nilay Shroff
2026-11-09 3:28 ` [PATCH 18/23] nvmet: fix nvmet_ns::device_path access using nvmet_subsys::lock Nilay Shroff
2026-11-09 21:57 ` sashiko-bot
2026-11-09 3:28 ` [PATCH 19/23] nvmet: add context annotation for PCI P2P parameters in struct nvmet_ns Nilay Shroff
2026-11-09 3:28 ` [PATCH 20/23] nvmet: fix PCI P2P parameters access using nvmet_subsys::lock Nilay Shroff
2026-11-09 22:12 ` sashiko-bot
2026-11-09 3:28 ` [PATCH 21/23] nvmet: add context annotation for integrity params in struct nvmet_ns Nilay Shroff
2026-11-09 3:28 ` [PATCH 22/23] nvmet: add context annotation for nvmet_ns::csi Nilay Shroff
2026-11-09 3:28 ` [PATCH 23/23] nvmet: add context annotation for nvmet_ns::debugfs_dir Nilay Shroff
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261109033102.982191-26-nilay@linux.ibm.com \
--to=nilay@linux.ibm.com \
--cc=axboe@kernel.dk \
--cc=bvanassche@acm.org \
--cc=chaitanyak@nvidia.com \
--cc=elver@google.com \
--cc=gjoyce@linux.ibm.com \
--cc=hch@lst.de \
--cc=kbusch@kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=sagi@grimberg.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox