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));

Reply via email to