NFS: Clean up cache validity checking
authorTrond Myklebust <trond.myklebust@primarydata.com>
Thu, 8 Dec 2016 23:18:38 +0000 (18:18 -0500)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Mon, 19 Dec 2016 22:29:35 +0000 (17:29 -0500)
Consolidate the open-coded checking of NFS_I(inode)->cache_validity
into a couple of helper functions.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/internal.h

index 64c11f399b3d4edfb0b9416550e5391277cf5a3e..599a602cb2fd1449771de506c102685fe88073e0 100644 (file)
@@ -101,21 +101,11 @@ EXPORT_SYMBOL_GPL(nfs_file_release);
 static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
 {
        struct nfs_server *server = NFS_SERVER(inode);
-       struct nfs_inode *nfsi = NFS_I(inode);
-       const unsigned long force_reval = NFS_INO_REVAL_PAGECACHE|NFS_INO_REVAL_FORCED;
-       unsigned long cache_validity = nfsi->cache_validity;
-
-       if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ) &&
-           (cache_validity & force_reval) != force_reval)
-               goto out_noreval;
 
        if (filp->f_flags & O_DIRECT)
                goto force_reval;
-       if (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
-               goto force_reval;
-       if (nfs_attribute_timeout(inode))
+       if (nfs_check_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE))
                goto force_reval;
-out_noreval:
        return 0;
 force_reval:
        return __nfs_revalidate_inode(server, inode);
index 2fc237cd338e7ac61dcca3f4ca102029a83a2bf3..e3194aa797f793bf40bc8fa5dd9ca153a9ce93ee 100644 (file)
@@ -160,6 +160,36 @@ int nfs_sync_mapping(struct address_space *mapping)
        return ret;
 }
 
+static bool nfs_check_cache_invalid_delegated(struct inode *inode, unsigned long flags)
+{
+       unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
+
+       /* Special case for the pagecache or access cache */
+       if (flags == NFS_INO_REVAL_PAGECACHE &&
+           !(cache_validity & NFS_INO_REVAL_FORCED))
+               return false;
+       return (cache_validity & flags) != 0;
+}
+
+static bool nfs_check_cache_invalid_not_delegated(struct inode *inode, unsigned long flags)
+{
+       unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
+
+       if ((cache_validity & flags) != 0)
+               return true;
+       if (nfs_attribute_timeout(inode))
+               return true;
+       return false;
+}
+
+bool nfs_check_cache_invalid(struct inode *inode, unsigned long flags)
+{
+       if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
+               return nfs_check_cache_invalid_delegated(inode, flags);
+
+       return nfs_check_cache_invalid_not_delegated(inode, flags);
+}
+
 static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
@@ -1116,17 +1146,8 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map
 
 bool nfs_mapping_need_revalidate_inode(struct inode *inode)
 {
-       unsigned long cache_validity = NFS_I(inode)->cache_validity;
-
-       if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) {
-               const unsigned long force_reval =
-                       NFS_INO_REVAL_PAGECACHE|NFS_INO_REVAL_FORCED;
-               return (cache_validity & force_reval) == force_reval;
-       }
-
-       return (cache_validity & NFS_INO_REVAL_PAGECACHE)
-               || nfs_attribute_timeout(inode)
-               || NFS_STALE(inode);
+       return nfs_check_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE) ||
+               NFS_STALE(inode);
 }
 
 int nfs_revalidate_mapping_rcu(struct inode *inode)
index 6b79c2ca9b9a5eed783117d43b12006f6260f107..09ca5095c04e427c881785170aefe7fdf58e7621 100644 (file)
@@ -381,6 +381,7 @@ extern int nfs_drop_inode(struct inode *);
 extern void nfs_clear_inode(struct inode *);
 extern void nfs_evict_inode(struct inode *);
 void nfs_zap_acl_cache(struct inode *inode);
+extern bool nfs_check_cache_invalid(struct inode *, unsigned long);
 extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);
 extern int nfs_wait_atomic_killable(atomic_t *p);