fs: Lift XFS_IDONTCACHE to the VFS layer
authorIra Weiny <ira.weiny@intel.com>
Thu, 30 Apr 2020 14:41:37 +0000 (07:41 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 13 May 2020 15:44:35 +0000 (08:44 -0700)
DAX effective mode (S_DAX) changes requires inode eviction.

XFS has an advisory flag (XFS_IDONTCACHE) to prevent caching of the
inode if no other additional references are taken.  We lift this flag to
the VFS layer and change the behavior slightly by allowing the flag to
remain even if multiple references are taken.

This will expedite the eviction of inodes to change S_DAX.

Cc: Al Viro <viro@zeniv.linux.org.uk>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Ira Weiny <ira.weiny@intel.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
fs/xfs/xfs_icache.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_super.c
include/linux/fs.h

index 8bf1d15be3f6a047c0727668641016e64fa11360..fa8554b3308daeafb32562185c64290ecde4f9e3 100644 (file)
@@ -479,7 +479,7 @@ xfs_iget_cache_hit(
                xfs_ilock(ip, lock_flags);
 
        if (!(flags & XFS_IGET_INCORE))
-               xfs_iflags_clear(ip, XFS_ISTALE | XFS_IDONTCACHE);
+               xfs_iflags_clear(ip, XFS_ISTALE);
        XFS_STATS_INC(mp, xs_ig_found);
 
        return 0;
@@ -561,7 +561,7 @@ xfs_iget_cache_miss(
         */
        iflags = XFS_INEW;
        if (flags & XFS_IGET_DONTCACHE)
-               iflags |= XFS_IDONTCACHE;
+               VFS_I(ip)->i_state |= I_DONTCACHE;
        ip->i_udquot = NULL;
        ip->i_gdquot = NULL;
        ip->i_pdquot = NULL;
index c6a63f6764a67bead76c69592e603f0010bafc59..95209e3256a23af64118b142c09e93952dead2a9 100644 (file)
@@ -218,8 +218,7 @@ static inline bool xfs_inode_has_cow_data(struct xfs_inode *ip)
 #define XFS_IFLOCK             (1 << __XFS_IFLOCK_BIT)
 #define __XFS_IPINNED_BIT      8        /* wakeup key for zero pin count */
 #define XFS_IPINNED            (1 << __XFS_IPINNED_BIT)
-#define XFS_IDONTCACHE         (1 << 9) /* don't cache the inode long term */
-#define XFS_IEOFBLOCKS         (1 << 10)/* has the preallocblocks tag set */
+#define XFS_IEOFBLOCKS         (1 << 9) /* has the preallocblocks tag set */
 /*
  * If this unlinked inode is in the middle of recovery, don't let drop_inode
  * truncate and free the inode.  This can happen if we iget the inode during
index 424bb9a2d53256b2d65ef3f6291ec6bbd53b642c..a7f8e387ebfefc1719b6dd940a519bf51ce1e8b9 100644 (file)
@@ -702,7 +702,7 @@ xfs_fs_drop_inode(
                return 0;
        }
 
-       return generic_drop_inode(inode) || (ip->i_flags & XFS_IDONTCACHE);
+       return generic_drop_inode(inode);
 }
 
 static void
index a87cc5845a02a30b574e71d908438859a06f8d6a..44bd45af760f23d87511d2901eba657518aa9922 100644 (file)
@@ -2156,6 +2156,8 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
  *
  * I_CREATING          New object's inode in the middle of setting up.
  *
+ * I_DONTCACHE         Evict inode as soon as it is not used anymore.
+ *
  * Q: What is the difference between I_WILL_FREE and I_FREEING?
  */
 #define I_DIRTY_SYNC           (1 << 0)
@@ -2178,6 +2180,7 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
 #define I_WB_SWITCH            (1 << 13)
 #define I_OVL_INUSE            (1 << 14)
 #define I_CREATING             (1 << 15)
+#define I_DONTCACHE            (1 << 16)
 
 #define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
 #define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES)
@@ -3049,7 +3052,8 @@ extern int inode_needs_sync(struct inode *inode);
 extern int generic_delete_inode(struct inode *inode);
 static inline int generic_drop_inode(struct inode *inode)
 {
-       return !inode->i_nlink || inode_unhashed(inode);
+       return !inode->i_nlink || inode_unhashed(inode) ||
+               (inode->i_state & I_DONTCACHE);
 }
 
 extern struct inode *ilookup5_nowait(struct super_block *sb,