diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-07 12:11:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-07 12:11:16 -0500 |
commit | e0d65113a70f1dc514e625cc4e7a7485a4bf72df (patch) | |
tree | 7320a130dc304623f5cf4b5dd8f67fb1776225ca /fs | |
parent | cf5e15fbd72c13977720aa15b7b7e00e1d8fd8f2 (diff) | |
parent | 48e546b7f281f251893baa40769581fd15f085fb (diff) |
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (226 commits)
mtd: tests: annotate as DANGEROUS in Kconfig
mtd: tests: don't use mtd0 as a default
mtd: clean up usage of MTD_DOCPROBE_ADDRESS
jffs2: add compr=lzo and compr=zlib options
jffs2: implement mount option parsing and compression overriding
mtd: nand: initialize ops.mode
mtd: provide an alias for the redboot module name
mtd: m25p80: don't probe device which has status of 'disabled'
mtd: nand_h1900 never worked
mtd: Add DiskOnChip G3 support
mtd: m25p80: add EON flash EN25Q32B into spi flash id table
mtd: mark block device queue as non-rotational
mtd: r852: make r852_pm_ops static
mtd: m25p80: add support for at25df321a spi data flash
mtd: mxc_nand: preset_v1_v2: unlock all NAND flash blocks
mtd: nand: switch `check_pattern()' to standard `memcmp()'
mtd: nand: invalidate cache on unaligned reads
mtd: nand: do not scan bad blocks with NAND_BBT_NO_OOB set
mtd: nand: wait to set BBT version
mtd: nand: scrub BBT on ECC errors
...
Fix up trivial conflicts:
- arch/arm/mach-at91/board-usb-a9260.c
Merged into board-usb-a926x.c
- drivers/mtd/maps/lantiq-flash.c
add_mtd_partitions -> mtd_device_register vs changed to use
mtd_device_parse_register.
Diffstat (limited to 'fs')
-rw-r--r-- | fs/jffs2/compr.c | 128 | ||||
-rw-r--r-- | fs/jffs2/compr.h | 2 | ||||
-rw-r--r-- | fs/jffs2/fs.c | 2 | ||||
-rw-r--r-- | fs/jffs2/jffs2_fs_sb.h | 6 | ||||
-rw-r--r-- | fs/jffs2/os-linux.h | 2 | ||||
-rw-r--r-- | fs/jffs2/scan.c | 4 | ||||
-rw-r--r-- | fs/jffs2/super.c | 119 | ||||
-rw-r--r-- | fs/jffs2/wbuf.c | 9 |
8 files changed, 225 insertions, 47 deletions
diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c index de4247021d25..5b6c9d1a2fb9 100644 --- a/fs/jffs2/compr.c +++ b/fs/jffs2/compr.c | |||
@@ -53,6 +53,78 @@ static int jffs2_is_best_compression(struct jffs2_compressor *this, | |||
53 | return 0; | 53 | return 0; |
54 | } | 54 | } |
55 | 55 | ||
56 | /* | ||
57 | * jffs2_selected_compress: | ||
58 | * @compr: Explicit compression type to use (ie, JFFS2_COMPR_ZLIB). | ||
59 | * If 0, just take the first available compression mode. | ||
60 | * @data_in: Pointer to uncompressed data | ||
61 | * @cpage_out: Pointer to returned pointer to buffer for compressed data | ||
62 | * @datalen: On entry, holds the amount of data available for compression. | ||
63 | * On exit, expected to hold the amount of data actually compressed. | ||
64 | * @cdatalen: On entry, holds the amount of space available for compressed | ||
65 | * data. On exit, expected to hold the actual size of the compressed | ||
66 | * data. | ||
67 | * | ||
68 | * Returns: the compression type used. Zero is used to show that the data | ||
69 | * could not be compressed; probably because we couldn't find the requested | ||
70 | * compression mode. | ||
71 | */ | ||
72 | static int jffs2_selected_compress(u8 compr, unsigned char *data_in, | ||
73 | unsigned char **cpage_out, u32 *datalen, u32 *cdatalen) | ||
74 | { | ||
75 | struct jffs2_compressor *this; | ||
76 | int err, ret = JFFS2_COMPR_NONE; | ||
77 | uint32_t orig_slen, orig_dlen; | ||
78 | char *output_buf; | ||
79 | |||
80 | output_buf = kmalloc(*cdatalen, GFP_KERNEL); | ||
81 | if (!output_buf) { | ||
82 | printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n"); | ||
83 | return ret; | ||
84 | } | ||
85 | orig_slen = *datalen; | ||
86 | orig_dlen = *cdatalen; | ||
87 | spin_lock(&jffs2_compressor_list_lock); | ||
88 | list_for_each_entry(this, &jffs2_compressor_list, list) { | ||
89 | /* Skip decompress-only and disabled modules */ | ||
90 | if (!this->compress || this->disabled) | ||
91 | continue; | ||
92 | |||
93 | /* Skip if not the desired compression type */ | ||
94 | if (compr && (compr != this->compr)) | ||
95 | continue; | ||
96 | |||
97 | /* | ||
98 | * Either compression type was unspecified, or we found our | ||
99 | * compressor; either way, we're good to go. | ||
100 | */ | ||
101 | this->usecount++; | ||
102 | spin_unlock(&jffs2_compressor_list_lock); | ||
103 | |||
104 | *datalen = orig_slen; | ||
105 | *cdatalen = orig_dlen; | ||
106 | err = this->compress(data_in, output_buf, datalen, cdatalen); | ||
107 | |||
108 | spin_lock(&jffs2_compressor_list_lock); | ||
109 | this->usecount--; | ||
110 | if (!err) { | ||
111 | /* Success */ | ||
112 | ret = this->compr; | ||
113 | this->stat_compr_blocks++; | ||
114 | this->stat_compr_orig_size += *datalen; | ||
115 | this->stat_compr_new_size += *cdatalen; | ||
116 | break; | ||
117 | } | ||
118 | } | ||
119 | spin_unlock(&jffs2_compressor_list_lock); | ||
120 | if (ret == JFFS2_COMPR_NONE) | ||
121 | kfree(output_buf); | ||
122 | else | ||
123 | *cpage_out = output_buf; | ||
124 | |||
125 | return ret; | ||
126 | } | ||
127 | |||
56 | /* jffs2_compress: | 128 | /* jffs2_compress: |
57 | * @data_in: Pointer to uncompressed data | 129 | * @data_in: Pointer to uncompressed data |
58 | * @cpage_out: Pointer to returned pointer to buffer for compressed data | 130 | * @cpage_out: Pointer to returned pointer to buffer for compressed data |
@@ -76,47 +148,23 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
76 | uint32_t *datalen, uint32_t *cdatalen) | 148 | uint32_t *datalen, uint32_t *cdatalen) |
77 | { | 149 | { |
78 | int ret = JFFS2_COMPR_NONE; | 150 | int ret = JFFS2_COMPR_NONE; |
79 | int compr_ret; | 151 | int mode, compr_ret; |
80 | struct jffs2_compressor *this, *best=NULL; | 152 | struct jffs2_compressor *this, *best=NULL; |
81 | unsigned char *output_buf = NULL, *tmp_buf; | 153 | unsigned char *output_buf = NULL, *tmp_buf; |
82 | uint32_t orig_slen, orig_dlen; | 154 | uint32_t orig_slen, orig_dlen; |
83 | uint32_t best_slen=0, best_dlen=0; | 155 | uint32_t best_slen=0, best_dlen=0; |
84 | 156 | ||
85 | switch (jffs2_compression_mode) { | 157 | if (c->mount_opts.override_compr) |
158 | mode = c->mount_opts.compr; | ||
159 | else | ||
160 | mode = jffs2_compression_mode; | ||
161 | |||
162 | switch (mode) { | ||
86 | case JFFS2_COMPR_MODE_NONE: | 163 | case JFFS2_COMPR_MODE_NONE: |
87 | break; | 164 | break; |
88 | case JFFS2_COMPR_MODE_PRIORITY: | 165 | case JFFS2_COMPR_MODE_PRIORITY: |
89 | output_buf = kmalloc(*cdatalen,GFP_KERNEL); | 166 | ret = jffs2_selected_compress(0, data_in, cpage_out, datalen, |
90 | if (!output_buf) { | 167 | cdatalen); |
91 | printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n"); | ||
92 | goto out; | ||
93 | } | ||
94 | orig_slen = *datalen; | ||
95 | orig_dlen = *cdatalen; | ||
96 | spin_lock(&jffs2_compressor_list_lock); | ||
97 | list_for_each_entry(this, &jffs2_compressor_list, list) { | ||
98 | /* Skip decompress-only backwards-compatibility and disabled modules */ | ||
99 | if ((!this->compress)||(this->disabled)) | ||
100 | continue; | ||
101 | |||
102 | this->usecount++; | ||
103 | spin_unlock(&jffs2_compressor_list_lock); | ||
104 | *datalen = orig_slen; | ||
105 | *cdatalen = orig_dlen; | ||
106 | compr_ret = this->compress(data_in, output_buf, datalen, cdatalen); | ||
107 | spin_lock(&jffs2_compressor_list_lock); | ||
108 | this->usecount--; | ||
109 | if (!compr_ret) { | ||
110 | ret = this->compr; | ||
111 | this->stat_compr_blocks++; | ||
112 | this->stat_compr_orig_size += *datalen; | ||
113 | this->stat_compr_new_size += *cdatalen; | ||
114 | break; | ||
115 | } | ||
116 | } | ||
117 | spin_unlock(&jffs2_compressor_list_lock); | ||
118 | if (ret == JFFS2_COMPR_NONE) | ||
119 | kfree(output_buf); | ||
120 | break; | 168 | break; |
121 | case JFFS2_COMPR_MODE_SIZE: | 169 | case JFFS2_COMPR_MODE_SIZE: |
122 | case JFFS2_COMPR_MODE_FAVOURLZO: | 170 | case JFFS2_COMPR_MODE_FAVOURLZO: |
@@ -174,22 +222,28 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
174 | best->stat_compr_orig_size += best_slen; | 222 | best->stat_compr_orig_size += best_slen; |
175 | best->stat_compr_new_size += best_dlen; | 223 | best->stat_compr_new_size += best_dlen; |
176 | ret = best->compr; | 224 | ret = best->compr; |
225 | *cpage_out = output_buf; | ||
177 | } | 226 | } |
178 | spin_unlock(&jffs2_compressor_list_lock); | 227 | spin_unlock(&jffs2_compressor_list_lock); |
179 | break; | 228 | break; |
229 | case JFFS2_COMPR_MODE_FORCELZO: | ||
230 | ret = jffs2_selected_compress(JFFS2_COMPR_LZO, data_in, | ||
231 | cpage_out, datalen, cdatalen); | ||
232 | break; | ||
233 | case JFFS2_COMPR_MODE_FORCEZLIB: | ||
234 | ret = jffs2_selected_compress(JFFS2_COMPR_ZLIB, data_in, | ||
235 | cpage_out, datalen, cdatalen); | ||
236 | break; | ||
180 | default: | 237 | default: |
181 | printk(KERN_ERR "JFFS2: unknown compression mode.\n"); | 238 | printk(KERN_ERR "JFFS2: unknown compression mode.\n"); |
182 | } | 239 | } |
183 | out: | 240 | |
184 | if (ret == JFFS2_COMPR_NONE) { | 241 | if (ret == JFFS2_COMPR_NONE) { |
185 | *cpage_out = data_in; | 242 | *cpage_out = data_in; |
186 | *datalen = *cdatalen; | 243 | *datalen = *cdatalen; |
187 | none_stat_compr_blocks++; | 244 | none_stat_compr_blocks++; |
188 | none_stat_compr_size += *datalen; | 245 | none_stat_compr_size += *datalen; |
189 | } | 246 | } |
190 | else { | ||
191 | *cpage_out = output_buf; | ||
192 | } | ||
193 | return ret; | 247 | return ret; |
194 | } | 248 | } |
195 | 249 | ||
diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h index 13bb7597ab39..5e91d578f4ed 100644 --- a/fs/jffs2/compr.h +++ b/fs/jffs2/compr.h | |||
@@ -40,6 +40,8 @@ | |||
40 | #define JFFS2_COMPR_MODE_PRIORITY 1 | 40 | #define JFFS2_COMPR_MODE_PRIORITY 1 |
41 | #define JFFS2_COMPR_MODE_SIZE 2 | 41 | #define JFFS2_COMPR_MODE_SIZE 2 |
42 | #define JFFS2_COMPR_MODE_FAVOURLZO 3 | 42 | #define JFFS2_COMPR_MODE_FAVOURLZO 3 |
43 | #define JFFS2_COMPR_MODE_FORCELZO 4 | ||
44 | #define JFFS2_COMPR_MODE_FORCEZLIB 5 | ||
43 | 45 | ||
44 | #define FAVOUR_LZO_PERCENT 80 | 46 | #define FAVOUR_LZO_PERCENT 80 |
45 | 47 | ||
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 7286e44ac665..4b8afe39a87f 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 | ||
382 | int jffs2_remount_fs (struct super_block *sb, int *flags, char *data) | 382 | int 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 | ||
30 | struct jffs2_inodirty; | 30 | struct jffs2_inodirty; |
31 | 31 | ||
32 | struct 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); | |||
176 | struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, | 176 | struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, |
177 | struct jffs2_raw_inode *ri); | 177 | struct jffs2_raw_inode *ri); |
178 | int jffs2_statfs (struct dentry *, struct kstatfs *); | 178 | int jffs2_statfs (struct dentry *, struct kstatfs *); |
179 | int jffs2_remount_fs (struct super_block *, int *, char *); | 179 | int jffs2_do_remount_fs(struct super_block *, int *, char *); |
180 | int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); | 180 | int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); |
181 | void jffs2_gc_release_inode(struct jffs2_sb_info *c, | 181 | void 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/scan.c b/fs/jffs2/scan.c index 8d8cd3419d02..28107ca136e4 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -275,9 +275,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) | |||
275 | else | 275 | else |
276 | c->mtd->unpoint(c->mtd, 0, c->mtd->size); | 276 | c->mtd->unpoint(c->mtd, 0, c->mtd->size); |
277 | #endif | 277 | #endif |
278 | if (s) | 278 | kfree(s); |
279 | kfree(s); | ||
280 | |||
281 | return ret; | 279 | return ret; |
282 | } | 280 | } |
283 | 281 | ||
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 853b8e300084..e7e974454115 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,37 @@ static void jffs2_write_super(struct super_block *sb) | |||
75 | unlock_super(sb); | 77 | unlock_super(sb); |
76 | } | 78 | } |
77 | 79 | ||
80 | static const char *jffs2_compr_name(unsigned int compr) | ||
81 | { | ||
82 | switch (compr) { | ||
83 | case JFFS2_COMPR_MODE_NONE: | ||
84 | return "none"; | ||
85 | #ifdef CONFIG_JFFS2_LZO | ||
86 | case JFFS2_COMPR_MODE_FORCELZO: | ||
87 | return "lzo"; | ||
88 | #endif | ||
89 | #ifdef CONFIG_JFFS2_ZLIB | ||
90 | case JFFS2_COMPR_MODE_FORCEZLIB: | ||
91 | return "zlib"; | ||
92 | #endif | ||
93 | default: | ||
94 | /* should never happen; programmer error */ | ||
95 | WARN_ON(1); | ||
96 | return ""; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | static int jffs2_show_options(struct seq_file *s, struct vfsmount *mnt) | ||
101 | { | ||
102 | struct jffs2_sb_info *c = JFFS2_SB_INFO(mnt->mnt_sb); | ||
103 | struct jffs2_mount_opts *opts = &c->mount_opts; | ||
104 | |||
105 | if (opts->override_compr) | ||
106 | seq_printf(s, ",compr=%s", jffs2_compr_name(opts->compr)); | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
78 | static int jffs2_sync_fs(struct super_block *sb, int wait) | 111 | static int jffs2_sync_fs(struct super_block *sb, int wait) |
79 | { | 112 | { |
80 | struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); | 113 | struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); |
@@ -133,6 +166,85 @@ static const struct export_operations jffs2_export_ops = { | |||
133 | .fh_to_parent = jffs2_fh_to_parent, | 166 | .fh_to_parent = jffs2_fh_to_parent, |
134 | }; | 167 | }; |
135 | 168 | ||
169 | /* | ||
170 | * JFFS2 mount options. | ||
171 | * | ||
172 | * Opt_override_compr: override default compressor | ||
173 | * Opt_err: just end of array marker | ||
174 | */ | ||
175 | enum { | ||
176 | Opt_override_compr, | ||
177 | Opt_err, | ||
178 | }; | ||
179 | |||
180 | static const match_table_t tokens = { | ||
181 | {Opt_override_compr, "compr=%s"}, | ||
182 | {Opt_err, NULL}, | ||
183 | }; | ||
184 | |||
185 | static int jffs2_parse_options(struct jffs2_sb_info *c, char *data) | ||
186 | { | ||
187 | substring_t args[MAX_OPT_ARGS]; | ||
188 | char *p, *name; | ||
189 | |||
190 | if (!data) | ||
191 | return 0; | ||
192 | |||
193 | while ((p = strsep(&data, ","))) { | ||
194 | int token; | ||
195 | |||
196 | if (!*p) | ||
197 | continue; | ||
198 | |||
199 | token = match_token(p, tokens, args); | ||
200 | switch (token) { | ||
201 | case Opt_override_compr: | ||
202 | name = match_strdup(&args[0]); | ||
203 | |||
204 | if (!name) | ||
205 | return -ENOMEM; | ||
206 | if (!strcmp(name, "none")) | ||
207 | c->mount_opts.compr = JFFS2_COMPR_MODE_NONE; | ||
208 | #ifdef CONFIG_JFFS2_LZO | ||
209 | else if (!strcmp(name, "lzo")) | ||
210 | c->mount_opts.compr = JFFS2_COMPR_MODE_FORCELZO; | ||
211 | #endif | ||
212 | #ifdef CONFIG_JFFS2_ZLIB | ||
213 | else if (!strcmp(name, "zlib")) | ||
214 | c->mount_opts.compr = | ||
215 | JFFS2_COMPR_MODE_FORCEZLIB; | ||
216 | #endif | ||
217 | else { | ||
218 | printk(KERN_ERR "JFFS2 Error: unknown compressor \"%s\"", | ||
219 | name); | ||
220 | kfree(name); | ||
221 | return -EINVAL; | ||
222 | } | ||
223 | kfree(name); | ||
224 | c->mount_opts.override_compr = true; | ||
225 | break; | ||
226 | default: | ||
227 | printk(KERN_ERR "JFFS2 Error: unrecognized mount option '%s' or missing value\n", | ||
228 | p); | ||
229 | return -EINVAL; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static int jffs2_remount_fs(struct super_block *sb, int *flags, char *data) | ||
237 | { | ||
238 | struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); | ||
239 | int err; | ||
240 | |||
241 | err = jffs2_parse_options(c, data); | ||
242 | if (err) | ||
243 | return -EINVAL; | ||
244 | |||
245 | return jffs2_do_remount_fs(sb, flags, data); | ||
246 | } | ||
247 | |||
136 | static const struct super_operations jffs2_super_operations = | 248 | static const struct super_operations jffs2_super_operations = |
137 | { | 249 | { |
138 | .alloc_inode = jffs2_alloc_inode, | 250 | .alloc_inode = jffs2_alloc_inode, |
@@ -143,6 +255,7 @@ static const struct super_operations jffs2_super_operations = | |||
143 | .remount_fs = jffs2_remount_fs, | 255 | .remount_fs = jffs2_remount_fs, |
144 | .evict_inode = jffs2_evict_inode, | 256 | .evict_inode = jffs2_evict_inode, |
145 | .dirty_inode = jffs2_dirty_inode, | 257 | .dirty_inode = jffs2_dirty_inode, |
258 | .show_options = jffs2_show_options, | ||
146 | .sync_fs = jffs2_sync_fs, | 259 | .sync_fs = jffs2_sync_fs, |
147 | }; | 260 | }; |
148 | 261 | ||
@@ -166,6 +279,12 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent) | |||
166 | c->os_priv = sb; | 279 | c->os_priv = sb; |
167 | sb->s_fs_info = c; | 280 | sb->s_fs_info = c; |
168 | 281 | ||
282 | ret = jffs2_parse_options(c, data); | ||
283 | if (ret) { | ||
284 | kfree(c); | ||
285 | return -EINVAL; | ||
286 | } | ||
287 | |||
169 | /* Initialize JFFS2 superblock locks, the further initialization will | 288 | /* Initialize JFFS2 superblock locks, the further initialization will |
170 | * be done later */ | 289 | * be done later */ |
171 | mutex_init(&c->alloc_sem); | 290 | mutex_init(&c->alloc_sem); |
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index 4515bea0268f..b09e51d2f81f 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c | |||
@@ -578,8 +578,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) | |||
578 | if (!jffs2_is_writebuffered(c)) | 578 | if (!jffs2_is_writebuffered(c)) |
579 | return 0; | 579 | return 0; |
580 | 580 | ||
581 | if (mutex_trylock(&c->alloc_sem)) { | 581 | if (!mutex_is_locked(&c->alloc_sem)) { |
582 | mutex_unlock(&c->alloc_sem); | ||
583 | printk(KERN_CRIT "jffs2_flush_wbuf() called with alloc_sem not locked!\n"); | 582 | printk(KERN_CRIT "jffs2_flush_wbuf() called with alloc_sem not locked!\n"); |
584 | BUG(); | 583 | BUG(); |
585 | } | 584 | } |
@@ -1026,7 +1025,7 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c, | |||
1026 | int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE); | 1025 | int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE); |
1027 | struct mtd_oob_ops ops; | 1026 | struct mtd_oob_ops ops; |
1028 | 1027 | ||
1029 | ops.mode = MTD_OOB_AUTO; | 1028 | ops.mode = MTD_OPS_AUTO_OOB; |
1030 | ops.ooblen = NR_OOB_SCAN_PAGES * c->oobavail; | 1029 | ops.ooblen = NR_OOB_SCAN_PAGES * c->oobavail; |
1031 | ops.oobbuf = c->oobbuf; | 1030 | ops.oobbuf = c->oobbuf; |
1032 | ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; | 1031 | ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; |
@@ -1069,7 +1068,7 @@ int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, | |||
1069 | struct mtd_oob_ops ops; | 1068 | struct mtd_oob_ops ops; |
1070 | int ret, cmlen = min_t(int, c->oobavail, OOB_CM_SIZE); | 1069 | int ret, cmlen = min_t(int, c->oobavail, OOB_CM_SIZE); |
1071 | 1070 | ||
1072 | ops.mode = MTD_OOB_AUTO; | 1071 | ops.mode = MTD_OPS_AUTO_OOB; |
1073 | ops.ooblen = cmlen; | 1072 | ops.ooblen = cmlen; |
1074 | ops.oobbuf = c->oobbuf; | 1073 | ops.oobbuf = c->oobbuf; |
1075 | ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; | 1074 | ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; |
@@ -1095,7 +1094,7 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, | |||
1095 | struct mtd_oob_ops ops; | 1094 | struct mtd_oob_ops ops; |
1096 | int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE); | 1095 | int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE); |
1097 | 1096 | ||
1098 | ops.mode = MTD_OOB_AUTO; | 1097 | ops.mode = MTD_OPS_AUTO_OOB; |
1099 | ops.ooblen = cmlen; | 1098 | ops.ooblen = cmlen; |
1100 | ops.oobbuf = (uint8_t *)&oob_cleanmarker; | 1099 | ops.oobbuf = (uint8_t *)&oob_cleanmarker; |
1101 | ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; | 1100 | ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; |