NFS: Fix atime revalidation in readdir()
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Fri, 28 Sep 2007 21:11:45 +0000 (17:11 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 9 Oct 2007 21:19:03 +0000 (17:19 -0400)
NFSv3 will correctly update atime on a readdir call, so there is no need to
set the NFS_INO_INVALID_ATIME flag unless the call to nfs_refresh_inode()
fails.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/dir.c
fs/nfs/inode.c
fs/nfs/nfs3proc.c
fs/nfs/nfs4proc.c
fs/nfs/proc.c
include/linux/nfs_fs.h

index 9f8ec3c..07df192 100644 (file)
@@ -200,9 +200,6 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
        desc->timestamp = timestamp;
        desc->timestamp_valid = 1;
        SetPageUptodate(page);
-       spin_lock(&inode->i_lock);
-       NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
-       spin_unlock(&inode->i_lock);
        /* Ensure consistent page alignment of the data.
         * Note: assumes we have exclusive access to this mapping either
         *       through inode->i_mutex or some other mechanism.
@@ -490,9 +487,6 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
                                                page,
                                                NFS_SERVER(inode)->dtsize,
                                                desc->plus);
-       spin_lock(&inode->i_lock);
-       NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
-       spin_unlock(&inode->i_lock);
        desc->page = page;
        desc->ptr = kmap(page);         /* matching kunmap in nfs_do_filldir */
        if (desc->error >= 0) {
index cd57f79..e37faa3 100644 (file)
@@ -156,6 +156,13 @@ static void nfs_zap_acl_cache(struct inode *inode)
        spin_unlock(&inode->i_lock);
 }
 
+void nfs_invalidate_atime(struct inode *inode)
+{
+       spin_lock(&inode->i_lock);
+       NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
+       spin_unlock(&inode->i_lock);
+}
+
 /*
  * Invalidate, but do not unhash, the inode.
  * NB: must be called with inode->i_lock held!
index c7ca5d7..0ae263c 100644 (file)
@@ -607,6 +607,9 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
 
        nfs_fattr_init(&dir_attr);
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+
+       nfs_invalidate_atime(dir);
+
        nfs_refresh_inode(dir, &dir_attr);
        dprintk("NFS reply readdir: %d\n", status);
        return status;
index 871c102..9c27a6e 100644 (file)
@@ -2197,6 +2197,9 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
        if (status == 0)
                memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
+
+       nfs_invalidate_atime(dir);
+
        dprintk("%s: returns %d\n", __FUNCTION__, status);
        return status;
 }
index 845cdde..cfc4130 100644 (file)
@@ -476,6 +476,8 @@ nfs_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
        dprintk("NFS call  readdir %d\n", (unsigned int)cookie);
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
 
+       nfs_invalidate_atime(dir);
+
        dprintk("NFS reply readdir: %d\n", status);
        return status;
 }
index fd2c5c8..63850a8 100644 (file)
@@ -288,6 +288,7 @@ static inline int nfs_verify_change_attribute(struct inode *inode, unsigned long
 extern int nfs_sync_mapping(struct address_space *mapping);
 extern void nfs_zap_mapping(struct inode *inode, struct address_space *mapping);
 extern void nfs_zap_caches(struct inode *);
+extern void nfs_invalidate_atime(struct inode *);
 extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
                                struct nfs_fattr *);
 extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);