forked from luck/tmp_suning_uos_patched
[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:
parent
5aa22af3d0
commit
a119ee8ee3
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user