> -----Original Message----- > From: Wangkai (Kevin,C) > Sent: Monday, August 07, 2017 5:55 PM > To: linux-fsdevel@xxxxxxxxxxxxxxx; viro@xxxxxxxxxxxxxxxxxx > Cc: Wangkai (Kevin,C); Renjinyong (Renjinyong, Business Support Dept) > Subject: [PATCH] fs/dcache: dentries should free after files unlinked or > directories removed > > sometimes, on my server, there were lots of files creating and removing, and I > found that memory usage were high, and I checked, almost all the memory was > occupied by slab recliamable, the slab struct was dentry, and I checked the > code of dcache, and found that when a file was deleted the dentry never free, > unless a memory recliam was triggerd. > > I made this patch to mark the dentry as a remove state after file unlinked or > directory removed, and when the dentry’s reference count dec to zero and > free it, and it worked well on my server base on kernel 4.4. > > > Signed-off-by: Wangkai <wangkai86@xxxxxxxxxx> > --- > fs/dcache.c | 12 +++++++++++- > fs/namei.c | 6 ++++++ > include/linux/dcache.h | 2 +- > 3 files changed, 18 insertions(+), 2 deletions(-) > mode change 100644 => 100755 fs/dcache.c > mode change 100644 => 100755 fs/namei.c > mode change 100644 => 100755 include/linux/dcache.h > > diff --git a/fs/dcache.c b/fs/dcache.c > old mode 100644 > new mode 100755 > index f901413..6828463 > --- a/fs/dcache.c > +++ b/fs/dcache.c > @@ -722,7 +722,8 @@ static inline bool fast_dput(struct dentry *dentry) > */ > smp_rmb(); > d_flags = ACCESS_ONCE(dentry->d_flags); > - d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST | > DCACHE_DISCONNECTED; > + d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST | > DCACHE_DISCONNECTED > + | DCACHE_FILE_REMOVED; > > /* Nothing to do? Dropping the reference was all we needed? */ > if (d_flags == (DCACHE_REFERENCED | DCACHE_LRU_LIST) > && !d_unhashed(dentry)) > @@ -816,6 +817,15 @@ void dput(struct dentry *dentry) > dentry_lru_add(dentry); > > dentry->d_lockref.count--; > + > + /* > + * if file has been declare as removed and reference count is zero > + * then we can free the dentry rather than leave it stay in dcache > + */ > + if (unlikely(dentry->d_flags & DCACHE_FILE_REMOVED)) { > + if (dentry->d_lockref.count == 0) > + goto kill_it; > + } > spin_unlock(&dentry->d_lock); > return; > > diff --git a/fs/namei.c b/fs/namei.c > old mode 100644 > new mode 100755 > index ddb6a7c..0ec1478 > --- a/fs/namei.c > +++ b/fs/namei.c > @@ -3918,6 +3918,9 @@ static long do_rmdir(int dfd, const char __user > *pathname) > goto exit3; > error = vfs_rmdir(path.dentry->d_inode, dentry); > exit3: > + /* after remove the dir set dentry remove flag */ > + if (!error) > + dentry->d_flags |= DCACHE_FILE_REMOVED; > dput(dentry); > exit2: > inode_unlock(path.dentry->d_inode); > @@ -4042,6 +4045,9 @@ static long do_unlinkat(int dfd, const char __user > *pathname) > goto exit2; > error = vfs_unlink(path.dentry->d_inode, dentry, &delegated_inode); > exit2: > + /* after unlink file set dentry remove flag */ > + if (!error) > + dentry->d_flags |= DCACHE_FILE_REMOVED; > dput(dentry); > } > inode_unlock(path.dentry->d_inode); > diff --git a/include/linux/dcache.h b/include/linux/dcache.h > old mode 100644 > new mode 100755 > index aae1cdb..2d65bd6 > --- a/include/linux/dcache.h > +++ b/include/linux/dcache.h > @@ -215,7 +215,7 @@ struct dentry_operations { > #define DCACHE_FALLTHRU 0x01000000 /* Fall through to lower > layer */ > #define DCACHE_ENCRYPTED_WITH_KEY 0x02000000 /* dir is encrypted > with a valid key */ > #define DCACHE_OP_REAL 0x04000000 > - > +#define DCACHE_FILE_REMOVED 0x08000000 /* file or dir has been > unlinked or removed */ > #define DCACHE_PAR_LOOKUP 0x10000000 /* being looked up (with > parent locked shared) */ > #define DCACHE_DENTRY_CURSOR 0x20000000 > > -- > 2.8.0.GIT Hi, all The negative dentries keep growing and waste a lots of kernel memory, this problem has been Occurred on my server, and I looked for internet, and many people had met the same problem. Recently, I discussed with Longman, we have two different patches to solve this problem, In my patch, remove the negative dentries with the files unlinked, I checked 15 years ago, Viro and linus had talked about this, that unlink was only worth doing. ref: http://yarchive.net/comp/linux/negative_dentries.html in Longman patch, limit the negative dentries number maybe we can discuss. Thanks, Kevin