[PATCH v2 05/10] ovl: cache dirty overlayfs' inode

From: Josef Bacik

Date: Wed Oct 28 2026 - 21:10:50 EST


From: Chengguang Xu <cgxu519@xxxxxxxxxxxx>

Now drop overlayfs' inode will sync dirty data,
so we change to only drop clean inode.

The purpose of doing this is to keep compatible
behavior with before because without this change
dropping overlayfs inode will not trigger syncing
of underlying dirty inode.

Signed-off-by: Chengguang Xu <cgxu519@xxxxxxxxxxxx>
[josef: also keep an inode that is under writeback, rebase]
Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
---
fs/overlayfs/super.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 4e06b3c772fe..a68eb78a9061 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -392,11 +392,27 @@ static int ovl_write_inode(struct inode *inode, struct writeback_control *wbc)
return ret;
}

+/*
+ * In iput_final(), clean inode will drop directly and dirty inode will
+ * keep in the cache until write back to sync dirty data then add to lru
+ * list to wait reclaim.
+ *
+ * An inode under writeback has had its dirty flags cleared, and only I_SYNC
+ * pins it. Such an inode is not clean. ovl_write_inode() may be about to mark
+ * it dirty again, and marking an inode dirty that is being freed has no effect.
+ */
+static int ovl_drop_inode(struct inode *inode)
+{
+ if (!(inode_state_read(inode) & (I_DIRTY_ALL | I_SYNC)))
+ return 1;
+ return inode_generic_drop(inode);
+}
+
static const struct super_operations ovl_super_operations = {
.alloc_inode = ovl_alloc_inode,
.free_inode = ovl_free_inode,
.destroy_inode = ovl_destroy_inode,
- .drop_inode = inode_just_drop,
+ .drop_inode = ovl_drop_inode,
.put_super = ovl_put_super,
.write_inode = ovl_write_inode,
.sync_fs = ovl_sync_fs,

--
2.55.0