svn commit: linux-cifs-client r42 - in branches/SOC/linux-2.6bk-dnotify/fs/cifs: .

asser at samba.org asser at samba.org
Wed Aug 31 20:21:46 GMT 2005


Author: asser
Date: 2005-08-31 20:21:45 +0000 (Wed, 31 Aug 2005)
New Revision: 42

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=linux-cifs-client&rev=42

Log:
Added updating of CompletionFilter. A notify request will be reissued if the
filter is updated.

Modified:
   branches/SOC/linux-2.6bk-dnotify/fs/cifs/cifsfs.c
   branches/SOC/linux-2.6bk-dnotify/fs/cifs/fcntl.c
   branches/SOC/linux-2.6bk-dnotify/fs/cifs/misc.c


Changeset:
Modified: branches/SOC/linux-2.6bk-dnotify/fs/cifs/cifsfs.c
===================================================================
--- branches/SOC/linux-2.6bk-dnotify/fs/cifs/cifsfs.c	2005-08-28 21:23:49 UTC (rev 41)
+++ branches/SOC/linux-2.6bk-dnotify/fs/cifs/cifsfs.c	2005-08-31 20:21:45 UTC (rev 42)
@@ -913,6 +913,8 @@
 				}
 				kmem_cache_free(cifs_dnotify_cachep, dnotify_req);
 				FreeXid(xid);
+			} else {
+				cFYI(1,("dnotify_req == NULL!"));
 			}
 		}
 	} while(!signal_pending(current));

Modified: branches/SOC/linux-2.6bk-dnotify/fs/cifs/fcntl.c
===================================================================
--- branches/SOC/linux-2.6bk-dnotify/fs/cifs/fcntl.c	2005-08-28 21:23:49 UTC (rev 41)
+++ branches/SOC/linux-2.6bk-dnotify/fs/cifs/fcntl.c	2005-08-31 20:21:45 UTC (rev 42)
@@ -72,9 +72,10 @@
 	struct cifsTconInfo *pTcon;
 	char *full_path = NULL;
 	__u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES;
+	__u32 newfilter;
 	__u16 netfid;
-	struct dir_notify_req *dnotify_req;
-	struct list_head *tmp, *tmp1;
+	struct dir_notify_req *dnotify_req, *tmpd;
+	struct list_head *tmp;
 
 	xid = GetXid();
 	cifs_sb = CIFS_SB(file->f_dentry->d_sb);
