aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsfs.c4
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/cifsproto.h10
-rw-r--r--fs/cifs/cifssmb.c169
4 files changed, 105 insertions, 80 deletions
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)
981 int rc = 0; 981 int rc = 0;
982 cifs_proc_init(); 982 cifs_proc_init();
983 INIT_LIST_HEAD(&cifs_tcp_ses_list); 983 INIT_LIST_HEAD(&cifs_tcp_ses_list);
984#ifdef CONFIG_CIFS_EXPERIMENTAL 984#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
985 INIT_LIST_HEAD(&GlobalDnotifyReqList); 985 INIT_LIST_HEAD(&GlobalDnotifyReqList);
986 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q); 986 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
987#endif 987#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
988/* 988/*
989 * Initialize Global counters 989 * Initialize Global counters
990 */ 990 */
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;
780 */ 780 */
781GLOBAL_EXTERN spinlock_t cifs_file_list_lock; 781GLOBAL_EXTERN spinlock_t cifs_file_list_lock;
782 782
783#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
783/* Outstanding dir notify requests */ 784/* Outstanding dir notify requests */
784GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; 785GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
785/* DirNotify response queue */ 786/* DirNotify response queue */
786GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q; 787GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q;
788#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
787 789
788/* 790/*
789 * Global transaction id (XID) information 791 * 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 *);
386extern void calc_lanman_hash(const char *password, const char *cryptkey, 386extern void calc_lanman_hash(const char *password, const char *cryptkey,
387 bool encrypt, char *lnm_session_key); 387 bool encrypt, char *lnm_session_key);
388#endif /* CIFS_WEAK_PW_HASH */ 388#endif /* CIFS_WEAK_PW_HASH */
389#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
390extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
391 const int notify_subdirs, const __u16 netfid,
392 __u32 filter, struct file *file, int multishot,
393 const struct nls_table *nls_codepage);
394#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
389extern int CIFSSMBCopy(int xid, 395extern int CIFSSMBCopy(int xid,
390 struct cifsTconInfo *source_tcon, 396 struct cifsTconInfo *source_tcon,
391 const char *fromName, 397 const char *fromName,
@@ -393,10 +399,6 @@ extern int CIFSSMBCopy(int xid,
393 const char *toName, const int flags, 399 const char *toName, const int flags,
394 const struct nls_table *nls_codepage, 400 const struct nls_table *nls_codepage,
395 int remap_special_chars); 401 int remap_special_chars);
396extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
397 const int notify_subdirs, const __u16 netfid,
398 __u32 filter, struct file *file, int multishot,
399 const struct nls_table *nls_codepage);
400extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, 402extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
401 const unsigned char *searchName, 403 const unsigned char *searchName,
402 const unsigned char *ea_name, char *EAData, 404 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:
5418 return rc; 5418 return rc;
5419} 5419}
5420 5420
5421int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5422 const int notify_subdirs, const __u16 netfid,
5423 __u32 filter, struct file *pfile, int multishot,
5424 const struct nls_table *nls_codepage)
5425{
5426 int rc = 0;
5427 struct smb_com_transaction_change_notify_req *pSMB = NULL;
5428 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
5429 struct dir_notify_req *dnotify_req;
5430 int bytes_returned;
5431
5432 cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
5433 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
5434 (void **) &pSMBr);
5435 if (rc)
5436 return rc;
5437
5438 pSMB->TotalParameterCount = 0 ;
5439 pSMB->TotalDataCount = 0;
5440 pSMB->MaxParameterCount = cpu_to_le32(2);
5441 /* BB find exact data count max from sess structure BB */
5442 pSMB->MaxDataCount = 0; /* same in little endian or be */
5443/* BB VERIFY verify which is correct for above BB */
5444 pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
5445 MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
5446
5447 pSMB->MaxSetupCount = 4;
5448 pSMB->Reserved = 0;
5449 pSMB->ParameterOffset = 0;
5450 pSMB->DataCount = 0;
5451 pSMB->DataOffset = 0;
5452 pSMB->SetupCount = 4; /* single byte does not need le conversion */
5453 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
5454 pSMB->ParameterCount = pSMB->TotalParameterCount;
5455 if (notify_subdirs)
5456 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
5457 pSMB->Reserved2 = 0;
5458 pSMB->CompletionFilter = cpu_to_le32(filter);
5459 pSMB->Fid = netfid; /* file handle always le */
5460 pSMB->ByteCount = 0;
5461
5462 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5463 (struct smb_hdr *)pSMBr, &bytes_returned,
5464 CIFS_ASYNC_OP);
5465 if (rc) {
5466 cFYI(1, "Error in Notify = %d", rc);
5467 } else {
5468 /* Add file to outstanding requests */
5469 /* BB change to kmem cache alloc */
5470 dnotify_req = kmalloc(
5471 sizeof(struct dir_notify_req),
5472 GFP_KERNEL);
5473 if (dnotify_req) {
5474 dnotify_req->Pid = pSMB->hdr.Pid;
5475 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
5476 dnotify_req->Mid = pSMB->hdr.Mid;
5477 dnotify_req->Tid = pSMB->hdr.Tid;
5478 dnotify_req->Uid = pSMB->hdr.Uid;
5479 dnotify_req->netfid = netfid;
5480 dnotify_req->pfile = pfile;
5481 dnotify_req->filter = filter;
5482 dnotify_req->multishot = multishot;
5483 spin_lock(&GlobalMid_Lock);
5484 list_add_tail(&dnotify_req->lhead,
5485 &GlobalDnotifyReqList);
5486 spin_unlock(&GlobalMid_Lock);
5487 } else
5488 rc = -ENOMEM;
5489 }
5490 cifs_buf_release(pSMB);
5491 return rc;
5492}
5493
5494#ifdef CONFIG_CIFS_XATTR 5421#ifdef CONFIG_CIFS_XATTR
5495/* 5422/*
5496 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common 5423 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
@@ -5787,5 +5714,99 @@ SetEARetry:
5787 5714
5788 return rc; 5715 return rc;
5789} 5716}
5790
5791#endif 5717#endif
5718
5719#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
5720/*
5721 * Years ago the kernel added a "dnotify" function for Samba server,
5722 * to allow network clients (such as Windows) to display updated
5723 * lists of files in directory listings automatically when
5724 * files are added by one user when another user has the
5725 * same directory open on their desktop. The Linux cifs kernel
5726 * client hooked into the kernel side of this interface for
5727 * the same reason, but ironically when the VFS moved from
5728 * "dnotify" to "inotify" it became harder to plug in Linux
5729 * network file system clients (the most obvious use case
5730 * for notify interfaces is when multiple users can update
5731 * the contents of the same directory - exactly what network
5732 * file systems can do) although the server (Samba) could
5733 * still use it. For the short term we leave the worker
5734 * function ifdeffed out (below) until inotify is fixed
5735 * in the VFS to make it easier to plug in network file
5736 * system clients. If inotify turns out to be permanently
5737 * incompatible for network fs clients, we could instead simply
5738 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
5739 */
5740int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5741 const int notify_subdirs, const __u16 netfid,
5742 __u32 filter, struct file *pfile, int multishot,
5743 const struct nls_table *nls_codepage)
5744{
5745 int rc = 0;
5746 struct smb_com_transaction_change_notify_req *pSMB = NULL;
5747 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
5748 struct dir_notify_req *dnotify_req;
5749 int bytes_returned;
5750
5751 cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
5752 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
5753 (void **) &pSMBr);
5754 if (rc)
5755 return rc;
5756
5757 pSMB->TotalParameterCount = 0 ;
5758 pSMB->TotalDataCount = 0;
5759 pSMB->MaxParameterCount = cpu_to_le32(2);
5760 /* BB find exact data count max from sess structure BB */
5761 pSMB->MaxDataCount = 0; /* same in little endian or be */
5762/* BB VERIFY verify which is correct for above BB */
5763 pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
5764 MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
5765
5766 pSMB->MaxSetupCount = 4;
5767 pSMB->Reserved = 0;
5768 pSMB->ParameterOffset = 0;
5769 pSMB->DataCount = 0;
5770 pSMB->DataOffset = 0;
5771 pSMB->SetupCount = 4; /* single byte does not need le conversion */
5772 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
5773 pSMB->ParameterCount = pSMB->TotalParameterCount;
5774 if (notify_subdirs)
5775 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
5776 pSMB->Reserved2 = 0;
5777 pSMB->CompletionFilter = cpu_to_le32(filter);
5778 pSMB->Fid = netfid; /* file handle always le */
5779 pSMB->ByteCount = 0;
5780
5781 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5782 (struct smb_hdr *)pSMBr, &bytes_returned,
5783 CIFS_ASYNC_OP);
5784 if (rc) {
5785 cFYI(1, "Error in Notify = %d", rc);
5786 } else {
5787 /* Add file to outstanding requests */
5788 /* BB change to kmem cache alloc */
5789 dnotify_req = kmalloc(
5790 sizeof(struct dir_notify_req),
5791 GFP_KERNEL);
5792 if (dnotify_req) {
5793 dnotify_req->Pid = pSMB->hdr.Pid;
5794 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
5795 dnotify_req->Mid = pSMB->hdr.Mid;
5796 dnotify_req->Tid = pSMB->hdr.Tid;
5797 dnotify_req->Uid = pSMB->hdr.Uid;
5798 dnotify_req->netfid = netfid;
5799 dnotify_req->pfile = pfile;
5800 dnotify_req->filter = filter;
5801 dnotify_req->multishot = multishot;
5802 spin_lock(&GlobalMid_Lock);
5803 list_add_tail(&dnotify_req->lhead,
5804 &GlobalDnotifyReqList);
5805 spin_unlock(&GlobalMid_Lock);
5806 } else
5807 rc = -ENOMEM;
5808 }
5809 cifs_buf_release(pSMB);
5810 return rc;
5811}
5812#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */