// SPDX-License-Identifier: GPL-2.0-only /* * This file is part of UBIFS. * * Copyright (C) 2006-2008 Nokia Corporation. * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter */ /* * This file implements UBIFS extended attributes support. * * Extended attributes are implemented as regular inodes with attached data, * which limits extended attribute size to UBIFS block size (4KiB). Names of * extended attributes are described by extended attribute entries (xentries), * which are almost identical to directory entries, but have different key type. * * In other words, the situation with extended attributes is very similar to * directories. Indeed, any inode (but of course not xattr inodes) may have a * number of associated xentries, just like directory inodes have associated * directory entries. Extended attribute entries store the name of the extended * attribute, the host inode number, and the extended attribute inode number. * Similarly, direntries store the name, the parent and the target inode * numbers. Thus, most of the common UBIFS mechanisms may be re-used for * extended attributes. * * The number of extended attributes is not limited, but there is Linux * limitation on the maximum possible size of the list of all extended * attributes associated with an inode (%XATTR_LIST_MAX), so UBIFS makes sure * the sum of all extended attribute names of the inode does not exceed that * limit. * * Extended attributes are synchronous, which means they are written to the * flash media synchronously and there is no write-back for extended attribute * inodes. The extended attribute values are not stored in compressed form on * the media. * * Since extended attributes are represented by regular inodes, they are cached * in the VFS inode cache. The xentries are cached in the LNC cache (see * tnc.c). * * ACL support is not implemented. */ #include "ubifs.h" #include <linux/fs.h> #include <linux/slab.h> #include <linux/xattr.h> /* * Extended attribute type constants. * * USER_XATTR: user extended attribute ("user.*") * TRUSTED_XATTR: trusted extended attribute ("trusted.*) * SECURITY_XATTR: security extended attribute ("security.*") */ enum { … }; static const struct inode_operations empty_iops; static const struct file_operations empty_fops; /** * create_xattr - create an extended attribute. * @c: UBIFS file-system description object * @host: host inode * @nm: extended attribute name * @value: extended attribute value * @size: size of extended attribute value * * This is a helper function which creates an extended attribute of name @nm * and value @value for inode @host. The host inode is also updated on flash * because the ctime and extended attribute accounting data changes. This * function returns zero in case of success and a negative error code in case * of failure. */ static int create_xattr(struct ubifs_info *c, struct inode *host, const struct fscrypt_name *nm, const void *value, int size) { … } /** * change_xattr - change an extended attribute. * @c: UBIFS file-system description object * @host: host inode * @inode: extended attribute inode * @value: extended attribute value * @size: size of extended attribute value * * This helper function changes the value of extended attribute @inode with new * data from @value. Returns zero in case of success and a negative error code * in case of failure. */ static int change_xattr(struct ubifs_info *c, struct inode *host, struct inode *inode, const void *value, int size) { … } static struct inode *iget_xattr(struct ubifs_info *c, ino_t inum) { … } int ubifs_xattr_set(struct inode *host, const char *name, const void *value, size_t size, int flags, bool check_lock) { … } ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf, size_t size) { … } static bool xattr_visible(const char *name) { … } ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size) { … } static int remove_xattr(struct ubifs_info *c, struct inode *host, struct inode *inode, const struct fscrypt_name *nm) { … } int ubifs_purge_xattrs(struct inode *host) { … } /** * ubifs_evict_xattr_inode - Evict an xattr inode. * @c: UBIFS file-system description object * @xattr_inum: xattr inode number * * When an inode that hosts xattrs is being removed we have to make sure * that cached inodes of the xattrs also get removed from the inode cache * otherwise we'd waste memory. This function looks up an inode from the * inode cache and clears the link counter such that iput() will evict * the inode. */ void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum) { … } static int ubifs_xattr_remove(struct inode *host, const char *name) { … } #ifdef CONFIG_UBIFS_FS_SECURITY static int init_xattrs(struct inode *inode, const struct xattr *xattr_array, void *fs_info) { … } int ubifs_init_security(struct inode *dentry, struct inode *inode, const struct qstr *qstr) { … } #endif static int xattr_get(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, void *buffer, size_t size) { … } static int xattr_set(const struct xattr_handler *handler, struct mnt_idmap *idmap, struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) { … } static const struct xattr_handler ubifs_user_xattr_handler = …; static const struct xattr_handler ubifs_trusted_xattr_handler = …; #ifdef CONFIG_UBIFS_FS_SECURITY static const struct xattr_handler ubifs_security_xattr_handler = …; #endif const struct xattr_handler * const ubifs_xattr_handlers[] = …;