yaffs: Batter read-only support handling
authorCharles Manning <cdhmanning@gmail.com>
Tue, 10 Aug 2010 00:38:32 +0000 (12:38 +1200)
committerCharles Manning <cdhmanning@gmail.com>
Tue, 10 Aug 2010 00:38:32 +0000 (12:38 +1200)
Check read only flags in both the mount flags and mtd flags.

If the mount is read only then don't do some clean ups or start the
background gc thread.

Signed-off-by: Charles Manning <cdhmanning@gmail.com>
yaffs_fs.c
yaffs_guts.c

index 8d1f3aa..49ff870 100644 (file)
@@ -2275,6 +2275,9 @@ static int yaffs_BackgroundStart(yaffs_Device *dev)
        int retval = 0;
        struct yaffs_LinuxContext *context = yaffs_DeviceToLC(dev);
 
+       if(dev->readOnly)
+               return -1;
+
        context->bgRunning = 1;
 
        context->bgThread = kthread_run(yaffs_BackgroundThread,
@@ -2566,6 +2569,8 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        struct yaffs_LinuxContext *context = NULL;
        yaffs_DeviceParam *param;
 
+       int readOnly = 0;
+
        yaffs_options options;
 
        unsigned mount_id;
@@ -2577,6 +2582,9 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        sb->s_op = &yaffs_super_ops;
        sb->s_flags |= MS_NOATIME;
 
+       readOnly =((sb->s_flags & MS_RDONLY) != 0);
+
+
 #ifdef YAFFS_COMPILE_EXPORTFS
        sb->s_export_op = &yaffs_export_ops;
 #endif
@@ -2588,9 +2596,10 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        else if (!yaffs_devname(sb, devname_buf))
                printk(KERN_INFO "yaffs: devname is NULL\n");
        else
-               printk(KERN_INFO "yaffs: dev is %d name is \"%s\"\n",
+               printk(KERN_INFO "yaffs: dev is %d name is \"%s\" %s\n",
                       sb->s_dev,
-                      yaffs_devname(sb, devname_buf));
+                      yaffs_devname(sb, devname_buf),
+                      readOnly ? "ro" : "rw");
 
        if (!data_str)
                data_str = "";
@@ -2730,6 +2739,12 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
         * Set the yaffs_Device up for mtd
         */
 
+       if (!readOnly && !(mtd->flags & MTD_WRITEABLE)){
+               readOnly = 1;
+               printk(KERN_INFO "yaffs: mtd is read only, setting superblock read only");
+               sb->s_flags |= MS_RDONLY;
+       }
+
        dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);
        context = kmalloc(sizeof(struct yaffs_LinuxContext),GFP_KERNEL);
        
@@ -2758,7 +2773,7 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        context->dev = dev;
        context->superBlock = sb;
 
-       
+       dev->readOnly = readOnly;
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
        sb->s_fs_info = dev;
index c01f00c..6524f5f 100644 (file)
@@ -4189,6 +4189,9 @@ static void yaffs_StripDeletedObjects(yaffs_Device *dev)
        struct ylist_head *n;
        yaffs_Object *l;
 
+       if (dev->readOnly)
+               return;
+
        /* Soft delete all the unlinked files */
        ylist_for_each_safe(i, n,
                &dev->unlinkedDir->variant.directoryVariant.children) {
@@ -4242,6 +4245,8 @@ static void yaffs_FixHangingObjects(yaffs_Device *dev)
        int depthLimit;
        int hanging;
 
+       if (dev->readOnly)
+               return;
 
        /* Iterate through the objects in each hash entry,
         * looking at each object.