[Yaffs] [PATCH] yaffs: fix missing checkpoint on yaffs

Top Page
Attachments:
Message as email
+ (text/plain)
Delete this message
Reply to this message
Author: Wenlin Kang
Date:  
To: yaffs
Subject: [Yaffs] [PATCH] yaffs: fix missing checkpoint on yaffs
For yaffs file system, the mode of reading or writing is restricted at
four pointer where are mnt->mnt_flags,mnt->mnt_sb->s_flags,mtd->flags
and dev->read_only,the first three is used handle file and file
system(eg,remount) operation, and last one(dev->read_only) almost is used
handle checkpoint of yaffs2. However, in current code, the dev->read_only
only can be changed at first time when the yaffs2 file system is mounted,
later it can't be changed again(eg,mount -o remount), the result is that
the checkpoint's saving operation always can't succeed if you set readonly
mode for yaffs2 file system when it is mounted at the first time.

To fix this issue, we implement yaffs_remount_fs() which allows the
rootfs to be remounted as r/w.

Signed-off-by: Wenlin Kang <>
---
yaffs_vfs_multi.c | 40 ++++++++++++++++++++++++++++++++++++++++
yaffs_vfs_single.c | 41 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 81 insertions(+)

diff --git a/yaffs_vfs_multi.c b/yaffs_vfs_multi.c
index 76bc1db..605438a 100644
--- a/yaffs_vfs_multi.c
+++ b/yaffs_vfs_multi.c
@@ -2580,6 +2580,45 @@ static int yaffs_sync_fs(struct super_block *sb)
}


+/* the function only is used to change dev->read_only when this file system
+ * is remounted.
+ */
+static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
+{
+    int read_only = 0;
+    struct mtd_info *mtd;
+    struct yaffs_dev *dev = 0;
+
+    /* Get the device */
+    mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
+    if (!mtd) {
+        yaffs_trace(YAFFS_TRACE_ALWAYS,
+            "MTD device #%u doesn't appear to exist",
+            MINOR(sb->s_dev));
+        return 1;
+    }
+
+    /* Check it's NAND */
+    if (mtd->type != MTD_NANDFLASH) {
+        yaffs_trace(YAFFS_TRACE_ALWAYS,
+            "MTD device is not NAND it's type %d",
+            mtd->type);
+        return 1;
+    }
+
+    read_only = ((*flags & MS_RDONLY) != 0);
+    if (!read_only && !(mtd->flags & MTD_WRITEABLE)) {
+        read_only = 1;
+        printk(KERN_INFO
+               "yaffs: mtd is read only, setting superblock read only");
+        *flags |= MS_RDONLY;
+    }
+
+    dev = sb->s_fs_info;
+    dev->read_only = read_only;
+
+    return 0;
+}


 static const struct super_operations yaffs_super_ops = {
     .statfs = yaffs_statfs,
@@ -2601,6 +2640,7 @@ static const struct super_operations yaffs_super_ops = {
 #ifdef YAFFS_HAS_WRITE_SUPER
     .write_super = yaffs_write_super,
 #endif
+    .remount_fs = yaffs_remount_fs,
 };


 struct yaffs_options {
diff --git a/yaffs_vfs_single.c b/yaffs_vfs_single.c
index 232dc26..a510f22 100644
--- a/yaffs_vfs_single.c
+++ b/yaffs_vfs_single.c
@@ -1952,12 +1952,53 @@ static void yaffs_put_super(struct super_block *sb)
         put_mtd_device(mtd);
 }


+/* the function only is used to change dev->read_only when this file system
+ * is remounted.
+ */
+static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
+{
+    int read_only = 0;
+    struct mtd_info *mtd;
+    struct yaffs_dev *dev = 0;
+
+    /* Get the device */
+    mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
+    if (!mtd) {
+        yaffs_trace(YAFFS_TRACE_ALWAYS,
+            "MTD device #%u doesn't appear to exist",
+            MINOR(sb->s_dev));
+        return 1;
+    }
+
+    /* Check it's NAND */
+    if (mtd->type != MTD_NANDFLASH) {
+        yaffs_trace(YAFFS_TRACE_ALWAYS,
+            "MTD device is not NAND it's type %d",
+            mtd->type);
+        return 1;
+    }
+
+    read_only = ((*flags & MS_RDONLY) != 0);
+    if (!read_only && !(mtd->flags & MTD_WRITEABLE)) {
+        read_only = 1;
+        printk(KERN_INFO
+               "yaffs: mtd is read only, setting superblock read only");
+        *flags |= MS_RDONLY;
+    }
+
+    dev = sb->s_fs_info;
+    dev->read_only = read_only;
+
+    return 0;
+}
+
 static const struct super_operations yaffs_super_ops = {
     .statfs = yaffs_statfs,
     .put_super = yaffs_put_super,
     .evict_inode = yaffs_evict_inode,
     .sync_fs = yaffs_sync_fs,
     .write_super = yaffs_write_super,
+    .remount_fs = yaffs_remount_fs,
 };


static struct super_block *yaffs_internal_read_super(int yaffs_version,
--
1.7.9.5