/* * JFFS2 -- Journalling Flash File System, Version 2. * * Copyright © 2006 NEC Corporation * * Created by KaiGai Kohei <[email protected]> * * For licensing information, see the file 'LICENCE' in this directory. * */ #define pr_fmt(fmt) … #define JFFS2_XATTR_IS_CORRUPTED … #include <linux/kernel.h> #include <linux/slab.h> #include <linux/fs.h> #include <linux/time.h> #include <linux/pagemap.h> #include <linux/highmem.h> #include <linux/crc32.h> #include <linux/jffs2.h> #include <linux/xattr.h> #include <linux/posix_acl_xattr.h> #include <linux/mtd/mtd.h> #include "nodelist.h" /* -------- xdatum related functions ---------------- * xattr_datum_hashkey(xprefix, xname, xvalue, xsize) * is used to calcurate xdatum hashkey. The reminder of hashkey into XATTRINDEX_HASHSIZE is * the index of the xattr name/value pair cache (c->xattrindex). * is_xattr_datum_unchecked(c, xd) * returns 1, if xdatum contains any unchecked raw nodes. if all raw nodes are not * unchecked, it returns 0. * unload_xattr_datum(c, xd) * is used to release xattr name/value pair and detach from c->xattrindex. * reclaim_xattr_datum(c) * is used to reclaim xattr name/value pairs on the xattr name/value pair cache when * memory usage by cache is over c->xdatum_mem_threshold. Currently, this threshold * is hard coded as 32KiB. * do_verify_xattr_datum(c, xd) * is used to load the xdatum informations without name/value pair from the medium. * It's necessary once, because those informations are not collected during mounting * process when EBS is enabled. * 0 will be returned, if success. An negative return value means recoverable error, and * positive return value means unrecoverable error. Thus, caller must remove this xdatum * and xref when it returned positive value. * do_load_xattr_datum(c, xd) * is used to load name/value pair from the medium. * The meanings of return value is same as do_verify_xattr_datum(). * load_xattr_datum(c, xd) * is used to be as a wrapper of do_verify_xattr_datum() and do_load_xattr_datum(). * If xd need to call do_verify_xattr_datum() at first, it's called before calling * do_load_xattr_datum(). The meanings of return value is same as do_verify_xattr_datum(). * save_xattr_datum(c, xd) * is used to write xdatum to medium. xd->version will be incremented. * create_xattr_datum(c, xprefix, xname, xvalue, xsize) * is used to create new xdatum and write to medium. * unrefer_xattr_datum(c, xd) * is used to delete a xdatum. When nobody refers this xdatum, JFFS2_XFLAGS_DEAD * is set on xd->flags and chained xattr_dead_list or release it immediately. * In the first case, the garbage collector release it later. * -------------------------------------------------- */ static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize) { … } static int is_xattr_datum_unchecked(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) { … } static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) { … } static void reclaim_xattr_datum(struct jffs2_sb_info *c) { … } static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) { … } static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) { … } static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) { … } static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) { … } static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c, int xprefix, const char *xname, const char *xvalue, int xsize) { … } static void unrefer_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) { … } /* -------- xref related functions ------------------ * verify_xattr_ref(c, ref) * is used to load xref information from medium. Because summary data does not * contain xid/ino, it's necessary to verify once while mounting process. * save_xattr_ref(c, ref) * is used to write xref to medium. If delete marker is marked, it write * a delete marker of xref into medium. * create_xattr_ref(c, ic, xd) * is used to create a new xref and write to medium. * delete_xattr_ref(c, ref) * is used to delete jffs2_xattr_ref. It marks xref XREF_DELETE_MARKER, * and allows GC to reclaim those physical nodes. * jffs2_xattr_delete_inode(c, ic) * is called to remove xrefs related to obsolete inode when inode is unlinked. * jffs2_xattr_free_inode(c, ic) * is called to release xattr related objects when unmounting. * check_xattr_ref_inode(c, ic) * is used to confirm inode does not have duplicate xattr name/value pair. * jffs2_xattr_do_crccheck_inode(c, ic) * is used to force xattr data integrity check during the initial gc scan. * -------------------------------------------------- */ static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) { … } static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) { … } static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, struct jffs2_xattr_datum *xd) { … } static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) { … } void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) { … } void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) { … } static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) { … } void jffs2_xattr_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) { … } /* -------- xattr subsystem functions --------------- * jffs2_init_xattr_subsystem(c) * is used to initialize semaphore and list_head, and some variables. * jffs2_find_xattr_datum(c, xid) * is used to lookup xdatum while scanning process. * jffs2_clear_xattr_subsystem(c) * is used to release any xattr related objects. * jffs2_build_xattr_subsystem(c) * is used to associate xdatum and xref while super block building process. * jffs2_setup_xattr_datum(c, xid, version) * is used to insert xdatum while scanning process. * -------------------------------------------------- */ void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c) { … } static struct jffs2_xattr_datum *jffs2_find_xattr_datum(struct jffs2_sb_info *c, uint32_t xid) { … } void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c) { … } #define XREF_TMPHASH_SIZE … int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) { … } struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, uint32_t xid, uint32_t version) { … } /* -------- xattr subsystem functions --------------- * xprefix_to_handler(xprefix) * is used to translate xprefix into xattr_handler. * jffs2_listxattr(dentry, buffer, size) * is an implementation of listxattr handler on jffs2. * do_jffs2_getxattr(inode, xprefix, xname, buffer, size) * is an implementation of getxattr handler on jffs2. * do_jffs2_setxattr(inode, xprefix, xname, buffer, size, flags) * is an implementation of setxattr handler on jffs2. * -------------------------------------------------- */ const struct xattr_handler * const jffs2_xattr_handlers[] = …; static const char *jffs2_xattr_prefix(int xprefix, struct dentry *dentry) { … } ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) { … } int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname, char *buffer, size_t size) { … } int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, const char *buffer, size_t size, int flags) { … } /* -------- garbage collector functions ------------- * jffs2_garbage_collect_xattr_datum(c, xd, raw) * is used to move xdatum into new node. * jffs2_garbage_collect_xattr_ref(c, ref, raw) * is used to move xref into new node. * jffs2_verify_xattr(c) * is used to call do_verify_xattr_datum() before garbage collecting. * jffs2_release_xattr_datum(c, xd) * is used to release an in-memory object of xdatum. * jffs2_release_xattr_ref(c, ref) * is used to release an in-memory object of xref. * -------------------------------------------------- */ int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd, struct jffs2_raw_node_ref *raw) { … } int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref, struct jffs2_raw_node_ref *raw) { … } int jffs2_verify_xattr(struct jffs2_sb_info *c) { … } void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) { … } void jffs2_release_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) { … }