aboutsummaryrefslogtreecommitdiffstats
path: root/features/yaffs2/yaffs2-fix-missing-checkpoint-on-yaffs.patch
blob: cd7cc582cff97ec3fa5bb4c404dd5469eb6f225a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
From fcdadf7cdb9659c76808ff5fc2f105c56436e6a8 Mon Sep 17 00:00:00 2001
From: He Zhe <zhe.he@windriver.com>
Date: Wed, 2 Dec 2015 01:31:31 -0500
Subject: [PATCH] fs/yaffs2: 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 <wenlin.kang@windriver.com>
Signed-off-by: He Zhe <zhe.he@windriver.com>
---
 fs/yaffs2/yaffs_vfs.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/fs/yaffs2/yaffs_vfs.c b/fs/yaffs2/yaffs_vfs.c
index 52177c1..16251d5 100644
--- a/fs/yaffs2/yaffs_vfs.c
+++ b/fs/yaffs2/yaffs_vfs.c
@@ -2614,7 +2614,45 @@ static int yaffs_sync_fs(struct super_block *sb)
 	return 0;
 }
 
+/* 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,
@@ -2636,6 +2674,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 {
-- 
1.9.1