Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * JFFS2 -- Journalling Flash File System, Version 2.
0003  *
0004  * Copyright © 2001-2007 Red Hat, Inc.
0005  *
0006  * Created by David Woodhouse <dwmw2@infradead.org>
0007  *
0008  * For licensing information, see the file 'LICENCE' in this directory.
0009  *
0010  */
0011 
0012 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0013 
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/slab.h>
0017 #include <linux/init.h>
0018 #include <linux/list.h>
0019 #include <linux/fs.h>
0020 #include <linux/err.h>
0021 #include <linux/mount.h>
0022 #include <linux/fs_context.h>
0023 #include <linux/fs_parser.h>
0024 #include <linux/jffs2.h>
0025 #include <linux/pagemap.h>
0026 #include <linux/mtd/super.h>
0027 #include <linux/ctype.h>
0028 #include <linux/namei.h>
0029 #include <linux/seq_file.h>
0030 #include <linux/exportfs.h>
0031 #include "compr.h"
0032 #include "nodelist.h"
0033 
0034 static void jffs2_put_super(struct super_block *);
0035 
0036 static struct kmem_cache *jffs2_inode_cachep;
0037 
0038 static struct inode *jffs2_alloc_inode(struct super_block *sb)
0039 {
0040     struct jffs2_inode_info *f;
0041 
0042     f = alloc_inode_sb(sb, jffs2_inode_cachep, GFP_KERNEL);
0043     if (!f)
0044         return NULL;
0045     return &f->vfs_inode;
0046 }
0047 
0048 static void jffs2_free_inode(struct inode *inode)
0049 {
0050     struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
0051 
0052     kfree(f->target);
0053     kmem_cache_free(jffs2_inode_cachep, f);
0054 }
0055 
0056 static void jffs2_i_init_once(void *foo)
0057 {
0058     struct jffs2_inode_info *f = foo;
0059 
0060     mutex_init(&f->sem);
0061     inode_init_once(&f->vfs_inode);
0062 }
0063 
0064 static const char *jffs2_compr_name(unsigned int compr)
0065 {
0066     switch (compr) {
0067     case JFFS2_COMPR_MODE_NONE:
0068         return "none";
0069 #ifdef CONFIG_JFFS2_LZO
0070     case JFFS2_COMPR_MODE_FORCELZO:
0071         return "lzo";
0072 #endif
0073 #ifdef CONFIG_JFFS2_ZLIB
0074     case JFFS2_COMPR_MODE_FORCEZLIB:
0075         return "zlib";
0076 #endif
0077     default:
0078         /* should never happen; programmer error */
0079         WARN_ON(1);
0080         return "";
0081     }
0082 }
0083 
0084 static int jffs2_show_options(struct seq_file *s, struct dentry *root)
0085 {
0086     struct jffs2_sb_info *c = JFFS2_SB_INFO(root->d_sb);
0087     struct jffs2_mount_opts *opts = &c->mount_opts;
0088 
0089     if (opts->override_compr)
0090         seq_printf(s, ",compr=%s", jffs2_compr_name(opts->compr));
0091     if (opts->set_rp_size)
0092         seq_printf(s, ",rp_size=%u", opts->rp_size / 1024);
0093 
0094     return 0;
0095 }
0096 
0097 static int jffs2_sync_fs(struct super_block *sb, int wait)
0098 {
0099     struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
0100 
0101 #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
0102     if (jffs2_is_writebuffered(c))
0103         cancel_delayed_work_sync(&c->wbuf_dwork);
0104 #endif
0105 
0106     mutex_lock(&c->alloc_sem);
0107     jffs2_flush_wbuf_pad(c);
0108     mutex_unlock(&c->alloc_sem);
0109     return 0;
0110 }
0111 
0112 static struct inode *jffs2_nfs_get_inode(struct super_block *sb, uint64_t ino,
0113                      uint32_t generation)
0114 {
0115     /* We don't care about i_generation. We'll destroy the flash
0116        before we start re-using inode numbers anyway. And even
0117        if that wasn't true, we'd have other problems...*/
0118     return jffs2_iget(sb, ino);
0119 }
0120 
0121 static struct dentry *jffs2_fh_to_dentry(struct super_block *sb, struct fid *fid,
0122                      int fh_len, int fh_type)
0123 {
0124         return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
0125                                     jffs2_nfs_get_inode);
0126 }
0127 
0128 static struct dentry *jffs2_fh_to_parent(struct super_block *sb, struct fid *fid,
0129                      int fh_len, int fh_type)
0130 {
0131         return generic_fh_to_parent(sb, fid, fh_len, fh_type,
0132                                     jffs2_nfs_get_inode);
0133 }
0134 
0135 static struct dentry *jffs2_get_parent(struct dentry *child)
0136 {
0137     struct jffs2_inode_info *f;
0138     uint32_t pino;
0139 
0140     BUG_ON(!d_is_dir(child));
0141 
0142     f = JFFS2_INODE_INFO(d_inode(child));
0143 
0144     pino = f->inocache->pino_nlink;
0145 
0146     JFFS2_DEBUG("Parent of directory ino #%u is #%u\n",
0147             f->inocache->ino, pino);
0148 
0149     return d_obtain_alias(jffs2_iget(child->d_sb, pino));
0150 }
0151 
0152 static const struct export_operations jffs2_export_ops = {
0153     .get_parent = jffs2_get_parent,
0154     .fh_to_dentry = jffs2_fh_to_dentry,
0155     .fh_to_parent = jffs2_fh_to_parent,
0156 };
0157 
0158 /*
0159  * JFFS2 mount options.
0160  *
0161  * Opt_source: The source device
0162  * Opt_override_compr: override default compressor
0163  * Opt_rp_size: size of reserved pool in KiB
0164  */
0165 enum {
0166     Opt_override_compr,
0167     Opt_rp_size,
0168 };
0169 
0170 static const struct constant_table jffs2_param_compr[] = {
0171     {"none",    JFFS2_COMPR_MODE_NONE },
0172 #ifdef CONFIG_JFFS2_LZO
0173     {"lzo",     JFFS2_COMPR_MODE_FORCELZO },
0174 #endif
0175 #ifdef CONFIG_JFFS2_ZLIB
0176     {"zlib",    JFFS2_COMPR_MODE_FORCEZLIB },
0177 #endif
0178     {}
0179 };
0180 
0181 static const struct fs_parameter_spec jffs2_fs_parameters[] = {
0182     fsparam_enum    ("compr",   Opt_override_compr, jffs2_param_compr),
0183     fsparam_u32 ("rp_size", Opt_rp_size),
0184     {}
0185 };
0186 
0187 static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
0188 {
0189     struct fs_parse_result result;
0190     struct jffs2_sb_info *c = fc->s_fs_info;
0191     int opt;
0192 
0193     opt = fs_parse(fc, jffs2_fs_parameters, param, &result);
0194     if (opt < 0)
0195         return opt;
0196 
0197     switch (opt) {
0198     case Opt_override_compr:
0199         c->mount_opts.compr = result.uint_32;
0200         c->mount_opts.override_compr = true;
0201         break;
0202     case Opt_rp_size:
0203         if (result.uint_32 > UINT_MAX / 1024)
0204             return invalf(fc, "jffs2: rp_size unrepresentable");
0205         c->mount_opts.rp_size = result.uint_32 * 1024;
0206         c->mount_opts.set_rp_size = true;
0207         break;
0208     default:
0209         return -EINVAL;
0210     }
0211 
0212     return 0;
0213 }
0214 
0215 static inline void jffs2_update_mount_opts(struct fs_context *fc)
0216 {
0217     struct jffs2_sb_info *new_c = fc->s_fs_info;
0218     struct jffs2_sb_info *c = JFFS2_SB_INFO(fc->root->d_sb);
0219 
0220     mutex_lock(&c->alloc_sem);
0221     if (new_c->mount_opts.override_compr) {
0222         c->mount_opts.override_compr = new_c->mount_opts.override_compr;
0223         c->mount_opts.compr = new_c->mount_opts.compr;
0224     }
0225     if (new_c->mount_opts.set_rp_size) {
0226         c->mount_opts.set_rp_size = new_c->mount_opts.set_rp_size;
0227         c->mount_opts.rp_size = new_c->mount_opts.rp_size;
0228     }
0229     mutex_unlock(&c->alloc_sem);
0230 }
0231 
0232 static int jffs2_reconfigure(struct fs_context *fc)
0233 {
0234     struct super_block *sb = fc->root->d_sb;
0235 
0236     sync_filesystem(sb);
0237     jffs2_update_mount_opts(fc);
0238 
0239     return jffs2_do_remount_fs(sb, fc);
0240 }
0241 
0242 static const struct super_operations jffs2_super_operations =
0243 {
0244     .alloc_inode =  jffs2_alloc_inode,
0245     .free_inode =   jffs2_free_inode,
0246     .put_super =    jffs2_put_super,
0247     .statfs =   jffs2_statfs,
0248     .evict_inode =  jffs2_evict_inode,
0249     .dirty_inode =  jffs2_dirty_inode,
0250     .show_options = jffs2_show_options,
0251     .sync_fs =  jffs2_sync_fs,
0252 };
0253 
0254 /*
0255  * fill in the superblock
0256  */
0257 static int jffs2_fill_super(struct super_block *sb, struct fs_context *fc)
0258 {
0259     struct jffs2_sb_info *c = sb->s_fs_info;
0260 
0261     jffs2_dbg(1, "jffs2_get_sb_mtd():"
0262           " New superblock for device %d (\"%s\")\n",
0263           sb->s_mtd->index, sb->s_mtd->name);
0264 
0265     c->mtd = sb->s_mtd;
0266     c->os_priv = sb;
0267 
0268     if (c->mount_opts.rp_size > c->mtd->size)
0269         return invalf(fc, "jffs2: Too large reserve pool specified, max is %llu KB",
0270                   c->mtd->size / 1024);
0271 
0272     /* Initialize JFFS2 superblock locks, the further initialization will
0273      * be done later */
0274     mutex_init(&c->alloc_sem);
0275     mutex_init(&c->erase_free_sem);
0276     init_waitqueue_head(&c->erase_wait);
0277     init_waitqueue_head(&c->inocache_wq);
0278     spin_lock_init(&c->erase_completion_lock);
0279     spin_lock_init(&c->inocache_lock);
0280 
0281     sb->s_op = &jffs2_super_operations;
0282     sb->s_export_op = &jffs2_export_ops;
0283     sb->s_flags = sb->s_flags | SB_NOATIME;
0284     sb->s_xattr = jffs2_xattr_handlers;
0285 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
0286     sb->s_flags |= SB_POSIXACL;
0287 #endif
0288     return jffs2_do_fill_super(sb, fc);
0289 }
0290 
0291 static int jffs2_get_tree(struct fs_context *fc)
0292 {
0293     return get_tree_mtd(fc, jffs2_fill_super);
0294 }
0295 
0296 static void jffs2_free_fc(struct fs_context *fc)
0297 {
0298     kfree(fc->s_fs_info);
0299 }
0300 
0301 static const struct fs_context_operations jffs2_context_ops = {
0302     .free       = jffs2_free_fc,
0303     .parse_param    = jffs2_parse_param,
0304     .get_tree   = jffs2_get_tree,
0305     .reconfigure    = jffs2_reconfigure,
0306 };
0307 
0308 static int jffs2_init_fs_context(struct fs_context *fc)
0309 {
0310     struct jffs2_sb_info *ctx;
0311 
0312     ctx = kzalloc(sizeof(struct jffs2_sb_info), GFP_KERNEL);
0313     if (!ctx)
0314         return -ENOMEM;
0315 
0316     fc->s_fs_info = ctx;
0317     fc->ops = &jffs2_context_ops;
0318     return 0;
0319 }
0320 
0321 static void jffs2_put_super (struct super_block *sb)
0322 {
0323     struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
0324 
0325     jffs2_dbg(2, "%s()\n", __func__);
0326 
0327     mutex_lock(&c->alloc_sem);
0328     jffs2_flush_wbuf_pad(c);
0329     mutex_unlock(&c->alloc_sem);
0330 
0331     jffs2_sum_exit(c);
0332 
0333     jffs2_free_ino_caches(c);
0334     jffs2_free_raw_node_refs(c);
0335     kvfree(c->blocks);
0336     jffs2_flash_cleanup(c);
0337     kfree(c->inocache_list);
0338     jffs2_clear_xattr_subsystem(c);
0339     mtd_sync(c->mtd);
0340     jffs2_dbg(1, "%s(): returning\n", __func__);
0341 }
0342 
0343 static void jffs2_kill_sb(struct super_block *sb)
0344 {
0345     struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
0346     if (c && !sb_rdonly(sb))
0347         jffs2_stop_garbage_collect_thread(c);
0348     kill_mtd_super(sb);
0349     kfree(c);
0350 }
0351 
0352 static struct file_system_type jffs2_fs_type = {
0353     .owner =    THIS_MODULE,
0354     .name =     "jffs2",
0355     .init_fs_context = jffs2_init_fs_context,
0356     .parameters =   jffs2_fs_parameters,
0357     .kill_sb =  jffs2_kill_sb,
0358 };
0359 MODULE_ALIAS_FS("jffs2");
0360 
0361 static int __init init_jffs2_fs(void)
0362 {
0363     int ret;
0364 
0365     /* Paranoia checks for on-medium structures. If we ask GCC
0366        to pack them with __attribute__((packed)) then it _also_
0367        assumes that they're not aligned -- so it emits crappy
0368        code on some architectures. Ideally we want an attribute
0369        which means just 'no padding', without the alignment
0370        thing. But GCC doesn't have that -- we have to just
0371        hope the structs are the right sizes, instead. */
0372     BUILD_BUG_ON(sizeof(struct jffs2_unknown_node) != 12);
0373     BUILD_BUG_ON(sizeof(struct jffs2_raw_dirent) != 40);
0374     BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68);
0375     BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32);
0376 
0377     pr_info("version 2.2."
0378 #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
0379            " (NAND)"
0380 #endif
0381 #ifdef CONFIG_JFFS2_SUMMARY
0382            " (SUMMARY) "
0383 #endif
0384            " © 2001-2006 Red Hat, Inc.\n");
0385 
0386     jffs2_inode_cachep = kmem_cache_create("jffs2_i",
0387                          sizeof(struct jffs2_inode_info),
0388                          0, (SLAB_RECLAIM_ACCOUNT|
0389                         SLAB_MEM_SPREAD|SLAB_ACCOUNT),
0390                          jffs2_i_init_once);
0391     if (!jffs2_inode_cachep) {
0392         pr_err("error: Failed to initialise inode cache\n");
0393         return -ENOMEM;
0394     }
0395     ret = jffs2_compressors_init();
0396     if (ret) {
0397         pr_err("error: Failed to initialise compressors\n");
0398         goto out;
0399     }
0400     ret = jffs2_create_slab_caches();
0401     if (ret) {
0402         pr_err("error: Failed to initialise slab caches\n");
0403         goto out_compressors;
0404     }
0405     ret = register_filesystem(&jffs2_fs_type);
0406     if (ret) {
0407         pr_err("error: Failed to register filesystem\n");
0408         goto out_slab;
0409     }
0410     return 0;
0411 
0412  out_slab:
0413     jffs2_destroy_slab_caches();
0414  out_compressors:
0415     jffs2_compressors_exit();
0416  out:
0417     kmem_cache_destroy(jffs2_inode_cachep);
0418     return ret;
0419 }
0420 
0421 static void __exit exit_jffs2_fs(void)
0422 {
0423     unregister_filesystem(&jffs2_fs_type);
0424     jffs2_destroy_slab_caches();
0425     jffs2_compressors_exit();
0426 
0427     /*
0428      * Make sure all delayed rcu free inodes are flushed before we
0429      * destroy cache.
0430      */
0431     rcu_barrier();
0432     kmem_cache_destroy(jffs2_inode_cachep);
0433 }
0434 
0435 module_init(init_jffs2_fs);
0436 module_exit(exit_jffs2_fs);
0437 
0438 MODULE_DESCRIPTION("The Journalling Flash File System, v2");
0439 MODULE_AUTHOR("Red Hat, Inc.");
0440 MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for
0441                // the sake of this tag. It's Free Software.