]> err.no Git - linux-2.6/commitdiff
[CIFS] When file is deleted locally but later recreated on the server
authorSteve French <sfrench@us.ibm.com>
Mon, 28 Nov 2005 16:16:13 +0000 (08:16 -0800)
committerSteve French <sfrench@us.ibm.com>
Mon, 28 Nov 2005 16:16:13 +0000 (08:16 -0800)
fix cifs negative dentries so they are freed faster (not requiring
umount or readdir e.g.) so the client recognizes the new file on
the server more quickly.

Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/CHANGES
fs/cifs/dir.c
fs/cifs/inode.c

index 6bded10c0d507c01ece3e758d162882398beafd7..c40bd0df80ad5dd7b4c2440086908b4373fb1a2b 100644 (file)
@@ -1,10 +1,12 @@
 Version 1.39
 ------------
-Defer close of a file handle slightly if pending writes depend on that file handle
+Defer close of a file handle slightly if pending writes depend on that handle
 (this reduces the EBADF bad file handle errors that can be logged under heavy
 stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2 
-Fix SFU style symlinks and mknod needed for servers which do not support the CIFS
-Unix Extensions.  Fix setfacl/getfacl on bigendian. 
+Fix SFU style symlinks and mknod needed for servers which do not support the
+CIFS Unix Extensions.  Fix setfacl/getfacl on bigendian. Timeout negative
+dentries so files that the client sees as deleted but that later get created
+on the server will be recognized.
 
 Version 1.38
 ------------
index 16b21522e8fe1bbd06a97a7da2297e38cc8056d3..aa4ea965b329a8d27763917ea0868bb4a220680b 100644 (file)
@@ -465,12 +465,20 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
                        direntry->d_op = &cifs_dentry_ops;
                d_add(direntry, newInode);
 
-               /* since paths are not looked up by component - the parent directories are presumed to be good here */
+               /* since paths are not looked up by component - the parent 
+                  directories are presumed to be good here */
                renew_parental_timestamps(direntry);
 
        } else if (rc == -ENOENT) {
                rc = 0;
+               direntry->d_time = jiffies;
+               if (pTcon->nocase)
+                       direntry->d_op = &cifs_ci_dentry_ops;
+               else
+                       direntry->d_op = &cifs_dentry_ops;
                d_add(direntry, NULL);
+       /*      if it was once a directory (but how can we tell?) we could do  
+                       shrink_dcache_parent(direntry); */
        } else {
                cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s",
                           rc,full_path));
@@ -489,21 +497,20 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
 {
        int isValid = 1;
 
-/*     lock_kernel(); *//* surely we do not want to lock the kernel for a whole network round trip which could take seconds */
-
        if (direntry->d_inode) {
                if (cifs_revalidate(direntry)) {
-                       /* unlock_kernel(); */
                        return 0;
                }
        } else {
-               cFYI(1,
-                    ("In cifs_d_revalidate with no inode but name = %s and dentry 0x%p",
-                     direntry->d_name.name, direntry));
+               cFYI(1, ("neg dentry 0x%p name = %s",
+                        direntry, direntry->d_name.name));
+               if(time_after(jiffies, direntry->d_time + HZ) || 
+                       !lookupCacheEnabled) {
+                       d_drop(direntry);
+                       isValid = 0;
+               } 
        }
 
-/*    unlock_kernel(); */
-
        return isValid;
 }
 
index 05b525812adb5ba238a8f2bc1138eac7f108a43c..d34325c887c4977bc2a6a0197372986423c0fd86 100644 (file)
@@ -1039,14 +1039,20 @@ int cifs_revalidate(struct dentry *direntry)
                filemap_fdatawrite(direntry->d_inode->i_mapping);
        }
        if (invalidate_inode) {
-               if (direntry->d_inode->i_mapping)
-                       filemap_fdatawait(direntry->d_inode->i_mapping);
-               /* may eventually have to do this for open files too */
-               if (list_empty(&(cifsInode->openFileList))) {
-                       /* Has changed on server - flush read ahead pages */
-                       cFYI(1, ("Invalidating read ahead data on "
-                                "closed file"));
-                       invalidate_remote_inode(direntry->d_inode);
+       /* shrink_dcache not necessary now that cifs dentry ops
+       are exported for negative dentries */
+/*             if(S_ISDIR(direntry->d_inode->i_mode)) 
+                       shrink_dcache_parent(direntry); */
+               if (S_ISREG(direntry->d_inode->i_mode)) {
+                       if (direntry->d_inode->i_mapping)
+                               filemap_fdatawait(direntry->d_inode->i_mapping);
+                       /* may eventually have to do this for open files too */
+                       if (list_empty(&(cifsInode->openFileList))) {
+                               /* changed on server - flush read ahead pages */
+                               cFYI(1, ("Invalidating read ahead data on "
+                                        "closed file"));
+                               invalidate_remote_inode(direntry->d_inode);
+                       }
                }
        }
 /*     up(&direntry->d_inode->i_sem); */