^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * JFFS2 -- Journalling Flash File System, Version 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright © 2001-2007 Red Hat, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Created by David Woodhouse <dwmw2@infradead.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * For licensing information, see the file 'LICENCE' in this directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/fs_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/fs_parser.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/jffs2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/mtd/super.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/exportfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "compr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "nodelist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static void jffs2_put_super(struct super_block *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static struct kmem_cache *jffs2_inode_cachep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static struct inode *jffs2_alloc_inode(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct jffs2_inode_info *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) f = kmem_cache_alloc(jffs2_inode_cachep, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (!f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return &f->vfs_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static void jffs2_free_inode(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) kfree(f->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) kmem_cache_free(jffs2_inode_cachep, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static void jffs2_i_init_once(void *foo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct jffs2_inode_info *f = foo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) mutex_init(&f->sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) inode_init_once(&f->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static const char *jffs2_compr_name(unsigned int compr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) switch (compr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) case JFFS2_COMPR_MODE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return "none";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #ifdef CONFIG_JFFS2_LZO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) case JFFS2_COMPR_MODE_FORCELZO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return "lzo";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #ifdef CONFIG_JFFS2_ZLIB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) case JFFS2_COMPR_MODE_FORCEZLIB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return "zlib";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* should never happen; programmer error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static int jffs2_show_options(struct seq_file *s, struct dentry *root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct jffs2_sb_info *c = JFFS2_SB_INFO(root->d_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct jffs2_mount_opts *opts = &c->mount_opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (opts->override_compr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) seq_printf(s, ",compr=%s", jffs2_compr_name(opts->compr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (opts->set_rp_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) seq_printf(s, ",rp_size=%u", opts->rp_size / 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static int jffs2_sync_fs(struct super_block *sb, int wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (jffs2_is_writebuffered(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) cancel_delayed_work_sync(&c->wbuf_dwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) mutex_lock(&c->alloc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) jffs2_flush_wbuf_pad(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) mutex_unlock(&c->alloc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static struct inode *jffs2_nfs_get_inode(struct super_block *sb, uint64_t ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) uint32_t generation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* We don't care about i_generation. We'll destroy the flash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) before we start re-using inode numbers anyway. And even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if that wasn't true, we'd have other problems...*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return jffs2_iget(sb, ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static struct dentry *jffs2_fh_to_dentry(struct super_block *sb, struct fid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int fh_len, int fh_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) jffs2_nfs_get_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static struct dentry *jffs2_fh_to_parent(struct super_block *sb, struct fid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int fh_len, int fh_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return generic_fh_to_parent(sb, fid, fh_len, fh_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) jffs2_nfs_get_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static struct dentry *jffs2_get_parent(struct dentry *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct jffs2_inode_info *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) uint32_t pino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) BUG_ON(!d_is_dir(child));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) f = JFFS2_INODE_INFO(d_inode(child));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) pino = f->inocache->pino_nlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) JFFS2_DEBUG("Parent of directory ino #%u is #%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) f->inocache->ino, pino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return d_obtain_alias(jffs2_iget(child->d_sb, pino));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static const struct export_operations jffs2_export_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .get_parent = jffs2_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .fh_to_dentry = jffs2_fh_to_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .fh_to_parent = jffs2_fh_to_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * JFFS2 mount options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * Opt_source: The source device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * Opt_override_compr: override default compressor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * Opt_rp_size: size of reserved pool in KiB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) Opt_override_compr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) Opt_rp_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static const struct constant_table jffs2_param_compr[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {"none", JFFS2_COMPR_MODE_NONE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #ifdef CONFIG_JFFS2_LZO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {"lzo", JFFS2_COMPR_MODE_FORCELZO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #ifdef CONFIG_JFFS2_ZLIB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {"zlib", JFFS2_COMPR_MODE_FORCEZLIB },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static const struct fs_parameter_spec jffs2_fs_parameters[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) fsparam_enum ("compr", Opt_override_compr, jffs2_param_compr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) fsparam_u32 ("rp_size", Opt_rp_size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct fs_parse_result result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct jffs2_sb_info *c = fc->s_fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) opt = fs_parse(fc, jffs2_fs_parameters, param, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (opt < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) switch (opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) case Opt_override_compr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) c->mount_opts.compr = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) c->mount_opts.override_compr = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case Opt_rp_size:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (result.uint_32 > UINT_MAX / 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return invalf(fc, "jffs2: rp_size unrepresentable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) c->mount_opts.rp_size = result.uint_32 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) c->mount_opts.set_rp_size = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static inline void jffs2_update_mount_opts(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct jffs2_sb_info *new_c = fc->s_fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct jffs2_sb_info *c = JFFS2_SB_INFO(fc->root->d_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) mutex_lock(&c->alloc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (new_c->mount_opts.override_compr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) c->mount_opts.override_compr = new_c->mount_opts.override_compr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) c->mount_opts.compr = new_c->mount_opts.compr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (new_c->mount_opts.set_rp_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) c->mount_opts.set_rp_size = new_c->mount_opts.set_rp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) c->mount_opts.rp_size = new_c->mount_opts.rp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) mutex_unlock(&c->alloc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static int jffs2_reconfigure(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct super_block *sb = fc->root->d_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) sync_filesystem(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) jffs2_update_mount_opts(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return jffs2_do_remount_fs(sb, fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static const struct super_operations jffs2_super_operations =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .alloc_inode = jffs2_alloc_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .free_inode = jffs2_free_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .put_super = jffs2_put_super,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .statfs = jffs2_statfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .evict_inode = jffs2_evict_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .dirty_inode = jffs2_dirty_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .show_options = jffs2_show_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .sync_fs = jffs2_sync_fs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * fill in the superblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int jffs2_fill_super(struct super_block *sb, struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct jffs2_sb_info *c = sb->s_fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) jffs2_dbg(1, "jffs2_get_sb_mtd():"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) " New superblock for device %d (\"%s\")\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) sb->s_mtd->index, sb->s_mtd->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) c->mtd = sb->s_mtd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) c->os_priv = sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (c->mount_opts.rp_size > c->mtd->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return invalf(fc, "jffs2: Too large reserve pool specified, max is %llu KB",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) c->mtd->size / 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* Initialize JFFS2 superblock locks, the further initialization will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * be done later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) mutex_init(&c->alloc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) mutex_init(&c->erase_free_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) init_waitqueue_head(&c->erase_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) init_waitqueue_head(&c->inocache_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) spin_lock_init(&c->erase_completion_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) spin_lock_init(&c->inocache_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) sb->s_op = &jffs2_super_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) sb->s_export_op = &jffs2_export_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) sb->s_flags = sb->s_flags | SB_NOATIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) sb->s_xattr = jffs2_xattr_handlers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #ifdef CONFIG_JFFS2_FS_POSIX_ACL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) sb->s_flags |= SB_POSIXACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return jffs2_do_fill_super(sb, fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int jffs2_get_tree(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return get_tree_mtd(fc, jffs2_fill_super);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static void jffs2_free_fc(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) kfree(fc->s_fs_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static const struct fs_context_operations jffs2_context_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .free = jffs2_free_fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) .parse_param = jffs2_parse_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) .get_tree = jffs2_get_tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) .reconfigure = jffs2_reconfigure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static int jffs2_init_fs_context(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct jffs2_sb_info *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ctx = kzalloc(sizeof(struct jffs2_sb_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (!ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) fc->s_fs_info = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) fc->ops = &jffs2_context_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static void jffs2_put_super (struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) jffs2_dbg(2, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) mutex_lock(&c->alloc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) jffs2_flush_wbuf_pad(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) mutex_unlock(&c->alloc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) jffs2_sum_exit(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) jffs2_free_ino_caches(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) jffs2_free_raw_node_refs(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) kvfree(c->blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) jffs2_flash_cleanup(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) kfree(c->inocache_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) jffs2_clear_xattr_subsystem(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) mtd_sync(c->mtd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) jffs2_dbg(1, "%s(): returning\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static void jffs2_kill_sb(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (c && !sb_rdonly(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) jffs2_stop_garbage_collect_thread(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) kill_mtd_super(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) kfree(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static struct file_system_type jffs2_fs_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) .name = "jffs2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .init_fs_context = jffs2_init_fs_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .parameters = jffs2_fs_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) .kill_sb = jffs2_kill_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) MODULE_ALIAS_FS("jffs2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static int __init init_jffs2_fs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* Paranoia checks for on-medium structures. If we ask GCC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) to pack them with __attribute__((packed)) then it _also_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) assumes that they're not aligned -- so it emits crappy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) code on some architectures. Ideally we want an attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) which means just 'no padding', without the alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) thing. But GCC doesn't have that -- we have to just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) hope the structs are the right sizes, instead. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) BUILD_BUG_ON(sizeof(struct jffs2_unknown_node) != 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) BUILD_BUG_ON(sizeof(struct jffs2_raw_dirent) != 40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) pr_info("version 2.2."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) " (NAND)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) #ifdef CONFIG_JFFS2_SUMMARY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) " (SUMMARY) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) " © 2001-2006 Red Hat, Inc.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) jffs2_inode_cachep = kmem_cache_create("jffs2_i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) sizeof(struct jffs2_inode_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 0, (SLAB_RECLAIM_ACCOUNT|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) SLAB_MEM_SPREAD|SLAB_ACCOUNT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) jffs2_i_init_once);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (!jffs2_inode_cachep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) pr_err("error: Failed to initialise inode cache\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ret = jffs2_compressors_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) pr_err("error: Failed to initialise compressors\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ret = jffs2_create_slab_caches();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) pr_err("error: Failed to initialise slab caches\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) goto out_compressors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ret = register_filesystem(&jffs2_fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) pr_err("error: Failed to register filesystem\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) goto out_slab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) out_slab:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) jffs2_destroy_slab_caches();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) out_compressors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) jffs2_compressors_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) kmem_cache_destroy(jffs2_inode_cachep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static void __exit exit_jffs2_fs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) unregister_filesystem(&jffs2_fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) jffs2_destroy_slab_caches();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) jffs2_compressors_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * Make sure all delayed rcu free inodes are flushed before we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * destroy cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) rcu_barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) kmem_cache_destroy(jffs2_inode_cachep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) module_init(init_jffs2_fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) module_exit(exit_jffs2_fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) MODULE_DESCRIPTION("The Journalling Flash File System, v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) MODULE_AUTHOR("Red Hat, Inc.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) // the sake of this tag. It's Free Software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY);