mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-02 20:29:20 +00:00
cifs: protect GlobalOplock_Q with its own spinlock
Right now, the GlobalOplock_Q is protected by the GlobalMid_Lock. That lock is also used for completely unrelated purposes (mostly for managing the global mid queue). Give the list its own dedicated spinlock (cifs_oplock_lock) and rename the list to cifs_oplock_list to eliminate the camel-case. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
parent
8e047d09ee
commit
1b49c55661
3 changed files with 20 additions and 16 deletions
|
@ -986,19 +986,19 @@ static int cifs_oplock_thread(void *dummyarg)
|
||||||
if (try_to_freeze())
|
if (try_to_freeze())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
spin_lock(&GlobalMid_Lock);
|
spin_lock(&cifs_oplock_lock);
|
||||||
if (list_empty(&GlobalOplock_Q)) {
|
if (list_empty(&cifs_oplock_list)) {
|
||||||
spin_unlock(&GlobalMid_Lock);
|
spin_unlock(&cifs_oplock_lock);
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
schedule_timeout(39*HZ);
|
schedule_timeout(39*HZ);
|
||||||
} else {
|
} else {
|
||||||
oplock_item = list_entry(GlobalOplock_Q.next,
|
oplock_item = list_entry(cifs_oplock_list.next,
|
||||||
struct oplock_q_entry, qhead);
|
struct oplock_q_entry, qhead);
|
||||||
cFYI(1, ("found oplock item to write out"));
|
cFYI(1, ("found oplock item to write out"));
|
||||||
pTcon = oplock_item->tcon;
|
pTcon = oplock_item->tcon;
|
||||||
inode = oplock_item->pinode;
|
inode = oplock_item->pinode;
|
||||||
netfid = oplock_item->netfid;
|
netfid = oplock_item->netfid;
|
||||||
spin_unlock(&GlobalMid_Lock);
|
spin_unlock(&cifs_oplock_lock);
|
||||||
DeleteOplockQEntry(oplock_item);
|
DeleteOplockQEntry(oplock_item);
|
||||||
/* can not grab inode sem here since it would
|
/* can not grab inode sem here since it would
|
||||||
deadlock when oplock received on delete
|
deadlock when oplock received on delete
|
||||||
|
@ -1055,7 +1055,7 @@ init_cifs(void)
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
cifs_proc_init();
|
cifs_proc_init();
|
||||||
INIT_LIST_HEAD(&cifs_tcp_ses_list);
|
INIT_LIST_HEAD(&cifs_tcp_ses_list);
|
||||||
INIT_LIST_HEAD(&GlobalOplock_Q);
|
INIT_LIST_HEAD(&cifs_oplock_list);
|
||||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||||
INIT_LIST_HEAD(&GlobalDnotifyReqList);
|
INIT_LIST_HEAD(&GlobalDnotifyReqList);
|
||||||
INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
|
INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
|
||||||
|
@ -1084,6 +1084,7 @@ init_cifs(void)
|
||||||
rwlock_init(&GlobalSMBSeslock);
|
rwlock_init(&GlobalSMBSeslock);
|
||||||
rwlock_init(&cifs_tcp_ses_lock);
|
rwlock_init(&cifs_tcp_ses_lock);
|
||||||
spin_lock_init(&GlobalMid_Lock);
|
spin_lock_init(&GlobalMid_Lock);
|
||||||
|
spin_lock_init(&cifs_oplock_lock);
|
||||||
|
|
||||||
if (cifs_max_pending < 2) {
|
if (cifs_max_pending < 2) {
|
||||||
cifs_max_pending = 2;
|
cifs_max_pending = 2;
|
||||||
|
|
|
@ -656,7 +656,11 @@ GLOBAL_EXTERN rwlock_t cifs_tcp_ses_lock;
|
||||||
*/
|
*/
|
||||||
GLOBAL_EXTERN rwlock_t GlobalSMBSeslock;
|
GLOBAL_EXTERN rwlock_t GlobalSMBSeslock;
|
||||||
|
|
||||||
GLOBAL_EXTERN struct list_head GlobalOplock_Q;
|
/* Global list of oplocks */
|
||||||
|
GLOBAL_EXTERN struct list_head cifs_oplock_list;
|
||||||
|
|
||||||
|
/* Protects the cifs_oplock_list */
|
||||||
|
GLOBAL_EXTERN spinlock_t cifs_oplock_lock;
|
||||||
|
|
||||||
/* Outstanding dir notify requests */
|
/* Outstanding dir notify requests */
|
||||||
GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
|
GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
|
||||||
|
|
|
@ -119,20 +119,19 @@ 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;
|
||||||
spin_lock(&GlobalMid_Lock);
|
spin_lock(&cifs_oplock_lock);
|
||||||
list_add_tail(&temp->qhead, &GlobalOplock_Q);
|
list_add_tail(&temp->qhead, &cifs_oplock_list);
|
||||||
spin_unlock(&GlobalMid_Lock);
|
spin_unlock(&cifs_oplock_lock);
|
||||||
}
|
}
|
||||||
return temp;
|
return temp;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry)
|
void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry)
|
||||||
{
|
{
|
||||||
spin_lock(&GlobalMid_Lock);
|
spin_lock(&cifs_oplock_lock);
|
||||||
/* should we check if list empty first? */
|
/* should we check if list empty first? */
|
||||||
list_del(&oplockEntry->qhead);
|
list_del(&oplockEntry->qhead);
|
||||||
spin_unlock(&GlobalMid_Lock);
|
spin_unlock(&cifs_oplock_lock);
|
||||||
kmem_cache_free(cifs_oplock_cachep, oplockEntry);
|
kmem_cache_free(cifs_oplock_cachep, oplockEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,14 +143,14 @@ void DeleteTconOplockQEntries(struct cifsTconInfo *tcon)
|
||||||
if (tcon == NULL)
|
if (tcon == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
spin_lock(&GlobalMid_Lock);
|
spin_lock(&cifs_oplock_lock);
|
||||||
list_for_each_entry(temp, &GlobalOplock_Q, qhead) {
|
list_for_each_entry(temp, &cifs_oplock_list, qhead) {
|
||||||
if ((temp->tcon) && (temp->tcon == tcon)) {
|
if ((temp->tcon) && (temp->tcon == tcon)) {
|
||||||
list_del(&temp->qhead);
|
list_del(&temp->qhead);
|
||||||
kmem_cache_free(cifs_oplock_cachep, temp);
|
kmem_cache_free(cifs_oplock_cachep, temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock(&GlobalMid_Lock);
|
spin_unlock(&cifs_oplock_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue