Merge tag 'xfs-6.4-rc1-fixes' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
[linux-block.git] / include / linux / nfs_fs.h
index bf89fe6fc3bad96134c07d44074fee7b8084496f..279262057a92582f81514e9d08bcfd57c57a19a0 100644 (file)
 #include <linux/sunrpc/auth.h>
 #include <linux/sunrpc/clnt.h>
 
+#ifdef CONFIG_NFS_FSCACHE
+#include <linux/netfs.h>
+#endif
+
 #include <linux/nfs.h>
 #include <linux/nfs2.h>
 #include <linux/nfs3.h>
@@ -191,6 +195,39 @@ struct nfs_inode {
        /* Open contexts for shared mmap writes */
        struct list_head        open_files;
 
+       /* Keep track of out-of-order replies.
+        * The ooo array contains start/end pairs of
+        * numbers from the changeid sequence when
+        * the inode's iversion has been updated.
+        * It also contains end/start pair (i.e. reverse order)
+        * of sections of the changeid sequence that have
+        * been seen in replies from the server.
+        * Normally these should match and when both
+        * A:B and B:A are found in ooo, they are both removed.
+        * And if a reply with A:B causes an iversion update
+        * of A:B, then neither are added.
+        * When a reply has pre_change that doesn't match
+        * iversion, then the changeid pair and any consequent
+        * change in iversion ARE added.  Later replies
+        * might fill in the gaps, or possibly a gap is caused
+        * by a change from another client.
+        * When a file or directory is opened, if the ooo table
+        * is not empty, then we assume the gaps were due to
+        * another client and we invalidate the cached data.
+        *
+        * We can only track a limited number of concurrent gaps.
+        * Currently that limit is 16.
+        * We allocate the table on demand.  If there is insufficient
+        * memory, then we probably cannot cache the file anyway
+        * so there is no loss.
+        */
+       struct {
+               int cnt;
+               struct {
+                       u64 start, end;
+               } gap[16];
+       } *ooo;
+
 #if IS_ENABLED(CONFIG_NFS_V4)
        struct nfs4_cached_acl  *nfs4_acl;
         /* NFSv4 state */
@@ -204,14 +241,15 @@ struct nfs_inode {
        /* how many bytes have been written/read and how many bytes queued up */
        __u64 write_io;
        __u64 read_io;
-#ifdef CONFIG_NFS_FSCACHE
-       struct fscache_cookie   *fscache;
-#endif
-       struct inode            vfs_inode;
-
 #ifdef CONFIG_NFS_V4_2
        struct nfs4_xattr_cache *xattr_cache;
 #endif
+       union {
+               struct inode            vfs_inode;
+#ifdef CONFIG_NFS_FSCACHE
+               struct netfs_inode      netfs; /* netfs context and VFS inode */
+#endif
+       };
 };
 
 struct nfs4_copy_state {
@@ -276,7 +314,6 @@ struct nfs4_copy_state {
 #define NFS_INO_ACL_LRU_SET    (2)             /* Inode is on the LRU list */
 #define NFS_INO_INVALIDATING   (3)             /* inode is being invalidated */
 #define NFS_INO_PRESERVE_UNLINKED (4)          /* preserve file if removed while open */
-#define NFS_INO_FSCACHE                (5)             /* inode can be cached by FS-Cache */
 #define NFS_INO_LAYOUTCOMMIT   (9)             /* layoutcommit required */
 #define NFS_INO_LAYOUTCOMMITTING (10)          /* layoutcommit inflight */
 #define NFS_INO_LAYOUTSTATS    (11)            /* layoutstats inflight */
@@ -329,15 +366,6 @@ static inline int NFS_STALE(const struct inode *inode)
        return test_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
 }
 
-static inline struct fscache_cookie *nfs_i_fscache(struct inode *inode)
-{
-#ifdef CONFIG_NFS_FSCACHE
-       return NFS_I(inode)->fscache;
-#else
-       return NULL;
-#endif
-}
-
 static inline __u64 NFS_FILEID(const struct inode *inode)
 {
        return NFS_I(inode)->fileid;
@@ -617,6 +645,20 @@ nfs_fileid_to_ino_t(u64 fileid)
        return ino;
 }
 
+static inline void nfs_ooo_clear(struct nfs_inode *nfsi)
+{
+       nfsi->cache_validity &= ~NFS_INO_DATA_INVAL_DEFER;
+       kfree(nfsi->ooo);
+       nfsi->ooo = NULL;
+}
+
+static inline bool nfs_ooo_test(struct nfs_inode *nfsi)
+{
+       return (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER) ||
+               (nfsi->ooo && nfsi->ooo->cnt > 0);
+
+}
+
 #define NFS_JUKEBOX_RETRY_TIME (5 * HZ)
 
 /* We need to block new opens while a file is being unlinked.