]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/nfs/inode.c
NFS: flush cached directory information slightly more readily.
[karo-tx-linux.git] / fs / nfs / inode.c
index 0c381686171e30cc1eab1f71128bce7837bd22dd..268ce3a462202b1546aba3ffd46c369c240d04b5 100644 (file)
@@ -670,9 +670,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
        if (NFS_STALE(inode))
                goto out;
 
-       if (NFS_STALE(inode))
-               goto out;
-
        nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
        status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr);
        if (status != 0) {
@@ -1116,8 +1113,16 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                                nfs_force_lookup_revalidate(inode);
                }
                /* If ctime has changed we should definitely clear access+acl caches */
-               if (!timespec_equal(&inode->i_ctime, &fattr->ctime))
+               if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) {
                        invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
+                       /* and probably clear data for a directory too as utimes can cause
+                        * havoc with our cache.
+                        */
+                       if (S_ISDIR(inode->i_mode)) {
+                               invalid |= NFS_INO_INVALID_DATA;
+                               nfs_force_lookup_revalidate(inode);
+                       }
+               }
        } else if (nfsi->change_attr != fattr->change_attr) {
                dprintk("NFS: change_attr change on server for file %s/%ld\n",
                                inode->i_sb->s_id, inode->i_ino);
@@ -1151,8 +1156,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
            inode->i_gid != fattr->gid)
                invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
 
-       if (inode->i_nlink != fattr->nlink)
+       if (inode->i_nlink != fattr->nlink) {
                invalid |= NFS_INO_INVALID_ATTR;
+               if (S_ISDIR(inode->i_mode))
+                       invalid |= NFS_INO_INVALID_DATA;
+       }
 
        inode->i_mode = fattr->mode;
        inode->i_nlink = fattr->nlink;