aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/nvme/target/fc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-04-28 14:39:37 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2021-04-28 14:39:37 -0700
commitfc0586062816559defb14c947319ef8c4c326fb3 (patch)
tree5ca73bd1fc9de596a11e6d3549fd8fbf6f87dafc /drivers/nvme/target/fc.c
parentMerge tag 'for-5.13/block-2021-04-27' of git://git.kernel.dk/linux-block (diff)
parentMerge branch 'md-next' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md into for-5.13/drivers (diff)
downloadwireguard-linux-fc0586062816559defb14c947319ef8c4c326fb3.tar.xz
wireguard-linux-fc0586062816559defb14c947319ef8c4c326fb3.zip
Merge tag 'for-5.13/drivers-2021-04-27' of git://git.kernel.dk/linux-block
Pull block driver updates from Jens Axboe: - MD changes via Song: - raid5 POWER fix - raid1 failure fix - UAF fix for md cluster - mddev_find_or_alloc() clean up - Fix NULL pointer deref with external bitmap - Performance improvement for raid10 discard requests - Fix missing information of /proc/mdstat - rsxx const qualifier removal (Arnd) - Expose allocated brd pages (Calvin) - rnbd via Gioh Kim: - Change maintainer - Change domain address of maintainers' email - Add polling IO mode and document update - Fix memory leak and some bug detected by static code analysis tools - Code refactoring - Series of floppy cleanups/fixes (Denis) - s390 dasd fixes (Julian) - kerneldoc fixes (Lee) - null_blk double free (Lv) - null_blk virtual boundary addition (Max) - Remove xsysace driver (Michal) - umem driver removal (Davidlohr) - ataflop fixes (Dan) - Revalidate disk removal (Christoph) - Bounce buffer cleanups (Christoph) - Mark lightnvm as deprecated (Christoph) - mtip32xx init cleanups (Shixin) - Various fixes (Tian, Gustavo, Coly, Yang, Zhang, Zhiqiang) * tag 'for-5.13/drivers-2021-04-27' of git://git.kernel.dk/linux-block: (143 commits) async_xor: increase src_offs when dropping destination page drivers/block/null_blk/main: Fix a double free in null_init. md/raid1: properly indicate failure when ending a failed write request md-cluster: fix use-after-free issue when removing rdev nvme: introduce generic per-namespace chardev nvme: cleanup nvme_configure_apst nvme: do not try to reconfigure APST when the controller is not live nvme: add 'kato' sysfs attribute nvme: sanitize KATO setting nvmet: avoid queuing keep-alive timer if it is disabled brd: expose number of allocated pages in debugfs ataflop: fix off by one in ataflop_probe() ataflop: potential out of bounds in do_format() drbd: Fix fall-through warnings for Clang block/rnbd: Use strscpy instead of strlcpy block/rnbd-clt-sysfs: Remove copy buffer overlap in rnbd_clt_get_path_name block/rnbd-clt: Remove max_segment_size block/rnbd-clt: Generate kobject_uevent when the rnbd device state changes block/rnbd-srv: Remove unused arguments of rnbd_srv_rdma_ev Documentation/ABI/rnbd-clt: Add description for nr_poll_queues ...
Diffstat (limited to 'drivers/nvme/target/fc.c')
-rw-r--r--drivers/nvme/target/fc.c78
1 files changed, 47 insertions, 31 deletions
diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c
index d375745fc4ed..19e113240fff 100644
--- a/drivers/nvme/target/fc.c
+++ b/drivers/nvme/target/fc.c
@@ -1021,60 +1021,75 @@ nvmet_fc_free_hostport(struct nvmet_fc_hostport *hostport)
}
static struct nvmet_fc_hostport *
+nvmet_fc_match_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle)
+{
+ struct nvmet_fc_hostport *host;
+
+ lockdep_assert_held(&tgtport->lock);
+
+ list_for_each_entry(host, &tgtport->host_list, host_list) {
+ if (host->hosthandle == hosthandle && !host->invalid) {
+ if (nvmet_fc_hostport_get(host))
+ return (host);
+ }
+ }
+
+ return NULL;
+}
+
+static struct nvmet_fc_hostport *
nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle)
{
- struct nvmet_fc_hostport *newhost, *host, *match = NULL;
+ struct nvmet_fc_hostport *newhost, *match = NULL;
unsigned long flags;
/* if LLDD not implemented, leave as NULL */
if (!hosthandle)
return NULL;
- /* take reference for what will be the newly allocated hostport */
+ /*
+ * take reference for what will be the newly allocated hostport if
+ * we end up using a new allocation
+ */
if (!nvmet_fc_tgtport_get(tgtport))
return ERR_PTR(-EINVAL);
+ spin_lock_irqsave(&tgtport->lock, flags);
+ match = nvmet_fc_match_hostport(tgtport, hosthandle);
+ spin_unlock_irqrestore(&tgtport->lock, flags);
+
+ if (match) {
+ /* no new allocation - release reference */
+ nvmet_fc_tgtport_put(tgtport);
+ return match;
+ }
+
newhost = kzalloc(sizeof(*newhost), GFP_KERNEL);
if (!newhost) {
- spin_lock_irqsave(&tgtport->lock, flags);
- list_for_each_entry(host, &tgtport->host_list, host_list) {
- if (host->hosthandle == hosthandle && !host->invalid) {
- if (nvmet_fc_hostport_get(host)) {
- match = host;
- break;
- }
- }
- }
- spin_unlock_irqrestore(&tgtport->lock, flags);
- /* no allocation - release reference */
+ /* no new allocation - release reference */
nvmet_fc_tgtport_put(tgtport);
- return (match) ? match : ERR_PTR(-ENOMEM);
+ return ERR_PTR(-ENOMEM);
}
- newhost->tgtport = tgtport;
- newhost->hosthandle = hosthandle;
- INIT_LIST_HEAD(&newhost->host_list);
- kref_init(&newhost->ref);
-
spin_lock_irqsave(&tgtport->lock, flags);
- list_for_each_entry(host, &tgtport->host_list, host_list) {
- if (host->hosthandle == hosthandle && !host->invalid) {
- if (nvmet_fc_hostport_get(host)) {
- match = host;
- break;
- }
- }
- }
+ match = nvmet_fc_match_hostport(tgtport, hosthandle);
if (match) {
+ /* new allocation not needed */
kfree(newhost);
- newhost = NULL;
- /* releasing allocation - release reference */
+ newhost = match;
+ /* no new allocation - release reference */
nvmet_fc_tgtport_put(tgtport);
- } else
+ } else {
+ newhost->tgtport = tgtport;
+ newhost->hosthandle = hosthandle;
+ INIT_LIST_HEAD(&newhost->host_list);
+ kref_init(&newhost->ref);
+
list_add_tail(&newhost->host_list, &tgtport->host_list);
+ }
spin_unlock_irqrestore(&tgtport->lock, flags);
- return (match) ? match : newhost;
+ return newhost;
}
static void
@@ -1996,6 +2011,7 @@ nvmet_fc_handle_ls_rqst_work(struct work_struct *work)
*
* @target_port: pointer to the (registered) target port the LS was
* received on.
+ * @hosthandle: pointer to the host specific data, gets stored in iod.
* @lsrsp: pointer to a lsrsp structure to be used to reference
* the exchange corresponding to the LS.
* @lsreqbuf: pointer to the buffer containing the LS Request