From 4c78eb9aa16a108e258ab6185f37a51c3b413cb8 Mon Sep 17 00:00:00 2001 From: Charles Manning Date: Tue, 10 Aug 2010 12:38:32 +1200 Subject: [PATCH] yaffs: Batter read-only support handling 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 --- yaffs_fs.c | 21 ++++++++++++++++++--- yaffs_guts.c | 5 +++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/yaffs_fs.c b/yaffs_fs.c index 8d1f3aa..49ff870 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -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; diff --git a/yaffs_guts.c b/yaffs_guts.c index c01f00c..6524f5f 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -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. -- 2.30.2