]> www.infradead.org Git - users/willy/xarray.git/commitdiff
scsi: Convert same_target_siblings to XArray
authorMatthew Wilcox <willy@infradead.org>
Thu, 15 Nov 2018 07:02:19 +0000 (02:02 -0500)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Fri, 9 Aug 2019 01:38:14 +0000 (21:38 -0400)
Generally each target has only one LUN, so the target will have a direct
pointer to the sdev.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
drivers/scsi/scsi.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
include/scsi/scsi_device.h

index 1f5b5c8a7f726d8d1f9bd758822f73d578a68197..7f46e258a56f08fd3e6ad43a1b011ba713a414c3 100644 (file)
@@ -656,11 +656,12 @@ struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *starget,
                                                   u64 lun)
 {
        struct scsi_device *sdev;
+       unsigned long index;
 
-       list_for_each_entry(sdev, &starget->devices, same_target_siblings) {
+       xa_for_each(&starget->devices, index, sdev) {
                if (sdev->sdev_state == SDEV_DEL)
                        continue;
-               if (sdev->lun ==lun)
+               if (sdev->lun == lun)
                        return sdev;
        }
 
index 11e64b50497f81949476014f2b31d40d024346ed..e1267c1a2d45338bd6eee8afa33654bc14b90d6d 100644 (file)
@@ -372,8 +372,9 @@ static void scsi_kick_queue(struct request_queue *q)
 static void scsi_single_lun_run(struct scsi_device *current_sdev)
 {
        struct Scsi_Host *shost = current_sdev->host;
-       struct scsi_device *sdev, *tmp;
+       struct scsi_device *sdev;
        struct scsi_target *starget = scsi_target(current_sdev);
+       unsigned long index;
        unsigned long flags;
 
        spin_lock_irqsave(shost->host_lock, flags);
@@ -391,8 +392,7 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
        spin_lock_irqsave(shost->host_lock, flags);
        if (starget->starget_sdev_user)
                goto out;
-       list_for_each_entry_safe(sdev, tmp, &starget->devices,
-                       same_target_siblings) {
+       xa_for_each(&starget->devices, index, sdev) {
                if (sdev == current_sdev)
                        continue;
                if (scsi_device_get(sdev))
index 058079f915f180694219ce178d9f43d0dd90d3ce..be21bb629a7b08c10b7de15becb44bc872e9f495 100644 (file)
@@ -235,7 +235,6 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
        mutex_init(&sdev->state_mutex);
        sdev->sdev_state = SDEV_CREATED;
        INIT_LIST_HEAD(&sdev->siblings);
-       INIT_LIST_HEAD(&sdev->same_target_siblings);
        INIT_LIST_HEAD(&sdev->cmd_list);
        INIT_LIST_HEAD(&sdev->starved_entry);
        INIT_LIST_HEAD(&sdev->event_list);
@@ -435,7 +434,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
        starget->channel = channel;
        starget->can_queue = 0;
        INIT_LIST_HEAD(&starget->siblings);
-       INIT_LIST_HEAD(&starget->devices);
+       xa_init_flags(&starget->devices, XA_FLAGS_ALLOC);
        starget->state = STARGET_CREATED;
        starget->scsi_level = SCSI_2;
        starget->max_target_blocked = SCSI_DEFAULT_TARGET_BLOCKED;
index 64c96c7828ee1056042da4a913d9f3f2b9506506..84aea8707fd744ebb8503f903ee578be15b2c29d 100644 (file)
@@ -447,7 +447,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
 
        spin_lock_irqsave(sdev->host->host_lock, flags);
        list_del(&sdev->siblings);
-       list_del(&sdev->same_target_siblings);
+       xa_erase(&sdev->sdev_target->devices, sdev->pertarget_id);
        list_del(&sdev->starved_entry);
        spin_unlock_irqrestore(sdev->host->host_lock, flags);
 
@@ -1557,7 +1557,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev)
 {
        unsigned long flags;
        struct Scsi_Host *shost = sdev->host;
-       struct scsi_target  *starget = sdev->sdev_target;
+       struct scsi_target *starget = sdev->sdev_target;
 
        device_initialize(&sdev->sdev_gendev);
        sdev->sdev_gendev.bus = &scsi_bus_type;
@@ -1584,8 +1584,9 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev)
                sdev->lun_in_cdb = 1;
 
        transport_setup_device(&sdev->sdev_gendev);
+       BUG_ON(xa_alloc(&starget->devices, &sdev->pertarget_id, sdev,
+                       xa_limit_32b, GFP_ATOMIC));
        spin_lock_irqsave(shost->host_lock, flags);
-       list_add_tail(&sdev->same_target_siblings, &starget->devices);
        list_add_tail(&sdev->siblings, &shost->__devices);
        spin_unlock_irqrestore(shost->host_lock, flags);
        /*
index 202f4d6a434212bd9914b4b3988aeff32a66dc09..26a8accbac3ed87f4eee829e7ae0fdf03f822ab9 100644 (file)
@@ -102,9 +102,9 @@ struct scsi_device {
        struct Scsi_Host *host;
        struct request_queue *request_queue;
 
-       /* the next two are protected by the host->host_lock */
+       /* protected by the host->host_lock */
        struct list_head    siblings;   /* list of all devices on this host */
-       struct list_head    same_target_siblings; /* just the devices sharing same target id */
+       u32 pertarget_id;               /* index into target's device list */
 
        atomic_t device_busy;           /* commands actually active on LLDD */
        atomic_t device_blocked;        /* Device returned QUEUE_FULL. */
@@ -279,7 +279,7 @@ enum scsi_target_state {
 struct scsi_target {
        struct scsi_device      *starget_sdev_user;
        struct list_head        siblings;
-       struct list_head        devices;
+       struct xarray           devices;
        struct device           dev;
        struct kref             reap_ref; /* last put renders target invisible */
        unsigned int            channel;