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.
Also fix one missing argument in yaffs_flush_whole_cache() call.
Signed-off-by: Wenlin Kang <wenlin.kang@windriver.com>
yaffs_flush_inodes(sb);
yaffs_update_dirty_dirs(dev);
yaffs_flush_inodes(sb);
yaffs_update_dirty_dirs(dev);
- yaffs_flush_whole_cache(dev);
+ yaffs_flush_whole_cache(dev, 1);
if (do_checkpoint)
yaffs_checkpoint_save(dev);
}
if (do_checkpoint)
yaffs_checkpoint_save(dev);
}
+/* 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,
static const struct super_operations yaffs_super_ops = {
.statfs = yaffs_statfs,
#ifdef YAFFS_HAS_WRITE_SUPER
.write_super = yaffs_write_super,
#endif
#ifdef YAFFS_HAS_WRITE_SUPER
.write_super = yaffs_write_super,
#endif
+ .remount_fs = yaffs_remount_fs,
};
struct yaffs_options {
};
struct yaffs_options {
yaffs_flush_inodes(sb);
yaffs_update_dirty_dirs(dev);
yaffs_flush_inodes(sb);
yaffs_update_dirty_dirs(dev);
- yaffs_flush_whole_cache(dev);
+ yaffs_flush_whole_cache(dev, 1);
if (do_checkpoint)
yaffs_checkpoint_save(dev);
}
if (do_checkpoint)
yaffs_checkpoint_save(dev);
}
if (mtd && mtd->sync)
mtd->sync(mtd);
if (mtd && mtd->sync)
mtd->sync(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,
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,
};
static struct super_block *yaffs_internal_read_super(int yaffs_version,