Skip to content

Commit 8eeae5b

Browse files
committed
Merge tag 'vfs-5.8-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull DAX updates part two from Darrick Wong: "This time around, we're hoisting the DONTCACHE flag from XFS into the VFS so that we can make the incore DAX mode changes become effective sooner. We can't change the file data access mode on a live inode because we don't have a safe way to change the file ops pointers. The incore state change becomes effective at inode loading time, which can happen if the inode is evicted. Therefore, we're making it so that filesystems can ask the VFS to evict the inode as soon as the last holder drops. The per-fs changes to make this call this will be in subsequent pull requests from Ted and myself. Summary: - Introduce DONTCACHE flags for dentries and inodes. This hint will cause the VFS to drop the associated objects immediately after the last put, so that we can change the file access mode (DAX or page cache) on the fly" * tag 'vfs-5.8-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: fs: Introduce DCACHE_DONTCACHE fs: Lift XFS_IDONTCACHE to the VFS layer
2 parents 96ed320 + 2c567af commit 8eeae5b

File tree

6 files changed

+31
-6
lines changed

6 files changed

+31
-6
lines changed

fs/dcache.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,10 @@ static inline bool retain_dentry(struct dentry *dentry)
647647
if (dentry->d_op->d_delete(dentry))
648648
return false;
649649
}
650+
651+
if (unlikely(dentry->d_flags & DCACHE_DONTCACHE))
652+
return false;
653+
650654
/* retain; LRU fodder */
651655
dentry->d_lockref.count--;
652656
if (unlikely(!(dentry->d_flags & DCACHE_LRU_LIST)))
@@ -656,6 +660,21 @@ static inline bool retain_dentry(struct dentry *dentry)
656660
return true;
657661
}
658662

663+
void d_mark_dontcache(struct inode *inode)
664+
{
665+
struct dentry *de;
666+
667+
spin_lock(&inode->i_lock);
668+
hlist_for_each_entry(de, &inode->i_dentry, d_u.d_alias) {
669+
spin_lock(&de->d_lock);
670+
de->d_flags |= DCACHE_DONTCACHE;
671+
spin_unlock(&de->d_lock);
672+
}
673+
inode->i_state |= I_DONTCACHE;
674+
spin_unlock(&inode->i_lock);
675+
}
676+
EXPORT_SYMBOL(d_mark_dontcache);
677+
659678
/*
660679
* Finish off a dentry we've decided to kill.
661680
* dentry->d_lock must be held, returns with it unlocked.

fs/xfs/xfs_icache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ xfs_iget_cache_hit(
479479
xfs_ilock(ip, lock_flags);
480480

481481
if (!(flags & XFS_IGET_INCORE))
482-
xfs_iflags_clear(ip, XFS_ISTALE | XFS_IDONTCACHE);
482+
xfs_iflags_clear(ip, XFS_ISTALE);
483483
XFS_STATS_INC(mp, xs_ig_found);
484484

485485
return 0;
@@ -585,7 +585,7 @@ xfs_iget_cache_miss(
585585
*/
586586
iflags = XFS_INEW;
587587
if (flags & XFS_IGET_DONTCACHE)
588-
iflags |= XFS_IDONTCACHE;
588+
d_mark_dontcache(VFS_I(ip));
589589
ip->i_udquot = NULL;
590590
ip->i_gdquot = NULL;
591591
ip->i_pdquot = NULL;

fs/xfs/xfs_inode.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,7 @@ static inline bool xfs_inode_has_cow_data(struct xfs_inode *ip)
215215
#define XFS_IFLOCK (1 << __XFS_IFLOCK_BIT)
216216
#define __XFS_IPINNED_BIT 8 /* wakeup key for zero pin count */
217217
#define XFS_IPINNED (1 << __XFS_IPINNED_BIT)
218-
#define XFS_IDONTCACHE (1 << 9) /* don't cache the inode long term */
219-
#define XFS_IEOFBLOCKS (1 << 10)/* has the preallocblocks tag set */
218+
#define XFS_IEOFBLOCKS (1 << 9) /* has the preallocblocks tag set */
220219
/*
221220
* If this unlinked inode is in the middle of recovery, don't let drop_inode
222221
* truncate and free the inode. This can happen if we iget the inode during

fs/xfs/xfs_super.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ xfs_fs_drop_inode(
737737
return 0;
738738
}
739739

740-
return generic_drop_inode(inode) || (ip->i_flags & XFS_IDONTCACHE);
740+
return generic_drop_inode(inode);
741741
}
742742

743743
static void

include/linux/dcache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ struct dentry_operations {
177177

178178
#define DCACHE_REFERENCED 0x00000040 /* Recently used, don't discard. */
179179

180+
#define DCACHE_DONTCACHE 0x00000080 /* Purge from memory on final dput() */
181+
180182
#define DCACHE_CANT_MOUNT 0x00000100
181183
#define DCACHE_GENOCIDE 0x00000200
182184
#define DCACHE_SHRINK_LIST 0x00000400

include/linux/fs.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2166,6 +2166,8 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
21662166
*
21672167
* I_CREATING New object's inode in the middle of setting up.
21682168
*
2169+
* I_DONTCACHE Evict inode as soon as it is not used anymore.
2170+
*
21692171
* Q: What is the difference between I_WILL_FREE and I_FREEING?
21702172
*/
21712173
#define I_DIRTY_SYNC (1 << 0)
@@ -2188,6 +2190,7 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
21882190
#define I_WB_SWITCH (1 << 13)
21892191
#define I_OVL_INUSE (1 << 14)
21902192
#define I_CREATING (1 << 15)
2193+
#define I_DONTCACHE (1 << 16)
21912194

21922195
#define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
21932196
#define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES)
@@ -3068,8 +3071,10 @@ extern int inode_needs_sync(struct inode *inode);
30683071
extern int generic_delete_inode(struct inode *inode);
30693072
static inline int generic_drop_inode(struct inode *inode)
30703073
{
3071-
return !inode->i_nlink || inode_unhashed(inode);
3074+
return !inode->i_nlink || inode_unhashed(inode) ||
3075+
(inode->i_state & I_DONTCACHE);
30723076
}
3077+
extern void d_mark_dontcache(struct inode *inode);
30733078

30743079
extern struct inode *ilookup5_nowait(struct super_block *sb,
30753080
unsigned long hashval, int (*test)(struct inode *, void *),

0 commit comments

Comments
 (0)