[SCSI] aacraid: fib context lock for management ioctls

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>
This commit is contained in:
Salyzyn, Mark 2008-01-24 07:40:10 -08:00 committed by James Bottomley
parent 5aa22af3d0
commit a119ee8ee3

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