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.c69
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
114static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type, 114static 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
172out_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
174static struct super_block *jffs2_get_sb_mtdnr(struct file_system_type *fs_type, 181static 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
189static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, 197static 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
271out: 279out:
272 path_release(&nd); 280 path_release(&nd);
273 return ERR_PTR(err); 281 return err;
274} 282}
275 283
276static void jffs2_put_super (struct super_block *sb) 284static 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),