@@ -89,51 +90,93 @@
 	} else {
 		cERROR(1,("cifs dir notify on file %s with arg 0x%lx (cifs arg 0x%lx)",full_path,arg,(unsigned long)convert_to_cifs_notify_flags(arg))); /* BB removeme BB */
 
+		/* Find pending request if it exists */
+		dnotify_req = NULL;
+		spin_lock(&GlobalMid_Lock);
+		list_for_each(tmp, &GlobalDnotifyReqList) {
+			tmpd = list_entry(tmp, struct dir_notify_req, lhead);
+
+			if(tmpd->file == file) {
+				dnotify_req = tmpd;
+				break;
+			}
+		}
+		spin_unlock(&GlobalMid_Lock);
+
 		if(arg == 0) {
-			cFYI(1,("arg = 0, cancelling notification on %s",full_path));
-			/* arg = 0 means cancel the notification */
-			spin_lock(&GlobalMid_Lock);
-			list_for_each_safe(tmp, tmp1, &GlobalDnotifyReqList) {
-				dnotify_req = list_entry(tmp, struct dir_notify_req, lhead);
+			if(dnotify_req) {
+				cFYI(1,("arg = 0, cancelling notification on %s (netfid %d)",full_path,(int)netfid));
+				/* arg = 0 means cancel the notification */
+				rc = CIFSSMBCancel(xid, pTcon, dnotify_req->Uid, dnotify_req->Pid,
+						dnotify_req->PidHigh, dnotify_req->Tid, dnotify_req->Mid);
 
-				if(dnotify_req->file == file) {
-					rc = CIFSSMBCancel(xid, pTcon, dnotify_req->Uid, dnotify_req->Pid,
-							dnotify_req->PidHigh, dnotify_req->Tid, dnotify_req->Mid);
+				if(rc) {
+					cERROR(1,("Error in CIFSSMBCancel = %d", rc));
+				} else {
+					rc = CIFSSMBClose(xid, pTcon, dnotify_req->netfid);
 
-					cFYI(1,("Error in CIFSSMBCancel = %d", rc));
 					if(rc) {
-						cFYI(1,("Error in CIFSSMBCancel = %d", rc));
+						cERROR(1,("Error in CIFSSMBClose = %d", rc));
 					}
 				}
 			}
-			spin_unlock(&GlobalMid_Lock);
 		} else {
-			rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, 
-				GENERIC_READ | SYNCHRONIZE, 0 /* create options */,
-				&netfid, &oplock,NULL, cifs_sb->local_nls,
-				cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
-			/* BB fixme - add this handle to a notify handle list */
-			if(rc) {
-				cERROR(1,("Could not open directory for notify"));  /* BB remove BB */
-			} else {
-				filter = convert_to_cifs_notify_flags(arg);
-				if(filter != 0) {
-					rc = CIFSSMBNotify(xid, pTcon, 0 /* no subdirs */, netfid, 
-						filter, cifs_sb->local_nls, file, arg & DN_MULTISHOT);
+			filter = convert_to_cifs_notify_flags(arg);
 
+			if(dnotify_req) {
+				newfilter = dnotify_req->filter | filter;
+				/* If CompletionFilter got added bits, re-request 
+				 * The kernel dnotify does this by doing
+				   i_dnotify_mask |= new_mask */
+				if((newfilter & filter) == filter && (newfilter & ~filter)) {
+					cFYI(1,("Updating filter on %s (netfid %d)",full_path,(int)netfid));
+					rc = CIFSSMBCancel(xid, pTcon, dnotify_req->Uid, dnotify_req->Pid,
+							dnotify_req->PidHigh, dnotify_req->Tid, dnotify_req->Mid);
+
+					if(rc) {
+						cERROR(1,("Error in CIFSSMBCancel: %d", rc));
+					} else {
+						rc = CIFSSMBNotify(xid, pTcon, 0 /* no subdirs */, netfid,
+							filter, cifs_sb->local_nls, file, arg & DN_MULTISHOT);
+
+						if(rc) {
+							cERROR(1,("Error in CIFSSMBNotify: %d", rc));
+						}
+					}
 				} else {
-					/* ASF TODO: Close the file handle */
-					rc = -EINVAL;
+					cERROR(1,("Filter didn't change, doing nothing (old:0x%lx new:0x%lx)",filter,newfilter));
 				}
-				/* BB add code to close file eventually (at unmount
-				it would close automatically but may be a way
-				to do it easily when inode freed or when
-				notify info is cleared/changed */
-				cERROR(1,("notify rc %d",rc));
+			} else {
+				rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, 
+					GENERIC_READ | SYNCHRONIZE, 0 /* create options */,
+					&netfid, &oplock,NULL, cifs_sb->local_nls,
+					cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+				/* BB fixme - add this handle to a notify handle list */
+				if(rc) {
+					cERROR(1,("Could not open directory for notify"));  /* BB remove BB */
+				} else {
+					if(filter != 0) {
+						rc = CIFSSMBNotify(xid, pTcon, 0 /* no subdirs */, netfid, 
+							filter, cifs_sb->local_nls, file, arg & DN_MULTISHOT);
+
+					} else {
+						rc = CIFSSMBClose(xid, pTcon, netfid);
+						if(rc) {
+							cERROR(1,("Could not close open directory (netfid %d) rc = %d", netfid, rc));
+						}
+						rc = -EINVAL;
+					}
+					/* BB add code to close file eventually (at unmount
+					it would close automatically but may be a way
+					to do it easily when inode freed or when
+					notify info is cleared/changed */
+					cERROR(1,("notify rc %d",rc));
+				}
 			}
 		}
 	}
 	
 	FreeXid(xid);
+	cERROR(1,("notify rc %d",rc));
 	return rc;
 }

Modified: branches/SOC/linux-2.6bk-dnotify/fs/cifs/misc.c
===================================================================
--- branches/SOC/linux-2.6bk-dnotify/fs/cifs/misc.c	2005-08-28 21:23:49 UTC (rev 41)
+++ branches/SOC/linux-2.6bk-dnotify/fs/cifs/misc.c	2005-08-31 20:21:45 UTC (rev 42)
@@ -406,9 +406,9 @@
 		__u32 data_offset = 0;
 		cFYI(1,("pSMBr ByteCount:%ld TotalParameterCount:%ld ParameterCount:%ld DataCount:%ld", (unsigned long)pSMBr->ByteCount, (unsigned long)pSMBr->TotalParameterCount, (unsigned long)pSMBr->ParameterCount, (unsigned long)pSMBr->DataCount));
 		cFYI(1,("pSMBr ParameterOffset:%ld DataOffset:%ld", (unsigned long)pSMBr->ParameterOffset, (unsigned long)pSMBr->DataOffset));
-		pnotify = (struct file_notify_information *) (&pSMBr->hdr.Protocol) + pSMBr->DataOffset;
-		cFYI(1,("pnotify NextEntryOffset:%lx Action:%lx FileNameLength:%ld",(unsigned long)pnotify->NextEntryOffset,(unsigned long)pnotify->Action,(unsigned long)pnotify->FileNameLength));
-		cFYI(1,("notify err 0x%x",pSMBr->hdr.Status.CifsError));
+		//pnotify = (struct file_notify_information *) (&pSMBr->hdr.Protocol) + pSMBr->DataOffset;
+		//cFYI(1,("pnotify NextEntryOffset:%lx Action:%lx FileNameLength:%ld",(unsigned long)pnotify->NextEntryOffset,(unsigned long)pnotify->Action,(unsigned long)pnotify->FileNameLength));
+		//cFYI(1,("notify err 0x%x",pSMBr->hdr.Status.CifsError));
 		/* Find the request on the req list */
 		spin_lock(&GlobalMid_Lock);
 		list_for_each_safe(tmp, tmp1, &GlobalDnotifyReqList) {
@@ -418,13 +418,15 @@
 			   dnotify_req->PidHigh == pSMBr->hdr.PidHigh && 
 			   dnotify_req->Pid == pSMBr->hdr.Pid)
 			{
-				list_del(tmp);
+				cFYI(1,("Found pending request with mid:%ld pidhigh:%d pid:%d",dnotify_req->Mid,dnotify_req->PidHigh,dnotify_req->Pid));
+				list_del(&dnotify_req->lhead);
 				if ((NT_STATUS_CANCELLED) == 
 				   le32_to_cpu(pSMBr->hdr.Status.CifsError)) {
 					cFYI(1,("Request was cancelled (err %lx)", pSMBr->hdr.Status.CifsError));
-					kfree(dnotify_req);
+					kmem_cache_free(cifs_dnotify_cachep, dnotify_req);
 				} else if(SUCCESS == le32_to_cpu(pSMBr->hdr.Status.CifsError) ||
 						  STATUS_NOTIFY_ENUM_DIR == le32_to_cpu(pSMBr->hdr.Status.CifsError)) {
+					cFYI(1,("success response (status %lx)", pSMBr->hdr.Status.CifsError));
 					list_add_tail(&dnotify_req->lhead, &GlobalDnotifyRsp_Q);
 				} else {
 					cFYI(1,("Unknown NOTIFY response 0x%lx", pSMBr->hdr.Status.CifsError));



More information about the samba-cvs mailing list