aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/super.c')
-rw-r--r--fs/jffs2/super.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 853b8e300084..40f6e6385fd1 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -17,11 +17,13 @@
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/mount.h> 19#include <linux/mount.h>
20#include <linux/parser.h>
20#include <linux/jffs2.h> 21#include <linux/jffs2.h>
21#include <linux/pagemap.h> 22#include <linux/pagemap.h>
22#include <linux/mtd/super.h> 23#include <linux/mtd/super.h>
23#include <linux/ctype.h> 24#include <linux/ctype.h>
24#include <linux/namei.h> 25#include <linux/namei.h>
26#include <linux/seq_file.h>
25#include <linux/exportfs.h> 27#include <linux/exportfs.h>
26#include "compr.h" 28#include "compr.h"
27#include "nodelist.h" 29#include "nodelist.h"
@@ -75,6 +77,29 @@ static void jffs2_write_super(struct super_block *sb)
75 unlock_super(sb); 77 unlock_super(sb);
76} 78}
77 79
80static const char *jffs2_compr_name(unsigned int compr)
81{
82 switch (compr) {
83 case JFFS2_COMPR_MODE_NONE:
84 return "none";
85 default:
86 /* should never happen; programmer error */
87 WARN_ON(1);
88 return "";
89 }
90}
91
92static int jffs2_show_options(struct seq_file *s, struct vfsmount *mnt)
93{
94 struct jffs2_sb_info *c = JFFS2_SB_INFO(mnt->mnt_sb);
95 struct jffs2_mount_opts *opts = &c->mount_opts;
96
97 if (opts->override_compr)
98 seq_printf(s, ",compr=%s", jffs2_compr_name(opts->compr));
99
100 return 0;
101}
102
78static int jffs2_sync_fs(struct super_block *sb, int wait) 103static int jffs2_sync_fs(struct super_block *sb, int wait)
79{ 104{
80 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 105 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
@@ -133,6 +158,71 @@ static const struct export_operations jffs2_export_ops = {
133 .fh_to_parent = jffs2_fh_to_parent, 158 .fh_to_parent = jffs2_fh_to_parent,
134}; 159};
135 160
161/*
162 * JFFS2 mount options.
163 *
164 * Opt_override_compr: override default compressor
165 * Opt_err: just end of array marker
166 */
167enum {
168 Opt_override_compr,
169 Opt_err,
170};
171
172static const match_table_t tokens = {
173 {Opt_override_compr, "compr=%s"},
174 {Opt_err, NULL},
175};
176
177static int jffs2_parse_options(struct jffs2_sb_info *c, char *data)
178{
179 substring_t args[MAX_OPT_ARGS];
180 char *p, *name;
181
182 if (!data)
183 return 0;
184
185 while ((p = strsep(&data, ","))) {
186 int token;
187
188 if (!*p)
189 continue;
190
191 token = match_token(p, tokens, args);
192 switch (token) {
193 case Opt_override_compr:
194 name = match_strdup(&args[0]);
195
196 if (!name)
197 return -ENOMEM;
198 if (!strcmp(name, "none")) {
199 c->mount_opts.compr = JFFS2_COMPR_MODE_NONE;
200 c->mount_opts.override_compr = true;
201 }
202 kfree(name);
203 break;
204 default:
205 printk(KERN_ERR "JFFS2 Error: unrecognized mount option '%s' or missing value\n",
206 p);
207 return -EINVAL;
208 }
209 }
210
211 return 0;
212}
213
214static int jffs2_remount_fs(struct super_block *sb, int *flags, char *data)
215{
216 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
217 int err;
218
219 err = jffs2_parse_options(c, data);
220 if (err)
221 return -EINVAL;
222
223 return jffs2_do_remount_fs(sb, flags, data);
224}
225
136static const struct super_operations jffs2_super_operations = 226static const struct super_operations jffs2_super_operations =
137{ 227{
138 .alloc_inode = jffs2_alloc_inode, 228 .alloc_inode = jffs2_alloc_inode,
@@ -143,6 +233,7 @@ static const struct super_operations jffs2_super_operations =
143 .remount_fs = jffs2_remount_fs, 233 .remount_fs = jffs2_remount_fs,
144 .evict_inode = jffs2_evict_inode, 234 .evict_inode = jffs2_evict_inode,
145 .dirty_inode = jffs2_dirty_inode, 235 .dirty_inode = jffs2_dirty_inode,
236 .show_options = jffs2_show_options,
146 .sync_fs = jffs2_sync_fs, 237 .sync_fs = jffs2_sync_fs,
147}; 238};
148 239
@@ -166,6 +257,12 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
166 c->os_priv = sb; 257 c->os_priv = sb;
167 sb->s_fs_info = c; 258 sb->s_fs_info = c;
168 259
260 ret = jffs2_parse_options(c, data);
261 if (ret) {
262 kfree(c);
263 return -EINVAL;
264 }
265
169 /* Initialize JFFS2 superblock locks, the further initialization will 266 /* Initialize JFFS2 superblock locks, the further initialization will
170 * be done later */ 267 * be done later */
171 mutex_init(&c->alloc_sem); 268 mutex_init(&c->alloc_sem);