1 /* 2 * JFFS2 -- Journalling Flash File System, Version 2. 3 * 4 * Copyright © 2001-2007 Red Hat, Inc. 5 * 6 * Created by David Woodhouse <dwmw2@infradead.org> 7 * 8 * For licensing information, see the file 'LICENCE' in this directory. 9 * 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/slab.h> 15 #include <linux/init.h> 16 #include <linux/list.h> 17 #include <linux/fs.h> 18 #include <linux/err.h> 19 #include <linux/mount.h> 20 #include <linux/jffs2.h> 21 #include <linux/pagemap.h> 22 #include <linux/mtd/mtd.h> 23 #include <linux/ctype.h> 24 #include <linux/namei.h> 25 #include "compr.h" 26 #include "nodelist.h" 27 28 static void jffs2_put_super(struct super_block *); 29 30 static struct kmem_cache *jffs2_inode_cachep; 31 32 static struct inode *jffs2_alloc_inode(struct super_block *sb) 33 { 34 struct jffs2_inode_info *ei; 35 ei = (struct jffs2_inode_info *)kmem_cache_alloc(jffs2_inode_cachep, GFP_KERNEL); 36 if (!ei) 37 return NULL; 38 return &ei->vfs_inode; 39 } 40 41 static void jffs2_destroy_inode(struct inode *inode) 42 { 43 kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode)); 44 } 45 46 static void jffs2_i_init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) 47 { 48 struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; 49 50 init_MUTEX(&ei->sem); 51 inode_init_once(&ei->vfs_inode); 52 } 53 54 static int jffs2_sync_fs(struct super_block *sb, int wait) 55 { 56 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 57 58 down(&c->alloc_sem); 59 jffs2_flush_wbuf_pad(c); 60 up(&c->alloc_sem); 61 return 0; 62 } 63 64 static const struct super_operations jffs2_super_operations = 65 { 66 .alloc_inode = jffs2_alloc_inode, 67 .destroy_inode =jffs2_destroy_inode, 68 .read_inode = jffs2_read_inode, 69 .put_super = jffs2_put_super, 70 .write_super = jffs2_write_super, 71 .statfs = jffs2_statfs, 72 .remount_fs = jffs2_remount_fs, 73 .clear_inode = jffs2_clear_inode, 74 .dirty_inode = jffs2_dirty_inode, 75 .sync_fs = jffs2_sync_fs, 76 }; 77 78 static int jffs2_sb_compare(struct super_block *sb, void *data) 79 { 80 struct jffs2_sb_info *p = data; 81 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 82 83 /* The superblocks are considered to be equivalent if the underlying MTD 84 device is the same one */ 85 if (c->mtd == p->mtd) { 86 D1(printk(KERN_DEBUG "jffs2_sb_compare: match on device %d (\"%s\")\n", p->mtd->index, p->mtd->name)); 87 return 1; 88 } else { 89 D1(printk(KERN_DEBUG "jffs2_sb_compare: No match, device %d (\"%s\"), device %d (\"%s\")\n", 90 c->mtd->index, c->mtd->name, p->mtd->index, p->mtd->name)); 91 return 0; 92 } 93 } 94 95 static int jffs2_sb_set(struct super_block *sb, void *data) 96 { 97 struct jffs2_sb_info *p = data; 98 99 /* For persistence of NFS exports etc. we use the same s_dev 100 each time we mount the device, don't just use an anonymous 101 device */ 102 sb->s_fs_info = p; 103 p->os_priv = sb; 104 sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, p->mtd->index); 105 106 return 0; 107 } 108 109 static int jffs2_get_sb_mtd(struct file_system_type *fs_type, 110 int flags, const char *dev_name, 111 void *data, struct mtd_info *mtd, 112 struct vfsmount *mnt) 113 { 114 struct super_block *sb; 115 struct jffs2_sb_info *c; 116 int ret; 117 118 c = kzalloc(sizeof(*c), GFP_KERNEL); 119 if (!c) 120 return -ENOMEM; 121 c->mtd = mtd; 122 123 sb = sget(fs_type, jffs2_sb_compare, jffs2_sb_set, c); 124 125 if (IS_ERR(sb)) 126 goto out_error; 127 128 if (sb->s_root) { 129 /* New mountpoint for JFFS2 which is already mounted */ 130 D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): Device %d (\"%s\") is already mounted\n", 131 mtd->index, mtd->name)); 132 ret = simple_set_mnt(mnt, sb); 133 goto out_put; 134 } 135 136 D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): New superblock for device %d (\"%s\")\n", 137 mtd->index, mtd->name)); 138 139 /* Initialize JFFS2 superblock locks, the further initialization will be 140 * done later */ 141 init_MUTEX(&c->alloc_sem); 142 init_MUTEX(&c->erase_free_sem); 143 init_waitqueue_head(&c->erase_wait); 144 init_waitqueue_head(&c->inocache_wq); 145 spin_lock_init(&c->erase_completion_lock); 146 spin_lock_init(&c->inocache_lock); 147 148 sb->s_op = &jffs2_super_operations; 149 sb->s_flags = flags | MS_NOATIME; 150 sb->s_xattr = jffs2_xattr_handlers; 151 #ifdef CONFIG_JFFS2_FS_POSIX_ACL 152 sb->s_flags |= MS_POSIXACL; 153 #endif 154 ret = jffs2_do_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); 155 156 if (ret) { 157 /* Failure case... */ 158 up_write(&sb->s_umount); 159 deactivate_super(sb); 160 return ret; 161 } 162 163 sb->s_flags |= MS_ACTIVE; 164 return simple_set_mnt(mnt, sb); 165 166 out_error: 167 ret = PTR_ERR(sb); 168 out_put: 169 kfree(c); 170 put_mtd_device(mtd); 171 172 return ret; 173 } 174 175 static int jffs2_get_sb_mtdnr(struct file_system_type *fs_type, 176 int flags, const char *dev_name, 177 void *data, int mtdnr, 178 struct vfsmount *mnt) 179 { 180 struct mtd_info *mtd; 181 182 mtd = get_mtd_device(NULL, mtdnr); 183 if (IS_ERR(mtd)) { 184 D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr)); 185 return PTR_ERR(mtd); 186 } 187 188 return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt); 189 } 190 191 static int jffs2_get_sb(struct file_system_type *fs_type, 192 int flags, const char *dev_name, 193 void *data, struct vfsmount *mnt) 194 { 195 int err; 196 struct nameidata nd; 197 int mtdnr; 198 199 if (!dev_name) 200 return -EINVAL; 201 202 D1(printk(KERN_DEBUG "jffs2_get_sb(): dev_name \"%s\"\n", dev_name)); 203 204 /* The preferred way of mounting in future; especially when 205 CONFIG_BLK_DEV is implemented - we specify the underlying 206 MTD device by number or by name, so that we don't require 207 block device support to be present in the kernel. */ 208 209 /* FIXME: How to do the root fs this way? */ 210 211 if (dev_name[0] == 'm' && dev_name[1] == 't' && dev_name[2] == 'd') { 212 /* Probably mounting without the blkdev crap */ 213 if (dev_name[3] == ':') { 214 struct mtd_info *mtd; 215 216 /* Mount by MTD device name */ 217 D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd:%%s, name \"%s\"\n", dev_name+4)); 218 for (mtdnr = 0; mtdnr < MAX_MTD_DEVICES; mtdnr++) { 219 mtd = get_mtd_device(NULL, mtdnr); 220 if (!IS_ERR(mtd)) { 221 if (!strcmp(mtd->name, dev_name+4)) 222 return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt); 223 put_mtd_device(mtd); 224 } 225 } 226 printk(KERN_NOTICE "jffs2_get_sb(): MTD device with name \"%s\" not found.\n", dev_name+4); 227 } else if (isdigit(dev_name[3])) { 228 /* Mount by MTD device number name */ 229 char *endptr; 230 231 mtdnr = simple_strtoul(dev_name+3, &endptr, 0); 232 if (!*endptr) { 233 /* It was a valid number */ 234 D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd%%d, mtdnr %d\n", mtdnr)); 235 return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt); 236 } 237 } 238 } 239 240 /* Try the old way - the hack where we allowed users to mount 241 /dev/mtdblock$(n) but didn't actually _use_ the blkdev */ 242 243 err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd); 244 245 D1(printk(KERN_DEBUG "jffs2_get_sb(): path_lookup() returned %d, inode %p\n", 246 err, nd.dentry->d_inode)); 247 248 if (err) 249 return err; 250 251 err = -EINVAL; 252 253 if (!S_ISBLK(nd.dentry->d_inode->i_mode)) 254 goto out; 255 256 if (nd.mnt->mnt_flags & MNT_NODEV) { 257 err = -EACCES; 258 goto out; 259 } 260 261 if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR) { 262 if (!(flags & MS_SILENT)) 263 printk(KERN_NOTICE "Attempt to mount non-MTD device \"%s\" as JFFS2\n", 264 dev_name); 265 goto out; 266 } 267 268 mtdnr = iminor(nd.dentry->d_inode); 269 path_release(&nd); 270 271 return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt); 272 273 out: 274 path_release(&nd); 275 return err; 276 } 277 278 static void jffs2_put_super (struct super_block *sb) 279 { 280 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 281 282 D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n")); 283 284 down(&c->alloc_sem); 285 jffs2_flush_wbuf_pad(c); 286 up(&c->alloc_sem); 287 288 jffs2_sum_exit(c); 289 290 jffs2_free_ino_caches(c); 291 jffs2_free_raw_node_refs(c); 292 if (jffs2_blocks_use_vmalloc(c)) 293 vfree(c->blocks); 294 else 295 kfree(c->blocks); 296 jffs2_flash_cleanup(c); 297 kfree(c->inocache_list); 298 jffs2_clear_xattr_subsystem(c); 299 if (c->mtd->sync) 300 c->mtd->sync(c->mtd); 301 302 D1(printk(KERN_DEBUG "jffs2_put_super returning\n")); 303 } 304 305 static void jffs2_kill_sb(struct super_block *sb) 306 { 307 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 308 if (!(sb->s_flags & MS_RDONLY)) 309 jffs2_stop_garbage_collect_thread(c); 310 generic_shutdown_super(sb); 311 put_mtd_device(c->mtd); 312 kfree(c); 313 } 314 315 static struct file_system_type jffs2_fs_type = { 316 .owner = THIS_MODULE, 317 .name = "jffs2", 318 .get_sb = jffs2_get_sb, 319 .kill_sb = jffs2_kill_sb, 320 }; 321 322 static int __init init_jffs2_fs(void) 323 { 324 int ret; 325 326 /* Paranoia checks for on-medium structures. If we ask GCC 327 to pack them with __attribute__((packed)) then it _also_ 328 assumes that they're not aligned -- so it emits crappy 329 code on some architectures. Ideally we want an attribute 330 which means just 'no padding', without the alignment 331 thing. But GCC doesn't have that -- we have to just 332 hope the structs are the right sizes, instead. */ 333 BUILD_BUG_ON(sizeof(struct jffs2_unknown_node) != 12); 334 BUILD_BUG_ON(sizeof(struct jffs2_raw_dirent) != 40); 335 BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68); 336 BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32); 337 338 printk(KERN_INFO "JFFS2 version 2.2." 339 #ifdef CONFIG_JFFS2_FS_WRITEBUFFER 340 " (NAND)" 341 #endif 342 #ifdef CONFIG_JFFS2_SUMMARY 343 " (SUMMARY) " 344 #endif 345 " © 2001-2006 Red Hat, Inc.\n"); 346 347 jffs2_inode_cachep = kmem_cache_create("jffs2_i", 348 sizeof(struct jffs2_inode_info), 349 0, (SLAB_RECLAIM_ACCOUNT| 350 SLAB_MEM_SPREAD), 351 jffs2_i_init_once, NULL); 352 if (!jffs2_inode_cachep) { 353 printk(KERN_ERR "JFFS2 error: Failed to initialise inode cache\n"); 354 return -ENOMEM; 355 } 356 ret = jffs2_compressors_init(); 357 if (ret) { 358 printk(KERN_ERR "JFFS2 error: Failed to initialise compressors\n"); 359 goto out; 360 } 361 ret = jffs2_create_slab_caches(); 362 if (ret) { 363 printk(KERN_ERR "JFFS2 error: Failed to initialise slab caches\n"); 364 goto out_compressors; 365 } 366 ret = register_filesystem(&jffs2_fs_type); 367 if (ret) { 368 printk(KERN_ERR "JFFS2 error: Failed to register filesystem\n"); 369 goto out_slab; 370 } 371 return 0; 372 373 out_slab: 374 jffs2_destroy_slab_caches(); 375 out_compressors: 376 jffs2_compressors_exit(); 377 out: 378 kmem_cache_destroy(jffs2_inode_cachep); 379 return ret; 380 } 381 382 static void __exit exit_jffs2_fs(void) 383 { 384 unregister_filesystem(&jffs2_fs_type); 385 jffs2_destroy_slab_caches(); 386 jffs2_compressors_exit(); 387 kmem_cache_destroy(jffs2_inode_cachep); 388 } 389 390 module_init(init_jffs2_fs); 391 module_exit(exit_jffs2_fs); 392 393 MODULE_DESCRIPTION("The Journalling Flash File System, v2"); 394 MODULE_AUTHOR("Red Hat, Inc."); 395 MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for 396 // the sake of this tag. It's Free Software. 397