diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 0742c269ef12..b45d38b89116 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -981,10 +981,10 @@ init_cifs(void) int rc = 0; cifs_proc_init(); INIT_LIST_HEAD(&cifs_tcp_ses_list); -#ifdef CONFIG_CIFS_EXPERIMENTAL +#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */ INIT_LIST_HEAD(&GlobalDnotifyReqList); INIT_LIST_HEAD(&GlobalDnotifyRsp_Q); -#endif +#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */ /* * Initialize Global counters */ diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index a5d1106fcbde..6e211b67b273 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -780,10 +780,12 @@ GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock; */ GLOBAL_EXTERN spinlock_t cifs_file_list_lock; +#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */ /* Outstanding dir notify requests */ GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; /* DirNotify response queue */ GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q; +#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */ /* * Global transaction id (XID) information diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 8096f27ad9a8..34bbd5cf46d0 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -386,6 +386,12 @@ extern int calc_seckey(struct cifsSesInfo *); extern void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt, char *lnm_session_key); #endif /* CIFS_WEAK_PW_HASH */ +#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */ +extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, + const int notify_subdirs, const __u16 netfid, + __u32 filter, struct file *file, int multishot, + const struct nls_table *nls_codepage); +#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */ extern int CIFSSMBCopy(int xid, struct cifsTconInfo *source_tcon, const char *fromName, @@ -393,10 +399,6 @@ extern int CIFSSMBCopy(int xid, const char *toName, const int flags, const struct nls_table *nls_codepage, int remap_special_chars); -extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, - const int notify_subdirs, const __u16 netfid, - __u32 filter, struct file *file, int multishot, - const struct nls_table *nls_codepage); extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, const unsigned char *ea_name, char *EAData, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index df959bae6728..5630282f2821 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -5418,79 +5418,6 @@ setPermsRetry: return rc; } -int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, - const int notify_subdirs, const __u16 netfid, - __u32 filter, struct file *pfile, int multishot, - const struct nls_table *nls_codepage) -{ - int rc = 0; - struct smb_com_transaction_change_notify_req *pSMB = NULL; - struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL; - struct dir_notify_req *dnotify_req; - int bytes_returned; - - cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid); - rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, - (void **) &pSMBr); - if (rc) - return rc; - - pSMB->TotalParameterCount = 0 ; - pSMB->TotalDataCount = 0; - pSMB->MaxParameterCount = cpu_to_le32(2); - /* BB find exact data count max from sess structure BB */ - pSMB->MaxDataCount = 0; /* same in little endian or be */ -/* BB VERIFY verify which is correct for above BB */ - pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); - - pSMB->MaxSetupCount = 4; - pSMB->Reserved = 0; - pSMB->ParameterOffset = 0; - pSMB->DataCount = 0; - pSMB->DataOffset = 0; - pSMB->SetupCount = 4; /* single byte does not need le conversion */ - pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE); - pSMB->ParameterCount = pSMB->TotalParameterCount; - if (notify_subdirs) - pSMB->WatchTree = 1; /* one byte - no le conversion needed */ - pSMB->Reserved2 = 0; - pSMB->CompletionFilter = cpu_to_le32(filter); - pSMB->Fid = netfid; /* file handle always le */ - pSMB->ByteCount = 0; - - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *)pSMBr, &bytes_returned, - CIFS_ASYNC_OP); - if (rc) { - cFYI(1, "Error in Notify = %d", rc); - } else { - /* Add file to outstanding requests */ - /* BB change to kmem cache alloc */ - dnotify_req = kmalloc( - sizeof(struct dir_notify_req), - GFP_KERNEL); - if (dnotify_req) { - dnotify_req->Pid = pSMB->hdr.Pid; - dnotify_req->PidHigh = pSMB->hdr.PidHigh; - dnotify_req->Mid = pSMB->hdr.Mid; - dnotify_req->Tid = pSMB->hdr.Tid; - dnotify_req->Uid = pSMB->hdr.Uid; - dnotify_req->netfid = netfid; - dnotify_req->pfile = pfile; - dnotify_req->filter = filter; - dnotify_req->multishot = multishot; - spin_lock(&GlobalMid_Lock); - list_add_tail(&dnotify_req->lhead, - &GlobalDnotifyReqList); - spin_unlock(&GlobalMid_Lock); - } else - rc = -ENOMEM; - } - cifs_buf_release(pSMB); - return rc; -} - #ifdef CONFIG_CIFS_XATTR /* * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common @@ -5787,5 +5714,99 @@ SetEARetry: return rc; } - #endif + +#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */ +/* + * Years ago the kernel added a "dnotify" function for Samba server, + * to allow network clients (such as Windows) to display updated + * lists of files in directory listings automatically when + * files are added by one user when another user has the + * same directory open on their desktop. The Linux cifs kernel + * client hooked into the kernel side of this interface for + * the same reason, but ironically when the VFS moved from + * "dnotify" to "inotify" it became harder to plug in Linux + * network file system clients (the most obvious use case + * for notify interfaces is when multiple users can update + * the contents of the same directory - exactly what network + * file systems can do) although the server (Samba) could + * still use it. For the short term we leave the worker + * function ifdeffed out (below) until inotify is fixed + * in the VFS to make it easier to plug in network file + * system clients. If inotify turns out to be permanently + * incompatible for network fs clients, we could instead simply + * expose this config flag by adding a future cifs (and smb2) notify ioctl. + */ +int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, + const int notify_subdirs, const __u16 netfid, + __u32 filter, struct file *pfile, int multishot, + const struct nls_table *nls_codepage) +{ + int rc = 0; + struct smb_com_transaction_change_notify_req *pSMB = NULL; + struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL; + struct dir_notify_req *dnotify_req; + int bytes_returned; + + cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid); + rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + pSMB->TotalParameterCount = 0 ; + pSMB->TotalDataCount = 0; + pSMB->MaxParameterCount = cpu_to_le32(2); + /* BB find exact data count max from sess structure BB */ + pSMB->MaxDataCount = 0; /* same in little endian or be */ +/* BB VERIFY verify which is correct for above BB */ + pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - + MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); + + pSMB->MaxSetupCount = 4; + pSMB->Reserved = 0; + pSMB->ParameterOffset = 0; + pSMB->DataCount = 0; + pSMB->DataOffset = 0; + pSMB->SetupCount = 4; /* single byte does not need le conversion */ + pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE); + pSMB->ParameterCount = pSMB->TotalParameterCount; + if (notify_subdirs) + pSMB->WatchTree = 1; /* one byte - no le conversion needed */ + pSMB->Reserved2 = 0; + pSMB->CompletionFilter = cpu_to_le32(filter); + pSMB->Fid = netfid; /* file handle always le */ + pSMB->ByteCount = 0; + + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *)pSMBr, &bytes_returned, + CIFS_ASYNC_OP); + if (rc) { + cFYI(1, "Error in Notify = %d", rc); + } else { + /* Add file to outstanding requests */ + /* BB change to kmem cache alloc */ + dnotify_req = kmalloc( + sizeof(struct dir_notify_req), + GFP_KERNEL); + if (dnotify_req) { + dnotify_req->Pid = pSMB->hdr.Pid; + dnotify_req->PidHigh = pSMB->hdr.PidHigh; + dnotify_req->Mid = pSMB->hdr.Mid; + dnotify_req->Tid = pSMB->hdr.Tid; + dnotify_req->Uid = pSMB->hdr.Uid; + dnotify_req->netfid = netfid; + dnotify_req->pfile = pfile; + dnotify_req->filter = filter; + dnotify_req->multishot = multishot; + spin_lock(&GlobalMid_Lock); + list_add_tail(&dnotify_req->lhead, + &GlobalDnotifyReqList); + spin_unlock(&GlobalMid_Lock); + } else + rc = -ENOMEM; + } + cifs_buf_release(pSMB); + return rc; +} +#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */