diff options
author | Steve French <sfrench@us.ibm.com> | 2005-11-29 20:55:11 -0800 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2005-11-29 20:55:11 -0800 |
commit | 6ab16d249513a50bef3f1b275cea6aa8d3f51832 (patch) | |
tree | 6440fb91b6336e3dc988f06d951ab272610000fb /fs/cifs/cifsfs.c | |
parent | 6473a559c336d5c407f9df412ca2f55357767ff8 (diff) |
[CIFS] Fix umount --force to wake up the pending response queue, not just
the request queue. Also periodically wakeup response_q so threads can
check if stuck requests have timed out. Workaround Windows server illegal smb
length on transact2 findfirst response.
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r-- | fs/cifs/cifsfs.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 51548ed2e9c..f4974b41e48 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -32,6 +32,7 @@ #include <linux/seq_file.h> #include <linux/vfs.h> #include <linux/mempool.h> +#include <linux/delay.h> #include "cifsfs.h" #include "cifspdu.h" #define DECLARE_GLOBALS_HERE @@ -429,6 +430,11 @@ static void cifs_umount_begin(struct super_block * sblock) { cFYI(1,("wake up tasks now - umount begin not complete")); wake_up_all(&tcon->ses->server->request_q); + wake_up_all(&tcon->ses->server->response_q); + msleep(1); /* yield */ + /* we have to kick the requests once more */ + wake_up_all(&tcon->ses->server->response_q); + msleep(1); } /* BB FIXME - finish add checks for tidStatus BB */ @@ -895,6 +901,9 @@ static int cifs_oplock_thread(void * dummyarg) static int cifs_dnotify_thread(void * dummyarg) { + struct list_head *tmp; + struct cifsSesInfo *ses; + daemonize("cifsdnotifyd"); allow_signal(SIGTERM); @@ -903,7 +912,19 @@ static int cifs_dnotify_thread(void * dummyarg) if(try_to_freeze()) continue; set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(39*HZ); + schedule_timeout(15*HZ); + read_lock(&GlobalSMBSeslock); + /* check if any stuck requests that need + to be woken up and wakeq so the + thread can wake up and error out */ + list_for_each(tmp, &GlobalSMBSessionList) { + ses = list_entry(tmp, struct cifsSesInfo, + cifsSessionList); + if(ses && ses->server && + atomic_read(&ses->server->inSend)) + wake_up_all(&ses->server->response_q); + } + read_unlock(&GlobalSMBSeslock); } while(!signal_pending(current)); complete_and_exit (&cifs_dnotify_exited, 0); } |