aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2009-08-28 10:11:11 -0400
committerSteve French <sfrench@us.ibm.com>2009-09-01 18:25:29 -0400
commit1b49c5566136455764a8d17ead25784f534c202d (patch)
tree6946842743140355a6f6b1fb1f27fbfa59132337 /fs
parent8e047d09ee1143058b71f40c5f4d028dde52d883 (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifsfs.c13
-rw-r--r--fs/cifs/cifsglob.h6
-rw-r--r--fs/cifs/transport.c17
3 files changed, 20 insertions, 16 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index b750aa502ff7..3610e9958b4c 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -986,19 +986,19 @@ static int cifs_oplock_thread(void *dummyarg)
986 if (try_to_freeze()) 986 if (try_to_freeze())
987 continue; 987 continue;
988 988
989 spin_lock(&GlobalMid_Lock); 989 spin_lock(&cifs_oplock_lock);
990 if (list_empty(&GlobalOplock_Q)) { 990 if (list_empty(&cifs_oplock_list)) {
991 spin_unlock(&GlobalMid_Lock); 991 spin_unlock(&cifs_oplock_lock);
992 set_current_state(TASK_INTERRUPTIBLE); 992 set_current_state(TASK_INTERRUPTIBLE);
993 schedule_timeout(39*HZ); 993 schedule_timeout(39*HZ);
994 } else { 994 } else {
995 oplock_item = list_entry(GlobalOplock_Q.next, 995 oplock_item = list_entry(cifs_oplock_list.next,
996 struct oplock_q_entry, qhead); 996 struct oplock_q_entry, qhead);
997 cFYI(1, ("found oplock item to write out")); 997 cFYI(1, ("found oplock item to write out"));
998 pTcon = oplock_item->tcon; 998 pTcon = oplock_item->tcon;
999 inode = oplock_item->pinode; 999 inode = oplock_item->pinode;
1000 netfid = oplock_item->netfid; 1000 netfid = oplock_item->netfid;
1001 spin_unlock(&GlobalMid_Lock); 1001 spin_unlock(&cifs_oplock_lock);
1002 DeleteOplockQEntry(oplock_item); 1002 DeleteOplockQEntry(oplock_item);
1003 /* can not grab inode sem here since it would 1003 /* can not grab inode sem here since it would
1004 deadlock when oplock received on delete 1004 deadlock when oplock received on delete
@@ -1055,7 +1055,7 @@ init_cifs(void)
1055 int rc = 0; 1055 int rc = 0;
1056 cifs_proc_init(); 1056 cifs_proc_init();
1057 INIT_LIST_HEAD(&cifs_tcp_ses_list); 1057 INIT_LIST_HEAD(&cifs_tcp_ses_list);
1058 INIT_LIST_HEAD(&GlobalOplock_Q); 1058 INIT_LIST_HEAD(&cifs_oplock_list);
1059#ifdef CONFIG_CIFS_EXPERIMENTAL 1059#ifdef CONFIG_CIFS_EXPERIMENTAL
1060 INIT_LIST_HEAD(&GlobalDnotifyReqList); 1060 INIT_LIST_HEAD(&GlobalDnotifyReqList);
1061 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q); 1061 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
@@ -1084,6 +1084,7 @@ init_cifs(void)
1084 rwlock_init(&GlobalSMBSeslock); 1084 rwlock_init(&GlobalSMBSeslock);
1085 rwlock_init(&cifs_tcp_ses_lock); 1085 rwlock_init(&cifs_tcp_ses_lock);
1086 spin_lock_init(&GlobalMid_Lock); 1086 spin_lock_init(&GlobalMid_Lock);
1087 spin_lock_init(&cifs_oplock_lock);
1087 1088
1088 if (cifs_max_pending < 2) { 1089 if (cifs_max_pending < 2) {
1089 cifs_max_pending = 2; 1090 cifs_max_pending = 2;
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 6084d6379c03..f100399ee05e 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -656,7 +656,11 @@ GLOBAL_EXTERN rwlock_t cifs_tcp_ses_lock;
656 */ 656 */
657GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; 657GLOBAL_EXTERN rwlock_t GlobalSMBSeslock;
658 658
659GLOBAL_EXTERN struct list_head GlobalOplock_Q; 659/* Global list of oplocks */
660GLOBAL_EXTERN struct list_head cifs_oplock_list;
661
662/* Protects the cifs_oplock_list */
663GLOBAL_EXTERN spinlock_t cifs_oplock_lock;
660 664
661/* Outstanding dir notify requests */ 665/* Outstanding dir notify requests */
662GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; 666GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 0ad3e2d116a6..1da4ab250eae 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -119,20 +119,19 @@ AllocOplockQEntry(struct inode *pinode, __u16 fid, struct cifsTconInfo *tcon)
119 temp->pinode = pinode; 119 temp->pinode = pinode;
120 temp->tcon = tcon; 120 temp->tcon = tcon;
121 temp->netfid = fid; 121 temp->netfid = fid;
122 spin_lock(&GlobalMid_Lock); 122 spin_lock(&cifs_oplock_lock);
123 list_add_tail(&temp->qhead, &GlobalOplock_Q); 123 list_add_tail(&temp->qhead, &cifs_oplock_list);
124 spin_unlock(&GlobalMid_Lock); 124 spin_unlock(&cifs_oplock_lock);
125 } 125 }
126 return temp; 126 return temp;
127
128} 127}
129 128
130void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry) 129void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry)
131{ 130{
132 spin_lock(&GlobalMid_Lock); 131 spin_lock(&cifs_oplock_lock);
133 /* should we check if list empty first? */ 132 /* should we check if list empty first? */
134 list_del(&oplockEntry->qhead); 133 list_del(&oplockEntry->qhead);
135 spin_unlock(&GlobalMid_Lock); 134 spin_unlock(&cifs_oplock_lock);
136 kmem_cache_free(cifs_oplock_cachep, oplockEntry); 135 kmem_cache_free(cifs_oplock_cachep, oplockEntry);
137} 136}
138 137
@@ -144,14 +143,14 @@ void DeleteTconOplockQEntries(struct cifsTconInfo *tcon)
144 if (tcon == NULL) 143 if (tcon == NULL)
145 return; 144 return;
146 145
147 spin_lock(&GlobalMid_Lock); 146 spin_lock(&cifs_oplock_lock);
148 list_for_each_entry(temp, &GlobalOplock_Q, qhead) { 147 list_for_each_entry(temp, &cifs_oplock_list, qhead) {
149 if ((temp->tcon) && (temp->tcon == tcon)) { 148 if ((temp->tcon) && (temp->tcon == tcon)) {
150 list_del(&temp->qhead); 149 list_del(&temp->qhead);
151 kmem_cache_free(cifs_oplock_cachep, temp); 150 kmem_cache_free(cifs_oplock_cachep, temp);
152 } 151 }
153 } 152 }
154 spin_unlock(&GlobalMid_Lock); 153 spin_unlock(&cifs_oplock_lock);
155} 154}
156 155
157static int 156static int