Commit 9b2a48c5 authored by Steve French's avatar Steve French Committed by Steve French

Fix spinlock usage for SMP safety

parent ee6fd424
...@@ -2,6 +2,7 @@ Version 0.92 ...@@ -2,6 +2,7 @@ Version 0.92
------------ ------------
Active smb transactions should never go negative (fix double FreeXid). Fix Active smb transactions should never go negative (fix double FreeXid). Fix
list processing in file routines. Check return code on kmalloc in open. list processing in file routines. Check return code on kmalloc in open.
Fix spinlock usage for SMP.
Version 0.91 Version 0.91
------------ ------------
......
/* /*
* fs/cifs_debug.c * fs/cifs_debug.c
* *
* Copyright (c) International Business Machines Corp., 2000,2002 * Copyright (C) International Business Machines Corp., 2000,2003
* *
* Modified by Steve French (sfrench@us.ibm.com) * Modified by Steve French (sfrench@us.ibm.com)
* *
...@@ -84,12 +84,12 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, ...@@ -84,12 +84,12 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
length = length =
sprintf(buf, sprintf(buf,
"\n%d) Name: %s Domain: %s Mounts: %d ServerOS: %s ServerNOS: %s\n\tCapabilities: 0x%x", "\n%d) Name: %s Domain: %s Mounts: %d ServerOS: %s \n\tServerNOS: %s\tCapabilities: 0x%x",
i, ses->serverName, ses->serverDomain, atomic_read(&ses->inUse), i, ses->serverName, ses->serverDomain, atomic_read(&ses->inUse),
ses->serverOS, ses->serverNOS, ses->capabilities); ses->serverOS, ses->serverNOS, ses->capabilities);
buf += length; buf += length;
if(ses->server) if(ses->server)
buf += sprintf(buf, "\tLocal Users To Same Server: %d SecMode: 0x%x", buf += sprintf(buf, "\n\tLocal Users To Same Server: %d SecMode: 0x%x",
atomic_read(&ses->server->socketUseCount),ses->server->secMode); atomic_read(&ses->server->socketUseCount),ses->server->secMode);
} }
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
...@@ -123,6 +123,8 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, ...@@ -123,6 +123,8 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
sprintf(buf, " type: %d ", sprintf(buf, " type: %d ",
tcon->fsDevInfo.DeviceType); tcon->fsDevInfo.DeviceType);
buf += length; buf += length;
if(tcon->tidStatus == CifsNeedReconnect)
buf += sprintf(buf, "\tDISCONNECTED ");
} }
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
length = sprintf(buf, "\n"); length = sprintf(buf, "\n");
......
/* /*
* fs/cifs/cifsencrypt.c * fs/cifs/cifsencrypt.c
* *
* Copyright (c) International Business Machines Corp., 2003 * Copyright (C) International Business Machines Corp., 2003
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)
* *
* This library is free software; you can redistribute it and/or modify * This library is free software; you can redistribute it and/or modify
...@@ -64,13 +64,13 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct cifsSesInfo * ses, ...@@ -64,13 +64,13 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct cifsSesInfo * ses,
if((le32_to_cpu(cifs_pdu->Flags2) & SMBFLG2_SECURITY_SIGNATURE) == 0) if((le32_to_cpu(cifs_pdu->Flags2) & SMBFLG2_SECURITY_SIGNATURE) == 0)
return rc; return rc;
write_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(ses->sequence_number); cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(ses->sequence_number);
cifs_pdu->Signature.Sequence.Reserved = 0; cifs_pdu->Signature.Sequence.Reserved = 0;
*pexpected_response_sequence_number = ses->sequence_number++; *pexpected_response_sequence_number = ses->sequence_number++;
ses->sequence_number++; ses->sequence_number++;
write_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
rc = cifs_calculate_signature(cifs_pdu, ses->mac_signing_key,smb_signature); rc = cifs_calculate_signature(cifs_pdu, ses->mac_signing_key,smb_signature);
if(rc) if(rc)
......
/* /*
* fs/cifs/cifsfs.c * fs/cifs/cifsfs.c
* *
* Copyright (c) International Business Machines Corp., 2002 * Copyright (C) International Business Machines Corp., 2002,2003
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)
* *
* Common Internet FileSystem (CIFS) client * Common Internet FileSystem (CIFS) client
...@@ -571,8 +571,6 @@ cifs_destroy_mids(void) ...@@ -571,8 +571,6 @@ cifs_destroy_mids(void)
static int cifs_oplock_thread(void * dummyarg) static int cifs_oplock_thread(void * dummyarg)
{ {
struct list_head * tmp;
struct list_head * tmp1;
struct oplock_q_entry * oplock_item; struct oplock_q_entry * oplock_item;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
struct inode * inode; struct inode * inode;
...@@ -585,18 +583,21 @@ static int cifs_oplock_thread(void * dummyarg) ...@@ -585,18 +583,21 @@ static int cifs_oplock_thread(void * dummyarg)
oplockThread = current; oplockThread = current;
do { do {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(100*HZ);
/* BB add missing code */ schedule_timeout(39*HZ);
write_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
list_for_each_safe(tmp, tmp1, &GlobalOplock_Q) { if(list_empty(&GlobalOplock_Q)) {
oplock_item = list_entry(tmp, struct oplock_q_entry, spin_unlock(&GlobalMid_Lock);
qhead); schedule_timeout(39*HZ);
} else {
oplock_item = list_entry(GlobalOplock_Q.next,
struct oplock_q_entry, qhead);
if(oplock_item) { if(oplock_item) {
pTcon = oplock_item->tcon; pTcon = oplock_item->tcon;
inode = oplock_item->pinode; inode = oplock_item->pinode;
netfid = oplock_item->netfid; netfid = oplock_item->netfid;
DeleteOplockQEntry(oplock_item); DeleteOplockQEntry(oplock_item);
write_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
if (S_ISREG(inode->i_mode)) if (S_ISREG(inode->i_mode))
rc = filemap_fdatawrite(inode->i_mapping); rc = filemap_fdatawrite(inode->i_mapping);
else else
...@@ -609,11 +610,9 @@ static int cifs_oplock_thread(void * dummyarg) ...@@ -609,11 +610,9 @@ static int cifs_oplock_thread(void * dummyarg)
0, LOCKING_ANDX_OPLOCK_RELEASE, 0, LOCKING_ANDX_OPLOCK_RELEASE,
0 /* wait flag */); 0 /* wait flag */);
cFYI(1,("Oplock release rc = %d ",rc)); cFYI(1,("Oplock release rc = %d ",rc));
write_lock(&GlobalMid_Lock);
} else } else
break; spin_unlock(&GlobalMid_Lock);
} }
write_unlock(&GlobalMid_Lock);
} while(!signal_pending(current)); } while(!signal_pending(current));
complete_and_exit (&cifs_oplock_exited, 0); complete_and_exit (&cifs_oplock_exited, 0);
} }
...@@ -640,7 +639,7 @@ init_cifs(void) ...@@ -640,7 +639,7 @@ init_cifs(void)
GlobalTotalActiveXid = 0; GlobalTotalActiveXid = 0;
GlobalMaxActiveXid = 0; GlobalMaxActiveXid = 0;
GlobalSMBSeslock = RW_LOCK_UNLOCKED; GlobalSMBSeslock = RW_LOCK_UNLOCKED;
GlobalMid_Lock = RW_LOCK_UNLOCKED; GlobalMid_Lock = SPIN_LOCK_UNLOCKED;
rc = cifs_init_inodecache(); rc = cifs_init_inodecache();
if (!rc) { if (!rc) {
......
/* /*
* fs/cifs/cifsglob.h * fs/cifs/cifsglob.h
* *
* Copyright (c) International Business Machines Corp., 2002 * Copyright (C) International Business Machines Corp., 2002,2003
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)
* *
* This library is free software; you can redistribute it and/or modify * This library is free software; you can redistribute it and/or modify
...@@ -212,6 +212,7 @@ struct cifsFileInfo { ...@@ -212,6 +212,7 @@ struct cifsFileInfo {
int endOfSearch:1; /* we have reached end of search */ int endOfSearch:1; /* we have reached end of search */
int closePend:1; /* file is marked to close */ int closePend:1; /* file is marked to close */
int emptyDir:1; int emptyDir:1;
int invalidHandle:1; /* file closed via session abend */
char * search_resume_name; char * search_resume_name;
unsigned int resume_name_length; unsigned int resume_name_length;
__u32 resume_key; __u32 resume_key;
...@@ -294,7 +295,27 @@ struct servers_not_supported { /* @z4a */ ...@@ -294,7 +295,27 @@ struct servers_not_supported { /* @z4a */
* following to be declared. * following to be declared.
*/ */
/* BB Every global should have an associated mutex for safe update BB */ /****************************************************************************
* Locking notes. All updates to global variables and lists should be
* protected by spinlocks or semaphores.
*
* Spinlocks
* ---------
* GlobalMid_Lock protects:
* list operations on pending_mid_q and oplockQ
* updates to XID counters, multiplex id and SMB sequence numbers
* GlobalSMBSesLock protects:
* list operations on tcp and SMB session lists and tCon lists
* f_owner.lock protects certain per file struct operations
* mapping->page_lock protects certain per page operations
*
* Semaphores
* ----------
* sesSem operations on smb session
* tconSem operations on tree connection
* i_sem inode operations
*
****************************************************************************/
#ifdef DECLARE_GLOBALS_HERE #ifdef DECLARE_GLOBALS_HERE
#define GLOBAL_EXTERN #define GLOBAL_EXTERN
...@@ -327,7 +348,7 @@ GLOBAL_EXTERN struct list_head GlobalOplock_Q; ...@@ -327,7 +348,7 @@ GLOBAL_EXTERN struct list_head GlobalOplock_Q;
GLOBAL_EXTERN unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */ GLOBAL_EXTERN unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */
GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */ GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */ GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
GLOBAL_EXTERN rwlock_t GlobalMid_Lock; /* protects above and list operations */ GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above and list operations */
/* on midQ entries */ /* on midQ entries */
GLOBAL_EXTERN char Local_System_Name[15]; GLOBAL_EXTERN char Local_System_Name[15];
......
/* /*
* fs/cifs/connect.c * fs/cifs/connect.c
* *
* Copyright (c) International Business Machines Corp., 2002 * Copyright (C) International Business Machines Corp., 2002,2003
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)
* *
* This library is free software; you can redistribute it and/or modify * This library is free software; you can redistribute it and/or modify
...@@ -272,7 +272,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -272,7 +272,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
} }
task_to_wake = NULL; task_to_wake = NULL;
read_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
list_for_each(tmp, &server->pending_mid_q) { list_for_each(tmp, &server->pending_mid_q) {
mid_entry = list_entry(tmp, struct mid_entry = list_entry(tmp, struct
mid_q_entry, mid_q_entry,
...@@ -288,7 +288,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -288,7 +288,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
MID_RESPONSE_RECEIVED; MID_RESPONSE_RECEIVED;
} }
} }
read_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
if (task_to_wake) { if (task_to_wake) {
smb_buffer = NULL; /* will be freed by users thread after he is done */ smb_buffer = NULL; /* will be freed by users thread after he is done */
wake_up_process(task_to_wake); wake_up_process(task_to_wake);
......
...@@ -218,6 +218,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -218,6 +218,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
pCifsFile->netfid = fileHandle; pCifsFile->netfid = fileHandle;
pCifsFile->pid = current->tgid; pCifsFile->pid = current->tgid;
pCifsFile->pInode = newinode; pCifsFile->pInode = newinode;
pCifsFile->invalidHandle = FALSE;
/* pCifsFile->pfile = file; */ /* put in at open time */ /* pCifsFile->pfile = file; */ /* put in at open time */
write_lock(&GlobalSMBSeslock); write_lock(&GlobalSMBSeslock);
list_add(&pCifsFile->tlist,&pTcon->openFileList); list_add(&pCifsFile->tlist,&pTcon->openFileList);
......
...@@ -144,6 +144,7 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -144,6 +144,7 @@ cifs_open(struct inode *inode, struct file *file)
pCifsFile->pid = current->pid; pCifsFile->pid = current->pid;
pCifsFile->pfile = file; /* needed for writepage */ pCifsFile->pfile = file; /* needed for writepage */
pCifsFile->pInode = inode; pCifsFile->pInode = inode;
pCifsFile->invalidHandle = FALSE;
write_lock(&file->f_owner.lock); write_lock(&file->f_owner.lock);
write_lock(&GlobalSMBSeslock); write_lock(&GlobalSMBSeslock);
list_add(&pCifsFile->tlist,&pTcon->openFileList); list_add(&pCifsFile->tlist,&pTcon->openFileList);
...@@ -215,11 +216,25 @@ int reopen_files(struct cifsTconInfo * pTcon, struct nls_table * nlsinfo) ...@@ -215,11 +216,25 @@ int reopen_files(struct cifsTconInfo * pTcon, struct nls_table * nlsinfo)
struct list_head *tmp; struct list_head *tmp;
struct list_head *tmp1; struct list_head *tmp1;
/* list all files open on tree connection */ /* list all files open on tree connection and mark them invalid */
write_lock(&GlobalSMBSeslock); /* BB change to semaphore */ write_lock(&GlobalSMBSeslock);
list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
open_file = list_entry(tmp,struct cifsFileInfo, tlist); open_file = list_entry(tmp,struct cifsFileInfo, tlist);
if(open_file) { if(open_file) {
open_file->invalidHandle = TRUE;
}
}
/* reopen files */
for(;;) {
/* BB need to fix above to check list end and skip entries we do not need to reopen */
if(list_empty(&pTcon->openFileList)) {
break;
} else {
open_file = list_entry(tmp,struct cifsFileInfo, tlist);
if(open_file) {
if(open_file->invalidHandle == FALSE)
continue;
if(open_file->search_resume_name) { if(open_file->search_resume_name) {
kfree(open_file->search_resume_name); kfree(open_file->search_resume_name);
} }
...@@ -232,7 +247,9 @@ int reopen_files(struct cifsTconInfo * pTcon, struct nls_table * nlsinfo) ...@@ -232,7 +247,9 @@ int reopen_files(struct cifsTconInfo * pTcon, struct nls_table * nlsinfo)
if(file->f_dentry == 0) { if(file->f_dentry == 0) {
cFYI(1,("Null dentry for file %p",file)); cFYI(1,("Null dentry for file %p",file));
} else { } else {
write_unlock(&GlobalSMBSeslock);
rc = cifs_open(file->f_dentry->d_inode,file); rc = cifs_open(file->f_dentry->d_inode,file);
write_lock(&GlobalSMBSeslock);
if(rc) { if(rc) {
cFYI(1,("reconnecting file %s failed with %d", cFYI(1,("reconnecting file %s failed with %d",
file->f_dentry->d_name.name,rc)); file->f_dentry->d_name.name,rc));
...@@ -243,6 +260,8 @@ int reopen_files(struct cifsTconInfo * pTcon, struct nls_table * nlsinfo) ...@@ -243,6 +260,8 @@ int reopen_files(struct cifsTconInfo * pTcon, struct nls_table * nlsinfo)
} }
} }
} }
}
} }
write_unlock(&GlobalSMBSeslock); write_unlock(&GlobalSMBSeslock);
return rc; return rc;
...@@ -264,6 +283,7 @@ cifs_close(struct inode *inode, struct file *file) ...@@ -264,6 +283,7 @@ cifs_close(struct inode *inode, struct file *file)
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
if (pSMBFile) { if (pSMBFile) {
write_lock(&file->f_owner.lock); write_lock(&file->f_owner.lock);
pSMBFile->invalidHandle = TRUE;
list_del(&pSMBFile->flist); list_del(&pSMBFile->flist);
list_del(&pSMBFile->tlist); list_del(&pSMBFile->tlist);
write_unlock(&file->f_owner.lock); write_unlock(&file->f_owner.lock);
...@@ -1242,8 +1262,10 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -1242,8 +1262,10 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
rc = 0; rc = 0;
break; break;
} }
} else } else {
cifsFile->invalidHandle = TRUE;
CIFSFindClose(xid, pTcon, cifsFile->netfid); CIFSFindClose(xid, pTcon, cifsFile->netfid);
}
if(cifsFile->search_resume_name) { if(cifsFile->search_resume_name) {
kfree(cifsFile->search_resume_name); kfree(cifsFile->search_resume_name);
cifsFile->search_resume_name = NULL; cifsFile->search_resume_name = NULL;
...@@ -1267,6 +1289,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -1267,6 +1289,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
cifsFile = cifsFile =
(struct cifsFileInfo *) file->private_data; (struct cifsFileInfo *) file->private_data;
cifsFile->netfid = searchHandle; cifsFile->netfid = searchHandle;
cifsFile->invalidHandle = FALSE;
} else { } else {
rc = -ENOMEM; rc = -ENOMEM;
break; break;
......
/* /*
* fs/cifs/misc.c * fs/cifs/misc.c
* *
* Copyright (c) International Business Machines Corp., 2002,2003 * Copyright (C) International Business Machines Corp., 2002,2003
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)
* *
* This library is free software; you can redistribute it and/or modify * This library is free software; you can redistribute it and/or modify
...@@ -42,23 +42,23 @@ _GetXid(void) ...@@ -42,23 +42,23 @@ _GetXid(void)
{ {
unsigned int xid; unsigned int xid;
write_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
GlobalTotalActiveXid++; GlobalTotalActiveXid++;
if (GlobalTotalActiveXid > GlobalMaxActiveXid) if (GlobalTotalActiveXid > GlobalMaxActiveXid)
GlobalMaxActiveXid = GlobalTotalActiveXid; /* keep high water mark for number of simultaneous vfs ops in our filesystem */ GlobalMaxActiveXid = GlobalTotalActiveXid; /* keep high water mark for number of simultaneous vfs ops in our filesystem */
xid = GlobalCurrentXid++; xid = GlobalCurrentXid++;
write_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
return xid; return xid;
} }
void void
_FreeXid(unsigned int xid) _FreeXid(unsigned int xid)
{ {
write_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
/* if(GlobalTotalActiveXid == 0) /* if(GlobalTotalActiveXid == 0)
BUG(); */ BUG(); */
GlobalTotalActiveXid--; GlobalTotalActiveXid--;
write_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
} }
struct cifsSesInfo * struct cifsSesInfo *
...@@ -217,10 +217,10 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , ...@@ -217,10 +217,10 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
buffer->Pid = tmp & 0xFFFF; buffer->Pid = tmp & 0xFFFF;
tmp >>= 16; tmp >>= 16;
buffer->PidHigh = tmp & 0xFFFF; buffer->PidHigh = tmp & 0xFFFF;
write_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
GlobalMid++; GlobalMid++;
buffer->Mid = GlobalMid; buffer->Mid = GlobalMid;
write_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
if (treeCon) { if (treeCon) {
buffer->Tid = treeCon->tid; buffer->Tid = treeCon->tid;
if (treeCon->ses) { if (treeCon->ses) {
......
/* /*
* fs/cifs/transport.c * fs/cifs/transport.c
* *
* Copyright (c) International Business Machines Corp., 2002 * Copyright (C) International Business Machines Corp., 2002,2003
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)
* *
* This library is free software; you can redistribute it and/or modify * This library is free software; you can redistribute it and/or modify
...@@ -39,7 +39,6 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) ...@@ -39,7 +39,6 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
struct mid_q_entry *temp; struct mid_q_entry *temp;
int timeout = 10 * HZ; int timeout = 10 * HZ;
/* BB add spinlock to protect midq for each session BB */
if (ses == NULL) { if (ses == NULL) {
cERROR(1, ("Null session passed in to AllocMidQEntry ")); cERROR(1, ("Null session passed in to AllocMidQEntry "));
return NULL; return NULL;
...@@ -72,11 +71,11 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) ...@@ -72,11 +71,11 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
} }
if (ses->server->tcpStatus == CifsGood) { if (ses->server->tcpStatus == CifsGood) {
write_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
list_add_tail(&temp->qhead, &ses->server->pending_mid_q); list_add_tail(&temp->qhead, &ses->server->pending_mid_q);
atomic_inc(&midCount); atomic_inc(&midCount);
temp->midState = MID_REQUEST_ALLOCATED; temp->midState = MID_REQUEST_ALLOCATED;
write_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
} else { } else {
cERROR(1,("Need to reconnect after session died to server")); cERROR(1,("Need to reconnect after session died to server"));
if (temp) if (temp)
...@@ -89,12 +88,11 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) ...@@ -89,12 +88,11 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
void void
DeleteMidQEntry(struct mid_q_entry *midEntry) DeleteMidQEntry(struct mid_q_entry *midEntry)
{ {
/* BB add spinlock to protect midq for each session BB */ spin_lock(&GlobalMid_Lock);
write_lock(&GlobalMid_Lock);
midEntry->midState = MID_FREE; midEntry->midState = MID_FREE;
list_del(&midEntry->qhead); list_del(&midEntry->qhead);
atomic_dec(&midCount); atomic_dec(&midCount);
write_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
buf_release(midEntry->resp_buf); buf_release(midEntry->resp_buf);
kmem_cache_free(cifs_mid_cachep, midEntry); kmem_cache_free(cifs_mid_cachep, midEntry);
} }
...@@ -115,9 +113,9 @@ AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon) ...@@ -115,9 +113,9 @@ AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon)
temp->pinode = pinode; temp->pinode = pinode;
temp->tcon = tcon; temp->tcon = tcon;
temp->netfid = fid; temp->netfid = fid;
write_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
list_add_tail(&temp->qhead, &GlobalOplock_Q); list_add_tail(&temp->qhead, &GlobalOplock_Q);
write_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
} }
return temp; return temp;
...@@ -125,11 +123,10 @@ AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon) ...@@ -125,11 +123,10 @@ AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon)
void DeleteOplockQEntry(struct oplock_q_entry * oplockEntry) void DeleteOplockQEntry(struct oplock_q_entry * oplockEntry)
{ {
/* BB add spinlock to protect midq for each session BB */ spin_lock(&GlobalMid_Lock);
write_lock(&GlobalMid_Lock);
/* should we check if list empty first? */ /* should we check if list empty first? */
list_del(&oplockEntry->qhead); list_del(&oplockEntry->qhead);
write_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
kmem_cache_free(cifs_oplock_cachep, oplockEntry); kmem_cache_free(cifs_oplock_cachep, oplockEntry);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment