diff options
author | Jeff Layton <jlayton@redhat.com> | 2009-08-28 10:11:11 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2009-09-01 18:25:29 -0400 |
commit | 1b49c5566136455764a8d17ead25784f534c202d (patch) | |
tree | 6946842743140355a6f6b1fb1f27fbfa59132337 /fs/cifs | |
parent | 8e047d09ee1143058b71f40c5f4d028dde52d883 (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/cifs')
-rw-r--r-- | fs/cifs/cifsfs.c | 13 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 6 | ||||
-rw-r--r-- | fs/cifs/transport.c | 17 |
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 | */ |
657 | GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; | 657 | GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; |
658 | 658 | ||
659 | GLOBAL_EXTERN struct list_head GlobalOplock_Q; | 659 | /* Global list of oplocks */ |
660 | GLOBAL_EXTERN struct list_head cifs_oplock_list; | ||
661 | |||
662 | /* Protects the cifs_oplock_list */ | ||
663 | GLOBAL_EXTERN spinlock_t cifs_oplock_lock; | ||
660 | 664 | ||
661 | /* Outstanding dir notify requests */ | 665 | /* Outstanding dir notify requests */ |
662 | GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; | 666 | GLOBAL_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 | ||
130 | void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry) | 129 | void 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 | ||
157 | static int | 156 | static int |