Handle cleanup when remounting rw after mounting read-only
authorCharles Manning <cdhmanning@gmail.com>
Fri, 15 May 2020 01:57:54 +0000 (13:57 +1200)
committerCharles Manning <cdhmanning@gmail.com>
Fri, 15 May 2020 01:57:54 +0000 (13:57 +1200)
Deferend clean ups were not happening properly.

Thanks to andriy.grytsenko@globallogic.com for providing a
patch that forms the babsis of these changes.

Signed-off-by: Charles Manning <cdhmanning@gmail.com>
direct/yaffsfs.c
yaffs_guts.c
yaffs_guts.h
yaffs_vfs_multi.c

index af8c82b..d1e4e4e 100644 (file)
@@ -3050,6 +3050,7 @@ int yaffs_remount_common(struct yaffs_dev *dev, const YCHAR *path,
                       int force, int read_only)
 {
        int retVal = -1;
+       int was_read_only;
 
        if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
@@ -3072,7 +3073,11 @@ int yaffs_remount_common(struct yaffs_dev *dev, const YCHAR *path,
                        if (force || !yaffsfs_IsDevBusy(dev)) {
                                if (read_only)
                                        yaffs_checkpoint_save(dev);
+                               was_read_only = dev->read_only;
                                dev->read_only = read_only ? 1 : 0;
+                               if (was_read_only && !read_only) {
+                                       yaffs_guts_cleanup(dev);
+                               }
                                retVal = 0;
                        } else
                                yaffsfs_SetError(-EBUSY);
index 40a5b46..c52ff84 100644 (file)
@@ -4799,6 +4799,18 @@ int yaffs_guts_format_dev(struct yaffs_dev *dev)
        return YAFFS_OK;
 }
 
+/*
+ * If the dev is mounted r/w then the cleanup will happen during
+ * yaffs_guts_initialise. However if the dev is mounted ro then
+ * the cleanup will be dfered until yaffs is remounted r/w.
+ */
+void yaffs_guts_cleanup(struct yaffs_dev *dev)
+{
+       yaffs_strip_deleted_objs(dev);
+       yaffs_fix_hanging_objs(dev);
+       if (dev->param.empty_lost_n_found)
+                       yaffs_empty_l_n_f(dev);
+}
 
 int yaffs_guts_initialise(struct yaffs_dev *dev)
 {
@@ -5012,10 +5024,7 @@ int yaffs_guts_initialise(struct yaffs_dev *dev)
                        init_failed = 1;
                }
 
-               yaffs_strip_deleted_objs(dev);
-               yaffs_fix_hanging_objs(dev);
-               if (dev->param.empty_lost_n_found)
-                       yaffs_empty_l_n_f(dev);
+               yaffs_guts_cleanup(dev);
        }
 
        if (init_failed) {
index 5ebc378..124e4c9 100644 (file)
@@ -885,6 +885,7 @@ struct yaffs_xattr_mod {
 
 int yaffs_guts_initialise(struct yaffs_dev *dev);
 void yaffs_deinitialise(struct yaffs_dev *dev);
+void yaffs_guts_cleanup(struct yaffs_dev *dev);
 
 int yaffs_get_n_free_chunks(struct yaffs_dev *dev);
 
index e4edb2c..3044db7 100644 (file)
@@ -2718,6 +2718,7 @@ static int yaffs_sync_fs(struct super_block *sb)
 static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
 {
        int read_only = 0;
+       int was_read_only = 0;
        struct mtd_info *mtd;
        struct yaffs_dev *dev = 0;
 
@@ -2747,8 +2748,18 @@ static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
        }
 
        dev = sb->s_fs_info;
+       was_read_only = dev->read_only;
        dev->read_only = read_only;
 
+       if (was_read_only && !read_only) {
+               yaffs_gross_lock(dev);
+               yaffs_guts_cleanup(dev);
+               yaffs_gross_unlock(dev);
+               yaffs_bg_start(dev);
+       } else if (!was_read_only && read_only) {
+               yaffs_bg_stop(dev);
+       }
+
        return 0;
 }