[SCSI] aacraid: fib context lock for management ioctls
authorSalyzyn, Mark <Mark_Salyzyn@adaptec.com>
Thu, 24 Jan 2008 15:40:10 +0000 (07:40 -0800)
committerJames Bottomley <James.Bottomley@HansenPartnership.com>
Fri, 25 Jan 2008 15:25:22 +0000 (09:25 -0600)
Alan noticed the lack of locking surrounding the driver's dealings
with the fib context managed by the trio of ioctls that are used by
the RAID management applications to retrieve Adapter Initiated FIBs. I
merely expanded the fib lock to include the fib context. There have
been no field reports of any issues generally because the applications
are relatively static and do not come and go often enough to stress
this area. I bloated this patch a little with some space junk.

Signed-off-by: Mark Salyzyn <aacraid@adaptec.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
drivers/scsi/aacraid/commctrl.c

index f8afa35..851a7e5 100644 (file)
@@ -243,6 +243,7 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
         *      Search the list of AdapterFibContext addresses on the adapter
         *      to be sure this is a valid address
         */
+       spin_lock_irqsave(&dev->fib_lock, flags);
        entry = dev->fib_list.next;
        fibctx = NULL;
 
@@ -251,24 +252,25 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
                /*
                 *      Extract the AdapterFibContext from the Input parameters.
                 */
-               if (fibctx->unique == f.fibctx) {   /* We found a winner */
+               if (fibctx->unique == f.fibctx) { /* We found a winner */
                        break;
                }
                entry = entry->next;
                fibctx = NULL;
        }
        if (!fibctx) {
+               spin_unlock_irqrestore(&dev->fib_lock, flags);
                dprintk ((KERN_INFO "Fib Context not found\n"));
                return -EINVAL;
        }
 
        if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
                 (fibctx->size != sizeof(struct aac_fib_context))) {
+               spin_unlock_irqrestore(&dev->fib_lock, flags);
                dprintk ((KERN_INFO "Fib Context corrupt?\n"));
                return -EINVAL;
        }
        status = 0;
-       spin_lock_irqsave(&dev->fib_lock, flags);
        /*
         *      If there are no fibs to send back, then either wait or return
         *      -EAGAIN
@@ -326,7 +328,9 @@ return_fib:
 int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
 {
        struct fib *fib;
+       unsigned long flags;
 
+       spin_lock_irqsave(&dev->fib_lock, flags);
        /*
         *      First free any FIBs that have not been consumed.
         */
@@ -349,6 +353,7 @@ int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
         *      Remove the Context from the AdapterFibContext List
         */
        list_del(&fibctx->next);
+       spin_unlock_irqrestore(&dev->fib_lock, flags);
        /*
         *      Invalidate context
         */
@@ -414,8 +419,8 @@ static int close_getadapter_fib(struct aac_dev * dev, void __user *arg)
  *     @arg: ioctl arguments
  *
  *     This routine returns the driver version.
- *      Under Linux, there have been no version incompatibilities, so this is
- *      simple!
+ *     Under Linux, there have been no version incompatibilities, so this is
+ *     simple!
  */
 
 static int check_revision(struct aac_dev *dev, void __user *arg)
@@ -463,7 +468,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
        u32 data_dir;
        void __user *sg_user[32];
        void *sg_list[32];
-       u32   sg_indx = 0;
+       u32 sg_indx = 0;
        u32 byte_count = 0;
        u32 actual_fibsize64, actual_fibsize = 0;
        int i;
@@ -517,11 +522,11 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
        // Fix up srb for endian and force some values
 
        srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);       // Force this
-       srbcmd->channel  = cpu_to_le32(user_srbcmd->channel);
+       srbcmd->channel  = cpu_to_le32(user_srbcmd->channel);
        srbcmd->id       = cpu_to_le32(user_srbcmd->id);
-       srbcmd->lun      = cpu_to_le32(user_srbcmd->lun);
-       srbcmd->timeout  = cpu_to_le32(user_srbcmd->timeout);
-       srbcmd->flags    = cpu_to_le32(flags);
+       srbcmd->lun      = cpu_to_le32(user_srbcmd->lun);
+       srbcmd->timeout  = cpu_to_le32(user_srbcmd->timeout);
+       srbcmd->flags    = cpu_to_le32(flags);
        srbcmd->retry_limit = 0; // Obsolete parameter
        srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size);
        memcpy(srbcmd->cdb, user_srbcmd->cdb, sizeof(srbcmd->cdb));
@@ -786,9 +791,9 @@ static int aac_get_pci_info(struct aac_dev* dev, void __user *arg)
        pci_info.bus = dev->pdev->bus->number;
        pci_info.slot = PCI_SLOT(dev->pdev->devfn);
 
-       if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) {
-              dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n"));
-              return -EFAULT;
+       if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) {
+               dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n"));
+               return -EFAULT;
        }
        return 0;
 }