Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=bd976f62cd6c6dda1ce57bf3e84447e94844868a
Commit:     bd976f62cd6c6dda1ce57bf3e84447e94844868a
Parent:     7fb1921b07a83f71a77f806a2a7d2dd721ea641b
Author:     Mike Christie <[EMAIL PROTECTED]>
AuthorDate: Thu Jan 31 13:36:46 2008 -0600
Committer:  James Bottomley <[EMAIL PROTECTED]>
CommitDate: Thu Feb 7 18:02:35 2008 -0600

    [SCSI] iscsi class: add session scanning
    
    This just adds iscsi session scanning which works like fc rport scanning.
    The future patches will hook the drivers into Mathew Wilcox's async
    scanning infrastructure, so userspace does not have to special case
    iscsi and so userspace does not have to make a extra special case for
    hardware iscsi root scanning.
    
    Signed-off-by: Mike Christie <[EMAIL PROTECTED]>
    Signed-off-by: James Bottomley <[EMAIL PROTECTED]>
---
 drivers/scsi/scsi_transport_iscsi.c |   37 ++++++++++++++++++++++++++++------
 include/scsi/scsi_transport_iscsi.h |    7 +++--
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index f876b0a..af88955 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -128,11 +128,11 @@ static int iscsi_setup_host(struct transport_container 
*tc, struct device *dev,
        INIT_LIST_HEAD(&ihost->sessions);
        mutex_init(&ihost->mutex);
 
-       snprintf(ihost->unbind_workq_name, KOBJ_NAME_LEN, "iscsi_unbind_%d",
+       snprintf(ihost->scan_workq_name, KOBJ_NAME_LEN, "iscsi_scan_%d",
                shost->host_no);
-       ihost->unbind_workq = create_singlethread_workqueue(
-                                               ihost->unbind_workq_name);
-       if (!ihost->unbind_workq)
+       ihost->scan_workq = create_singlethread_workqueue(
+                                               ihost->scan_workq_name);
+       if (!ihost->scan_workq)
                return -ENOMEM;
        return 0;
 }
@@ -143,7 +143,7 @@ static int iscsi_remove_host(struct transport_container 
*tc, struct device *dev,
        struct Scsi_Host *shost = dev_to_shost(dev);
        struct iscsi_host *ihost = shost->shost_data;
 
-       destroy_workqueue(ihost->unbind_workq);
+       destroy_workqueue(ihost->scan_workq);
        return 0;
 }
 
@@ -302,6 +302,23 @@ static int iscsi_user_scan(struct Scsi_Host *shost, uint 
channel,
        return 0;
 }
 
+static void iscsi_scan_session(struct work_struct *work)
+{
+       struct iscsi_cls_session *session =
+                       container_of(work, struct iscsi_cls_session, scan_work);
+       unsigned long flags;
+
+       spin_lock_irqsave(&session->lock, flags);
+       if (session->state != ISCSI_SESSION_LOGGED_IN) {
+               spin_unlock_irqrestore(&session->lock, flags);
+               return;
+       }
+       spin_unlock_irqrestore(&session->lock, flags);
+
+       scsi_scan_target(&session->dev, 0, session->target_id,
+                        SCAN_WILD_CARD, 1);
+}
+
 static void session_recovery_timedout(struct work_struct *work)
 {
        struct iscsi_cls_session *session =
@@ -340,6 +357,8 @@ void __iscsi_unblock_session(struct iscsi_cls_session 
*session)
 
 void iscsi_unblock_session(struct iscsi_cls_session *session)
 {
+       struct Scsi_Host *shost = iscsi_session_to_shost(session);
+       struct iscsi_host *ihost = shost->shost_data;
        unsigned long flags;
 
        spin_lock_irqsave(&session->lock, flags);
@@ -347,6 +366,7 @@ void iscsi_unblock_session(struct iscsi_cls_session 
*session)
        spin_unlock_irqrestore(&session->lock, flags);
 
        __iscsi_unblock_session(session);
+       queue_work(ihost->scan_workq, &session->scan_work);
 }
 EXPORT_SYMBOL_GPL(iscsi_unblock_session);
 
@@ -390,7 +410,7 @@ static int iscsi_unbind_session(struct iscsi_cls_session 
*session)
        struct Scsi_Host *shost = iscsi_session_to_shost(session);
        struct iscsi_host *ihost = shost->shost_data;
 
-       return queue_work(ihost->unbind_workq, &session->unbind_work);
+       return queue_work(ihost->scan_workq, &session->unbind_work);
 }
 
 struct iscsi_cls_session *
@@ -411,6 +431,7 @@ iscsi_alloc_session(struct Scsi_Host *shost,
        INIT_LIST_HEAD(&session->host_list);
        INIT_LIST_HEAD(&session->sess_list);
        INIT_WORK(&session->unbind_work, __iscsi_unbind_session);
+       INIT_WORK(&session->scan_work, iscsi_scan_session);
        spin_lock_init(&session->lock);
 
        /* this is released in the dev's release function */
@@ -530,13 +551,15 @@ void iscsi_remove_session(struct iscsi_cls_session 
*session)
        spin_unlock_irqrestore(&session->lock, flags);
        __iscsi_unblock_session(session);
        iscsi_unbind_session(session);
+
+       /* flush running scans */
+       flush_workqueue(ihost->scan_workq);
        /*
         * If the session dropped while removing devices then we need to make
         * sure it is not blocked
         */
        if (!cancel_delayed_work(&session->recovery_work))
                flush_workqueue(iscsi_eh_timer_workq);
-       flush_workqueue(ihost->unbind_workq);
 
        /* hw iscsi may not have removed all connections from session */
        err = device_for_each_child(&session->dev, NULL,
diff --git a/include/scsi/scsi_transport_iscsi.h 
b/include/scsi/scsi_transport_iscsi.h
index 0e869d9..1f0ec46 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -177,11 +177,12 @@ struct iscsi_cls_session {
        struct list_head host_list;
        struct iscsi_transport *transport;
        spinlock_t lock;
+       struct work_struct scan_work;
+       struct work_struct unbind_work;
 
        /* recovery fields */
        int recovery_tmo;
        struct delayed_work recovery_work;
-       struct work_struct unbind_work;
 
        int target_id;
 
@@ -203,8 +204,8 @@ struct iscsi_cls_session {
 struct iscsi_host {
        struct list_head sessions;
        struct mutex mutex;
-       struct workqueue_struct *unbind_workq;
-       char unbind_workq_name[KOBJ_NAME_LEN];
+       struct workqueue_struct *scan_workq;
+       char scan_workq_name[KOBJ_NAME_LEN];
 };
 
 /*
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to