[SCSI] libfc: make rport module maintain the rport list
authorJoe Eykholt <jeykholt@cisco.com>
Tue, 25 Aug 2009 21:01:50 +0000 (14:01 -0700)
committerJames Bottomley <James.Bottomley@suse.de>
Thu, 10 Sep 2009 17:07:46 +0000 (12:07 -0500)
The list of remote ports (struct fc_rport_priv) has been
maintained by the discovery module.  In preparation for having
lport->tt.rport_create() do a lookup first, maintain the
rports list in the rport module.  It will still be protected
by the disc_mutex.

The DNS rport is an exception for until after further patches.
For now, do not add it to the list.

The point-to-point rport will be in the discovery list.
So at shutdown, it doesn't need to be separately logged out.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/libfc/fc_disc.c
drivers/scsi/libfc/fc_lport.c
drivers/scsi/libfc/fc_rport.c

index 8427396909e856786062da02431c8fb49e2ab4bb..e6b13bfecf735b017bf0420c8158dd31a3fb716a 100644 (file)
@@ -115,9 +115,6 @@ static void fc_disc_rport_callback(struct fc_lport *lport,
        case RPORT_EV_LOGO:
        case RPORT_EV_FAILED:
        case RPORT_EV_STOP:
-               mutex_lock(&disc->disc_mutex);
-               list_del(&rdata->peers);
-               mutex_unlock(&disc->disc_mutex);
                break;
        default:
                break;
@@ -385,9 +382,6 @@ static int fc_disc_new_target(struct fc_disc *disc,
                                rdata = lport->tt.rport_create(lport, ids);
                                if (!rdata)
                                        error = -ENOMEM;
-                               else
-                                       list_add_tail(&rdata->peers,
-                                                     &disc->rports);
                        }
                }
                if (rdata) {
@@ -562,7 +556,6 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
                        rdata = lport->tt.rport_create(lport, &ids);
                        if (rdata) {
                                rdata->ops = &fc_disc_rport_ops;
-                               list_add_tail(&rdata->peers, &disc->rports);
                                lport->tt.rport_login(rdata);
                        } else
                                printk(KERN_WARNING "libfc: Failed to allocate "
@@ -709,7 +702,6 @@ static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp)
        if (rdata) {
                rdata->ops = &fc_disc_rport_ops;
                kfree(dp);
-               list_add_tail(&rdata->peers, &disc->rports);
                lport->tt.rport_login(rdata);
        }
        return;
index 22c0f7bc004f98f4e99dded6d821c4d4631fe29d..f33e5732e3fc2f3c5f74a18c7c08da4abeac14e1 100644 (file)
@@ -205,12 +205,11 @@ static void fc_lport_ptp_setup(struct fc_lport *lport,
        ids.node_name = remote_wwnn;
        ids.roles = FC_RPORT_ROLE_UNKNOWN;
 
-       if (lport->ptp_rp) {
+       mutex_lock(&lport->disc.disc_mutex);
+       if (lport->ptp_rp)
                lport->tt.rport_logoff(lport->ptp_rp);
-               lport->ptp_rp = NULL;
-       }
-
        lport->ptp_rp = lport->tt.rport_create(lport, &ids);
+       mutex_unlock(&lport->disc.disc_mutex);
 
        lport->tt.rport_login(lport->ptp_rp);
 
@@ -931,10 +930,7 @@ static void fc_lport_reset_locked(struct fc_lport *lport)
        if (lport->dns_rp)
                lport->tt.rport_logoff(lport->dns_rp);
 
-       if (lport->ptp_rp) {
-               lport->tt.rport_logoff(lport->ptp_rp);
-               lport->ptp_rp = NULL;
-       }
+       lport->ptp_rp = NULL;
 
        lport->tt.disc_stop(lport);
 
@@ -1304,7 +1300,9 @@ static void fc_lport_enter_dns(struct fc_lport *lport)
 
        fc_lport_state_enter(lport, LPORT_ST_DNS);
 
+       mutex_lock(&lport->disc.disc_mutex);
        rdata = lport->tt.rport_create(lport, &ids);
+       mutex_unlock(&lport->disc.disc_mutex);
        if (!rdata)
                goto err;
 
index 6ecf36d4708c0a8cc2623f3c6bc37b23cd535830..a9087b31bce9190b53b59c4a8f857dbd44e71e1a 100644 (file)
@@ -91,8 +91,7 @@ static const char *fc_rport_state_names[] = {
  * @lport: local port.
  * @ids: remote port identifiers.
  *
- * Locking note: this may be called without locks held, but
- * is usually called from discovery with the disc_mutex held.
+ * Locking note:  must be called with the disc_mutex held.
  */
 static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport,
                                             struct fc_rport_identifiers *ids)
@@ -115,6 +114,8 @@ static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport,
        rdata->maxframe_size = FC_MIN_MAX_PAYLOAD;
        INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout);
        INIT_WORK(&rdata->event_work, fc_rport_work);
+       if (ids->port_id != FC_FID_DIR_SERV)
+               list_add(&rdata->peers, &lport->disc.rports);
        return rdata;
 }
 
@@ -258,6 +259,12 @@ static void fc_rport_work(struct work_struct *work)
                port_id = rdata->ids.port_id;
                mutex_unlock(&rdata->rp_mutex);
 
+               if (port_id != FC_FID_DIR_SERV) {
+                       mutex_lock(&lport->disc.disc_mutex);
+                       list_del(&rdata->peers);
+                       mutex_unlock(&lport->disc.disc_mutex);
+               }
+
                if (rport_ops->event_callback) {
                        FC_RPORT_DBG(rdata, "callback ev %d\n", event);
                        rport_ops->event_callback(lport, rdata, event);