[Yaffs] Saving checkpoint on remount read-only

Top Page
Attachments:
Message as email
+ (text/plain)
+ (text/html)
+ remount.diff (text/plain)
Delete this message
Reply to this message
Author: Mikhail Ryleev
Date:  
To: yaffs
Subject: [Yaffs] Saving checkpoint on remount read-only
Hi, all

The attached patch implements saving of yaffs checkpoint in case fs is
remounted read-only. This allows the usage of checkpoint mechanizm even if,
for some reason, the system can not cleanly unmount yaffs filesystem but can
remount it read-only.

It also fixes a problem with an implementation of yaffs_put_super that
"puts" mtd device before saving yaffs checkpoint.

M.
--- old/yaffs_fs.c    2007-02-13 17:09:06.000000000 -0800
+++ new/yaffs_fs.c    2007-03-09 19:26:49.000000000 -0800
@@ -158,6 +158,8 @@
 static int yaffs_write_super(struct super_block *sb);
 #endif


+static int yaffs_remount_fs(struct super_block *, int *, char *);
+
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
 static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf);
 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
@@ -250,6 +252,7 @@
     .read_inode = yaffs_read_inode,
     .put_inode = yaffs_put_inode,
     .put_super = yaffs_put_super,
+    .remount_fs = yaffs_remount_fs,
     .delete_inode = yaffs_delete_inode,
     .clear_inode = yaffs_clear_inode,
     .sync_fs = yaffs_sync_fs,
@@ -1414,6 +1417,35 @@


static LIST_HEAD(yaffs_dev_list);

+static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
+{
+    yaffs_Device    *dev = yaffs_SuperToDevice(sb);
+
+    if( *flags & MS_RDONLY ) {
+        struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
+        
+        T(YAFFS_TRACE_OS,
+            (KERN_DEBUG "yaffs_remount_fs: %s: RO\n", dev->name ));
+
+        yaffs_GrossLock(dev);
+          
+        yaffs_FlushEntireDeviceCache(dev);
+        
+        yaffs_CheckpointSave(dev);
+ 
+        if (mtd->sync)
+            mtd->sync(mtd);
+
+        yaffs_GrossUnlock(dev);
+    }
+    else {
+        T(YAFFS_TRACE_OS, 
+            (KERN_DEBUG "yaffs_remount_fs: %s: RW\n", dev->name ));
+    }
+ 
+    return 0;
+}
+
 static void yaffs_put_super(struct super_block *sb)
 {
     yaffs_Device *dev = yaffs_SuperToDevice(sb);
@@ -1423,12 +1455,13 @@
     yaffs_GrossLock(dev);

    
     yaffs_FlushEntireDeviceCache(dev);
-    
+
+    yaffs_CheckpointSave(dev);
+
     if (dev->putSuperFunc) {
         dev->putSuperFunc(sb);
     }
-    
-    yaffs_CheckpointSave(dev);
+
     yaffs_Deinitialise(dev);

    
     yaffs_GrossUnlock(dev);