// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) International Business Machines Corp., 2000-2004 * Copyright (C) Christoph Hellwig, 2002 */ #include <linux/capability.h> #include <linux/fs.h> #include <linux/xattr.h> #include <linux/posix_acl_xattr.h> #include <linux/slab.h> #include <linux/quotaops.h> #include <linux/security.h> #include "jfs_incore.h" #include "jfs_superblock.h" #include "jfs_dmap.h" #include "jfs_debug.h" #include "jfs_dinode.h" #include "jfs_extent.h" #include "jfs_metapage.h" #include "jfs_xattr.h" #include "jfs_acl.h" /* * jfs_xattr.c: extended attribute service * * Overall design -- * * Format: * * Extended attribute lists (jfs_ea_list) consist of an overall size (32 bit * value) and a variable (0 or more) number of extended attribute * entries. Each extended attribute entry (jfs_ea) is a <name,value> double * where <name> is constructed from a null-terminated ascii string * (1 ... 255 bytes in the name) and <value> is arbitrary 8 bit data * (1 ... 65535 bytes). The in-memory format is * * 0 1 2 4 4 + namelen + 1 * +-------+--------+--------+----------------+-------------------+ * | Flags | Name | Value | Name String \0 | Data . . . . | * | | Length | Length | | | * +-------+--------+--------+----------------+-------------------+ * * A jfs_ea_list then is structured as * * 0 4 4 + EA_SIZE(ea1) * +------------+-------------------+--------------------+----- * | Overall EA | First FEA Element | Second FEA Element | ..... * | List Size | | | * +------------+-------------------+--------------------+----- * * On-disk: * * FEALISTs are stored on disk using blocks allocated by dbAlloc() and * written directly. An EA list may be in-lined in the inode if there is * sufficient room available. */ struct ea_buffer { … }; /* * ea_buffer.flag values */ #define EA_INLINE … #define EA_EXTENT … #define EA_NEW … #define EA_MALLOC … /* * Mapping of on-disk attribute names: for on-disk attribute names with an * unknown prefix (not "system.", "user.", "security.", or "trusted."), the * prefix "os2." is prepended. On the way back to disk, "os2." prefixes are * stripped and we make sure that the remaining name does not start with one * of the know prefixes. */ static int is_known_namespace(const char *name) { … } static inline int name_size(struct jfs_ea *ea) { … } static inline int copy_name(char *buffer, struct jfs_ea *ea) { … } /* Forward references */ static void ea_release(struct inode *inode, struct ea_buffer *ea_buf); /* * NAME: ea_write_inline * * FUNCTION: Attempt to write an EA inline if area is available * * PRE CONDITIONS: * Already verified that the specified EA is small enough to fit inline * * PARAMETERS: * ip - Inode pointer * ealist - EA list pointer * size - size of ealist in bytes * ea - dxd_t structure to be filled in with necessary EA information * if we successfully copy the EA inline * * NOTES: * Checks if the inode's inline area is available. If so, copies EA inline * and sets <ea> fields appropriately. Otherwise, returns failure, EA will * have to be put into an extent. * * RETURNS: 0 for successful copy to inline area; -1 if area not available */ static int ea_write_inline(struct inode *ip, struct jfs_ea_list *ealist, int size, dxd_t * ea) { … } /* * NAME: ea_write * * FUNCTION: Write an EA for an inode * * PRE CONDITIONS: EA has been verified * * PARAMETERS: * ip - Inode pointer * ealist - EA list pointer * size - size of ealist in bytes * ea - dxd_t structure to be filled in appropriately with where the * EA was copied * * NOTES: Will write EA inline if able to, otherwise allocates blocks for an * extent and synchronously writes it to those blocks. * * RETURNS: 0 for success; Anything else indicates failure */ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size, dxd_t * ea) { … } /* * NAME: ea_read_inline * * FUNCTION: Read an inlined EA into user's buffer * * PARAMETERS: * ip - Inode pointer * ealist - Pointer to buffer to fill in with EA * * RETURNS: 0 */ static int ea_read_inline(struct inode *ip, struct jfs_ea_list *ealist) { … } /* * NAME: ea_read * * FUNCTION: copy EA data into user's buffer * * PARAMETERS: * ip - Inode pointer * ealist - Pointer to buffer to fill in with EA * * NOTES: If EA is inline calls ea_read_inline() to copy EA. * * RETURNS: 0 for success; other indicates failure */ static int ea_read(struct inode *ip, struct jfs_ea_list *ealist) { … } /* * NAME: ea_get * * FUNCTION: Returns buffer containing existing extended attributes. * The size of the buffer will be the larger of the existing * attributes size, or min_size. * * The buffer, which may be inlined in the inode or in the * page cache must be release by calling ea_release or ea_put * * PARAMETERS: * inode - Inode pointer * ea_buf - Structure to be populated with ealist and its metadata * min_size- minimum size of buffer to be returned * * RETURNS: 0 for success; Other indicates failure */ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) { … } static void ea_release(struct inode *inode, struct ea_buffer *ea_buf) { … } static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf, int new_size) { … } int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, const void *value, size_t value_len, int flags) { … } ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, size_t buf_size) { … } /* * No special permissions are needed to list attributes except for trusted.* */ static inline int can_list(struct jfs_ea *ea) { … } ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size) { … } static int __jfs_xattr_set(struct inode *inode, const char *name, const void *value, size_t size, int flags) { … } static int jfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *name, void *value, size_t size) { … } static int jfs_xattr_set(const struct xattr_handler *handler, struct mnt_idmap *idmap, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) { … } static int jfs_xattr_get_os2(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *name, void *value, size_t size) { … } static int jfs_xattr_set_os2(const struct xattr_handler *handler, struct mnt_idmap *idmap, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) { … } static const struct xattr_handler jfs_user_xattr_handler = …; static const struct xattr_handler jfs_os2_xattr_handler = …; static const struct xattr_handler jfs_security_xattr_handler = …; static const struct xattr_handler jfs_trusted_xattr_handler = …; const struct xattr_handler * const jfs_xattr_handlers[] = …; #ifdef CONFIG_JFS_SECURITY static int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array, void *fs_info) { … } int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir, const struct qstr *qstr) { … } #endif