aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jffs2/compr.c9
-rw-r--r--fs/jffs2/fs.c2
-rw-r--r--fs/jffs2/jffs2_fs_sb.h6
-rw-r--r--fs/jffs2/os-linux.h2
-rw-r--r--fs/jffs2/super.c97
5 files changed, 112 insertions, 4 deletions
diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c
index de4247021d25..97bc74db2c96 100644
--- a/fs/jffs2/compr.c
+++ b/fs/jffs2/compr.c
@@ -76,13 +76,18 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
76 uint32_t *datalen, uint32_t *cdatalen) 76 uint32_t *datalen, uint32_t *cdatalen)
77{ 77{
78 int ret = JFFS2_COMPR_NONE; 78 int ret = JFFS2_COMPR_NONE;
79 int compr_ret; 79 int mode, compr_ret;
80 struct jffs2_compressor *this, *best=NULL; 80 struct jffs2_compressor *this, *best=NULL;
81 unsigned char *output_buf = NULL, *tmp_buf; 81 unsigned char *output_buf = NULL, *tmp_buf;
82 uint32_t orig_slen, orig_dlen; 82 uint32_t orig_slen, orig_dlen;
83 uint32_t best_slen=0, best_dlen=0; 83 uint32_t best_slen=0, best_dlen=0;
84 84
85 switch (jffs2_compression_mode) { 85 if (c->mount_opts.override_compr)
86 mode = c->mount_opts.compr;
87 else
88 mode = jffs2_compression_mode;
89
90 switch (mode) {
86 case JFFS2_COMPR_MODE_NONE: 91 case JFFS2_COMPR_MODE_NONE:
87 break; 92 break;
88 case JFFS2_COMPR_MODE_PRIORITY: 93 case JFFS2_COMPR_MODE_PRIORITY:
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index bbcb9755dd2b..5d54b4ed1b6c 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -379,7 +379,7 @@ void jffs2_dirty_inode(struct inode *inode, int flags)
379 jffs2_do_setattr(inode, &iattr); 379 jffs2_do_setattr(inode, &iattr);
380} 380}
381 381
382int jffs2_remount_fs (struct super_block *sb, int *flags, char *data) 382int jffs2_do_remount_fs(struct super_block *sb, int *flags, char *data)
383{ 383{
384 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 384 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
385 385
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h
index 0bc6a6c80a56..55a0c1dceadf 100644
--- a/fs/jffs2/jffs2_fs_sb.h
+++ b/fs/jffs2/jffs2_fs_sb.h
@@ -29,6 +29,11 @@
29 29
30struct jffs2_inodirty; 30struct jffs2_inodirty;
31 31
32struct jffs2_mount_opts {
33 bool override_compr;
34 unsigned int compr;
35};
36
32/* A struct for the overall file system control. Pointers to 37/* A struct for the overall file system control. Pointers to
33 jffs2_sb_info structs are named `c' in the source code. 38 jffs2_sb_info structs are named `c' in the source code.
34 Nee jffs_control 39 Nee jffs_control
@@ -126,6 +131,7 @@ struct jffs2_sb_info {
126#endif 131#endif
127 132
128 struct jffs2_summary *summary; /* Summary information */ 133 struct jffs2_summary *summary; /* Summary information */
134 struct jffs2_mount_opts mount_opts;
129 135
130#ifdef CONFIG_JFFS2_FS_XATTR 136#ifdef CONFIG_JFFS2_FS_XATTR
131#define XATTRINDEX_HASHSIZE (57) 137#define XATTRINDEX_HASHSIZE (57)
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index 6c1755c59c0f..ab65ee3ec858 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -176,7 +176,7 @@ void jffs2_dirty_inode(struct inode *inode, int flags);
176struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, 176struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode,
177 struct jffs2_raw_inode *ri); 177 struct jffs2_raw_inode *ri);
178int jffs2_statfs (struct dentry *, struct kstatfs *); 178int jffs2_statfs (struct dentry *, struct kstatfs *);
179int jffs2_remount_fs (struct super_block *, int *, char *); 179int jffs2_do_remount_fs(struct super_block *, int *, char *);
180int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); 180int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
181void jffs2_gc_release_inode(struct jffs2_sb_info *c, 181void jffs2_gc_release_inode(struct jffs2_sb_info *c,
182 struct jffs2_inode_info *f); 182 struct jffs2_inode_info *f);
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);