diff options
Diffstat (limited to 'fs/jffs2/super.c')
-rw-r--r-- | fs/jffs2/super.c | 69 |
1 files changed, 45 insertions, 24 deletions
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index ffd8e84b22cc..2378a662c256 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c | |||
@@ -111,9 +111,10 @@ static int jffs2_sb_set(struct super_block *sb, void *data) | |||
111 | return 0; | 111 | return 0; |
112 | } | 112 | } |
113 | 113 | ||
114 | static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type, | 114 | static int jffs2_get_sb_mtd(struct file_system_type *fs_type, |
115 | int flags, const char *dev_name, | 115 | int flags, const char *dev_name, |
116 | void *data, struct mtd_info *mtd) | 116 | void *data, struct mtd_info *mtd, |
117 | struct vfsmount *mnt) | ||
117 | { | 118 | { |
118 | struct super_block *sb; | 119 | struct super_block *sb; |
119 | struct jffs2_sb_info *c; | 120 | struct jffs2_sb_info *c; |
@@ -121,19 +122,20 @@ static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type, | |||
121 | 122 | ||
122 | c = kmalloc(sizeof(*c), GFP_KERNEL); | 123 | c = kmalloc(sizeof(*c), GFP_KERNEL); |
123 | if (!c) | 124 | if (!c) |
124 | return ERR_PTR(-ENOMEM); | 125 | return -ENOMEM; |
125 | memset(c, 0, sizeof(*c)); | 126 | memset(c, 0, sizeof(*c)); |
126 | c->mtd = mtd; | 127 | c->mtd = mtd; |
127 | 128 | ||
128 | sb = sget(fs_type, jffs2_sb_compare, jffs2_sb_set, c); | 129 | sb = sget(fs_type, jffs2_sb_compare, jffs2_sb_set, c); |
129 | 130 | ||
130 | if (IS_ERR(sb)) | 131 | if (IS_ERR(sb)) |
131 | goto out_put; | 132 | goto out_error; |
132 | 133 | ||
133 | if (sb->s_root) { | 134 | if (sb->s_root) { |
134 | /* New mountpoint for JFFS2 which is already mounted */ | 135 | /* New mountpoint for JFFS2 which is already mounted */ |
135 | D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): Device %d (\"%s\") is already mounted\n", | 136 | D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): Device %d (\"%s\") is already mounted\n", |
136 | mtd->index, mtd->name)); | 137 | mtd->index, mtd->name)); |
138 | ret = simple_set_mnt(mnt, sb); | ||
137 | goto out_put; | 139 | goto out_put; |
138 | } | 140 | } |
139 | 141 | ||
@@ -151,51 +153,57 @@ static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type, | |||
151 | 153 | ||
152 | sb->s_op = &jffs2_super_operations; | 154 | sb->s_op = &jffs2_super_operations; |
153 | sb->s_flags = flags | MS_NOATIME; | 155 | sb->s_flags = flags | MS_NOATIME; |
154 | 156 | sb->s_xattr = jffs2_xattr_handlers; | |
157 | #ifdef CONFIG_JFFS2_FS_POSIX_ACL | ||
158 | sb->s_flags |= MS_POSIXACL; | ||
159 | #endif | ||
155 | ret = jffs2_do_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); | 160 | ret = jffs2_do_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); |
156 | 161 | ||
157 | if (ret) { | 162 | if (ret) { |
158 | /* Failure case... */ | 163 | /* Failure case... */ |
159 | up_write(&sb->s_umount); | 164 | up_write(&sb->s_umount); |
160 | deactivate_super(sb); | 165 | deactivate_super(sb); |
161 | return ERR_PTR(ret); | 166 | return ret; |
162 | } | 167 | } |
163 | 168 | ||
164 | sb->s_flags |= MS_ACTIVE; | 169 | sb->s_flags |= MS_ACTIVE; |
165 | return sb; | 170 | return simple_set_mnt(mnt, sb); |
166 | 171 | ||
172 | out_error: | ||
173 | ret = PTR_ERR(sb); | ||
167 | out_put: | 174 | out_put: |
168 | kfree(c); | 175 | kfree(c); |
169 | put_mtd_device(mtd); | 176 | put_mtd_device(mtd); |
170 | 177 | ||
171 | return sb; | 178 | return ret; |
172 | } | 179 | } |
173 | 180 | ||
174 | static struct super_block *jffs2_get_sb_mtdnr(struct file_system_type *fs_type, | 181 | static int jffs2_get_sb_mtdnr(struct file_system_type *fs_type, |
175 | int flags, const char *dev_name, | 182 | int flags, const char *dev_name, |
176 | void *data, int mtdnr) | 183 | void *data, int mtdnr, |
184 | struct vfsmount *mnt) | ||
177 | { | 185 | { |
178 | struct mtd_info *mtd; | 186 | struct mtd_info *mtd; |
179 | 187 | ||
180 | mtd = get_mtd_device(NULL, mtdnr); | 188 | mtd = get_mtd_device(NULL, mtdnr); |
181 | if (!mtd) { | 189 | if (!mtd) { |
182 | D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr)); | 190 | D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr)); |
183 | return ERR_PTR(-EINVAL); | 191 | return -EINVAL; |
184 | } | 192 | } |
185 | 193 | ||
186 | return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd); | 194 | return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt); |
187 | } | 195 | } |
188 | 196 | ||
189 | static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, | 197 | static int jffs2_get_sb(struct file_system_type *fs_type, |
190 | int flags, const char *dev_name, | 198 | int flags, const char *dev_name, |
191 | void *data) | 199 | void *data, struct vfsmount *mnt) |
192 | { | 200 | { |
193 | int err; | 201 | int err; |
194 | struct nameidata nd; | 202 | struct nameidata nd; |
195 | int mtdnr; | 203 | int mtdnr; |
196 | 204 | ||
197 | if (!dev_name) | 205 | if (!dev_name) |
198 | return ERR_PTR(-EINVAL); | 206 | return -EINVAL; |
199 | 207 | ||
200 | D1(printk(KERN_DEBUG "jffs2_get_sb(): dev_name \"%s\"\n", dev_name)); | 208 | D1(printk(KERN_DEBUG "jffs2_get_sb(): dev_name \"%s\"\n", dev_name)); |
201 | 209 | ||
@@ -217,7 +225,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, | |||
217 | mtd = get_mtd_device(NULL, mtdnr); | 225 | mtd = get_mtd_device(NULL, mtdnr); |
218 | if (mtd) { | 226 | if (mtd) { |
219 | if (!strcmp(mtd->name, dev_name+4)) | 227 | if (!strcmp(mtd->name, dev_name+4)) |
220 | return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd); | 228 | return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt); |
221 | put_mtd_device(mtd); | 229 | put_mtd_device(mtd); |
222 | } | 230 | } |
223 | } | 231 | } |
@@ -230,7 +238,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, | |||
230 | if (!*endptr) { | 238 | if (!*endptr) { |
231 | /* It was a valid number */ | 239 | /* It was a valid number */ |
232 | D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd%%d, mtdnr %d\n", mtdnr)); | 240 | D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd%%d, mtdnr %d\n", mtdnr)); |
233 | return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr); | 241 | return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt); |
234 | } | 242 | } |
235 | } | 243 | } |
236 | } | 244 | } |
@@ -244,7 +252,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, | |||
244 | err, nd.dentry->d_inode)); | 252 | err, nd.dentry->d_inode)); |
245 | 253 | ||
246 | if (err) | 254 | if (err) |
247 | return ERR_PTR(err); | 255 | return err; |
248 | 256 | ||
249 | err = -EINVAL; | 257 | err = -EINVAL; |
250 | 258 | ||
@@ -266,11 +274,11 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, | |||
266 | mtdnr = iminor(nd.dentry->d_inode); | 274 | mtdnr = iminor(nd.dentry->d_inode); |
267 | path_release(&nd); | 275 | path_release(&nd); |
268 | 276 | ||
269 | return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr); | 277 | return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt); |
270 | 278 | ||
271 | out: | 279 | out: |
272 | path_release(&nd); | 280 | path_release(&nd); |
273 | return ERR_PTR(err); | 281 | return err; |
274 | } | 282 | } |
275 | 283 | ||
276 | static void jffs2_put_super (struct super_block *sb) | 284 | static void jffs2_put_super (struct super_block *sb) |
@@ -293,6 +301,7 @@ static void jffs2_put_super (struct super_block *sb) | |||
293 | kfree(c->blocks); | 301 | kfree(c->blocks); |
294 | jffs2_flash_cleanup(c); | 302 | jffs2_flash_cleanup(c); |
295 | kfree(c->inocache_list); | 303 | kfree(c->inocache_list); |
304 | jffs2_clear_xattr_subsystem(c); | ||
296 | if (c->mtd->sync) | 305 | if (c->mtd->sync) |
297 | c->mtd->sync(c->mtd); | 306 | c->mtd->sync(c->mtd); |
298 | 307 | ||
@@ -320,6 +329,18 @@ static int __init init_jffs2_fs(void) | |||
320 | { | 329 | { |
321 | int ret; | 330 | int ret; |
322 | 331 | ||
332 | /* Paranoia checks for on-medium structures. If we ask GCC | ||
333 | to pack them with __attribute__((packed)) then it _also_ | ||
334 | assumes that they're not aligned -- so it emits crappy | ||
335 | code on some architectures. Ideally we want an attribute | ||
336 | which means just 'no padding', without the alignment | ||
337 | thing. But GCC doesn't have that -- we have to just | ||
338 | hope the structs are the right sizes, instead. */ | ||
339 | BUG_ON(sizeof(struct jffs2_unknown_node) != 12); | ||
340 | BUG_ON(sizeof(struct jffs2_raw_dirent) != 40); | ||
341 | BUG_ON(sizeof(struct jffs2_raw_inode) != 68); | ||
342 | BUG_ON(sizeof(struct jffs2_raw_summary) != 32); | ||
343 | |||
323 | printk(KERN_INFO "JFFS2 version 2.2." | 344 | printk(KERN_INFO "JFFS2 version 2.2." |
324 | #ifdef CONFIG_JFFS2_FS_WRITEBUFFER | 345 | #ifdef CONFIG_JFFS2_FS_WRITEBUFFER |
325 | " (NAND)" | 346 | " (NAND)" |
@@ -327,7 +348,7 @@ static int __init init_jffs2_fs(void) | |||
327 | #ifdef CONFIG_JFFS2_SUMMARY | 348 | #ifdef CONFIG_JFFS2_SUMMARY |
328 | " (SUMMARY) " | 349 | " (SUMMARY) " |
329 | #endif | 350 | #endif |
330 | " (C) 2001-2003 Red Hat, Inc.\n"); | 351 | " (C) 2001-2006 Red Hat, Inc.\n"); |
331 | 352 | ||
332 | jffs2_inode_cachep = kmem_cache_create("jffs2_i", | 353 | jffs2_inode_cachep = kmem_cache_create("jffs2_i", |
333 | sizeof(struct jffs2_inode_info), | 354 | sizeof(struct jffs2_inode_info), |