^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) International Business Machines Corp., 2000-2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) Christoph Hellwig, 2002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/posix_acl_xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/quotaops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "jfs_incore.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "jfs_superblock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "jfs_dmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "jfs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "jfs_dinode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "jfs_extent.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "jfs_metapage.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "jfs_xattr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "jfs_acl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * jfs_xattr.c: extended attribute service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Overall design --
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Extended attribute lists (jfs_ea_list) consist of an overall size (32 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * value) and a variable (0 or more) number of extended attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * entries. Each extended attribute entry (jfs_ea) is a <name,value> double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * where <name> is constructed from a null-terminated ascii string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * (1 ... 255 bytes in the name) and <value> is arbitrary 8 bit data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * (1 ... 65535 bytes). The in-memory format is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * 0 1 2 4 4 + namelen + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * +-------+--------+--------+----------------+-------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * | Flags | Name | Value | Name String \0 | Data . . . . |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * | | Length | Length | | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * +-------+--------+--------+----------------+-------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * A jfs_ea_list then is structured as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * 0 4 4 + EA_SIZE(ea1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * +------------+-------------------+--------------------+-----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * | Overall EA | First FEA Element | Second FEA Element | .....
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * | List Size | | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * +------------+-------------------+--------------------+-----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * On-disk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * FEALISTs are stored on disk using blocks allocated by dbAlloc() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * written directly. An EA list may be in-lined in the inode if there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * sufficient room available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct ea_buffer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int flag; /* Indicates what storage xattr points to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int max_size; /* largest xattr that fits in current buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) dxd_t new_ea; /* dxd to replace ea when modifying xattr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct metapage *mp; /* metapage containing ea list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct jfs_ea_list *xattr; /* buffer containing ea list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * ea_buffer.flag values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define EA_INLINE 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define EA_EXTENT 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define EA_NEW 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define EA_MALLOC 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Mapping of on-disk attribute names: for on-disk attribute names with an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * unknown prefix (not "system.", "user.", "security.", or "trusted."), the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * prefix "os2." is prepended. On the way back to disk, "os2." prefixes are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * stripped and we make sure that the remaining name does not start with one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * of the know prefixes.
^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 is_known_namespace(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static inline int name_size(struct jfs_ea *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (is_known_namespace(ea->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return ea->namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return ea->namelen + XATTR_OS2_PREFIX_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static inline int copy_name(char *buffer, struct jfs_ea *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int len = ea->namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (!is_known_namespace(ea->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) memcpy(buffer, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) buffer += XATTR_OS2_PREFIX_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) len += XATTR_OS2_PREFIX_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) memcpy(buffer, ea->name, ea->namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) buffer[ea->namelen] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* Forward references */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static void ea_release(struct inode *inode, struct ea_buffer *ea_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * NAME: ea_write_inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * FUNCTION: Attempt to write an EA inline if area is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * PRE CONDITIONS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * Already verified that the specified EA is small enough to fit inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * ip - Inode pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * ealist - EA list pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * size - size of ealist in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * ea - dxd_t structure to be filled in with necessary EA information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * if we successfully copy the EA inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * NOTES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * Checks if the inode's inline area is available. If so, copies EA inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * and sets <ea> fields appropriately. Otherwise, returns failure, EA will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * have to be put into an extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * RETURNS: 0 for successful copy to inline area; -1 if area not available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static int ea_write_inline(struct inode *ip, struct jfs_ea_list *ealist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int size, dxd_t * ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct jfs_inode_info *ji = JFS_IP(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Make sure we have an EA -- the NULL EA list is valid, but you
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * can't copy it!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (ealist && size > sizeof (struct jfs_ea_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) assert(size <= sizeof (ji->i_inline_ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * See if the space is available or if it is already being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * used for an inline EA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (!(ji->mode2 & INLINEEA) && !(ji->ea.flag & DXD_INLINE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) DXDsize(ea, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) DXDlength(ea, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) DXDaddress(ea, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) memcpy(ji->i_inline_ea, ealist, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ea->flag = DXD_INLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ji->mode2 &= ~INLINEEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ea->flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) DXDsize(ea, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) DXDlength(ea, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) DXDaddress(ea, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* Free up INLINE area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (ji->ea.flag & DXD_INLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ji->mode2 |= INLINEEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * NAME: ea_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * FUNCTION: Write an EA for an inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * PRE CONDITIONS: EA has been verified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * ip - Inode pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * ealist - EA list pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * size - size of ealist in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * ea - dxd_t structure to be filled in appropriately with where the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * EA was copied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * NOTES: Will write EA inline if able to, otherwise allocates blocks for an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * extent and synchronously writes it to those blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * RETURNS: 0 for success; Anything else indicates failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) dxd_t * ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct super_block *sb = ip->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct jfs_inode_info *ji = JFS_IP(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct jfs_sb_info *sbi = JFS_SBI(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int nblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) s64 blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int rc = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) char *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) s32 nbytes, nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) s32 bytes_to_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * Quick check to see if this is an in-linable EA. Short EAs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * and empty EAs are all in-linable, provided the space exists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!ealist || size <= sizeof (ji->i_inline_ea)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (!ea_write_inline(ip, ealist, size, ea))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* figure out how many blocks we need */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) nblocks = (size + (sb->s_blocksize - 1)) >> sb->s_blocksize_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* Allocate new blocks to quota. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) rc = dquot_alloc_block(ip, nblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /*Rollback quota allocation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) dquot_free_block(ip, nblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * Now have nblocks worth of storage to stuff into the FEALIST.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * loop over the FEALIST copying data into the buffer one page at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * a time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) cp = (char *) ealist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) nbytes = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) for (i = 0; i < nblocks; i += sbi->nbperpage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * Determine how many bytes for this request, and round up to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * the nearest aggregate block size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) nb = min(PSIZE, nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) bytes_to_write =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ((((nb + sb->s_blocksize - 1)) >> sb->s_blocksize_bits))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) << sb->s_blocksize_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (!(mp = get_metapage(ip, blkno + i, bytes_to_write, 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) memcpy(mp->data, cp, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * We really need a way to propagate errors for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * forced writes like this one. --hch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * (__write_metapage => release_metapage => flush_metapage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #ifdef _JFS_FIXME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if ((rc = flush_metapage(mp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * the write failed -- this means that the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * is still assigned and the blocks are not being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * used. this seems like the best error recovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * we can get ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) flush_metapage(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) cp += PSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) nbytes -= nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ea->flag = DXD_EXTENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) DXDsize(ea, le32_to_cpu(ealist->size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) DXDlength(ea, nblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) DXDaddress(ea, blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* Free up INLINE area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (ji->ea.flag & DXD_INLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ji->mode2 |= INLINEEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* Rollback quota allocation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) dquot_free_block(ip, nblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) dbFree(ip, blkno, nblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * NAME: ea_read_inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * FUNCTION: Read an inlined EA into user's buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * ip - Inode pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * ealist - Pointer to buffer to fill in with EA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * RETURNS: 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static int ea_read_inline(struct inode *ip, struct jfs_ea_list *ealist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct jfs_inode_info *ji = JFS_IP(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int ea_size = sizeDXD(&ji->ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (ea_size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ealist->size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* Sanity Check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if ((sizeDXD(&ji->ea) > sizeof (ji->i_inline_ea)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (le32_to_cpu(((struct jfs_ea_list *) &ji->i_inline_ea)->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) != ea_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) memcpy(ealist, ji->i_inline_ea, ea_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * NAME: ea_read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * FUNCTION: copy EA data into user's buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * ip - Inode pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * ealist - Pointer to buffer to fill in with EA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * NOTES: If EA is inline calls ea_read_inline() to copy EA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * RETURNS: 0 for success; other indicates failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static int ea_read(struct inode *ip, struct jfs_ea_list *ealist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct super_block *sb = ip->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct jfs_inode_info *ji = JFS_IP(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct jfs_sb_info *sbi = JFS_SBI(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int nblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) s64 blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) char *cp = (char *) ealist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int nbytes, nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) s32 bytes_to_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /* quick check for in-line EA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (ji->ea.flag & DXD_INLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return ea_read_inline(ip, ealist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) nbytes = sizeDXD(&ji->ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (!nbytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) jfs_error(sb, "nbytes is 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * Figure out how many blocks were allocated when this EA list was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * originally written to disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) nblocks = lengthDXD(&ji->ea) << sbi->l2nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) blkno = addressDXD(&ji->ea) << sbi->l2nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * I have found the disk blocks which were originally used to store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * the FEALIST. now i loop over each contiguous block copying the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * data into the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) for (i = 0; i < nblocks; i += sbi->nbperpage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * Determine how many bytes for this request, and round up to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * the nearest aggregate block size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) nb = min(PSIZE, nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) bytes_to_read =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ((((nb + sb->s_blocksize - 1)) >> sb->s_blocksize_bits))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) << sb->s_blocksize_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (!(mp = read_metapage(ip, blkno + i, bytes_to_read, 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) memcpy(cp, mp->data, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) release_metapage(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) cp += PSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) nbytes -= nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * NAME: ea_get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * FUNCTION: Returns buffer containing existing extended attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * The size of the buffer will be the larger of the existing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * attributes size, or min_size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * The buffer, which may be inlined in the inode or in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * page cache must be release by calling ea_release or ea_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * inode - Inode pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * ea_buf - Structure to be populated with ealist and its metadata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * min_size- minimum size of buffer to be returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * RETURNS: 0 for success; Other indicates failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct jfs_inode_info *ji = JFS_IP(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct super_block *sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int ea_size = sizeDXD(&ji->ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int blocks_needed, current_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) s64 blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) int quota_allocation = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* When fsck.jfs clears a bad ea, it doesn't clear the size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (ji->ea.flag == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) ea_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (ea_size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (min_size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ea_buf->flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ea_buf->max_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) ea_buf->xattr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if ((min_size <= sizeof (ji->i_inline_ea)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) (ji->mode2 & INLINEEA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ea_buf->flag = EA_INLINE | EA_NEW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) ea_buf->max_size = sizeof (ji->i_inline_ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) ea_buf->xattr = (struct jfs_ea_list *) ji->i_inline_ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) DXDlength(&ea_buf->new_ea, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) DXDaddress(&ea_buf->new_ea, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ea_buf->new_ea.flag = DXD_INLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) DXDsize(&ea_buf->new_ea, min_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) current_blocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) } else if (ji->ea.flag & DXD_INLINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (min_size <= sizeof (ji->i_inline_ea)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ea_buf->flag = EA_INLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ea_buf->max_size = sizeof (ji->i_inline_ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ea_buf->xattr = (struct jfs_ea_list *) ji->i_inline_ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) goto size_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) current_blocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (!(ji->ea.flag & DXD_EXTENT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) jfs_error(sb, "invalid ea.flag\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) current_blocks = (ea_size + sb->s_blocksize - 1) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) sb->s_blocksize_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) size = max(min_size, ea_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (size > PSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * To keep the rest of the code simple. Allocate a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * contiguous buffer to work with. Make the buffer large
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * enough to make use of the whole extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) ea_buf->max_size = (size + sb->s_blocksize - 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ~(sb->s_blocksize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ea_buf->xattr = kmalloc(ea_buf->max_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (ea_buf->xattr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ea_buf->flag = EA_MALLOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (ea_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if ((rc = ea_read(inode, ea_buf->xattr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) kfree(ea_buf->xattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ea_buf->xattr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) goto size_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) blocks_needed = (min_size + sb->s_blocksize - 1) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) sb->s_blocksize_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (blocks_needed > current_blocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* Allocate new blocks to quota. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) rc = dquot_alloc_block(inode, blocks_needed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return -EDQUOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) quota_allocation = blocks_needed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) rc = dbAlloc(inode, INOHINT(inode), (s64) blocks_needed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) &blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) DXDlength(&ea_buf->new_ea, blocks_needed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) DXDaddress(&ea_buf->new_ea, blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ea_buf->new_ea.flag = DXD_EXTENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) DXDsize(&ea_buf->new_ea, min_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) ea_buf->flag = EA_EXTENT | EA_NEW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ea_buf->mp = get_metapage(inode, blkno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) blocks_needed << sb->s_blocksize_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (ea_buf->mp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) dbFree(inode, blkno, (s64) blocks_needed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ea_buf->xattr = ea_buf->mp->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ea_buf->max_size = (min_size + sb->s_blocksize - 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) ~(sb->s_blocksize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (ea_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if ((rc = ea_read(inode, ea_buf->xattr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) discard_metapage(ea_buf->mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) dbFree(inode, blkno, (s64) blocks_needed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) goto size_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ea_buf->flag = EA_EXTENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ea_buf->mp = read_metapage(inode, addressDXD(&ji->ea),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) lengthDXD(&ji->ea) << sb->s_blocksize_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (ea_buf->mp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ea_buf->xattr = ea_buf->mp->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) ea_buf->max_size = (ea_size + sb->s_blocksize - 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ~(sb->s_blocksize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) size_check:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (EALIST_SIZE(ea_buf->xattr) != ea_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) printk(KERN_ERR "ea_get: invalid extended attribute\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) ea_buf->xattr, ea_size, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) ea_release(inode, ea_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return ea_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) clean_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /* Rollback quota allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (quota_allocation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) dquot_free_block(inode, quota_allocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static void ea_release(struct inode *inode, struct ea_buffer *ea_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (ea_buf->flag & EA_MALLOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) kfree(ea_buf->xattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) else if (ea_buf->flag & EA_EXTENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) assert(ea_buf->mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) release_metapage(ea_buf->mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (ea_buf->flag & EA_NEW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) dbFree(inode, addressDXD(&ea_buf->new_ea),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) lengthDXD(&ea_buf->new_ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) int new_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct jfs_inode_info *ji = JFS_IP(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) unsigned long old_blocks, new_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (new_size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ea_release(inode, ea_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) ea_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) } else if (ea_buf->flag & EA_INLINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) assert(new_size <= sizeof (ji->i_inline_ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ji->mode2 &= ~INLINEEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) ea_buf->new_ea.flag = DXD_INLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) DXDsize(&ea_buf->new_ea, new_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) DXDaddress(&ea_buf->new_ea, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) DXDlength(&ea_buf->new_ea, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) } else if (ea_buf->flag & EA_MALLOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) rc = ea_write(inode, ea_buf->xattr, new_size, &ea_buf->new_ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) kfree(ea_buf->xattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) } else if (ea_buf->flag & EA_NEW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* We have already allocated a new dxd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) flush_metapage(ea_buf->mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* ->xattr must point to original ea's metapage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) rc = ea_write(inode, ea_buf->xattr, new_size, &ea_buf->new_ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) discard_metapage(ea_buf->mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) old_blocks = new_blocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (ji->ea.flag & DXD_EXTENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) invalidate_dxd_metapages(inode, ji->ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) old_blocks = lengthDXD(&ji->ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (ea_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) txEA(tid, inode, &ji->ea, &ea_buf->new_ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (ea_buf->new_ea.flag & DXD_EXTENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) new_blocks = lengthDXD(&ea_buf->new_ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (ji->ea.flag & DXD_INLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ji->mode2 |= INLINEEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) ji->ea = ea_buf->new_ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) txEA(tid, inode, &ji->ea, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (ji->ea.flag & DXD_INLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) ji->mode2 |= INLINEEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ji->ea.flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) ji->ea.size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /* If old blocks exist, they must be removed from quota allocation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (old_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) dquot_free_block(inode, old_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) inode->i_ctime = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) const void *value, size_t value_len, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct jfs_ea_list *ealist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct jfs_ea *ea, *old_ea = NULL, *next_ea = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct ea_buffer ea_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) int old_ea_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) int xattr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) int new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) int namelen = strlen(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) down_write(&JFS_IP(inode)->xattr_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) xattr_size = ea_get(inode, &ea_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (xattr_size < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) rc = xattr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) ealist = (struct jfs_ea_list *) ea_buf.xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) new_size = sizeof (struct jfs_ea_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (xattr_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ea = NEXT_EA(ea)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if ((namelen == ea->namelen) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) (memcmp(name, ea->name, namelen) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (flags & XATTR_CREATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) rc = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) old_ea = ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) old_ea_size = EA_SIZE(ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) next_ea = NEXT_EA(ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) new_size += EA_SIZE(ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (flags & XATTR_REPLACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) rc = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (value == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) new_size += sizeof (struct jfs_ea) + namelen + 1 + value_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (new_size > ea_buf.max_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * We need to allocate more space for merged ea list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) * We should only have loop to again: once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) ea_release(inode, &ea_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) xattr_size = ea_get(inode, &ea_buf, new_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (xattr_size < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) rc = xattr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* Remove old ea of the same name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /* number of bytes following target EA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) length = (char *) END_EALIST(ealist) - (char *) next_ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (length > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) memmove(old_ea, next_ea, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) xattr_size -= old_ea_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /* Add new entry to the end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (xattr_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) /* Completely new ea list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) xattr_size = sizeof (struct jfs_ea_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * The size of EA value is limitted by on-disk format up to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * __le16, there would be an overflow if the size is equal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * to XATTR_SIZE_MAX (65536). In order to avoid this issue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * we can pre-checkup the value size against USHRT_MAX, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * return -E2BIG in this case, which is consistent with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * VFS setxattr interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (value_len >= USHRT_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) rc = -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) ea = (struct jfs_ea *) ((char *) ealist + xattr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) ea->flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ea->namelen = namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ea->valuelen = (cpu_to_le16(value_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) memcpy(ea->name, name, namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) ea->name[namelen] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (value_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) memcpy(&ea->name[namelen + 1], value, value_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) xattr_size += EA_SIZE(ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) /* DEBUG - If we did this right, these number match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (xattr_size != new_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) "__jfs_setxattr: xattr_size = %d, new_size = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) xattr_size, new_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * If we're left with an empty list, there's no ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (new_size == sizeof (struct jfs_ea_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) new_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) ealist->size = cpu_to_le32(new_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) rc = ea_put(tid, inode, &ea_buf, new_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) ea_release(inode, &ea_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) up_write(&JFS_IP(inode)->xattr_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) size_t buf_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) struct jfs_ea_list *ealist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) struct jfs_ea *ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct ea_buffer ea_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) int xattr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) ssize_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) int namelen = strlen(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) char *value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) down_read(&JFS_IP(inode)->xattr_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) xattr_size = ea_get(inode, &ea_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (xattr_size < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) size = xattr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (xattr_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) ealist = (struct jfs_ea_list *) ea_buf.xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) /* Find the named attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if ((namelen == ea->namelen) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) memcmp(name, ea->name, namelen) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /* Found it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) size = le16_to_cpu(ea->valuelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) else if (size > buf_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) size = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) value = ((char *) &ea->name) + ea->namelen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) memcpy(data, value, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) not_found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) size = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) ea_release(inode, &ea_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) up_read(&JFS_IP(inode)->xattr_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * No special permissions are needed to list attributes except for trusted.*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static inline int can_list(struct jfs_ea *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return (strncmp(ea->name, XATTR_TRUSTED_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) XATTR_TRUSTED_PREFIX_LEN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) capable(CAP_SYS_ADMIN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) char *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) ssize_t size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) int xattr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct jfs_ea_list *ealist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct jfs_ea *ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct ea_buffer ea_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) down_read(&JFS_IP(inode)->xattr_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) xattr_size = ea_get(inode, &ea_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (xattr_size < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) size = xattr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (xattr_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) ealist = (struct jfs_ea_list *) ea_buf.xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) /* compute required size of list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (can_list(ea))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) size += name_size(ea) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (size > buf_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) size = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) /* Copy attribute names to buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) buffer = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (can_list(ea)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) int namelen = copy_name(buffer, ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) buffer += namelen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) ea_release(inode, &ea_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) up_read(&JFS_IP(inode)->xattr_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) static int __jfs_xattr_set(struct inode *inode, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) const void *value, size_t size, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) struct jfs_inode_info *ji = JFS_IP(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) tid_t tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) tid = txBegin(inode->i_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) mutex_lock(&ji->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) rc = __jfs_setxattr(tid, inode, name, value, size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) rc = txCommit(tid, 1, &inode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) mutex_unlock(&ji->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) static int jfs_xattr_get(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) struct dentry *unused, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) const char *name, void *value, size_t size, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) name = xattr_full_name(handler, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) return __jfs_getxattr(inode, name, value, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static int jfs_xattr_set(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) struct dentry *unused, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) const char *name, const void *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) size_t size, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) name = xattr_full_name(handler, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) return __jfs_xattr_set(inode, name, value, size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) static int jfs_xattr_get_os2(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) struct dentry *unused, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) const char *name, void *value, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (is_known_namespace(name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) return __jfs_getxattr(inode, name, value, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) static int jfs_xattr_set_os2(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct dentry *unused, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) const char *name, const void *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) size_t size, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (is_known_namespace(name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return __jfs_xattr_set(inode, name, value, size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static const struct xattr_handler jfs_user_xattr_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .prefix = XATTR_USER_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) .get = jfs_xattr_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) .set = jfs_xattr_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) static const struct xattr_handler jfs_os2_xattr_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .prefix = XATTR_OS2_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .get = jfs_xattr_get_os2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) .set = jfs_xattr_set_os2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) static const struct xattr_handler jfs_security_xattr_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) .prefix = XATTR_SECURITY_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) .get = jfs_xattr_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) .set = jfs_xattr_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) static const struct xattr_handler jfs_trusted_xattr_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .prefix = XATTR_TRUSTED_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .get = jfs_xattr_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) .set = jfs_xattr_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) const struct xattr_handler *jfs_xattr_handlers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) #ifdef CONFIG_JFS_POSIX_ACL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) &posix_acl_access_xattr_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) &posix_acl_default_xattr_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) &jfs_os2_xattr_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) &jfs_user_xattr_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) &jfs_security_xattr_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) &jfs_trusted_xattr_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) #ifdef CONFIG_JFS_SECURITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) static int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) void *fs_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) const struct xattr *xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) tid_t *tid = fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) for (xattr = xattr_array; xattr->name != NULL; xattr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) strlen(xattr->name) + 1, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (!name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) strcpy(name, XATTR_SECURITY_PREFIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) err = __jfs_setxattr(*tid, inode, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) xattr->value, xattr->value_len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) kfree(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) const struct qstr *qstr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return security_inode_init_security(inode, dir, qstr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) &jfs_initxattrs, &tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) #endif