|
@@ -224,8 +224,6 @@ struct fcloop_nport {
|
|
struct fcloop_lport *lport;
|
|
struct fcloop_lport *lport;
|
|
struct list_head nport_list;
|
|
struct list_head nport_list;
|
|
struct kref ref;
|
|
struct kref ref;
|
|
- struct completion rport_unreg_done;
|
|
|
|
- struct completion tport_unreg_done;
|
|
|
|
u64 node_name;
|
|
u64 node_name;
|
|
u64 port_name;
|
|
u64 port_name;
|
|
u32 port_role;
|
|
u32 port_role;
|
|
@@ -576,7 +574,7 @@ fcloop_tgt_fcp_abort(struct nvmet_fc_target_port *tgtport,
|
|
tfcp_req->aborted = true;
|
|
tfcp_req->aborted = true;
|
|
spin_unlock(&tfcp_req->reqlock);
|
|
spin_unlock(&tfcp_req->reqlock);
|
|
|
|
|
|
- tfcp_req->status = NVME_SC_FC_TRANSPORT_ABORTED;
|
|
|
|
|
|
+ tfcp_req->status = NVME_SC_INTERNAL;
|
|
|
|
|
|
/*
|
|
/*
|
|
* nothing more to do. If io wasn't active, the transport should
|
|
* nothing more to do. If io wasn't active, the transport should
|
|
@@ -630,6 +628,32 @@ fcloop_fcp_abort(struct nvme_fc_local_port *localport,
|
|
schedule_work(&inireq->iniwork);
|
|
schedule_work(&inireq->iniwork);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void
|
|
|
|
+fcloop_nport_free(struct kref *ref)
|
|
|
|
+{
|
|
|
|
+ struct fcloop_nport *nport =
|
|
|
|
+ container_of(ref, struct fcloop_nport, ref);
|
|
|
|
+ unsigned long flags;
|
|
|
|
+
|
|
|
|
+ spin_lock_irqsave(&fcloop_lock, flags);
|
|
|
|
+ list_del(&nport->nport_list);
|
|
|
|
+ spin_unlock_irqrestore(&fcloop_lock, flags);
|
|
|
|
+
|
|
|
|
+ kfree(nport);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void
|
|
|
|
+fcloop_nport_put(struct fcloop_nport *nport)
|
|
|
|
+{
|
|
|
|
+ kref_put(&nport->ref, fcloop_nport_free);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int
|
|
|
|
+fcloop_nport_get(struct fcloop_nport *nport)
|
|
|
|
+{
|
|
|
|
+ return kref_get_unless_zero(&nport->ref);
|
|
|
|
+}
|
|
|
|
+
|
|
static void
|
|
static void
|
|
fcloop_localport_delete(struct nvme_fc_local_port *localport)
|
|
fcloop_localport_delete(struct nvme_fc_local_port *localport)
|
|
{
|
|
{
|
|
@@ -644,8 +668,7 @@ fcloop_remoteport_delete(struct nvme_fc_remote_port *remoteport)
|
|
{
|
|
{
|
|
struct fcloop_rport *rport = remoteport->private;
|
|
struct fcloop_rport *rport = remoteport->private;
|
|
|
|
|
|
- /* release any threads waiting for the unreg to complete */
|
|
|
|
- complete(&rport->nport->rport_unreg_done);
|
|
|
|
|
|
+ fcloop_nport_put(rport->nport);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
static void
|
|
@@ -653,8 +676,7 @@ fcloop_targetport_delete(struct nvmet_fc_target_port *targetport)
|
|
{
|
|
{
|
|
struct fcloop_tport *tport = targetport->private;
|
|
struct fcloop_tport *tport = targetport->private;
|
|
|
|
|
|
- /* release any threads waiting for the unreg to complete */
|
|
|
|
- complete(&tport->nport->tport_unreg_done);
|
|
|
|
|
|
+ fcloop_nport_put(tport->nport);
|
|
}
|
|
}
|
|
|
|
|
|
#define FCLOOP_HW_QUEUES 4
|
|
#define FCLOOP_HW_QUEUES 4
|
|
@@ -722,6 +744,7 @@ fcloop_create_local_port(struct device *dev, struct device_attribute *attr,
|
|
goto out_free_opts;
|
|
goto out_free_opts;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ memset(&pinfo, 0, sizeof(pinfo));
|
|
pinfo.node_name = opts->wwnn;
|
|
pinfo.node_name = opts->wwnn;
|
|
pinfo.port_name = opts->wwpn;
|
|
pinfo.port_name = opts->wwpn;
|
|
pinfo.port_role = opts->roles;
|
|
pinfo.port_role = opts->roles;
|
|
@@ -804,32 +827,6 @@ fcloop_delete_local_port(struct device *dev, struct device_attribute *attr,
|
|
return ret ? ret : count;
|
|
return ret ? ret : count;
|
|
}
|
|
}
|
|
|
|
|
|
-static void
|
|
|
|
-fcloop_nport_free(struct kref *ref)
|
|
|
|
-{
|
|
|
|
- struct fcloop_nport *nport =
|
|
|
|
- container_of(ref, struct fcloop_nport, ref);
|
|
|
|
- unsigned long flags;
|
|
|
|
-
|
|
|
|
- spin_lock_irqsave(&fcloop_lock, flags);
|
|
|
|
- list_del(&nport->nport_list);
|
|
|
|
- spin_unlock_irqrestore(&fcloop_lock, flags);
|
|
|
|
-
|
|
|
|
- kfree(nport);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void
|
|
|
|
-fcloop_nport_put(struct fcloop_nport *nport)
|
|
|
|
-{
|
|
|
|
- kref_put(&nport->ref, fcloop_nport_free);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int
|
|
|
|
-fcloop_nport_get(struct fcloop_nport *nport)
|
|
|
|
-{
|
|
|
|
- return kref_get_unless_zero(&nport->ref);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static struct fcloop_nport *
|
|
static struct fcloop_nport *
|
|
fcloop_alloc_nport(const char *buf, size_t count, bool remoteport)
|
|
fcloop_alloc_nport(const char *buf, size_t count, bool remoteport)
|
|
{
|
|
{
|
|
@@ -938,6 +935,7 @@ fcloop_create_remote_port(struct device *dev, struct device_attribute *attr,
|
|
if (!nport)
|
|
if (!nport)
|
|
return -EIO;
|
|
return -EIO;
|
|
|
|
|
|
|
|
+ memset(&pinfo, 0, sizeof(pinfo));
|
|
pinfo.node_name = nport->node_name;
|
|
pinfo.node_name = nport->node_name;
|
|
pinfo.port_name = nport->port_name;
|
|
pinfo.port_name = nport->port_name;
|
|
pinfo.port_role = nport->port_role;
|
|
pinfo.port_role = nport->port_role;
|
|
@@ -979,24 +977,12 @@ __unlink_remote_port(struct fcloop_nport *nport)
|
|
}
|
|
}
|
|
|
|
|
|
static int
|
|
static int
|
|
-__wait_remoteport_unreg(struct fcloop_nport *nport, struct fcloop_rport *rport)
|
|
|
|
|
|
+__remoteport_unreg(struct fcloop_nport *nport, struct fcloop_rport *rport)
|
|
{
|
|
{
|
|
- int ret;
|
|
|
|
-
|
|
|
|
if (!rport)
|
|
if (!rport)
|
|
return -EALREADY;
|
|
return -EALREADY;
|
|
|
|
|
|
- init_completion(&nport->rport_unreg_done);
|
|
|
|
-
|
|
|
|
- ret = nvme_fc_unregister_remoteport(rport->remoteport);
|
|
|
|
- if (ret)
|
|
|
|
- return ret;
|
|
|
|
-
|
|
|
|
- wait_for_completion(&nport->rport_unreg_done);
|
|
|
|
-
|
|
|
|
- fcloop_nport_put(nport);
|
|
|
|
-
|
|
|
|
- return ret;
|
|
|
|
|
|
+ return nvme_fc_unregister_remoteport(rport->remoteport);
|
|
}
|
|
}
|
|
|
|
|
|
static ssize_t
|
|
static ssize_t
|
|
@@ -1029,7 +1015,7 @@ fcloop_delete_remote_port(struct device *dev, struct device_attribute *attr,
|
|
if (!nport)
|
|
if (!nport)
|
|
return -ENOENT;
|
|
return -ENOENT;
|
|
|
|
|
|
- ret = __wait_remoteport_unreg(nport, rport);
|
|
|
|
|
|
+ ret = __remoteport_unreg(nport, rport);
|
|
|
|
|
|
return ret ? ret : count;
|
|
return ret ? ret : count;
|
|
}
|
|
}
|
|
@@ -1086,24 +1072,12 @@ __unlink_target_port(struct fcloop_nport *nport)
|
|
}
|
|
}
|
|
|
|
|
|
static int
|
|
static int
|
|
-__wait_targetport_unreg(struct fcloop_nport *nport, struct fcloop_tport *tport)
|
|
|
|
|
|
+__targetport_unreg(struct fcloop_nport *nport, struct fcloop_tport *tport)
|
|
{
|
|
{
|
|
- int ret;
|
|
|
|
-
|
|
|
|
if (!tport)
|
|
if (!tport)
|
|
return -EALREADY;
|
|
return -EALREADY;
|
|
|
|
|
|
- init_completion(&nport->tport_unreg_done);
|
|
|
|
-
|
|
|
|
- ret = nvmet_fc_unregister_targetport(tport->targetport);
|
|
|
|
- if (ret)
|
|
|
|
- return ret;
|
|
|
|
-
|
|
|
|
- wait_for_completion(&nport->tport_unreg_done);
|
|
|
|
-
|
|
|
|
- fcloop_nport_put(nport);
|
|
|
|
-
|
|
|
|
- return ret;
|
|
|
|
|
|
+ return nvmet_fc_unregister_targetport(tport->targetport);
|
|
}
|
|
}
|
|
|
|
|
|
static ssize_t
|
|
static ssize_t
|
|
@@ -1136,7 +1110,7 @@ fcloop_delete_target_port(struct device *dev, struct device_attribute *attr,
|
|
if (!nport)
|
|
if (!nport)
|
|
return -ENOENT;
|
|
return -ENOENT;
|
|
|
|
|
|
- ret = __wait_targetport_unreg(nport, tport);
|
|
|
|
|
|
+ ret = __targetport_unreg(nport, tport);
|
|
|
|
|
|
return ret ? ret : count;
|
|
return ret ? ret : count;
|
|
}
|
|
}
|
|
@@ -1223,11 +1197,11 @@ static void __exit fcloop_exit(void)
|
|
|
|
|
|
spin_unlock_irqrestore(&fcloop_lock, flags);
|
|
spin_unlock_irqrestore(&fcloop_lock, flags);
|
|
|
|
|
|
- ret = __wait_targetport_unreg(nport, tport);
|
|
|
|
|
|
+ ret = __targetport_unreg(nport, tport);
|
|
if (ret)
|
|
if (ret)
|
|
pr_warn("%s: Failed deleting target port\n", __func__);
|
|
pr_warn("%s: Failed deleting target port\n", __func__);
|
|
|
|
|
|
- ret = __wait_remoteport_unreg(nport, rport);
|
|
|
|
|
|
+ ret = __remoteport_unreg(nport, rport);
|
|
if (ret)
|
|
if (ret)
|
|
pr_warn("%s: Failed deleting remote port\n", __func__);
|
|
pr_warn("%s: Failed deleting remote port\n", __func__);
|
|
|
|
|