X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=fs%2Fcifs%2Fcifsfs.c;h=682b0235ad9a170df904563eea37d9a132291ce2;hb=3b621ee5df437d3f332a635ab6421aaa61a7dc2b;hp=1ebf7dafc1d757128e4084d6a1794485399b7ecc;hpb=9472d8ce147fecb80a2f29ad8ab781e596858916;p=powerpc.git diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 1ebf7dafc1..682b0235ad 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -59,6 +59,8 @@ unsigned int ntlmv2_support = 0; unsigned int sign_CIFS_PDUs = 1; extern struct task_struct * oplockThread; /* remove sparse warning */ struct task_struct * oplockThread = NULL; +extern struct task_struct * dnotifyThread; /* remove sparse warning */ +struct task_struct * dnotifyThread = NULL; unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; module_param(CIFSMaxBufSize, int, 0); MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048"); @@ -73,6 +75,7 @@ module_param(cifs_max_pending, int, 0); MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); static DECLARE_COMPLETION(cifs_oplock_exited); +static DECLARE_COMPLETION(cifs_dnotify_exited); extern mempool_t *cifs_sm_req_poolp; extern mempool_t *cifs_req_poolp; @@ -202,6 +205,10 @@ cifs_statfs(struct super_block *sb, struct kstatfs *buf) #endif /* CIFS_EXPERIMENTAL */ rc = CIFSSMBQFSInfo(xid, pTcon, buf); + /* Old Windows servers do not support level 103, retry with level + one if old server failed the previous call */ + if(rc) + rc = SMBOldQFSInfo(xid, pTcon, buf); /* int f_type; __fsid_t f_fsid; @@ -253,7 +260,7 @@ cifs_alloc_inode(struct super_block *sb) cifs_inode->clientCanCacheAll = FALSE; cifs_inode->vfs_inode.i_blksize = CIFS_MAX_MSGSIZE; cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ - + cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME; INIT_LIST_HEAD(&cifs_inode->openFileList); return &cifs_inode->vfs_inode; } @@ -398,6 +405,37 @@ static struct quotactl_ops cifs_quotactl_ops = { }; #endif +#ifdef CONFIG_CIFS_EXPERIMENTAL +static void cifs_umount_begin(struct super_block * sblock) +{ + struct cifs_sb_info *cifs_sb; + struct cifsTconInfo * tcon; + + cifs_sb = CIFS_SB(sblock); + if(cifs_sb == NULL) + return; + + tcon = cifs_sb->tcon; + if(tcon == NULL) + return; + down(&tcon->tconSem); + if (atomic_read(&tcon->useCount) == 1) + tcon->tidStatus = CifsExiting; + up(&tcon->tconSem); + + /* cancel_brl_requests(tcon); */ + /* cancel_notify_requests(tcon); */ + if(tcon->ses && tcon->ses->server) + { + cFYI(1,("wake up tasks now - umount begin not complete")); + wake_up_all(&tcon->ses->server->request_q); + } +/* BB FIXME - finish add checks for tidStatus BB */ + + return; +} +#endif + static int cifs_remount(struct super_block *sb, int *flags, char *data) { *flags |= MS_NODIRATIME; @@ -415,7 +453,9 @@ struct super_operations cifs_super_ops = { unless later we add lazy close of inodes or unless the kernel forgets to call us with the same number of releases (closes) as opens */ .show_options = cifs_show_options, -/* .umount_begin = cifs_umount_begin, *//* consider adding in the future */ +#ifdef CONFIG_CIFS_EXPERIMENTAL + .umount_begin = cifs_umount_begin, +#endif .remount_fs = cifs_remount, }; @@ -783,9 +823,7 @@ static int cifs_oplock_thread(void * dummyarg) do { if (try_to_freeze()) continue; - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1*HZ); spin_lock(&GlobalMid_Lock); if(list_empty(&GlobalOplock_Q)) { spin_unlock(&GlobalMid_Lock); @@ -834,10 +872,27 @@ static int cifs_oplock_thread(void * dummyarg) } } else spin_unlock(&GlobalMid_Lock); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); /* yield in case q were corrupt */ } } while(!signal_pending(current)); - complete_and_exit (&cifs_oplock_exited, 0); oplockThread = NULL; + complete_and_exit (&cifs_oplock_exited, 0); +} + +static int cifs_dnotify_thread(void * dummyarg) +{ + daemonize("cifsdnotifyd"); + allow_signal(SIGTERM); + + dnotifyThread = current; + do { + if(try_to_freeze()) + continue; + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(39*HZ); + } while(!signal_pending(current)); + complete_and_exit (&cifs_dnotify_exited, 0); } static int __init @@ -851,6 +906,10 @@ init_cifs(void) INIT_LIST_HEAD(&GlobalSMBSessionList); INIT_LIST_HEAD(&GlobalTreeConnectionList); INIT_LIST_HEAD(&GlobalOplock_Q); +#ifdef CONFIG_CIFS_EXPERIMENTAL + INIT_LIST_HEAD(&GlobalDnotifyReqList); + INIT_LIST_HEAD(&GlobalDnotifyRsp_Q); +#endif /* * Initialize Global counters */ @@ -886,10 +945,16 @@ init_cifs(void) if (!rc) { rc = (int)kernel_thread(cifs_oplock_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_VM); - if(rc > 0) - return 0; - else + if(rc > 0) { + rc = (int)kernel_thread(cifs_dnotify_thread, NULL, + CLONE_FS | CLONE_FILES | CLONE_VM); + if(rc > 0) + return 0; + else + cERROR(1,("error %d create dnotify thread", rc)); + } else { cERROR(1,("error %d create oplock thread",rc)); + } } cifs_destroy_request_bufs(); } @@ -918,6 +983,10 @@ exit_cifs(void) send_sig(SIGTERM, oplockThread, 1); wait_for_completion(&cifs_oplock_exited); } + if(dnotifyThread) { + send_sig(SIGTERM, dnotifyThread, 1); + wait_for_completion(&cifs_dnotify_exited); + } } MODULE_AUTHOR("Steve French ");