From ae46662afaa2d3e8710623a4ae02f8b307dbe4cc Mon Sep 17 00:00:00 2001 From: Paul Lawrence Date: Thu, 23 Feb 2023 08:59:38 -0800 Subject: [PATCH] ANDROID: incremental fs: Evict inodes before freeing mount data Since evicting inodes triggers writes to the backing file, which uses the mi_owner field from the mount_info struct, make sure inodes are evicted before we free the mount_info data Test: incfs_test Bug: 270117845 Change-Id: I673b2e0e04b5adc3998caf6f22443598a30338af Signed-off-by: Paul Lawrence (cherry picked from commit 7899985277527b29c47929a6d6a89c5c89b406ad) (cherry picked from commit faf3626b8e34df3dfff3a99e6582a9abd24410ce) --- fs/incfs/main.c | 10 ++++++++++ fs/incfs/vfs.c | 8 +++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/fs/incfs/main.c b/fs/incfs/main.c index 0fde230d5337..18994c3b8943 100644 --- a/fs/incfs/main.c +++ b/fs/incfs/main.c @@ -30,6 +30,15 @@ static ssize_t corefs_show(struct kobject *kobj, static struct kobj_attribute corefs_attr = __ATTR_RO(corefs); +static ssize_t bugfix_inode_eviction_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buff) +{ + return snprintf(buff, PAGE_SIZE, "supported\n"); +} + +static struct kobj_attribute bugfix_inode_eviction_attr = + __ATTR_RO(bugfix_inode_eviction); + static ssize_t mounter_context_for_backing_rw_show(struct kobject *kobj, struct kobj_attribute *attr, char *buff) { @@ -41,6 +50,7 @@ static struct kobj_attribute mounter_context_for_backing_rw_attr = static struct attribute *attributes[] = { &corefs_attr.attr, + &bugfix_inode_eviction_attr.attr, &mounter_context_for_backing_rw_attr.attr, NULL, }; diff --git a/fs/incfs/vfs.c b/fs/incfs/vfs.c index 27dcdaf49347..721fab54126d 100644 --- a/fs/incfs/vfs.c +++ b/fs/incfs/vfs.c @@ -2311,6 +2311,13 @@ void incfs_kill_sb(struct super_block *sb) pr_debug("incfs: unmount\n"); + /* + * We must kill the super before freeing mi, since killing the super + * triggers inode eviction, which triggers the final update of the + * backing file, which uses certain information for mi + */ + kill_anon_super(sb); + if (mi) { if (mi->mi_backing_dir_path.dentry) dinode = d_inode(mi->mi_backing_dir_path.dentry); @@ -2322,7 +2329,6 @@ void incfs_kill_sb(struct super_block *sb) incfs_free_mount_info(mi); sb->s_fs_info = NULL; } - kill_anon_super(sb); } static int show_options(struct seq_file *m, struct dentry *root)