b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100 1) // SPDX-License-Identifier: GPL-2.0
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2) /*
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 3) * linux/fs/ext4/xattr.c
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 4) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 5) * Copyright (C) 2001-2003 Andreas Gruenbacher, <agruen@suse.de>
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 6) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 7) * Fix by Harrison Xing <harrison@mountainviewdata.com>.
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 8) * Ext4 code with a lot of help from Eric Jarman <ejarman@acm.org>.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 9) * Extended attributes for symlinks and special files added per
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 10) * suggestion of Luka Renko <luka.renko@hermes.si>.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 11) * xattr consolidation Copyright (c) 2004 James Morris <jmorris@redhat.com>,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 12) * Red Hat Inc.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 13) * ea-in-inode support by Alex Tomas <alex@clusterfs.com> aka bzzz
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 14) * and Andreas Gruenbacher <agruen@suse.de>.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 15) */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 16)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 17) /*
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 18) * Extended attributes are stored directly in inodes (on file systems with
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 19) * inodes bigger than 128 bytes) and on additional disk blocks. The i_file_acl
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 20) * field contains the block number if an inode uses an additional block. All
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 21) * attributes must fit in the inode and one additional block. Blocks that
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 22) * contain the identical set of attributes may be shared among several inodes.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 23) * Identical blocks are detected by keeping a cache of blocks that have
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 24) * recently been accessed.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 25) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 26) * The attributes in inodes and on blocks have a different header; the entries
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 27) * are stored in the same format:
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 28) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 29) * +------------------+
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 30) * | header |
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 31) * | entry 1 | |
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 32) * | entry 2 | | growing downwards
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 33) * | entry 3 | v
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 34) * | four null bytes |
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 35) * | . . . |
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 36) * | value 1 | ^
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 37) * | value 3 | | growing upwards
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 38) * | value 2 | |
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 39) * +------------------+
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 40) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 41) * The header is followed by multiple entry descriptors. In disk blocks, the
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 42) * entry descriptors are kept sorted. In inodes, they are unsorted. The
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 43) * attribute values are aligned to the end of the block in no specific order.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 44) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 45) * Locking strategy
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 46) * ----------------
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 47) * EXT4_I(inode)->i_file_acl is protected by EXT4_I(inode)->xattr_sem.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 48) * EA blocks are only changed if they are exclusive to an inode, so
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 49) * holding xattr_sem also means that nothing but the EA block's reference
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 50) * count can change. Multiple writers to the same block are synchronized
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 51) * by the buffer lock.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 52) */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 53)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 54) #include <linux/init.h>
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 55) #include <linux/fs.h>
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 56) #include <linux/slab.h>
7a2508e1b657c (Jan Kara 2016-02-22 22:35:22 -0500 57) #include <linux/mbcache.h>
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 58) #include <linux/quotaops.h>
ee73f9a52a343 (Jeff Layton 2018-01-09 08:21:39 -0500 59) #include <linux/iversion.h>
3dcf54515aa49 (Christoph Hellwig 2008-04-29 18:13:32 -0400 60) #include "ext4_jbd2.h"
3dcf54515aa49 (Christoph Hellwig 2008-04-29 18:13:32 -0400 61) #include "ext4.h"
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 62) #include "xattr.h"
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 63) #include "acl.h"
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 64)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 65) #ifdef EXT4_XATTR_DEBUG
d74f3d25289aa (Joe Perches 2016-10-15 09:57:31 -0400 66) # define ea_idebug(inode, fmt, ...) \
d74f3d25289aa (Joe Perches 2016-10-15 09:57:31 -0400 67) printk(KERN_DEBUG "inode %s:%lu: " fmt "\n", \
d74f3d25289aa (Joe Perches 2016-10-15 09:57:31 -0400 68) inode->i_sb->s_id, inode->i_ino, ##__VA_ARGS__)
d74f3d25289aa (Joe Perches 2016-10-15 09:57:31 -0400 69) # define ea_bdebug(bh, fmt, ...) \
d74f3d25289aa (Joe Perches 2016-10-15 09:57:31 -0400 70) printk(KERN_DEBUG "block %pg:%lu: " fmt "\n", \
d74f3d25289aa (Joe Perches 2016-10-15 09:57:31 -0400 71) bh->b_bdev, (unsigned long)bh->b_blocknr, ##__VA_ARGS__)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 72) #else
ace36ad431c68 (Joe Perches 2012-03-19 23:11:43 -0400 73) # define ea_idebug(inode, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
ace36ad431c68 (Joe Perches 2012-03-19 23:11:43 -0400 74) # define ea_bdebug(bh, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 75) #endif
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 76)
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 77) static void ext4_xattr_block_cache_insert(struct mb_cache *,
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 78) struct buffer_head *);
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 79) static struct buffer_head *
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 80) ext4_xattr_block_cache_find(struct inode *, struct ext4_xattr_header *,
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 81) struct mb_cache_entry **);
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 82) static __le32 ext4_xattr_hash_entry(char *name, size_t name_len, __le32 *value,
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 83) size_t value_count);
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 84) static void ext4_xattr_rehash(struct ext4_xattr_header *);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 85)
d60061867303a (Eric Biggers 2017-04-29 23:47:50 -0400 86) static const struct xattr_handler * const ext4_xattr_handler_map[] = {
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 87) [EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler,
03010a3350301 (Theodore Ts'o 2008-10-10 20:02:48 -0400 88) #ifdef CONFIG_EXT4_FS_POSIX_ACL
64e178a7118b1 (Christoph Hellwig 2013-12-20 05:16:44 -0800 89) [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
64e178a7118b1 (Christoph Hellwig 2013-12-20 05:16:44 -0800 90) [EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 91) #endif
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 92) [EXT4_XATTR_INDEX_TRUSTED] = &ext4_xattr_trusted_handler,
03010a3350301 (Theodore Ts'o 2008-10-10 20:02:48 -0400 93) #ifdef CONFIG_EXT4_FS_SECURITY
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 94) [EXT4_XATTR_INDEX_SECURITY] = &ext4_xattr_security_handler,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 95) #endif
88ee9d571b6d8 (Jan (janneke) Nieuwenhuizen 2020-05-25 21:39:40 +0200 96) [EXT4_XATTR_INDEX_HURD] = &ext4_xattr_hurd_handler,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 97) };
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 98)
11e27528076e7 (Stephen Hemminger 2010-05-13 17:53:18 -0700 99) const struct xattr_handler *ext4_xattr_handlers[] = {
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 100) &ext4_xattr_user_handler,
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 101) &ext4_xattr_trusted_handler,
03010a3350301 (Theodore Ts'o 2008-10-10 20:02:48 -0400 102) #ifdef CONFIG_EXT4_FS_POSIX_ACL
64e178a7118b1 (Christoph Hellwig 2013-12-20 05:16:44 -0800 103) &posix_acl_access_xattr_handler,
64e178a7118b1 (Christoph Hellwig 2013-12-20 05:16:44 -0800 104) &posix_acl_default_xattr_handler,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 105) #endif
03010a3350301 (Theodore Ts'o 2008-10-10 20:02:48 -0400 106) #ifdef CONFIG_EXT4_FS_SECURITY
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 107) &ext4_xattr_security_handler,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 108) #endif
88ee9d571b6d8 (Jan (janneke) Nieuwenhuizen 2020-05-25 21:39:40 +0200 109) &ext4_xattr_hurd_handler,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 110) NULL
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 111) };
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 112)
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 113) #define EA_BLOCK_CACHE(inode) (((struct ext4_sb_info *) \
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 114) inode->i_sb->s_fs_info)->s_ea_block_cache)
9c191f701ce9f (T Makphaibulchoke 2014-03-18 19:24:49 -0400 115)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 116) #define EA_INODE_CACHE(inode) (((struct ext4_sb_info *) \
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 117) inode->i_sb->s_fs_info)->s_ea_inode_cache)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 118)
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 119) static int
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 120) ext4_expand_inode_array(struct ext4_xattr_inode_array **ea_inode_array,
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 121) struct inode *inode);
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 122)
33d201e0277b2 (Tahsin Erdogan 2017-06-21 21:17:10 -0400 123) #ifdef CONFIG_LOCKDEP
33d201e0277b2 (Tahsin Erdogan 2017-06-21 21:17:10 -0400 124) void ext4_xattr_inode_set_class(struct inode *ea_inode)
33d201e0277b2 (Tahsin Erdogan 2017-06-21 21:17:10 -0400 125) {
33d201e0277b2 (Tahsin Erdogan 2017-06-21 21:17:10 -0400 126) lockdep_set_subclass(&ea_inode->i_rwsem, 1);
33d201e0277b2 (Tahsin Erdogan 2017-06-21 21:17:10 -0400 127) }
33d201e0277b2 (Tahsin Erdogan 2017-06-21 21:17:10 -0400 128) #endif
33d201e0277b2 (Tahsin Erdogan 2017-06-21 21:17:10 -0400 129)
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 130) static __le32 ext4_xattr_block_csum(struct inode *inode,
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 131) sector_t block_nr,
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 132) struct ext4_xattr_header *hdr)
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 133) {
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 134) struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
d6a771056b321 (Theodore Ts'o 2013-04-09 23:59:55 -0400 135) __u32 csum;
d6a771056b321 (Theodore Ts'o 2013-04-09 23:59:55 -0400 136) __le64 dsk_block_nr = cpu_to_le64(block_nr);
b47820edd1634 (Daeho Jeong 2016-07-03 17:51:39 -0400 137) __u32 dummy_csum = 0;
b47820edd1634 (Daeho Jeong 2016-07-03 17:51:39 -0400 138) int offset = offsetof(struct ext4_xattr_header, h_checksum);
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 139)
d6a771056b321 (Theodore Ts'o 2013-04-09 23:59:55 -0400 140) csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&dsk_block_nr,
d6a771056b321 (Theodore Ts'o 2013-04-09 23:59:55 -0400 141) sizeof(dsk_block_nr));
b47820edd1634 (Daeho Jeong 2016-07-03 17:51:39 -0400 142) csum = ext4_chksum(sbi, csum, (__u8 *)hdr, offset);
b47820edd1634 (Daeho Jeong 2016-07-03 17:51:39 -0400 143) csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum));
b47820edd1634 (Daeho Jeong 2016-07-03 17:51:39 -0400 144) offset += sizeof(dummy_csum);
b47820edd1634 (Daeho Jeong 2016-07-03 17:51:39 -0400 145) csum = ext4_chksum(sbi, csum, (__u8 *)hdr + offset,
b47820edd1634 (Daeho Jeong 2016-07-03 17:51:39 -0400 146) EXT4_BLOCK_SIZE(inode->i_sb) - offset);
41eb70dde42b2 (Tao Ma 2012-07-09 16:29:27 -0400 147)
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 148) return cpu_to_le32(csum);
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 149) }
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 150)
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 151) static int ext4_xattr_block_csum_verify(struct inode *inode,
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 152) struct buffer_head *bh)
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 153) {
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 154) struct ext4_xattr_header *hdr = BHDR(bh);
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 155) int ret = 1;
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 156)
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 157) if (ext4_has_metadata_csum(inode->i_sb)) {
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 158) lock_buffer(bh);
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 159) ret = (hdr->h_checksum == ext4_xattr_block_csum(inode,
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 160) bh->b_blocknr, hdr));
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 161) unlock_buffer(bh);
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 162) }
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 163) return ret;
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 164) }
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 165)
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 166) static void ext4_xattr_block_csum_set(struct inode *inode,
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 167) struct buffer_head *bh)
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 168) {
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 169) if (ext4_has_metadata_csum(inode->i_sb))
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 170) BHDR(bh)->h_checksum = ext4_xattr_block_csum(inode,
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 171) bh->b_blocknr, BHDR(bh));
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 172) }
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 173)
11e27528076e7 (Stephen Hemminger 2010-05-13 17:53:18 -0700 174) static inline const struct xattr_handler *
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 175) ext4_xattr_handler(int name_index)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 176) {
11e27528076e7 (Stephen Hemminger 2010-05-13 17:53:18 -0700 177) const struct xattr_handler *handler = NULL;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 178)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 179) if (name_index > 0 && name_index < ARRAY_SIZE(ext4_xattr_handler_map))
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 180) handler = ext4_xattr_handler_map[name_index];
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 181) return handler;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 182) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 183)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 184) static int
2c4f992337484 (Eric Biggers 2017-04-29 23:56:52 -0400 185) ext4_xattr_check_entries(struct ext4_xattr_entry *entry, void *end,
2c4f992337484 (Eric Biggers 2017-04-29 23:56:52 -0400 186) void *value_start)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 187) {
a0626e7595407 (Darrick J. Wong 2014-09-16 14:34:59 -0400 188) struct ext4_xattr_entry *e = entry;
a0626e7595407 (Darrick J. Wong 2014-09-16 14:34:59 -0400 189)
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 190) /* Find the end of the names list */
a0626e7595407 (Darrick J. Wong 2014-09-16 14:34:59 -0400 191) while (!IS_LAST_ENTRY(e)) {
a0626e7595407 (Darrick J. Wong 2014-09-16 14:34:59 -0400 192) struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 193) if ((void *)next >= end)
6a797d2737838 (Darrick J. Wong 2015-10-17 16:16:04 -0400 194) return -EFSCORRUPTED;
7d95178c77014 (Theodore Ts'o 2018-08-01 12:36:52 -0400 195) if (strnlen(e->e_name, e->e_name_len) != e->e_name_len)
7d95178c77014 (Theodore Ts'o 2018-08-01 12:36:52 -0400 196) return -EFSCORRUPTED;
a0626e7595407 (Darrick J. Wong 2014-09-16 14:34:59 -0400 197) e = next;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 198) }
a0626e7595407 (Darrick J. Wong 2014-09-16 14:34:59 -0400 199)
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 200) /* Check the values */
a0626e7595407 (Darrick J. Wong 2014-09-16 14:34:59 -0400 201) while (!IS_LAST_ENTRY(entry)) {
ce3fd194fcc6f (Eric Biggers 2018-03-29 14:31:42 -0400 202) u32 size = le32_to_cpu(entry->e_value_size);
ce3fd194fcc6f (Eric Biggers 2018-03-29 14:31:42 -0400 203)
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 204) if (size > EXT4_XATTR_SIZE_MAX)
ce3fd194fcc6f (Eric Biggers 2018-03-29 14:31:42 -0400 205) return -EFSCORRUPTED;
ce3fd194fcc6f (Eric Biggers 2018-03-29 14:31:42 -0400 206)
ce3fd194fcc6f (Eric Biggers 2018-03-29 14:31:42 -0400 207) if (size != 0 && entry->e_value_inum == 0) {
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 208) u16 offs = le16_to_cpu(entry->e_value_offs);
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 209) void *value;
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 210)
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 211) /*
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 212) * The value cannot overlap the names, and the value
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 213) * with padding cannot extend beyond 'end'. Check both
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 214) * the padded and unpadded sizes, since the size may
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 215) * overflow to 0 when adding padding.
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 216) */
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 217) if (offs > end - value_start)
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 218) return -EFSCORRUPTED;
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 219) value = value_start + offs;
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 220) if (value < (void *)e + sizeof(u32) ||
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 221) size > end - value ||
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 222) EXT4_XATTR_SIZE(size) > end - value)
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 223) return -EFSCORRUPTED;
d7614cc16146e (Eric Biggers 2016-12-01 14:57:29 -0500 224) }
a0626e7595407 (Darrick J. Wong 2014-09-16 14:34:59 -0400 225) entry = EXT4_XATTR_NEXT(entry);
a0626e7595407 (Darrick J. Wong 2014-09-16 14:34:59 -0400 226) }
a0626e7595407 (Darrick J. Wong 2014-09-16 14:34:59 -0400 227)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 228) return 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 229) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 230)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 231) static inline int
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 232) __ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh,
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 233) const char *function, unsigned int line)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 234) {
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 235) int error = -EFSCORRUPTED;
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 236)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 237) if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 238) BHDR(bh)->h_blocks != cpu_to_le32(1))
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 239) goto errout;
513f86d73855c (Theodore Ts'o 2018-06-13 00:51:28 -0400 240) if (buffer_verified(bh))
513f86d73855c (Theodore Ts'o 2018-06-13 00:51:28 -0400 241) return 0;
513f86d73855c (Theodore Ts'o 2018-06-13 00:51:28 -0400 242)
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 243) error = -EFSBADCRC;
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 244) if (!ext4_xattr_block_csum_verify(inode, bh))
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 245) goto errout;
2c4f992337484 (Eric Biggers 2017-04-29 23:56:52 -0400 246) error = ext4_xattr_check_entries(BFIRST(bh), bh->b_data + bh->b_size,
2c4f992337484 (Eric Biggers 2017-04-29 23:56:52 -0400 247) bh->b_data);
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 248) errout:
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 249) if (error)
54d3adbc29f0c (Theodore Ts'o 2020-03-28 19:33:43 -0400 250) __ext4_error_inode(inode, function, line, 0, -error,
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 251) "corrupted xattr block %llu",
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 252) (unsigned long long) bh->b_blocknr);
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 253) else
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 254) set_buffer_verified(bh);
cc8e94fd126ab (Darrick J. Wong 2012-04-29 18:43:10 -0400 255) return error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 256) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 257)
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 258) #define ext4_xattr_check_block(inode, bh) \
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 259) __ext4_xattr_check_block((inode), (bh), __func__, __LINE__)
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 260)
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 261)
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 262) static int
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 263) __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 264) void *end, const char *function, unsigned int line)
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 265) {
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 266) int error = -EFSCORRUPTED;
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 267)
290ab230016f1 (Eric Biggers 2016-12-01 14:51:58 -0500 268) if (end - (void *)header < sizeof(*header) + sizeof(u32) ||
199625098a18a (Eric Biggers 2016-10-15 09:39:31 -0400 269) (header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)))
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 270) goto errout;
2c4f992337484 (Eric Biggers 2017-04-29 23:56:52 -0400 271) error = ext4_xattr_check_entries(IFIRST(header), end, IFIRST(header));
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 272) errout:
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 273) if (error)
54d3adbc29f0c (Theodore Ts'o 2020-03-28 19:33:43 -0400 274) __ext4_error_inode(inode, function, line, 0, -error,
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 275) "corrupted in-inode xattr");
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 276) return error;
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 277) }
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 278)
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 279) #define xattr_check_inode(inode, header, end) \
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 280) __xattr_check_inode((inode), (header), (end), __func__, __LINE__)
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 281)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 282) static int
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 283) xattr_find_entry(struct inode *inode, struct ext4_xattr_entry **pentry,
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 284) void *end, int name_index, const char *name, int sorted)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 285) {
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 286) struct ext4_xattr_entry *entry, *next;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 287) size_t name_len;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 288) int cmp = 1;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 289)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 290) if (name == NULL)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 291) return -EINVAL;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 292) name_len = strlen(name);
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 293) for (entry = *pentry; !IS_LAST_ENTRY(entry); entry = next) {
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 294) next = EXT4_XATTR_NEXT(entry);
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 295) if ((void *) next >= end) {
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 296) EXT4_ERROR_INODE(inode, "corrupted xattr entries");
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 297) return -EFSCORRUPTED;
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 298) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 299) cmp = name_index - entry->e_name_index;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 300) if (!cmp)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 301) cmp = name_len - entry->e_name_len;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 302) if (!cmp)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 303) cmp = memcmp(name, entry->e_name, name_len);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 304) if (cmp <= 0 && (sorted || cmp == 0))
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 305) break;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 306) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 307) *pentry = entry;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 308) return cmp ? -ENODATA : 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 309) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 310)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 311) static u32
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 312) ext4_xattr_inode_hash(struct ext4_sb_info *sbi, const void *buffer, size_t size)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 313) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 314) return ext4_chksum(sbi, sbi->s_csum_seed, buffer, size);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 315) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 316)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 317) static u64 ext4_xattr_inode_get_ref(struct inode *ea_inode)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 318) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 319) return ((u64)ea_inode->i_ctime.tv_sec << 32) |
ee73f9a52a343 (Jeff Layton 2018-01-09 08:21:39 -0500 320) (u32) inode_peek_iversion_raw(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 321) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 322)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 323) static void ext4_xattr_inode_set_ref(struct inode *ea_inode, u64 ref_count)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 324) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 325) ea_inode->i_ctime.tv_sec = (u32)(ref_count >> 32);
ee73f9a52a343 (Jeff Layton 2018-01-09 08:21:39 -0500 326) inode_set_iversion_raw(ea_inode, ref_count & 0xffffffff);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 327) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 328)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 329) static u32 ext4_xattr_inode_get_hash(struct inode *ea_inode)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 330) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 331) return (u32)ea_inode->i_atime.tv_sec;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 332) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 333)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 334) static void ext4_xattr_inode_set_hash(struct inode *ea_inode, u32 hash)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 335) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 336) ea_inode->i_atime.tv_sec = hash;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 337) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 338)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 339) /*
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 340) * Read the EA value from an inode.
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 341) */
909666933210e (Tahsin Erdogan 2017-06-21 21:57:36 -0400 342) static int ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t size)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 343) {
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 344) int blocksize = 1 << ea_inode->i_blkbits;
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 345) int bh_count = (size + blocksize - 1) >> ea_inode->i_blkbits;
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 346) int tail_size = (size % blocksize) ?: blocksize;
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 347) struct buffer_head *bhs_inline[8];
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 348) struct buffer_head **bhs = bhs_inline;
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 349) int i, ret;
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 350)
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 351) if (bh_count > ARRAY_SIZE(bhs_inline)) {
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 352) bhs = kmalloc_array(bh_count, sizeof(*bhs), GFP_NOFS);
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 353) if (!bhs)
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 354) return -ENOMEM;
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 355) }
909666933210e (Tahsin Erdogan 2017-06-21 21:57:36 -0400 356)
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 357) ret = ext4_bread_batch(ea_inode, 0 /* block */, bh_count,
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 358) true /* wait */, bhs);
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 359) if (ret)
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 360) goto free_bhs;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 361)
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 362) for (i = 0; i < bh_count; i++) {
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 363) /* There shouldn't be any holes in ea_inode. */
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 364) if (!bhs[i]) {
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 365) ret = -EFSCORRUPTED;
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 366) goto put_bhs;
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 367) }
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 368) memcpy((char *)buf + blocksize * i, bhs[i]->b_data,
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 369) i < bh_count - 1 ? blocksize : tail_size);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 370) }
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 371) ret = 0;
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 372) put_bhs:
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 373) for (i = 0; i < bh_count; i++)
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 374) brelse(bhs[i]);
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 375) free_bhs:
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 376) if (bhs != bhs_inline)
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 377) kfree(bhs);
9699d4f91d9bd (Tahsin Erdogan 2017-08-06 00:07:01 -0400 378) return ret;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 379) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 380)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 381) #define EXT4_XATTR_INODE_GET_PARENT(inode) ((__u32)(inode)->i_mtime.tv_sec)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 382)
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 383) static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino,
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 384) u32 ea_inode_hash, struct inode **ea_inode)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 385) {
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 386) struct inode *inode;
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 387) int err;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 388)
8a363970d1dc3 (Theodore Ts'o 2018-12-19 12:29:13 -0500 389) inode = ext4_iget(parent->i_sb, ea_ino, EXT4_IGET_NORMAL);
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 390) if (IS_ERR(inode)) {
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 391) err = PTR_ERR(inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 392) ext4_error(parent->i_sb,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 393) "error while reading EA inode %lu err=%d", ea_ino,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 394) err);
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 395) return err;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 396) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 397)
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 398) if (is_bad_inode(inode)) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 399) ext4_error(parent->i_sb,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 400) "error while reading EA inode %lu is_bad_inode",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 401) ea_ino);
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 402) err = -EIO;
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 403) goto error;
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 404) }
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 405)
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 406) if (!(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 407) ext4_error(parent->i_sb,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 408) "EA inode %lu does not have EXT4_EA_INODE_FL flag",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 409) ea_ino);
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 410) err = -EINVAL;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 411) goto error;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 412) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 413)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 414) ext4_xattr_inode_set_class(inode);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 415)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 416) /*
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 417) * Check whether this is an old Lustre-style xattr inode. Lustre
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 418) * implementation does not have hash validation, rather it has a
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 419) * backpointer from ea_inode to the parent inode.
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 420) */
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 421) if (ea_inode_hash != ext4_xattr_inode_get_hash(inode) &&
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 422) EXT4_XATTR_INODE_GET_PARENT(inode) == parent->i_ino &&
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 423) inode->i_generation == parent->i_generation) {
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 424) ext4_set_inode_state(inode, EXT4_STATE_LUSTRE_EA_INODE);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 425) ext4_xattr_inode_set_ref(inode, 1);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 426) } else {
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 427) inode_lock(inode);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 428) inode->i_flags |= S_NOQUOTA;
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 429) inode_unlock(inode);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 430) }
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 431)
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 432) *ea_inode = inode;
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 433) return 0;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 434) error:
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 435) iput(inode);
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 436) return err;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 437) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 438)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 439) static int
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 440) ext4_xattr_inode_verify_hashes(struct inode *ea_inode,
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 441) struct ext4_xattr_entry *entry, void *buffer,
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 442) size_t size)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 443) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 444) u32 hash;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 445)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 446) /* Verify stored hash matches calculated hash. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 447) hash = ext4_xattr_inode_hash(EXT4_SB(ea_inode->i_sb), buffer, size);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 448) if (hash != ext4_xattr_inode_get_hash(ea_inode))
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 449) return -EFSCORRUPTED;
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 450)
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 451) if (entry) {
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 452) __le32 e_hash, tmp_data;
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 453)
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 454) /* Verify entry hash. */
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 455) tmp_data = cpu_to_le32(hash);
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 456) e_hash = ext4_xattr_hash_entry(entry->e_name, entry->e_name_len,
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 457) &tmp_data, 1);
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 458) if (e_hash != entry->e_hash)
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 459) return -EFSCORRUPTED;
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 460) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 461) return 0;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 462) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 463)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 464) /*
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 465) * Read xattr value from the EA inode.
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 466) */
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 467) static int
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 468) ext4_xattr_inode_get(struct inode *inode, struct ext4_xattr_entry *entry,
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 469) void *buffer, size_t size)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 470) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 471) struct mb_cache *ea_inode_cache = EA_INODE_CACHE(inode);
bab79b04999cc (Tahsin Erdogan 2017-06-21 21:49:53 -0400 472) struct inode *ea_inode;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 473) int err;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 474)
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 475) err = ext4_xattr_inode_iget(inode, le32_to_cpu(entry->e_value_inum),
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 476) le32_to_cpu(entry->e_hash), &ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 477) if (err) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 478) ea_inode = NULL;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 479) goto out;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 480) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 481)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 482) if (i_size_read(ea_inode) != size) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 483) ext4_warning_inode(ea_inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 484) "ea_inode file size=%llu entry size=%zu",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 485) i_size_read(ea_inode), size);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 486) err = -EFSCORRUPTED;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 487) goto out;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 488) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 489)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 490) err = ext4_xattr_inode_read(ea_inode, buffer, size);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 491) if (err)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 492) goto out;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 493)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 494) if (!ext4_test_inode_state(ea_inode, EXT4_STATE_LUSTRE_EA_INODE)) {
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 495) err = ext4_xattr_inode_verify_hashes(ea_inode, entry, buffer,
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 496) size);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 497) if (err) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 498) ext4_warning_inode(ea_inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 499) "EA inode hash validation failed");
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 500) goto out;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 501) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 502)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 503) if (ea_inode_cache)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 504) mb_cache_entry_create(ea_inode_cache, GFP_NOFS,
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 505) ext4_xattr_inode_get_hash(ea_inode),
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 506) ea_inode->i_ino, true /* reusable */);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 507) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 508) out:
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 509) iput(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 510) return err;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 511) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 512)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 513) static int
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 514) ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 515) void *buffer, size_t buffer_size)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 516) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 517) struct buffer_head *bh = NULL;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 518) struct ext4_xattr_entry *entry;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 519) size_t size;
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 520) void *end;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 521) int error;
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 522) struct mb_cache *ea_block_cache = EA_BLOCK_CACHE(inode);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 523)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 524) ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 525) name_index, name, buffer, (long)buffer_size);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 526)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 527) if (!EXT4_I(inode)->i_file_acl)
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 528) return -ENODATA;
ace36ad431c68 (Joe Perches 2012-03-19 23:11:43 -0400 529) ea_idebug(inode, "reading block %llu",
ace36ad431c68 (Joe Perches 2012-03-19 23:11:43 -0400 530) (unsigned long long)EXT4_I(inode)->i_file_acl);
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 531) bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 532) if (IS_ERR(bh))
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 533) return PTR_ERR(bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 534) ea_bdebug(bh, "b_count=%d, refcount=%d",
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 535) atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 536) error = ext4_xattr_check_block(inode, bh);
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 537) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 538) goto cleanup;
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 539) ext4_xattr_block_cache_insert(ea_block_cache, bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 540) entry = BFIRST(bh);
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 541) end = bh->b_data + bh->b_size;
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 542) error = xattr_find_entry(inode, &entry, end, name_index, name, 1);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 543) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 544) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 545) size = le32_to_cpu(entry->e_value_size);
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 546) error = -ERANGE;
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 547) if (unlikely(size > EXT4_XATTR_SIZE_MAX))
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 548) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 549) if (buffer) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 550) if (size > buffer_size)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 551) goto cleanup;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 552) if (entry->e_value_inum) {
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 553) error = ext4_xattr_inode_get(inode, entry, buffer,
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 554) size);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 555) if (error)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 556) goto cleanup;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 557) } else {
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 558) u16 offset = le16_to_cpu(entry->e_value_offs);
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 559) void *p = bh->b_data + offset;
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 560)
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 561) if (unlikely(p + size > end))
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 562) goto cleanup;
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 563) memcpy(buffer, p, size);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 564) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 565) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 566) error = size;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 567)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 568) cleanup:
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 569) brelse(bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 570) return error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 571) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 572)
879b38257bf2b (Tao Ma 2012-12-05 10:28:46 -0500 573) int
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 574) ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 575) void *buffer, size_t buffer_size)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 576) {
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 577) struct ext4_xattr_ibody_header *header;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 578) struct ext4_xattr_entry *entry;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 579) struct ext4_inode *raw_inode;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 580) struct ext4_iloc iloc;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 581) size_t size;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 582) void *end;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 583) int error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 584)
19f5fb7ad679b (Theodore Ts'o 2010-01-24 14:34:07 -0500 585) if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR))
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 586) return -ENODATA;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 587) error = ext4_get_inode_loc(inode, &iloc);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 588) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 589) return error;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 590) raw_inode = ext4_raw_inode(&iloc);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 591) header = IHDR(inode, raw_inode);
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 592) end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 593) error = xattr_check_inode(inode, header, end);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 594) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 595) goto cleanup;
6ba644b9fd8ce (Eric Biggers 2017-04-30 00:01:02 -0400 596) entry = IFIRST(header);
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 597) error = xattr_find_entry(inode, &entry, end, name_index, name, 0);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 598) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 599) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 600) size = le32_to_cpu(entry->e_value_size);
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 601) error = -ERANGE;
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 602) if (unlikely(size > EXT4_XATTR_SIZE_MAX))
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 603) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 604) if (buffer) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 605) if (size > buffer_size)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 606) goto cleanup;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 607) if (entry->e_value_inum) {
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 608) error = ext4_xattr_inode_get(inode, entry, buffer,
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 609) size);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 610) if (error)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 611) goto cleanup;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 612) } else {
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 613) u16 offset = le16_to_cpu(entry->e_value_offs);
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 614) void *p = (void *)IFIRST(header) + offset;
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 615)
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 616) if (unlikely(p + size > end))
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 617) goto cleanup;
54dd0e0a1b255 (Theodore Ts'o 2018-03-30 20:04:11 -0400 618) memcpy(buffer, p, size);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 619) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 620) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 621) error = size;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 622)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 623) cleanup:
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 624) brelse(iloc.bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 625) return error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 626) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 627)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 628) /*
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 629) * ext4_xattr_get()
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 630) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 631) * Copy an extended attribute into the buffer
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 632) * provided, or compute the buffer size required.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 633) * Buffer is NULL to compute the size of the buffer required.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 634) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 635) * Returns a negative error number on failure, or the number of bytes
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 636) * used / required on success.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 637) */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 638) int
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 639) ext4_xattr_get(struct inode *inode, int name_index, const char *name,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 640) void *buffer, size_t buffer_size)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 641) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 642) int error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 643)
0db1ff222d40f (Theodore Ts'o 2017-02-05 01:28:48 -0500 644) if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
0db1ff222d40f (Theodore Ts'o 2017-02-05 01:28:48 -0500 645) return -EIO;
0db1ff222d40f (Theodore Ts'o 2017-02-05 01:28:48 -0500 646)
230b8c1a7b388 (Zhang Zhen 2014-05-12 09:57:59 -0400 647) if (strlen(name) > 255)
230b8c1a7b388 (Zhang Zhen 2014-05-12 09:57:59 -0400 648) return -ERANGE;
230b8c1a7b388 (Zhang Zhen 2014-05-12 09:57:59 -0400 649)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 650) down_read(&EXT4_I(inode)->xattr_sem);
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 651) error = ext4_xattr_ibody_get(inode, name_index, name, buffer,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 652) buffer_size);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 653) if (error == -ENODATA)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 654) error = ext4_xattr_block_get(inode, name_index, name, buffer,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 655) buffer_size);
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 656) up_read(&EXT4_I(inode)->xattr_sem);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 657) return error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 658) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 659)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 660) static int
431547b3c4533 (Christoph Hellwig 2009-11-13 09:52:56 +0000 661) ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 662) char *buffer, size_t buffer_size)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 663) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 664) size_t rest = buffer_size;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 665)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 666) for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
11e27528076e7 (Stephen Hemminger 2010-05-13 17:53:18 -0700 667) const struct xattr_handler *handler =
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 668) ext4_xattr_handler(entry->e_name_index);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 669)
764a5c6b1fa43 (Andreas Gruenbacher 2015-12-02 14:44:43 +0100 670) if (handler && (!handler->list || handler->list(dentry))) {
764a5c6b1fa43 (Andreas Gruenbacher 2015-12-02 14:44:43 +0100 671) const char *prefix = handler->prefix ?: handler->name;
764a5c6b1fa43 (Andreas Gruenbacher 2015-12-02 14:44:43 +0100 672) size_t prefix_len = strlen(prefix);
764a5c6b1fa43 (Andreas Gruenbacher 2015-12-02 14:44:43 +0100 673) size_t size = prefix_len + entry->e_name_len + 1;
764a5c6b1fa43 (Andreas Gruenbacher 2015-12-02 14:44:43 +0100 674)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 675) if (buffer) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 676) if (size > rest)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 677) return -ERANGE;
764a5c6b1fa43 (Andreas Gruenbacher 2015-12-02 14:44:43 +0100 678) memcpy(buffer, prefix, prefix_len);
764a5c6b1fa43 (Andreas Gruenbacher 2015-12-02 14:44:43 +0100 679) buffer += prefix_len;
764a5c6b1fa43 (Andreas Gruenbacher 2015-12-02 14:44:43 +0100 680) memcpy(buffer, entry->e_name, entry->e_name_len);
764a5c6b1fa43 (Andreas Gruenbacher 2015-12-02 14:44:43 +0100 681) buffer += entry->e_name_len;
764a5c6b1fa43 (Andreas Gruenbacher 2015-12-02 14:44:43 +0100 682) *buffer++ = 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 683) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 684) rest -= size;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 685) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 686) }
764a5c6b1fa43 (Andreas Gruenbacher 2015-12-02 14:44:43 +0100 687) return buffer_size - rest; /* total size */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 688) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 689)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 690) static int
431547b3c4533 (Christoph Hellwig 2009-11-13 09:52:56 +0000 691) ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 692) {
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 693) struct inode *inode = d_inode(dentry);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 694) struct buffer_head *bh = NULL;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 695) int error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 696)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 697) ea_idebug(inode, "buffer=%p, buffer_size=%ld",
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 698) buffer, (long)buffer_size);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 699)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 700) if (!EXT4_I(inode)->i_file_acl)
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 701) return 0;
ace36ad431c68 (Joe Perches 2012-03-19 23:11:43 -0400 702) ea_idebug(inode, "reading block %llu",
ace36ad431c68 (Joe Perches 2012-03-19 23:11:43 -0400 703) (unsigned long long)EXT4_I(inode)->i_file_acl);
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 704) bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 705) if (IS_ERR(bh))
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 706) return PTR_ERR(bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 707) ea_bdebug(bh, "b_count=%d, refcount=%d",
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 708) atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 709) error = ext4_xattr_check_block(inode, bh);
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 710) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 711) goto cleanup;
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 712) ext4_xattr_block_cache_insert(EA_BLOCK_CACHE(inode), bh);
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 713) error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer,
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 714) buffer_size);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 715) cleanup:
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 716) brelse(bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 717) return error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 718) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 719)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 720) static int
431547b3c4533 (Christoph Hellwig 2009-11-13 09:52:56 +0000 721) ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 722) {
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 723) struct inode *inode = d_inode(dentry);
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 724) struct ext4_xattr_ibody_header *header;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 725) struct ext4_inode *raw_inode;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 726) struct ext4_iloc iloc;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 727) void *end;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 728) int error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 729)
19f5fb7ad679b (Theodore Ts'o 2010-01-24 14:34:07 -0500 730) if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR))
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 731) return 0;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 732) error = ext4_get_inode_loc(inode, &iloc);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 733) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 734) return error;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 735) raw_inode = ext4_raw_inode(&iloc);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 736) header = IHDR(inode, raw_inode);
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 737) end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 738) error = xattr_check_inode(inode, header, end);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 739) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 740) goto cleanup;
431547b3c4533 (Christoph Hellwig 2009-11-13 09:52:56 +0000 741) error = ext4_xattr_list_entries(dentry, IFIRST(header),
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 742) buffer, buffer_size);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 743)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 744) cleanup:
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 745) brelse(iloc.bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 746) return error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 747) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 748)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 749) /*
ba7ea1d8f4538 (Eric Biggers 2017-04-29 23:53:17 -0400 750) * Inode operation listxattr()
ba7ea1d8f4538 (Eric Biggers 2017-04-29 23:53:17 -0400 751) *
ba7ea1d8f4538 (Eric Biggers 2017-04-29 23:53:17 -0400 752) * d_inode(dentry)->i_rwsem: don't care
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 753) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 754) * Copy a list of attribute names into the buffer
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 755) * provided, or compute the buffer size required.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 756) * Buffer is NULL to compute the size of the buffer required.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 757) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 758) * Returns a negative error number on failure, or the number of bytes
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 759) * used / required on success.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 760) */
ba7ea1d8f4538 (Eric Biggers 2017-04-29 23:53:17 -0400 761) ssize_t
ba7ea1d8f4538 (Eric Biggers 2017-04-29 23:53:17 -0400 762) ext4_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 763) {
eaeef86718249 (Theodore Ts'o 2011-01-10 12:10:07 -0500 764) int ret, ret2;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 765)
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 766) down_read(&EXT4_I(d_inode(dentry))->xattr_sem);
eaeef86718249 (Theodore Ts'o 2011-01-10 12:10:07 -0500 767) ret = ret2 = ext4_xattr_ibody_list(dentry, buffer, buffer_size);
eaeef86718249 (Theodore Ts'o 2011-01-10 12:10:07 -0500 768) if (ret < 0)
eaeef86718249 (Theodore Ts'o 2011-01-10 12:10:07 -0500 769) goto errout;
eaeef86718249 (Theodore Ts'o 2011-01-10 12:10:07 -0500 770) if (buffer) {
eaeef86718249 (Theodore Ts'o 2011-01-10 12:10:07 -0500 771) buffer += ret;
eaeef86718249 (Theodore Ts'o 2011-01-10 12:10:07 -0500 772) buffer_size -= ret;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 773) }
eaeef86718249 (Theodore Ts'o 2011-01-10 12:10:07 -0500 774) ret = ext4_xattr_block_list(dentry, buffer, buffer_size);
eaeef86718249 (Theodore Ts'o 2011-01-10 12:10:07 -0500 775) if (ret < 0)
eaeef86718249 (Theodore Ts'o 2011-01-10 12:10:07 -0500 776) goto errout;
eaeef86718249 (Theodore Ts'o 2011-01-10 12:10:07 -0500 777) ret += ret2;
eaeef86718249 (Theodore Ts'o 2011-01-10 12:10:07 -0500 778) errout:
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 779) up_read(&EXT4_I(d_inode(dentry))->xattr_sem);
eaeef86718249 (Theodore Ts'o 2011-01-10 12:10:07 -0500 780) return ret;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 781) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 782)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 783) /*
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 784) * If the EXT4_FEATURE_COMPAT_EXT_ATTR feature of this file system is
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 785) * not set, set it.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 786) */
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 787) static void ext4_xattr_update_super_block(handle_t *handle,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 788) struct super_block *sb)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 789) {
e2b911c53584a (Darrick J. Wong 2015-10-17 16:18:43 -0400 790) if (ext4_has_feature_xattr(sb))
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 791) return;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 792)
5d60125530b01 (liang xie 2014-05-12 22:06:43 -0400 793) BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access");
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 794) if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) {
05c2c00f3769a (Jan Kara 2020-12-16 11:18:39 +0100 795) lock_buffer(EXT4_SB(sb)->s_sbh);
e2b911c53584a (Darrick J. Wong 2015-10-17 16:18:43 -0400 796) ext4_set_feature_xattr(sb);
05c2c00f3769a (Jan Kara 2020-12-16 11:18:39 +0100 797) ext4_superblock_csum_set(sb);
05c2c00f3769a (Jan Kara 2020-12-16 11:18:39 +0100 798) unlock_buffer(EXT4_SB(sb)->s_sbh);
a3f5cf14ff917 (Jan Kara 2020-12-16 11:18:44 +0100 799) ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 800) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 801) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 802)
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 803) int ext4_get_inode_usage(struct inode *inode, qsize_t *usage)
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 804) {
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 805) struct ext4_iloc iloc = { .bh = NULL };
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 806) struct buffer_head *bh = NULL;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 807) struct ext4_inode *raw_inode;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 808) struct ext4_xattr_ibody_header *header;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 809) struct ext4_xattr_entry *entry;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 810) qsize_t ea_inode_refs = 0;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 811) void *end;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 812) int ret;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 813)
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 814) lockdep_assert_held_read(&EXT4_I(inode)->xattr_sem);
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 815)
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 816) if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) {
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 817) ret = ext4_get_inode_loc(inode, &iloc);
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 818) if (ret)
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 819) goto out;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 820) raw_inode = ext4_raw_inode(&iloc);
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 821) header = IHDR(inode, raw_inode);
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 822) end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 823) ret = xattr_check_inode(inode, header, end);
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 824) if (ret)
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 825) goto out;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 826)
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 827) for (entry = IFIRST(header); !IS_LAST_ENTRY(entry);
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 828) entry = EXT4_XATTR_NEXT(entry))
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 829) if (entry->e_value_inum)
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 830) ea_inode_refs++;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 831) }
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 832)
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 833) if (EXT4_I(inode)->i_file_acl) {
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 834) bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 835) if (IS_ERR(bh)) {
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 836) ret = PTR_ERR(bh);
7159a986b4202 (Dan Carpenter 2019-02-21 11:17:34 -0500 837) bh = NULL;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 838) goto out;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 839) }
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 840)
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 841) ret = ext4_xattr_check_block(inode, bh);
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 842) if (ret)
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 843) goto out;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 844)
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 845) for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry);
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 846) entry = EXT4_XATTR_NEXT(entry))
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 847) if (entry->e_value_inum)
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 848) ea_inode_refs++;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 849) }
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 850) *usage = ea_inode_refs + 1;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 851) ret = 0;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 852) out:
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 853) brelse(iloc.bh);
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 854) brelse(bh);
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 855) return ret;
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 856) }
7a9ca53aea10a (Tahsin Erdogan 2017-06-22 11:46:48 -0400 857)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 858) static inline size_t round_up_cluster(struct inode *inode, size_t length)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 859) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 860) struct super_block *sb = inode->i_sb;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 861) size_t cluster_size = 1 << (EXT4_SB(sb)->s_cluster_bits +
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 862) inode->i_blkbits);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 863) size_t mask = ~(cluster_size - 1);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 864)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 865) return (length + cluster_size - 1) & mask;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 866) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 867)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 868) static int ext4_xattr_inode_alloc_quota(struct inode *inode, size_t len)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 869) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 870) int err;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 871)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 872) err = dquot_alloc_inode(inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 873) if (err)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 874) return err;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 875) err = dquot_alloc_space_nodirty(inode, round_up_cluster(inode, len));
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 876) if (err)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 877) dquot_free_inode(inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 878) return err;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 879) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 880)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 881) static void ext4_xattr_inode_free_quota(struct inode *parent,
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 882) struct inode *ea_inode,
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 883) size_t len)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 884) {
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 885) if (ea_inode &&
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 886) ext4_test_inode_state(ea_inode, EXT4_STATE_LUSTRE_EA_INODE))
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 887) return;
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 888) dquot_free_space_nodirty(parent, round_up_cluster(parent, len));
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 889) dquot_free_inode(parent);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 890) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 891)
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 892) int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode,
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 893) struct buffer_head *block_bh, size_t value_len,
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 894) bool is_create)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 895) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 896) int credits;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 897) int blocks;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 898)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 899) /*
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 900) * 1) Owner inode update
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 901) * 2) Ref count update on old xattr block
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 902) * 3) new xattr block
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 903) * 4) block bitmap update for new xattr block
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 904) * 5) group descriptor for new xattr block
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 905) * 6) block bitmap update for old xattr block
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 906) * 7) group descriptor for old block
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 907) *
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 908) * 6 & 7 can happen if we have two racing threads T_a and T_b
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 909) * which are each trying to set an xattr on inodes I_a and I_b
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 910) * which were both initially sharing an xattr block.
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 911) */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 912) credits = 7;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 913)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 914) /* Quota updates. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 915) credits += EXT4_MAXQUOTAS_TRANS_BLOCKS(sb);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 916)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 917) /*
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 918) * In case of inline data, we may push out the data to a block,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 919) * so we need to reserve credits for this eventuality
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 920) */
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 921) if (inode && ext4_has_inline_data(inode))
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 922) credits += ext4_writepage_trans_blocks(inode) + 1;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 923)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 924) /* We are done if ea_inode feature is not enabled. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 925) if (!ext4_has_feature_ea_inode(sb))
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 926) return credits;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 927)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 928) /* New ea_inode, inode map, block bitmap, group descriptor. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 929) credits += 4;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 930)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 931) /* Data blocks. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 932) blocks = (value_len + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 933)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 934) /* Indirection block or one level of extent tree. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 935) blocks += 1;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 936)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 937) /* Block bitmap and group descriptor updates for each block. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 938) credits += blocks * 2;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 939)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 940) /* Blocks themselves. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 941) credits += blocks;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 942)
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 943) if (!is_create) {
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 944) /* Dereference ea_inode holding old xattr value.
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 945) * Old ea_inode, inode map, block bitmap, group descriptor.
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 946) */
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 947) credits += 4;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 948)
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 949) /* Data blocks for old ea_inode. */
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 950) blocks = XATTR_SIZE_MAX >> sb->s_blocksize_bits;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 951)
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 952) /* Indirection block or one level of extent tree for old
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 953) * ea_inode.
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 954) */
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 955) blocks += 1;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 956)
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 957) /* Block bitmap and group descriptor updates for each block. */
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 958) credits += blocks * 2;
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 959) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 960)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 961) /* We may need to clone the existing xattr block in which case we need
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 962) * to increment ref counts for existing ea_inodes referenced by it.
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 963) */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 964) if (block_bh) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 965) struct ext4_xattr_entry *entry = BFIRST(block_bh);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 966)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 967) for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry))
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 968) if (entry->e_value_inum)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 969) /* Ref count update on ea_inode. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 970) credits += 1;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 971) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 972) return credits;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 973) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 974)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 975) static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 976) int ref_change)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 977) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 978) struct mb_cache *ea_inode_cache = EA_INODE_CACHE(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 979) struct ext4_iloc iloc;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 980) s64 ref_count;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 981) u32 hash;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 982) int ret;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 983)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 984) inode_lock(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 985)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 986) ret = ext4_reserve_inode_write(handle, ea_inode, &iloc);
1bfc204dc0e7a (Vasily Averin 2018-11-06 17:45:02 -0500 987) if (ret)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 988) goto out;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 989)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 990) ref_count = ext4_xattr_inode_get_ref(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 991) ref_count += ref_change;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 992) ext4_xattr_inode_set_ref(ea_inode, ref_count);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 993)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 994) if (ref_change > 0) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 995) WARN_ONCE(ref_count <= 0, "EA inode %lu ref_count=%lld",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 996) ea_inode->i_ino, ref_count);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 997)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 998) if (ref_count == 1) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 999) WARN_ONCE(ea_inode->i_nlink, "EA inode %lu i_nlink=%u",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1000) ea_inode->i_ino, ea_inode->i_nlink);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1001)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1002) set_nlink(ea_inode, 1);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1003) ext4_orphan_del(handle, ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1004)
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1005) if (ea_inode_cache) {
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1006) hash = ext4_xattr_inode_get_hash(ea_inode);
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1007) mb_cache_entry_create(ea_inode_cache,
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1008) GFP_NOFS, hash,
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1009) ea_inode->i_ino,
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1010) true /* reusable */);
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1011) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1012) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1013) } else {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1014) WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1015) ea_inode->i_ino, ref_count);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1016)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1017) if (ref_count == 0) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1018) WARN_ONCE(ea_inode->i_nlink != 1,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1019) "EA inode %lu i_nlink=%u",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1020) ea_inode->i_ino, ea_inode->i_nlink);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1021)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1022) clear_nlink(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1023) ext4_orphan_add(handle, ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1024)
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1025) if (ea_inode_cache) {
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1026) hash = ext4_xattr_inode_get_hash(ea_inode);
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1027) mb_cache_entry_delete(ea_inode_cache, hash,
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1028) ea_inode->i_ino);
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1029) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1030) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1031) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1032)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1033) ret = ext4_mark_iloc_dirty(handle, ea_inode, &iloc);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1034) if (ret)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1035) ext4_warning_inode(ea_inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1036) "ext4_mark_iloc_dirty() failed ret=%d", ret);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1037) out:
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1038) inode_unlock(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1039) return ret;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1040) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1041)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1042) static int ext4_xattr_inode_inc_ref(handle_t *handle, struct inode *ea_inode)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1043) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1044) return ext4_xattr_inode_update_ref(handle, ea_inode, 1);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1045) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1046)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1047) static int ext4_xattr_inode_dec_ref(handle_t *handle, struct inode *ea_inode)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1048) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1049) return ext4_xattr_inode_update_ref(handle, ea_inode, -1);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1050) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1051)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1052) static int ext4_xattr_inode_inc_ref_all(handle_t *handle, struct inode *parent,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1053) struct ext4_xattr_entry *first)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1054) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1055) struct inode *ea_inode;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1056) struct ext4_xattr_entry *entry;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1057) struct ext4_xattr_entry *failed_entry;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1058) unsigned int ea_ino;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1059) int err, saved_err;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1060)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1061) for (entry = first; !IS_LAST_ENTRY(entry);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1062) entry = EXT4_XATTR_NEXT(entry)) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1063) if (!entry->e_value_inum)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1064) continue;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1065) ea_ino = le32_to_cpu(entry->e_value_inum);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1066) err = ext4_xattr_inode_iget(parent, ea_ino,
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1067) le32_to_cpu(entry->e_hash),
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1068) &ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1069) if (err)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1070) goto cleanup;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1071) err = ext4_xattr_inode_inc_ref(handle, ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1072) if (err) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1073) ext4_warning_inode(ea_inode, "inc ref error %d", err);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1074) iput(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1075) goto cleanup;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1076) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1077) iput(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1078) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1079) return 0;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1080)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1081) cleanup:
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1082) saved_err = err;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1083) failed_entry = entry;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1084)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1085) for (entry = first; entry != failed_entry;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1086) entry = EXT4_XATTR_NEXT(entry)) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1087) if (!entry->e_value_inum)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1088) continue;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1089) ea_ino = le32_to_cpu(entry->e_value_inum);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1090) err = ext4_xattr_inode_iget(parent, ea_ino,
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1091) le32_to_cpu(entry->e_hash),
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1092) &ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1093) if (err) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1094) ext4_warning(parent->i_sb,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1095) "cleanup ea_ino %u iget error %d", ea_ino,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1096) err);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1097) continue;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1098) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1099) err = ext4_xattr_inode_dec_ref(handle, ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1100) if (err)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1101) ext4_warning_inode(ea_inode, "cleanup dec ref error %d",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1102) err);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1103) iput(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1104) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1105) return saved_err;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1106) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1107)
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1108) static int ext4_xattr_restart_fn(handle_t *handle, struct inode *inode,
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1109) struct buffer_head *bh, bool block_csum, bool dirty)
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1110) {
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1111) int error;
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1112)
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1113) if (bh && dirty) {
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1114) if (block_csum)
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1115) ext4_xattr_block_csum_set(inode, bh);
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1116) error = ext4_handle_dirty_metadata(handle, NULL, bh);
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1117) if (error) {
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1118) ext4_warning(inode->i_sb, "Handle metadata (error %d)",
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1119) error);
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1120) return error;
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1121) }
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1122) }
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1123) return 0;
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1124) }
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1125)
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1126) static void
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1127) ext4_xattr_inode_dec_ref_all(handle_t *handle, struct inode *parent,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1128) struct buffer_head *bh,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1129) struct ext4_xattr_entry *first, bool block_csum,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1130) struct ext4_xattr_inode_array **ea_inode_array,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1131) int extra_credits, bool skip_quota)
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1132) {
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1133) struct inode *ea_inode;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1134) struct ext4_xattr_entry *entry;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1135) bool dirty = false;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1136) unsigned int ea_ino;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1137) int err;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1138) int credits;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1139)
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1140) /* One credit for dec ref on ea_inode, one for orphan list addition, */
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1141) credits = 2 + extra_credits;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1142)
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1143) for (entry = first; !IS_LAST_ENTRY(entry);
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1144) entry = EXT4_XATTR_NEXT(entry)) {
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1145) if (!entry->e_value_inum)
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1146) continue;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1147) ea_ino = le32_to_cpu(entry->e_value_inum);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1148) err = ext4_xattr_inode_iget(parent, ea_ino,
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1149) le32_to_cpu(entry->e_hash),
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1150) &ea_inode);
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1151) if (err)
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1152) continue;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1153)
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1154) err = ext4_expand_inode_array(ea_inode_array, ea_inode);
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1155) if (err) {
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1156) ext4_warning_inode(ea_inode,
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1157) "Expand inode array err=%d", err);
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1158) iput(ea_inode);
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1159) continue;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1160) }
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1161)
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1162) err = ext4_journal_ensure_credits_fn(handle, credits, credits,
83448bdfb5973 (Jan Kara 2019-11-05 17:44:29 +0100 1163) ext4_free_metadata_revoke_credits(parent->i_sb, 1),
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1164) ext4_xattr_restart_fn(handle, parent, bh, block_csum,
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1165) dirty));
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1166) if (err < 0) {
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1167) ext4_warning_inode(ea_inode, "Ensure credits err=%d",
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1168) err);
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1169) continue;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1170) }
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1171) if (err > 0) {
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1172) err = ext4_journal_get_write_access(handle, bh);
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1173) if (err) {
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1174) ext4_warning_inode(ea_inode,
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1175) "Re-get write access err=%d",
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1176) err);
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1177) continue;
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1178) }
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 1179) }
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1180)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1181) err = ext4_xattr_inode_dec_ref(handle, ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1182) if (err) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1183) ext4_warning_inode(ea_inode, "ea_inode dec ref err=%d",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1184) err);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1185) continue;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1186) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1187)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1188) if (!skip_quota)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1189) ext4_xattr_inode_free_quota(parent, ea_inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1190) le32_to_cpu(entry->e_value_size));
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1191)
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1192) /*
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1193) * Forget about ea_inode within the same transaction that
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1194) * decrements the ref count. This avoids duplicate decrements in
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1195) * case the rest of the work spills over to subsequent
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1196) * transactions.
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1197) */
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1198) entry->e_value_inum = 0;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1199) entry->e_value_size = 0;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1200)
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1201) dirty = true;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1202) }
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1203)
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1204) if (dirty) {
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1205) /*
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1206) * Note that we are deliberately skipping csum calculation for
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1207) * the final update because we do not expect any journal
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1208) * restarts until xattr block is freed.
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1209) */
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1210)
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1211) err = ext4_handle_dirty_metadata(handle, NULL, bh);
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1212) if (err)
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1213) ext4_warning_inode(parent,
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1214) "handle dirty metadata err=%d", err);
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1215) }
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1216) }
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 1217)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1218) /*
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1219) * Release the xattr block BH: If the reference count is > 1, decrement it;
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1220) * otherwise free the block.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1221) */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1222) static void
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 1223) ext4_xattr_release_block(handle_t *handle, struct inode *inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1224) struct buffer_head *bh,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1225) struct ext4_xattr_inode_array **ea_inode_array,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1226) int extra_credits)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1227) {
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 1228) struct mb_cache *ea_block_cache = EA_BLOCK_CACHE(inode);
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1229) u32 hash, ref;
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1230) int error = 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1231)
5d60125530b01 (liang xie 2014-05-12 22:06:43 -0400 1232) BUFFER_TRACE(bh, "get_write_access");
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1233) error = ext4_journal_get_write_access(handle, bh);
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1234) if (error)
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1235) goto out;
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1236)
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1237) lock_buffer(bh);
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1238) hash = le32_to_cpu(BHDR(bh)->h_hash);
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1239) ref = le32_to_cpu(BHDR(bh)->h_refcount);
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1240) if (ref == 1) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1241) ea_bdebug(bh, "refcount now=0; freeing");
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 1242) /*
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 1243) * This must happen under buffer lock for
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 1244) * ext4_xattr_block_set() to reliably detect freed block
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 1245) */
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1246) if (ea_block_cache)
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1247) mb_cache_entry_delete(ea_block_cache, hash,
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1248) bh->b_blocknr);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1249) get_bh(bh);
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1250) unlock_buffer(bh);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1251)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1252) if (ext4_has_feature_ea_inode(inode->i_sb))
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1253) ext4_xattr_inode_dec_ref_all(handle, inode, bh,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1254) BFIRST(bh),
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1255) true /* block_csum */,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1256) ea_inode_array,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1257) extra_credits,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1258) true /* skip_quota */);
e6362609b6c71 (Theodore Ts'o 2009-11-23 07:17:05 -0500 1259) ext4_free_blocks(handle, inode, bh, 0, 1,
e6362609b6c71 (Theodore Ts'o 2009-11-23 07:17:05 -0500 1260) EXT4_FREE_BLOCKS_METADATA |
e6362609b6c71 (Theodore Ts'o 2009-11-23 07:17:05 -0500 1261) EXT4_FREE_BLOCKS_FORGET);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1262) } else {
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1263) ref--;
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1264) BHDR(bh)->h_refcount = cpu_to_le32(ref);
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1265) if (ref == EXT4_XATTR_REFCOUNT_MAX - 1) {
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1266) struct mb_cache_entry *ce;
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1267)
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1268) if (ea_block_cache) {
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1269) ce = mb_cache_entry_get(ea_block_cache, hash,
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1270) bh->b_blocknr);
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1271) if (ce) {
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1272) ce->e_reusable = 1;
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1273) mb_cache_entry_put(ea_block_cache, ce);
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1274) }
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1275) }
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1276) }
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1277)
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 1278) ext4_xattr_block_csum_set(inode, bh);
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1279) /*
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1280) * Beware of this ugliness: Releasing of xattr block references
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1281) * from different inodes can race and so we have to protect
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1282) * from a race where someone else frees the block (and releases
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1283) * its journal_head) before we are done dirtying the buffer. In
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1284) * nojournal mode this race is harmless and we actually cannot
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 1285) * call ext4_handle_dirty_metadata() with locked buffer as
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1286) * that function can call sync_dirty_buffer() so for that case
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1287) * we handle the dirtying after unlocking the buffer.
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1288) */
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1289) if (ext4_handle_valid(handle))
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 1290) error = ext4_handle_dirty_metadata(handle, inode, bh);
c1bb05a657fb3 (Eric Sandeen 2012-02-20 23:06:18 -0500 1291) unlock_buffer(bh);
ec4cb1aa2b7ba (Jan Kara 2014-04-07 10:54:21 -0400 1292) if (!ext4_handle_valid(handle))
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 1293) error = ext4_handle_dirty_metadata(handle, inode, bh);
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1294) if (IS_SYNC(inode))
0390131ba84fd (Frank Mayhar 2009-01-07 00:06:22 -0500 1295) ext4_handle_sync(handle);
1231b3a1eb574 (Lukas Czerner 2013-02-18 12:12:07 -0500 1296) dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1));
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1297) ea_bdebug(bh, "refcount now=%d; releasing",
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1298) le32_to_cpu(BHDR(bh)->h_refcount));
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1299) }
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1300) out:
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1301) ext4_std_error(inode->i_sb, error);
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1302) return;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1303) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1304)
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1305) /*
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1306) * Find the available free space for EAs. This also returns the total number of
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1307) * bytes used by EA entries.
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1308) */
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1309) static size_t ext4_xattr_free_space(struct ext4_xattr_entry *last,
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1310) size_t *min_offs, void *base, int *total)
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1311) {
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1312) for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1313) if (!last->e_value_inum && last->e_value_size) {
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1314) size_t offs = le16_to_cpu(last->e_value_offs);
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1315) if (offs < *min_offs)
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1316) *min_offs = offs;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1317) }
7b1b2c1b9c397 (Theodore Ts'o 2014-02-19 20:15:21 -0500 1318) if (total)
7b1b2c1b9c397 (Theodore Ts'o 2014-02-19 20:15:21 -0500 1319) *total += EXT4_XATTR_LEN(last->e_name_len);
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1320) }
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1321) return (*min_offs - ((void *)last - base) - sizeof(__u32));
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1322) }
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 1323)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1324) /*
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1325) * Write the value of the EA in an inode.
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1326) */
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1327) static int ext4_xattr_inode_write(handle_t *handle, struct inode *ea_inode,
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1328) const void *buf, int bufsize)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1329) {
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1330) struct buffer_head *bh = NULL;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1331) unsigned long block = 0;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1332) int blocksize = ea_inode->i_sb->s_blocksize;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1333) int max_blocks = (bufsize + blocksize - 1) >> ea_inode->i_blkbits;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1334) int csize, wsize = 0;
4209ae12b1226 (Harshad Shirwadkar 2020-04-26 18:34:37 -0700 1335) int ret = 0, ret2 = 0;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1336) int retries = 0;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1337)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1338) retry:
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1339) while (ret >= 0 && ret < max_blocks) {
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1340) struct ext4_map_blocks map;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1341) map.m_lblk = block += ret;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1342) map.m_len = max_blocks -= ret;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1343)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1344) ret = ext4_map_blocks(handle, ea_inode, &map,
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1345) EXT4_GET_BLOCKS_CREATE);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1346) if (ret <= 0) {
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1347) ext4_mark_inode_dirty(handle, ea_inode);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1348) if (ret == -ENOSPC &&
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1349) ext4_should_retry_alloc(ea_inode->i_sb, &retries)) {
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1350) ret = 0;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1351) goto retry;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1352) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1353) break;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1354) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1355) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1356)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1357) if (ret < 0)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1358) return ret;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1359)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1360) block = 0;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1361) while (wsize < bufsize) {
e0f49d270d9d0 (Markus Elfring 2020-06-13 19:12:24 +0200 1362) brelse(bh);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1363) csize = (bufsize - wsize) > blocksize ? blocksize :
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1364) bufsize - wsize;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1365) bh = ext4_getblk(handle, ea_inode, block, 0);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1366) if (IS_ERR(bh))
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1367) return PTR_ERR(bh);
eb6984fa4ce28 (Vasily Averin 2018-11-09 11:34:40 -0500 1368) if (!bh) {
eb6984fa4ce28 (Vasily Averin 2018-11-09 11:34:40 -0500 1369) WARN_ON_ONCE(1);
eb6984fa4ce28 (Vasily Averin 2018-11-09 11:34:40 -0500 1370) EXT4_ERROR_INODE(ea_inode,
eb6984fa4ce28 (Vasily Averin 2018-11-09 11:34:40 -0500 1371) "ext4_getblk() return bh = NULL");
eb6984fa4ce28 (Vasily Averin 2018-11-09 11:34:40 -0500 1372) return -EFSCORRUPTED;
eb6984fa4ce28 (Vasily Averin 2018-11-09 11:34:40 -0500 1373) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1374) ret = ext4_journal_get_write_access(handle, bh);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1375) if (ret)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1376) goto out;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1377)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1378) memcpy(bh->b_data, buf, csize);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1379) set_buffer_uptodate(bh);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1380) ext4_handle_dirty_metadata(handle, ea_inode, bh);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1381)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1382) buf += csize;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1383) wsize += csize;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1384) block += 1;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1385) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1386)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1387) inode_lock(ea_inode);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1388) i_size_write(ea_inode, wsize);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1389) ext4_update_i_disksize(ea_inode, wsize);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1390) inode_unlock(ea_inode);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1391)
4209ae12b1226 (Harshad Shirwadkar 2020-04-26 18:34:37 -0700 1392) ret2 = ext4_mark_inode_dirty(handle, ea_inode);
4209ae12b1226 (Harshad Shirwadkar 2020-04-26 18:34:37 -0700 1393) if (unlikely(ret2 && !ret))
4209ae12b1226 (Harshad Shirwadkar 2020-04-26 18:34:37 -0700 1394) ret = ret2;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1395)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1396) out:
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1397) brelse(bh);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1398)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1399) return ret;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1400) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1401)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1402) /*
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1403) * Create an inode to store the value of a large EA.
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1404) */
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1405) static struct inode *ext4_xattr_inode_create(handle_t *handle,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1406) struct inode *inode, u32 hash)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1407) {
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1408) struct inode *ea_inode = NULL;
9e1ba00161a6f (Tahsin Erdogan 2017-06-21 21:27:00 -0400 1409) uid_t owner[2] = { i_uid_read(inode), i_gid_read(inode) };
bd3b963b273e2 (Tahsin Erdogan 2017-06-21 21:24:31 -0400 1410) int err;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1411)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1412) /*
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1413) * Let the next inode be the goal, so we try and allocate the EA inode
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1414) * in the same group, or nearby one.
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1415) */
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1416) ea_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode,
9e1ba00161a6f (Tahsin Erdogan 2017-06-21 21:27:00 -0400 1417) S_IFREG | 0600, NULL, inode->i_ino + 1, owner,
1b917ed8ae0d4 (Tahsin Erdogan 2017-06-21 21:21:39 -0400 1418) EXT4_EA_INODE_FL);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1419) if (!IS_ERR(ea_inode)) {
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1420) ea_inode->i_op = &ext4_file_inode_operations;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1421) ea_inode->i_fop = &ext4_file_operations;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1422) ext4_set_aops(ea_inode);
33d201e0277b2 (Tahsin Erdogan 2017-06-21 21:17:10 -0400 1423) ext4_xattr_inode_set_class(ea_inode);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1424) unlock_new_inode(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1425) ext4_xattr_inode_set_ref(ea_inode, 1);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1426) ext4_xattr_inode_set_hash(ea_inode, hash);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1427) err = ext4_mark_inode_dirty(handle, ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1428) if (!err)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1429) err = ext4_inode_attach_jinode(ea_inode);
bd3b963b273e2 (Tahsin Erdogan 2017-06-21 21:24:31 -0400 1430) if (err) {
bd3b963b273e2 (Tahsin Erdogan 2017-06-21 21:24:31 -0400 1431) iput(ea_inode);
bd3b963b273e2 (Tahsin Erdogan 2017-06-21 21:24:31 -0400 1432) return ERR_PTR(err);
bd3b963b273e2 (Tahsin Erdogan 2017-06-21 21:24:31 -0400 1433) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1434)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1435) /*
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1436) * Xattr inodes are shared therefore quota charging is performed
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1437) * at a higher level.
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1438) */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1439) dquot_free_inode(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1440) dquot_drop(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1441) inode_lock(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1442) ea_inode->i_flags |= S_NOQUOTA;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1443) inode_unlock(ea_inode);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1444) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1445)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1446) return ea_inode;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1447) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1448)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1449) static struct inode *
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1450) ext4_xattr_inode_cache_find(struct inode *inode, const void *value,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1451) size_t value_len, u32 hash)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1452) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1453) struct inode *ea_inode;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1454) struct mb_cache_entry *ce;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1455) struct mb_cache *ea_inode_cache = EA_INODE_CACHE(inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1456) void *ea_data;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1457)
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1458) if (!ea_inode_cache)
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1459) return NULL;
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1460)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1461) ce = mb_cache_entry_find_first(ea_inode_cache, hash);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1462) if (!ce)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1463) return NULL;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1464)
163f0ec1df33c (Jan Kara 2021-02-22 18:16:26 +0100 1465) WARN_ON_ONCE(ext4_handle_valid(journal_current_handle()) &&
163f0ec1df33c (Jan Kara 2021-02-22 18:16:26 +0100 1466) !(current->flags & PF_MEMALLOC_NOFS));
163f0ec1df33c (Jan Kara 2021-02-22 18:16:26 +0100 1467)
71b565ceff377 (Theodore Ts'o 2020-01-16 10:08:16 -0500 1468) ea_data = kvmalloc(value_len, GFP_KERNEL);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1469) if (!ea_data) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1470) mb_cache_entry_put(ea_inode_cache, ce);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1471) return NULL;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1472) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1473)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1474) while (ce) {
8a363970d1dc3 (Theodore Ts'o 2018-12-19 12:29:13 -0500 1475) ea_inode = ext4_iget(inode->i_sb, ce->e_value,
8a363970d1dc3 (Theodore Ts'o 2018-12-19 12:29:13 -0500 1476) EXT4_IGET_NORMAL);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1477) if (!IS_ERR(ea_inode) &&
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1478) !is_bad_inode(ea_inode) &&
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1479) (EXT4_I(ea_inode)->i_flags & EXT4_EA_INODE_FL) &&
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1480) i_size_read(ea_inode) == value_len &&
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1481) !ext4_xattr_inode_read(ea_inode, ea_data, value_len) &&
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1482) !ext4_xattr_inode_verify_hashes(ea_inode, NULL, ea_data,
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1483) value_len) &&
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1484) !memcmp(value, ea_data, value_len)) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1485) mb_cache_entry_touch(ea_inode_cache, ce);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1486) mb_cache_entry_put(ea_inode_cache, ce);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1487) kvfree(ea_data);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1488) return ea_inode;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1489) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1490)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1491) if (!IS_ERR(ea_inode))
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1492) iput(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1493) ce = mb_cache_entry_find_next(ea_inode_cache, ce);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1494) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1495) kvfree(ea_data);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1496) return NULL;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1497) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1498)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1499) /*
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1500) * Add value of the EA in an inode.
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1501) */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1502) static int ext4_xattr_inode_lookup_create(handle_t *handle, struct inode *inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1503) const void *value, size_t value_len,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1504) struct inode **ret_inode)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1505) {
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1506) struct inode *ea_inode;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1507) u32 hash;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1508) int err;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1509)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1510) hash = ext4_xattr_inode_hash(EXT4_SB(inode->i_sb), value, value_len);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1511) ea_inode = ext4_xattr_inode_cache_find(inode, value, value_len, hash);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1512) if (ea_inode) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1513) err = ext4_xattr_inode_inc_ref(handle, ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1514) if (err) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1515) iput(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1516) return err;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1517) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1518)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1519) *ret_inode = ea_inode;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1520) return 0;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1521) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1522)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1523) /* Create an inode for the EA value */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1524) ea_inode = ext4_xattr_inode_create(handle, inode, hash);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1525) if (IS_ERR(ea_inode))
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1526) return PTR_ERR(ea_inode);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1527)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1528) err = ext4_xattr_inode_write(handle, ea_inode, value, value_len);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1529) if (err) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1530) ext4_xattr_inode_dec_ref(handle, ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1531) iput(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1532) return err;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1533) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1534)
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1535) if (EA_INODE_CACHE(inode))
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1536) mb_cache_entry_create(EA_INODE_CACHE(inode), GFP_NOFS, hash,
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1537) ea_inode->i_ino, true /* reusable */);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1538)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1539) *ret_inode = ea_inode;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1540) return 0;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1541) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1542)
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1543) /*
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1544) * Reserve min(block_size/8, 1024) bytes for xattr entries/names if ea_inode
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1545) * feature is enabled.
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1546) */
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1547) #define EXT4_XATTR_BLOCK_RESERVE(inode) min(i_blocksize(inode)/8, 1024U)
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1548)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1549) static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1550) struct ext4_xattr_search *s,
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 1551) handle_t *handle, struct inode *inode,
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 1552) bool is_block)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1553) {
5369a762c882c (Theodore Ts'o 2018-06-13 00:23:11 -0400 1554) struct ext4_xattr_entry *last, *next;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1555) struct ext4_xattr_entry *here = s->here;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1556) size_t min_offs = s->end - s->base, name_len = strlen(i->name);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1557) int in_inode = i->in_inode;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1558) struct inode *old_ea_inode = NULL;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1559) struct inode *new_ea_inode = NULL;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1560) size_t old_size, new_size;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1561) int ret;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1562)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1563) /* Space used by old and new values. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1564) old_size = (!s->not_found && !here->e_value_inum) ?
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1565) EXT4_XATTR_SIZE(le32_to_cpu(here->e_value_size)) : 0;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1566) new_size = (i->value && !in_inode) ? EXT4_XATTR_SIZE(i->value_len) : 0;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1567)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1568) /*
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1569) * Optimization for the simple case when old and new values have the
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1570) * same padded sizes. Not applicable if external inodes are involved.
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1571) */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1572) if (new_size && new_size == old_size) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1573) size_t offs = le16_to_cpu(here->e_value_offs);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1574) void *val = s->base + offs;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1575)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1576) here->e_value_size = cpu_to_le32(i->value_len);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1577) if (i->value == EXT4_ZERO_XATTR_VALUE) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1578) memset(val, 0, new_size);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1579) } else {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1580) memcpy(val, i->value, i->value_len);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1581) /* Clear padding bytes. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1582) memset(val + i->value_len, 0, new_size - i->value_len);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1583) }
32aaf194201e9 (Tahsin Erdogan 2017-08-14 08:30:06 -0400 1584) goto update_hash;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1585) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1586)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1587) /* Compute min_offs and last. */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1588) last = s->first;
5369a762c882c (Theodore Ts'o 2018-06-13 00:23:11 -0400 1589) for (; !IS_LAST_ENTRY(last); last = next) {
5369a762c882c (Theodore Ts'o 2018-06-13 00:23:11 -0400 1590) next = EXT4_XATTR_NEXT(last);
5369a762c882c (Theodore Ts'o 2018-06-13 00:23:11 -0400 1591) if ((void *)next >= s->end) {
5369a762c882c (Theodore Ts'o 2018-06-13 00:23:11 -0400 1592) EXT4_ERROR_INODE(inode, "corrupted xattr entries");
5369a762c882c (Theodore Ts'o 2018-06-13 00:23:11 -0400 1593) ret = -EFSCORRUPTED;
5369a762c882c (Theodore Ts'o 2018-06-13 00:23:11 -0400 1594) goto out;
5369a762c882c (Theodore Ts'o 2018-06-13 00:23:11 -0400 1595) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1596) if (!last->e_value_inum && last->e_value_size) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1597) size_t offs = le16_to_cpu(last->e_value_offs);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1598) if (offs < min_offs)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1599) min_offs = offs;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1600) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1601) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1602)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1603) /* Check whether we have enough space. */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1604) if (i->value) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1605) size_t free;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1606)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1607) free = min_offs - ((void *)last - s->base) - sizeof(__u32);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1608) if (!s->not_found)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1609) free += EXT4_XATTR_LEN(name_len) + old_size;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1610)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1611) if (free < EXT4_XATTR_LEN(name_len) + new_size) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1612) ret = -ENOSPC;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1613) goto out;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1614) }
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1615)
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1616) /*
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1617) * If storing the value in an external inode is an option,
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1618) * reserve space for xattr entries/names in the external
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1619) * attribute block so that a long value does not occupy the
3088e5a5153cd (Bhaskar Chowdhury 2021-03-27 16:00:05 +0530 1620) * whole space and prevent further entries being added.
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1621) */
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 1622) if (ext4_has_feature_ea_inode(inode->i_sb) &&
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 1623) new_size && is_block &&
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1624) (min_offs + old_size - new_size) <
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1625) EXT4_XATTR_BLOCK_RESERVE(inode)) {
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1626) ret = -ENOSPC;
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1627) goto out;
9c6e7853c531c (Tahsin Erdogan 2017-06-22 11:48:53 -0400 1628) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1629) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1630)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1631) /*
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1632) * Getting access to old and new ea inodes is subject to failures.
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1633) * Finish that work before doing any modifications to the xattr data.
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1634) */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1635) if (!s->not_found && here->e_value_inum) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1636) ret = ext4_xattr_inode_iget(inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1637) le32_to_cpu(here->e_value_inum),
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1638) le32_to_cpu(here->e_hash),
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1639) &old_ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1640) if (ret) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1641) old_ea_inode = NULL;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1642) goto out;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1643) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1644) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1645) if (i->value && in_inode) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1646) WARN_ON_ONCE(!i->value_len);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1647)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1648) ret = ext4_xattr_inode_alloc_quota(inode, i->value_len);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1649) if (ret)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1650) goto out;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1651)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1652) ret = ext4_xattr_inode_lookup_create(handle, inode, i->value,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1653) i->value_len,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1654) &new_ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1655) if (ret) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1656) new_ea_inode = NULL;
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1657) ext4_xattr_inode_free_quota(inode, NULL, i->value_len);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1658) goto out;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1659) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1660) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1661)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1662) if (old_ea_inode) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1663) /* We are ready to release ref count on the old_ea_inode. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1664) ret = ext4_xattr_inode_dec_ref(handle, old_ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1665) if (ret) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1666) /* Release newly required ref count on new_ea_inode. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1667) if (new_ea_inode) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1668) int err;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1669)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1670) err = ext4_xattr_inode_dec_ref(handle,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1671) new_ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1672) if (err)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1673) ext4_warning_inode(new_ea_inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1674) "dec ref new_ea_inode err=%d",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1675) err);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1676) ext4_xattr_inode_free_quota(inode, new_ea_inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1677) i->value_len);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1678) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1679) goto out;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1680) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1681)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1682) ext4_xattr_inode_free_quota(inode, old_ea_inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1683) le32_to_cpu(here->e_value_size));
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1684) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1685)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1686) /* No failures allowed past this point. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1687)
e5d01196c0428 (Theodore Ts'o 2019-04-10 00:37:36 -0400 1688) if (!s->not_found && here->e_value_size && !here->e_value_inum) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1689) /* Remove the old value. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1690) void *first_val = s->base + min_offs;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1691) size_t offs = le16_to_cpu(here->e_value_offs);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1692) void *val = s->base + offs;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1693)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1694) memmove(first_val + old_size, first_val, val - first_val);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1695) memset(first_val, 0, old_size);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1696) min_offs += old_size;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1697)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1698) /* Adjust all value offsets. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1699) last = s->first;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1700) while (!IS_LAST_ENTRY(last)) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1701) size_t o = le16_to_cpu(last->e_value_offs);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1702)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1703) if (!last->e_value_inum &&
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1704) last->e_value_size && o < offs)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1705) last->e_value_offs = cpu_to_le16(o + old_size);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1706) last = EXT4_XATTR_NEXT(last);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1707) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1708) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1709)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1710) if (!i->value) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1711) /* Remove old name. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1712) size_t size = EXT4_XATTR_LEN(name_len);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1713)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1714) last = ENTRY((void *)last - size);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1715) memmove(here, (void *)here + size,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1716) (void *)last - (void *)here + sizeof(__u32));
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1717) memset(last, 0, size);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1718) } else if (s->not_found) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1719) /* Insert new name. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1720) size_t size = EXT4_XATTR_LEN(name_len);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1721) size_t rest = (void *)last - (void *)here + sizeof(__u32);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1722)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1723) memmove((void *)here + size, here, rest);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1724) memset(here, 0, size);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1725) here->e_name_index = i->name_index;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1726) here->e_name_len = name_len;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1727) memcpy(here->e_name, i->name, name_len);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1728) } else {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1729) /* This is an update, reset value info. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1730) here->e_value_inum = 0;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1731) here->e_value_offs = 0;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1732) here->e_value_size = 0;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1733) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1734)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1735) if (i->value) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1736) /* Insert new value. */
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1737) if (in_inode) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1738) here->e_value_inum = cpu_to_le32(new_ea_inode->i_ino);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1739) } else if (i->value_len) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1740) void *val = s->base + min_offs - new_size;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1741)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1742) here->e_value_offs = cpu_to_le16(min_offs - new_size);
bd9926e80330d (Theodore Ts'o 2012-12-11 03:31:49 -0500 1743) if (i->value == EXT4_ZERO_XATTR_VALUE) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1744) memset(val, 0, new_size);
bd9926e80330d (Theodore Ts'o 2012-12-11 03:31:49 -0500 1745) } else {
bd9926e80330d (Theodore Ts'o 2012-12-11 03:31:49 -0500 1746) memcpy(val, i->value, i->value_len);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1747) /* Clear padding bytes. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1748) memset(val + i->value_len, 0,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1749) new_size - i->value_len);
bd9926e80330d (Theodore Ts'o 2012-12-11 03:31:49 -0500 1750) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1751) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1752) here->e_value_size = cpu_to_le32(i->value_len);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1753) }
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 1754)
32aaf194201e9 (Tahsin Erdogan 2017-08-14 08:30:06 -0400 1755) update_hash:
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1756) if (i->value) {
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1757) __le32 hash = 0;
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1758)
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1759) /* Entry hash calculation. */
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1760) if (in_inode) {
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1761) __le32 crc32c_hash;
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1762)
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1763) /*
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1764) * Feed crc32c hash instead of the raw value for entry
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1765) * hash calculation. This is to avoid walking
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1766) * potentially long value buffer again.
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1767) */
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1768) crc32c_hash = cpu_to_le32(
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1769) ext4_xattr_inode_get_hash(new_ea_inode));
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1770) hash = ext4_xattr_hash_entry(here->e_name,
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1771) here->e_name_len,
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1772) &crc32c_hash, 1);
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1773) } else if (is_block) {
32aaf194201e9 (Tahsin Erdogan 2017-08-14 08:30:06 -0400 1774) __le32 *value = s->base + le16_to_cpu(
32aaf194201e9 (Tahsin Erdogan 2017-08-14 08:30:06 -0400 1775) here->e_value_offs);
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1776)
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1777) hash = ext4_xattr_hash_entry(here->e_name,
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1778) here->e_name_len, value,
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1779) new_size >> 2);
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1780) }
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1781) here->e_hash = hash;
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 1782) }
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 1783)
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1784) if (is_block)
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1785) ext4_xattr_rehash((struct ext4_xattr_header *)s->base);
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 1786)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1787) ret = 0;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 1788) out:
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1789) iput(old_ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1790) iput(new_ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1791) return ret;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1792) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1793)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 1794) struct ext4_xattr_block_find {
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 1795) struct ext4_xattr_search s;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1796) struct buffer_head *bh;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1797) };
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1798)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1799) static int
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 1800) ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i,
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 1801) struct ext4_xattr_block_find *bs)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1802) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1803) struct super_block *sb = inode->i_sb;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1804) int error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1805)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1806) ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1807) i->name_index, i->name, i->value, (long)i->value_len);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1808)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 1809) if (EXT4_I(inode)->i_file_acl) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1810) /* The inode already has an extended attribute block. */
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 1811) bs->bh = ext4_sb_bread(sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
8418897f1bf87 (Jeffle Xu 2020-04-23 15:46:44 +0800 1812) if (IS_ERR(bs->bh)) {
8418897f1bf87 (Jeffle Xu 2020-04-23 15:46:44 +0800 1813) error = PTR_ERR(bs->bh);
8418897f1bf87 (Jeffle Xu 2020-04-23 15:46:44 +0800 1814) bs->bh = NULL;
8418897f1bf87 (Jeffle Xu 2020-04-23 15:46:44 +0800 1815) return error;
8418897f1bf87 (Jeffle Xu 2020-04-23 15:46:44 +0800 1816) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1817) ea_bdebug(bs->bh, "b_count=%d, refcount=%d",
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1818) atomic_read(&(bs->bh->b_count)),
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1819) le32_to_cpu(BHDR(bs->bh)->h_refcount));
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 1820) error = ext4_xattr_check_block(inode, bs->bh);
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 1821) if (error)
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 1822) return error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1823) /* Find the named attribute. */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1824) bs->s.base = BHDR(bs->bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1825) bs->s.first = BFIRST(bs->bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1826) bs->s.end = bs->bh->b_data + bs->bh->b_size;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1827) bs->s.here = bs->s.first;
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 1828) error = xattr_find_entry(inode, &bs->s.here, bs->s.end,
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 1829) i->name_index, i->name, 1);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1830) if (error && error != -ENODATA)
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 1831) return error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1832) bs->s.not_found = error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1833) }
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 1834) return 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1835) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1836)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1837) static int
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 1838) ext4_xattr_block_set(handle_t *handle, struct inode *inode,
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 1839) struct ext4_xattr_info *i,
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 1840) struct ext4_xattr_block_find *bs)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1841) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1842) struct super_block *sb = inode->i_sb;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1843) struct buffer_head *new_bh = NULL;
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 1844) struct ext4_xattr_search s_copy = bs->s;
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 1845) struct ext4_xattr_search *s = &s_copy;
7a2508e1b657c (Jan Kara 2016-02-22 22:35:22 -0500 1846) struct mb_cache_entry *ce = NULL;
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1847) int error = 0;
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 1848) struct mb_cache *ea_block_cache = EA_BLOCK_CACHE(inode);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1849) struct inode *ea_inode = NULL, *tmp_inode;
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1850) size_t old_ea_inode_quota = 0;
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1851) unsigned int ea_ino;
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1852)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1853)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 1854) #define header(x) ((struct ext4_xattr_header *)(x))
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1855)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1856) if (s->base) {
5d60125530b01 (liang xie 2014-05-12 22:06:43 -0400 1857) BUFFER_TRACE(bs->bh, "get_write_access");
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1858) error = ext4_journal_get_write_access(handle, bs->bh);
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1859) if (error)
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1860) goto cleanup;
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1861) lock_buffer(bs->bh);
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1862)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1863) if (header(s->base)->h_refcount == cpu_to_le32(1)) {
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 1864) __u32 hash = le32_to_cpu(BHDR(bs->bh)->h_hash);
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 1865)
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 1866) /*
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 1867) * This must happen under buffer lock for
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 1868) * ext4_xattr_block_set() to reliably detect modified
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 1869) * block
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 1870) */
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1871) if (ea_block_cache)
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1872) mb_cache_entry_delete(ea_block_cache, hash,
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 1873) bs->bh->b_blocknr);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1874) ea_bdebug(bs->bh, "modifying in-place");
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 1875) error = ext4_xattr_set_entry(i, s, handle, inode,
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 1876) true /* is_block */);
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 1877) ext4_xattr_block_csum_set(inode, bs->bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1878) unlock_buffer(bs->bh);
6a797d2737838 (Darrick J. Wong 2015-10-17 16:16:04 -0400 1879) if (error == -EFSCORRUPTED)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1880) goto bad_block;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1881) if (!error)
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 1882) error = ext4_handle_dirty_metadata(handle,
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 1883) inode,
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 1884) bs->bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1885) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1886) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1887) goto inserted;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1888) } else {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1889) int offset = (char *)s->here - bs->bh->b_data;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1890)
8a2bfdcbfa441 (Mingming Cao 2007-02-28 20:13:35 -0800 1891) unlock_buffer(bs->bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1892) ea_bdebug(bs->bh, "cloning");
216553c4b7f3e (Josef Bacik 2008-04-29 22:02:02 -0400 1893) s->base = kmalloc(bs->bh->b_size, GFP_NOFS);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1894) error = -ENOMEM;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1895) if (s->base == NULL)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1896) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1897) memcpy(s->base, BHDR(bs->bh), bs->bh->b_size);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1898) s->first = ENTRY(header(s->base)+1);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1899) header(s->base)->h_refcount = cpu_to_le32(1);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1900) s->here = ENTRY(s->base + offset);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1901) s->end = s->base + bs->bh->b_size;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1902)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1903) /*
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1904) * If existing entry points to an xattr inode, we need
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1905) * to prevent ext4_xattr_set_entry() from decrementing
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1906) * ref count on it because the reference belongs to the
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1907) * original block. In this case, make the entry look
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1908) * like it has an empty value.
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1909) */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1910) if (!s->not_found && s->here->e_value_inum) {
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1911) ea_ino = le32_to_cpu(s->here->e_value_inum);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1912) error = ext4_xattr_inode_iget(inode, ea_ino,
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1913) le32_to_cpu(s->here->e_hash),
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1914) &tmp_inode);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1915) if (error)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1916) goto cleanup;
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1917)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1918) if (!ext4_test_inode_state(tmp_inode,
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1919) EXT4_STATE_LUSTRE_EA_INODE)) {
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1920) /*
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1921) * Defer quota free call for previous
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1922) * inode until success is guaranteed.
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1923) */
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1924) old_ea_inode_quota = le32_to_cpu(
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1925) s->here->e_value_size);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1926) }
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1927) iput(tmp_inode);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1928)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1929) s->here->e_value_inum = 0;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1930) s->here->e_value_size = 0;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1931) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1932) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1933) } else {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1934) /* Allocate a buffer where we construct the new block. */
216553c4b7f3e (Josef Bacik 2008-04-29 22:02:02 -0400 1935) s->base = kzalloc(sb->s_blocksize, GFP_NOFS);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1936) error = -ENOMEM;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1937) if (s->base == NULL)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1938) goto cleanup;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 1939) header(s->base)->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1940) header(s->base)->h_blocks = cpu_to_le32(1);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1941) header(s->base)->h_refcount = cpu_to_le32(1);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1942) s->first = ENTRY(header(s->base)+1);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1943) s->here = ENTRY(header(s->base)+1);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1944) s->end = s->base + sb->s_blocksize;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1945) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1946)
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 1947) error = ext4_xattr_set_entry(i, s, handle, inode, true /* is_block */);
6a797d2737838 (Darrick J. Wong 2015-10-17 16:16:04 -0400 1948) if (error == -EFSCORRUPTED)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1949) goto bad_block;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1950) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1951) goto cleanup;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1952)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1953) if (i->value && s->here->e_value_inum) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1954) /*
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1955) * A ref count on ea_inode has been taken as part of the call to
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1956) * ext4_xattr_set_entry() above. We would like to drop this
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1957) * extra ref but we have to wait until the xattr block is
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1958) * initialized and has its own ref count on the ea_inode.
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1959) */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1960) ea_ino = le32_to_cpu(s->here->e_value_inum);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1961) error = ext4_xattr_inode_iget(inode, ea_ino,
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1962) le32_to_cpu(s->here->e_hash),
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 1963) &ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1964) if (error) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1965) ea_inode = NULL;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1966) goto cleanup;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1967) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1968) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 1969)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1970) inserted:
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1971) if (!IS_LAST_ENTRY(s->first)) {
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 1972) new_bh = ext4_xattr_block_cache_find(inode, header(s->base),
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 1973) &ce);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1974) if (new_bh) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1975) /* We found an identical block in the cache. */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1976) if (new_bh == bs->bh)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1977) ea_bdebug(new_bh, "keeping");
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1978) else {
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1979) u32 ref;
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1980)
b8cb5a545c3dd (Tahsin Erdogan 2017-05-24 18:24:07 -0400 1981) WARN_ON_ONCE(dquot_initialize_needed(inode));
b8cb5a545c3dd (Tahsin Erdogan 2017-05-24 18:24:07 -0400 1982)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1983) /* The old block is released after updating
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1984) the inode. */
1231b3a1eb574 (Lukas Czerner 2013-02-18 12:12:07 -0500 1985) error = dquot_alloc_block(inode,
1231b3a1eb574 (Lukas Czerner 2013-02-18 12:12:07 -0500 1986) EXT4_C2B(EXT4_SB(sb), 1));
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 1987) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1988) goto cleanup;
5d60125530b01 (liang xie 2014-05-12 22:06:43 -0400 1989) BUFFER_TRACE(new_bh, "get_write_access");
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 1990) error = ext4_journal_get_write_access(handle,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1991) new_bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1992) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1993) goto cleanup_dquot;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 1994) lock_buffer(new_bh);
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 1995) /*
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 1996) * We have to be careful about races with
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1997) * freeing, rehashing or adding references to
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1998) * xattr block. Once we hold buffer lock xattr
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 1999) * block's state is stable so we can check
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2000) * whether the block got freed / rehashed or
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2001) * not. Since we unhash mbcache entry under
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2002) * buffer lock when freeing / rehashing xattr
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2003) * block, checking whether entry is still
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2004) * hashed is reliable. Same rules hold for
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2005) * e_reusable handling.
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2006) */
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2007) if (hlist_bl_unhashed(&ce->e_hash_list) ||
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2008) !ce->e_reusable) {
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2009) /*
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2010) * Undo everything and check mbcache
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2011) * again.
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2012) */
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2013) unlock_buffer(new_bh);
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2014) dquot_free_block(inode,
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2015) EXT4_C2B(EXT4_SB(sb),
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2016) 1));
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2017) brelse(new_bh);
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 2018) mb_cache_entry_put(ea_block_cache, ce);
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2019) ce = NULL;
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2020) new_bh = NULL;
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2021) goto inserted;
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2022) }
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2023) ref = le32_to_cpu(BHDR(new_bh)->h_refcount) + 1;
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2024) BHDR(new_bh)->h_refcount = cpu_to_le32(ref);
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2025) if (ref >= EXT4_XATTR_REFCOUNT_MAX)
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2026) ce->e_reusable = 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2027) ea_bdebug(new_bh, "reusing; refcount now=%d",
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2028) ref);
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 2029) ext4_xattr_block_csum_set(inode, new_bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2030) unlock_buffer(new_bh);
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 2031) error = ext4_handle_dirty_metadata(handle,
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 2032) inode,
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 2033) new_bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2034) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2035) goto cleanup_dquot;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2036) }
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 2037) mb_cache_entry_touch(ea_block_cache, ce);
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 2038) mb_cache_entry_put(ea_block_cache, ce);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2039) ce = NULL;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2040) } else if (bs->bh && s->base == bs->bh->b_data) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2041) /* We were modifying this block in-place. */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2042) ea_bdebug(bs->bh, "keeping this block");
ec00022030da5 (Tahsin Erdogan 2017-08-05 22:41:42 -0400 2043) ext4_xattr_block_cache_insert(ea_block_cache, bs->bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2044) new_bh = bs->bh;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2045) get_bh(new_bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2046) } else {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2047) /* We need to allocate a new block */
fb0a387dcdcd2 (Eric Sandeen 2009-09-16 14:45:10 -0400 2048) ext4_fsblk_t goal, block;
fb0a387dcdcd2 (Eric Sandeen 2009-09-16 14:45:10 -0400 2049)
b8cb5a545c3dd (Tahsin Erdogan 2017-05-24 18:24:07 -0400 2050) WARN_ON_ONCE(dquot_initialize_needed(inode));
b8cb5a545c3dd (Tahsin Erdogan 2017-05-24 18:24:07 -0400 2051)
fb0a387dcdcd2 (Eric Sandeen 2009-09-16 14:45:10 -0400 2052) goal = ext4_group_first_block_no(sb,
d00a6d7b40b44 (Akinobu Mita 2008-04-17 10:38:59 -0400 2053) EXT4_I(inode)->i_block_group);
fb0a387dcdcd2 (Eric Sandeen 2009-09-16 14:45:10 -0400 2054)
fb0a387dcdcd2 (Eric Sandeen 2009-09-16 14:45:10 -0400 2055) /* non-extent files can't have physical blocks past 2^32 */
12e9b892002d9 (Dmitry Monakhov 2010-05-16 22:00:00 -0400 2056) if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
fb0a387dcdcd2 (Eric Sandeen 2009-09-16 14:45:10 -0400 2057) goal = goal & EXT4_MAX_BLOCK_FILE_PHYS;
fb0a387dcdcd2 (Eric Sandeen 2009-09-16 14:45:10 -0400 2058)
55f020db66ce1 (Allison Henderson 2011-05-25 07:41:26 -0400 2059) block = ext4_new_meta_blocks(handle, inode, goal, 0,
55f020db66ce1 (Allison Henderson 2011-05-25 07:41:26 -0400 2060) NULL, &error);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2061) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2062) goto cleanup;
fb0a387dcdcd2 (Eric Sandeen 2009-09-16 14:45:10 -0400 2063)
12e9b892002d9 (Dmitry Monakhov 2010-05-16 22:00:00 -0400 2064) if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
fb0a387dcdcd2 (Eric Sandeen 2009-09-16 14:45:10 -0400 2065) BUG_ON(block > EXT4_MAX_BLOCK_FILE_PHYS);
fb0a387dcdcd2 (Eric Sandeen 2009-09-16 14:45:10 -0400 2066)
ace36ad431c68 (Joe Perches 2012-03-19 23:11:43 -0400 2067) ea_idebug(inode, "creating block %llu",
ace36ad431c68 (Joe Perches 2012-03-19 23:11:43 -0400 2068) (unsigned long long)block);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2069)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2070) new_bh = sb_getblk(sb, block);
aebf02430d25b (Wang Shilong 2013-01-12 16:28:47 -0500 2071) if (unlikely(!new_bh)) {
860d21e2c585f (Theodore Ts'o 2013-01-12 16:19:36 -0500 2072) error = -ENOMEM;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2073) getblk_failed:
7dc576158d7e5 (Peter Huewe 2011-02-21 21:01:42 -0500 2074) ext4_free_blocks(handle, inode, NULL, block, 1,
e6362609b6c71 (Theodore Ts'o 2009-11-23 07:17:05 -0500 2075) EXT4_FREE_BLOCKS_METADATA);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2076) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2077) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2078) error = ext4_xattr_inode_inc_ref_all(handle, inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2079) ENTRY(header(s->base)+1));
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2080) if (error)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2081) goto getblk_failed;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2082) if (ea_inode) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2083) /* Drop the extra ref on ea_inode. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2084) error = ext4_xattr_inode_dec_ref(handle,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2085) ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2086) if (error)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2087) ext4_warning_inode(ea_inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2088) "dec ref error=%d",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2089) error);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2090) iput(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2091) ea_inode = NULL;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2092) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2093)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2094) lock_buffer(new_bh);
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2095) error = ext4_journal_get_create_access(handle, new_bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2096) if (error) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2097) unlock_buffer(new_bh);
860d21e2c585f (Theodore Ts'o 2013-01-12 16:19:36 -0500 2098) error = -EIO;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2099) goto getblk_failed;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2100) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2101) memcpy(new_bh->b_data, s->base, new_bh->b_size);
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 2102) ext4_xattr_block_csum_set(inode, new_bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2103) set_buffer_uptodate(new_bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2104) unlock_buffer(new_bh);
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 2105) ext4_xattr_block_cache_insert(ea_block_cache, new_bh);
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 2106) error = ext4_handle_dirty_metadata(handle, inode,
dac7a4b4b1f66 (Theodore Ts'o 2017-03-25 17:22:47 -0400 2107) new_bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2108) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2109) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2110) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2111) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2112)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2113) if (old_ea_inode_quota)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2114) ext4_xattr_inode_free_quota(inode, NULL, old_ea_inode_quota);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2115)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2116) /* Update the inode. */
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2117) EXT4_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2118)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2119) /* Drop the previous xattr block. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2120) if (bs->bh && bs->bh != new_bh) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2121) struct ext4_xattr_inode_array *ea_inode_array = NULL;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2122)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2123) ext4_xattr_release_block(handle, inode, bs->bh,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2124) &ea_inode_array,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2125) 0 /* extra_credits */);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2126) ext4_xattr_inode_array_free(ea_inode_array);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2127) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2128) error = 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2129)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2130) cleanup:
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2131) if (ea_inode) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2132) int error2;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2133)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2134) error2 = ext4_xattr_inode_dec_ref(handle, ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2135) if (error2)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2136) ext4_warning_inode(ea_inode, "dec ref error=%d",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2137) error2);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2138)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2139) /* If there was an error, revert the quota charge. */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2140) if (error)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2141) ext4_xattr_inode_free_quota(inode, ea_inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2142) i_size_read(ea_inode));
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2143) iput(ea_inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2144) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2145) if (ce)
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 2146) mb_cache_entry_put(ea_block_cache, ce);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2147) brelse(new_bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2148) if (!(bs->bh && s->base == bs->bh->b_data))
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2149) kfree(s->base);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2150)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2151) return error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2152)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2153) cleanup_dquot:
1231b3a1eb574 (Lukas Czerner 2013-02-18 12:12:07 -0500 2154) dquot_free_block(inode, EXT4_C2B(EXT4_SB(sb), 1));
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2155) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2156)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2157) bad_block:
24676da469f50 (Theodore Ts'o 2010-05-16 21:00:00 -0400 2158) EXT4_ERROR_INODE(inode, "bad block %llu",
24676da469f50 (Theodore Ts'o 2010-05-16 21:00:00 -0400 2159) EXT4_I(inode)->i_file_acl);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2160) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2161)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2162) #undef header
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2163) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2164)
879b38257bf2b (Tao Ma 2012-12-05 10:28:46 -0500 2165) int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
879b38257bf2b (Tao Ma 2012-12-05 10:28:46 -0500 2166) struct ext4_xattr_ibody_find *is)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2167) {
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2168) struct ext4_xattr_ibody_header *header;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2169) struct ext4_inode *raw_inode;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2170) int error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2171)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2172) if (EXT4_I(inode)->i_extra_isize == 0)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2173) return 0;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2174) raw_inode = ext4_raw_inode(&is->iloc);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2175) header = IHDR(inode, raw_inode);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2176) is->s.base = is->s.first = IFIRST(header);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2177) is->s.here = is->s.first;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2178) is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
19f5fb7ad679b (Theodore Ts'o 2010-01-24 14:34:07 -0500 2179) if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) {
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 2180) error = xattr_check_inode(inode, header, is->s.end);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2181) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2182) return error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2183) /* Find the named attribute. */
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 2184) error = xattr_find_entry(inode, &is->s.here, is->s.end,
9496005d6ca4c (Theodore Ts'o 2018-03-30 20:00:56 -0400 2185) i->name_index, i->name, 0);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2186) if (error && error != -ENODATA)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2187) return error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2188) is->s.not_found = error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2189) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2190) return 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2191) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2192)
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2193) int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode,
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2194) struct ext4_xattr_info *i,
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2195) struct ext4_xattr_ibody_find *is)
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2196) {
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2197) struct ext4_xattr_ibody_header *header;
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2198) struct ext4_xattr_search *s = &is->s;
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2199) int error;
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2200)
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2201) if (EXT4_I(inode)->i_extra_isize == 0)
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2202) return -ENOSPC;
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 2203) error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */);
8bc1379b82b8e (Theodore Ts'o 2018-06-16 23:41:59 -0400 2204) if (error)
8bc1379b82b8e (Theodore Ts'o 2018-06-16 23:41:59 -0400 2205) return error;
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2206) header = IHDR(inode, ext4_raw_inode(&is->iloc));
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2207) if (!IS_LAST_ENTRY(s->first)) {
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2208) header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2209) ext4_set_inode_state(inode, EXT4_STATE_XATTR);
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2210) } else {
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2211) header->h_magic = cpu_to_le32(0);
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2212) ext4_clear_inode_state(inode, EXT4_STATE_XATTR);
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2213) }
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2214) return 0;
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2215) }
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2216)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2217) static int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2218) struct ext4_xattr_info *i,
0d812f77b36c1 (Tao Ma 2012-12-10 14:06:02 -0500 2219) struct ext4_xattr_ibody_find *is)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2220) {
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2221) struct ext4_xattr_ibody_header *header;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2222) struct ext4_xattr_search *s = &is->s;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2223) int error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2224)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2225) if (EXT4_I(inode)->i_extra_isize == 0)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2226) return -ENOSPC;
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 2227) error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2228) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2229) return error;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2230) header = IHDR(inode, ext4_raw_inode(&is->iloc));
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2231) if (!IS_LAST_ENTRY(s->first)) {
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2232) header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
19f5fb7ad679b (Theodore Ts'o 2010-01-24 14:34:07 -0500 2233) ext4_set_inode_state(inode, EXT4_STATE_XATTR);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2234) } else {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2235) header->h_magic = cpu_to_le32(0);
19f5fb7ad679b (Theodore Ts'o 2010-01-24 14:34:07 -0500 2236) ext4_clear_inode_state(inode, EXT4_STATE_XATTR);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2237) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2238) return 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2239) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2240)
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2241) static int ext4_xattr_value_same(struct ext4_xattr_search *s,
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2242) struct ext4_xattr_info *i)
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2243) {
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2244) void *value;
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2245)
0bd454c04f02e (Tahsin Erdogan 2017-06-21 22:02:06 -0400 2246) /* When e_value_inum is set the value is stored externally. */
0bd454c04f02e (Tahsin Erdogan 2017-06-21 22:02:06 -0400 2247) if (s->here->e_value_inum)
0bd454c04f02e (Tahsin Erdogan 2017-06-21 22:02:06 -0400 2248) return 0;
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2249) if (le32_to_cpu(s->here->e_value_size) != i->value_len)
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2250) return 0;
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2251) value = ((void *)s->base) + le16_to_cpu(s->here->e_value_offs);
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2252) return !memcmp(value, i->value, i->value_len);
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2253) }
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2254)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2255) static struct buffer_head *ext4_xattr_get_block(struct inode *inode)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2256) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2257) struct buffer_head *bh;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2258) int error;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2259)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2260) if (!EXT4_I(inode)->i_file_acl)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2261) return NULL;
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 2262) bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 2263) if (IS_ERR(bh))
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 2264) return bh;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2265) error = ext4_xattr_check_block(inode, bh);
ecaaf408478b6 (Vasily Averin 2018-11-07 11:01:33 -0500 2266) if (error) {
ecaaf408478b6 (Vasily Averin 2018-11-07 11:01:33 -0500 2267) brelse(bh);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2268) return ERR_PTR(error);
ecaaf408478b6 (Vasily Averin 2018-11-07 11:01:33 -0500 2269) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2270) return bh;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2271) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2272)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2273) /*
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2274) * ext4_xattr_set_handle()
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2275) *
6e9510b0e0de6 (Wang Sheng-Hui 2011-01-10 12:10:30 -0500 2276) * Create, replace or remove an extended attribute for this inode. Value
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2277) * is NULL to remove an existing extended attribute, and non-NULL to
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2278) * either replace an existing extended attribute, or create a new extended
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2279) * attribute. The flags XATTR_REPLACE and XATTR_CREATE
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2280) * specify that an extended attribute must exist and must not exist
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2281) * previous to the call, respectively.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2282) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2283) * Returns 0, or a negative error number on failure.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2284) */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2285) int
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2286) ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2287) const char *name, const void *value, size_t value_len,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2288) int flags)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2289) {
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2290) struct ext4_xattr_info i = {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2291) .name_index = name_index,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2292) .name = name,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2293) .value = value,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2294) .value_len = value_len,
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2295) .in_inode = 0,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2296) };
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2297) struct ext4_xattr_ibody_find is = {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2298) .s = { .not_found = -ENODATA, },
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2299) };
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2300) struct ext4_xattr_block_find bs = {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2301) .s = { .not_found = -ENODATA, },
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2302) };
c755e251357a0 (Theodore Ts'o 2017-01-11 21:50:46 -0500 2303) int no_expand;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2304) int error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2305)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2306) if (!name)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2307) return -EINVAL;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2308) if (strlen(name) > 255)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2309) return -ERANGE;
b8cb5a545c3dd (Tahsin Erdogan 2017-05-24 18:24:07 -0400 2310)
c755e251357a0 (Theodore Ts'o 2017-01-11 21:50:46 -0500 2311) ext4_write_lock_xattr(inode, &no_expand);
4d20c685fa365 (Kalpak Shah 2008-10-08 23:21:54 -0400 2312)
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2313) /* Check journal credits under write lock. */
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2314) if (ext4_handle_valid(handle)) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2315) struct buffer_head *bh;
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2316) int credits;
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2317)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2318) bh = ext4_xattr_get_block(inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2319) if (IS_ERR(bh)) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2320) error = PTR_ERR(bh);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2321) goto cleanup;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2322) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2323)
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 2324) credits = __ext4_xattr_set_credits(inode->i_sb, inode, bh,
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 2325) value_len,
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 2326) flags & XATTR_CREATE);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2327) brelse(bh);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2328)
a9a8344ee1714 (Jan Kara 2019-11-05 17:44:17 +0100 2329) if (jbd2_handle_buffer_credits(handle) < credits) {
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2330) error = -ENOSPC;
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2331) goto cleanup;
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2332) }
163f0ec1df33c (Jan Kara 2021-02-22 18:16:26 +0100 2333) WARN_ON_ONCE(!(current->flags & PF_MEMALLOC_NOFS));
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2334) }
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2335)
665436175c3ca (Eric Sandeen 2011-10-26 03:32:07 -0400 2336) error = ext4_reserve_inode_write(handle, inode, &is.iloc);
86ebfd08a1930 (Eric Sandeen 2009-11-15 15:30:52 -0500 2337) if (error)
86ebfd08a1930 (Eric Sandeen 2009-11-15 15:30:52 -0500 2338) goto cleanup;
86ebfd08a1930 (Eric Sandeen 2009-11-15 15:30:52 -0500 2339)
19f5fb7ad679b (Theodore Ts'o 2010-01-24 14:34:07 -0500 2340) if (ext4_test_inode_state(inode, EXT4_STATE_NEW)) {
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2341) struct ext4_inode *raw_inode = ext4_raw_inode(&is.iloc);
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2342) memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size);
19f5fb7ad679b (Theodore Ts'o 2010-01-24 14:34:07 -0500 2343) ext4_clear_inode_state(inode, EXT4_STATE_NEW);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2344) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2345)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2346) error = ext4_xattr_ibody_find(inode, &i, &is);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2347) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2348) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2349) if (is.s.not_found)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2350) error = ext4_xattr_block_find(inode, &i, &bs);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2351) if (error)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2352) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2353) if (is.s.not_found && bs.s.not_found) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2354) error = -ENODATA;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2355) if (flags & XATTR_REPLACE)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2356) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2357) error = 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2358) if (!value)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2359) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2360) } else {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2361) error = -EEXIST;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2362) if (flags & XATTR_CREATE)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2363) goto cleanup;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2364) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2365)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2366) if (!value) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2367) if (!is.s.not_found)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2368) error = ext4_xattr_ibody_set(handle, inode, &i, &is);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2369) else if (!bs.s.not_found)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2370) error = ext4_xattr_block_set(handle, inode, &i, &bs);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2371) } else {
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2372) error = 0;
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2373) /* Xattr value did not change? Save us some work and bail out */
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2374) if (!is.s.not_found && ext4_xattr_value_same(&is.s, &i))
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2375) goto cleanup;
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2376) if (!bs.s.not_found && ext4_xattr_value_same(&bs.s, &i))
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2377) goto cleanup;
3fd164629d25b (Jan Kara 2016-02-22 22:43:04 -0500 2378)
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2379) if (ext4_has_feature_ea_inode(inode->i_sb) &&
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2380) (EXT4_XATTR_SIZE(i.value_len) >
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2381) EXT4_XATTR_MIN_LARGE_EA_SIZE(inode->i_sb->s_blocksize)))
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2382) i.in_inode = 1;
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2383) retry_inode:
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2384) error = ext4_xattr_ibody_set(handle, inode, &i, &is);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2385) if (!error && !bs.s.not_found) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2386) i.value = NULL;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2387) error = ext4_xattr_block_set(handle, inode, &i, &bs);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2388) } else if (error == -ENOSPC) {
7e01c8e5420b6 (Tiger Yang 2008-05-14 16:05:47 -0700 2389) if (EXT4_I(inode)->i_file_acl && !bs.s.base) {
45ae932d246f7 (Vasily Averin 2018-11-07 11:07:01 -0500 2390) brelse(bs.bh);
45ae932d246f7 (Vasily Averin 2018-11-07 11:07:01 -0500 2391) bs.bh = NULL;
7e01c8e5420b6 (Tiger Yang 2008-05-14 16:05:47 -0700 2392) error = ext4_xattr_block_find(inode, &i, &bs);
7e01c8e5420b6 (Tiger Yang 2008-05-14 16:05:47 -0700 2393) if (error)
7e01c8e5420b6 (Tiger Yang 2008-05-14 16:05:47 -0700 2394) goto cleanup;
7e01c8e5420b6 (Tiger Yang 2008-05-14 16:05:47 -0700 2395) }
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2396) error = ext4_xattr_block_set(handle, inode, &i, &bs);
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2397) if (!error && !is.s.not_found) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2398) i.value = NULL;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2399) error = ext4_xattr_ibody_set(handle, inode, &i,
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2400) &is);
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2401) } else if (error == -ENOSPC) {
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2402) /*
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2403) * Xattr does not fit in the block, store at
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2404) * external inode if possible.
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2405) */
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2406) if (ext4_has_feature_ea_inode(inode->i_sb) &&
6b22489911b72 (zhangyi (F) 2021-03-05 20:05:08 +0800 2407) i.value_len && !i.in_inode) {
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2408) i.in_inode = 1;
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2409) goto retry_inode;
b347e2bcd18eb (Tahsin Erdogan 2017-06-21 22:20:32 -0400 2410) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2411) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2412) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2413) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2414) if (!error) {
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2415) ext4_xattr_update_super_block(handle, inode->i_sb);
eeca7ea1baa93 (Deepa Dinamani 2016-11-14 21:40:10 -0500 2416) inode->i_ctime = current_time(inode);
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2417) if (!value)
c755e251357a0 (Theodore Ts'o 2017-01-11 21:50:46 -0500 2418) no_expand = 0;
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2419) error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2420) /*
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2421) * The bh is consumed by ext4_mark_iloc_dirty, even with
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2422) * error != 0.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2423) */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2424) is.iloc.bh = NULL;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2425) if (IS_SYNC(inode))
0390131ba84fd (Frank Mayhar 2009-01-07 00:06:22 -0500 2426) ext4_handle_sync(handle);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2427) }
aa75f4d3daaeb (Harshad Shirwadkar 2020-10-15 13:37:57 -0700 2428) ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2429)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2430) cleanup:
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2431) brelse(is.iloc.bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2432) brelse(bs.bh);
c755e251357a0 (Theodore Ts'o 2017-01-11 21:50:46 -0500 2433) ext4_write_unlock_xattr(inode, &no_expand);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2434) return error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2435) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2436)
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 2437) int ext4_xattr_set_credits(struct inode *inode, size_t value_len,
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 2438) bool is_create, int *credits)
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2439) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2440) struct buffer_head *bh;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2441) int err;
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2442)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2443) *credits = 0;
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2444)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2445) if (!EXT4_SB(inode->i_sb)->s_journal)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2446) return 0;
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2447)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2448) down_read(&EXT4_I(inode)->xattr_sem);
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2449)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2450) bh = ext4_xattr_get_block(inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2451) if (IS_ERR(bh)) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2452) err = PTR_ERR(bh);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2453) } else {
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 2454) *credits = __ext4_xattr_set_credits(inode->i_sb, inode, bh,
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 2455) value_len, is_create);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2456) brelse(bh);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2457) err = 0;
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2458) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2459)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2460) up_read(&EXT4_I(inode)->xattr_sem);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2461) return err;
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2462) }
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2463)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2464) /*
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2465) * ext4_xattr_set()
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2466) *
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2467) * Like ext4_xattr_set_handle, but start from an inode. This extended
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2468) * attribute modification is a filesystem transaction by itself.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2469) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2470) * Returns 0, or a negative error number on failure.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2471) */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2472) int
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2473) ext4_xattr_set(struct inode *inode, int name_index, const char *name,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2474) const void *value, size_t value_len, int flags)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2475) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2476) handle_t *handle;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2477) struct super_block *sb = inode->i_sb;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2478) int error, retries = 0;
c1a5d5f6ab21e (Tahsin Erdogan 2017-06-21 22:28:40 -0400 2479) int credits;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2480)
b8cb5a545c3dd (Tahsin Erdogan 2017-05-24 18:24:07 -0400 2481) error = dquot_initialize(inode);
b8cb5a545c3dd (Tahsin Erdogan 2017-05-24 18:24:07 -0400 2482) if (error)
b8cb5a545c3dd (Tahsin Erdogan 2017-05-24 18:24:07 -0400 2483) return error;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2484)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2485) retry:
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 2486) error = ext4_xattr_set_credits(inode, value_len, flags & XATTR_CREATE,
af65207c76ce8 (Tahsin Erdogan 2017-07-06 00:01:59 -0400 2487) &credits);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2488) if (error)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2489) return error;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2490)
9924a92a8c217 (Theodore Ts'o 2013-02-08 21:59:22 -0500 2491) handle = ext4_journal_start(inode, EXT4_HT_XATTR, credits);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2492) if (IS_ERR(handle)) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2493) error = PTR_ERR(handle);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2494) } else {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2495) int error2;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2496)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2497) error = ext4_xattr_set_handle(handle, inode, name_index, name,
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2498) value, value_len, flags);
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2499) error2 = ext4_journal_stop(handle);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2500) if (error == -ENOSPC &&
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2501) ext4_should_retry_alloc(sb, &retries))
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2502) goto retry;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2503) if (error == 0)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2504) error = error2;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2505) }
aa75f4d3daaeb (Harshad Shirwadkar 2020-10-15 13:37:57 -0700 2506) ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2507)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2508) return error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2509) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2510)
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2511) /*
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2512) * Shift the EA entries in the inode to create space for the increased
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2513) * i_extra_isize.
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2514) */
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2515) static void ext4_xattr_shift_entries(struct ext4_xattr_entry *entry,
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2516) int value_offs_shift, void *to,
94405713889d4 (Jan Kara 2016-08-29 15:41:11 -0400 2517) void *from, size_t n)
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2518) {
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2519) struct ext4_xattr_entry *last = entry;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2520) int new_offs;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2521)
94405713889d4 (Jan Kara 2016-08-29 15:41:11 -0400 2522) /* We always shift xattr headers further thus offsets get lower */
94405713889d4 (Jan Kara 2016-08-29 15:41:11 -0400 2523) BUG_ON(value_offs_shift > 0);
94405713889d4 (Jan Kara 2016-08-29 15:41:11 -0400 2524)
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2525) /* Adjust the value offsets of the entries */
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2526) for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2527) if (!last->e_value_inum && last->e_value_size) {
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2528) new_offs = le16_to_cpu(last->e_value_offs) +
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2529) value_offs_shift;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2530) last->e_value_offs = cpu_to_le16(new_offs);
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2531) }
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2532) }
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2533) /* Shift the entries by n bytes */
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2534) memmove(to, from, n);
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2535) }
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2536)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2537) /*
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2538) * Move xattr pointed to by 'entry' from inode into external xattr block
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2539) */
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2540) static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2541) struct ext4_inode *raw_inode,
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2542) struct ext4_xattr_entry *entry)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2543) {
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2544) struct ext4_xattr_ibody_find *is = NULL;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2545) struct ext4_xattr_block_find *bs = NULL;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2546) char *buffer = NULL, *b_entry_name = NULL;
f6109100ba869 (Tahsin Erdogan 2017-06-21 22:11:54 -0400 2547) size_t value_size = le32_to_cpu(entry->e_value_size);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2548) struct ext4_xattr_info i = {
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2549) .value = NULL,
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2550) .value_len = 0,
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2551) .name_index = entry->e_name_index,
f6109100ba869 (Tahsin Erdogan 2017-06-21 22:11:54 -0400 2552) .in_inode = !!entry->e_value_inum,
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2553) };
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2554) struct ext4_xattr_ibody_header *header = IHDR(inode, raw_inode);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2555) int error;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2556)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2557) is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2558) bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2559) buffer = kmalloc(value_size, GFP_NOFS);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2560) b_entry_name = kmalloc(entry->e_name_len + 1, GFP_NOFS);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2561) if (!is || !bs || !buffer || !b_entry_name) {
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2562) error = -ENOMEM;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2563) goto out;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2564) }
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2565)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2566) is->s.not_found = -ENODATA;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2567) bs->s.not_found = -ENODATA;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2568) is->iloc.bh = NULL;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2569) bs->bh = NULL;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2570)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2571) /* Save the entry name and the entry value */
f6109100ba869 (Tahsin Erdogan 2017-06-21 22:11:54 -0400 2572) if (entry->e_value_inum) {
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 2573) error = ext4_xattr_inode_get(inode, entry, buffer, value_size);
f6109100ba869 (Tahsin Erdogan 2017-06-21 22:11:54 -0400 2574) if (error)
f6109100ba869 (Tahsin Erdogan 2017-06-21 22:11:54 -0400 2575) goto out;
f6109100ba869 (Tahsin Erdogan 2017-06-21 22:11:54 -0400 2576) } else {
f6109100ba869 (Tahsin Erdogan 2017-06-21 22:11:54 -0400 2577) size_t value_offs = le16_to_cpu(entry->e_value_offs);
f6109100ba869 (Tahsin Erdogan 2017-06-21 22:11:54 -0400 2578) memcpy(buffer, (void *)IFIRST(header) + value_offs, value_size);
f6109100ba869 (Tahsin Erdogan 2017-06-21 22:11:54 -0400 2579) }
f6109100ba869 (Tahsin Erdogan 2017-06-21 22:11:54 -0400 2580)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2581) memcpy(b_entry_name, entry->e_name, entry->e_name_len);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2582) b_entry_name[entry->e_name_len] = '\0';
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2583) i.name = b_entry_name;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2584)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2585) error = ext4_get_inode_loc(inode, &is->iloc);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2586) if (error)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2587) goto out;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2588)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2589) error = ext4_xattr_ibody_find(inode, &i, is);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2590) if (error)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2591) goto out;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2592)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2593) /* Remove the chosen entry from the inode */
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2594) error = ext4_xattr_ibody_set(handle, inode, &i, is);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2595) if (error)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2596) goto out;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2597)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2598) i.value = buffer;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2599) i.value_len = value_size;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2600) error = ext4_xattr_block_find(inode, &i, bs);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2601) if (error)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2602) goto out;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2603)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2604) /* Add entry which was removed from the inode into the block */
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2605) error = ext4_xattr_block_set(handle, inode, &i, bs);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2606) if (error)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2607) goto out;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2608) error = 0;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2609) out:
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2610) kfree(b_entry_name);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2611) kfree(buffer);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2612) if (is)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2613) brelse(is->iloc.bh);
6bdc9977fcded (Vasily Averin 2018-11-07 11:10:21 -0500 2614) if (bs)
6bdc9977fcded (Vasily Averin 2018-11-07 11:10:21 -0500 2615) brelse(bs->bh);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2616) kfree(is);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2617) kfree(bs);
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2618)
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2619) return error;
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2620) }
3f2571c1f91f2 (Jan Kara 2016-08-29 15:42:11 -0400 2621)
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2622) static int ext4_xattr_make_inode_space(handle_t *handle, struct inode *inode,
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2623) struct ext4_inode *raw_inode,
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2624) int isize_diff, size_t ifree,
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2625) size_t bfree, int *total_ino)
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2626) {
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2627) struct ext4_xattr_ibody_header *header = IHDR(inode, raw_inode);
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2628) struct ext4_xattr_entry *small_entry;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2629) struct ext4_xattr_entry *entry;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2630) struct ext4_xattr_entry *last;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2631) unsigned int entry_size; /* EA entry size */
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2632) unsigned int total_size; /* EA entry size + value size */
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2633) unsigned int min_total_size;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2634) int error;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2635)
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2636) while (isize_diff > ifree) {
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2637) entry = NULL;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2638) small_entry = NULL;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2639) min_total_size = ~0U;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2640) last = IFIRST(header);
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2641) /* Find the entry best suited to be pushed into EA block */
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2642) for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
8cdb5240ec592 (Theodore Ts'o 2018-06-16 15:40:48 -0400 2643) /* never move system.data out of the inode */
8cdb5240ec592 (Theodore Ts'o 2018-06-16 15:40:48 -0400 2644) if ((last->e_name_len == 4) &&
8cdb5240ec592 (Theodore Ts'o 2018-06-16 15:40:48 -0400 2645) (last->e_name_index == EXT4_XATTR_INDEX_SYSTEM) &&
8cdb5240ec592 (Theodore Ts'o 2018-06-16 15:40:48 -0400 2646) !memcmp(last->e_name, "data", 4))
8cdb5240ec592 (Theodore Ts'o 2018-06-16 15:40:48 -0400 2647) continue;
9bb21cedda7cd (Tahsin Erdogan 2017-06-21 22:05:44 -0400 2648) total_size = EXT4_XATTR_LEN(last->e_name_len);
9bb21cedda7cd (Tahsin Erdogan 2017-06-21 22:05:44 -0400 2649) if (!last->e_value_inum)
9bb21cedda7cd (Tahsin Erdogan 2017-06-21 22:05:44 -0400 2650) total_size += EXT4_XATTR_SIZE(
9bb21cedda7cd (Tahsin Erdogan 2017-06-21 22:05:44 -0400 2651) le32_to_cpu(last->e_value_size));
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2652) if (total_size <= bfree &&
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2653) total_size < min_total_size) {
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2654) if (total_size + ifree < isize_diff) {
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2655) small_entry = last;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2656) } else {
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2657) entry = last;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2658) min_total_size = total_size;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2659) }
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2660) }
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2661) }
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2662)
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2663) if (entry == NULL) {
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2664) if (small_entry == NULL)
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2665) return -ENOSPC;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2666) entry = small_entry;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2667) }
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2668)
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2669) entry_size = EXT4_XATTR_LEN(entry->e_name_len);
9bb21cedda7cd (Tahsin Erdogan 2017-06-21 22:05:44 -0400 2670) total_size = entry_size;
9bb21cedda7cd (Tahsin Erdogan 2017-06-21 22:05:44 -0400 2671) if (!entry->e_value_inum)
9bb21cedda7cd (Tahsin Erdogan 2017-06-21 22:05:44 -0400 2672) total_size += EXT4_XATTR_SIZE(
9bb21cedda7cd (Tahsin Erdogan 2017-06-21 22:05:44 -0400 2673) le32_to_cpu(entry->e_value_size));
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2674) error = ext4_xattr_move_to_block(handle, inode, raw_inode,
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2675) entry);
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2676) if (error)
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2677) return error;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2678)
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2679) *total_ino -= entry_size;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2680) ifree += total_size;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2681) bfree -= total_size;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2682) }
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2683)
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2684) return 0;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2685) }
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2686)
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2687) /*
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2688) * Expand an inode by new_extra_isize bytes when EAs are present.
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2689) * Returns 0 on success or negative error number on failure.
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2690) */
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2691) int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2692) struct ext4_inode *raw_inode, handle_t *handle)
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2693) {
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2694) struct ext4_xattr_ibody_header *header;
cf0a5e818fe21 (Miao Xie 2017-08-06 00:40:01 -0400 2695) struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
cf0a5e818fe21 (Miao Xie 2017-08-06 00:40:01 -0400 2696) static unsigned int mnt_count;
e3014d14a81ed (Jan Kara 2016-08-29 15:38:11 -0400 2697) size_t min_offs;
e3014d14a81ed (Jan Kara 2016-08-29 15:38:11 -0400 2698) size_t ifree, bfree;
7b1b2c1b9c397 (Theodore Ts'o 2014-02-19 20:15:21 -0500 2699) int total_ino;
6e0cd088c0102 (Jan Kara 2016-08-29 15:43:11 -0400 2700) void *base, *end;
d0141191a2028 (Jan Kara 2016-08-11 11:50:30 -0400 2701) int error = 0, tried_min_extra_isize = 0;
cf0a5e818fe21 (Miao Xie 2017-08-06 00:40:01 -0400 2702) int s_min_extra_isize = le16_to_cpu(sbi->s_es->s_min_extra_isize);
d0141191a2028 (Jan Kara 2016-08-11 11:50:30 -0400 2703) int isize_diff; /* How much do we need to grow i_extra_isize */
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2704)
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2705) retry:
d0141191a2028 (Jan Kara 2016-08-11 11:50:30 -0400 2706) isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize;
2e81a4eeedcaa (Jan Kara 2016-08-11 12:38:55 -0400 2707) if (EXT4_I(inode)->i_extra_isize >= new_extra_isize)
b640b2c51b264 (Miao Xie 2017-08-06 00:55:48 -0400 2708) return 0;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2709)
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2710) header = IHDR(inode, raw_inode);
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2711)
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2712) /*
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2713) * Check if enough free space is available in the inode to shift the
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2714) * entries ahead by new_extra_isize.
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2715) */
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2716)
6e0cd088c0102 (Jan Kara 2016-08-29 15:43:11 -0400 2717) base = IFIRST(header);
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2718) end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2719) min_offs = end - base;
a805622a757b6 (Theodore Ts'o 2018-12-19 12:28:13 -0500 2720) total_ino = sizeof(struct ext4_xattr_ibody_header) + sizeof(u32);
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2721)
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 2722) error = xattr_check_inode(inode, header, end);
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 2723) if (error)
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 2724) goto cleanup;
9e92f48c34eb2 (Theodore Ts'o 2016-03-22 16:13:15 -0400 2725)
6e0cd088c0102 (Jan Kara 2016-08-29 15:43:11 -0400 2726) ifree = ext4_xattr_free_space(base, &min_offs, base, &total_ino);
e3014d14a81ed (Jan Kara 2016-08-29 15:38:11 -0400 2727) if (ifree >= isize_diff)
e3014d14a81ed (Jan Kara 2016-08-29 15:38:11 -0400 2728) goto shift;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2729)
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2730) /*
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2731) * Enough free space isn't available in the inode, check if
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2732) * EA block can hold new_extra_isize bytes.
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2733) */
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2734) if (EXT4_I(inode)->i_file_acl) {
53692ec074d00 (Vasily Averin 2018-11-07 11:14:35 -0500 2735) struct buffer_head *bh;
53692ec074d00 (Vasily Averin 2018-11-07 11:14:35 -0500 2736)
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 2737) bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 2738) if (IS_ERR(bh)) {
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 2739) error = PTR_ERR(bh);
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2740) goto cleanup;
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 2741) }
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 2742) error = ext4_xattr_check_block(inode, bh);
53692ec074d00 (Vasily Averin 2018-11-07 11:14:35 -0500 2743) if (error) {
53692ec074d00 (Vasily Averin 2018-11-07 11:14:35 -0500 2744) brelse(bh);
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2745) goto cleanup;
53692ec074d00 (Vasily Averin 2018-11-07 11:14:35 -0500 2746) }
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2747) base = BHDR(bh);
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2748) end = bh->b_data + bh->b_size;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2749) min_offs = end - base;
6e0cd088c0102 (Jan Kara 2016-08-29 15:43:11 -0400 2750) bfree = ext4_xattr_free_space(BFIRST(bh), &min_offs, base,
6e0cd088c0102 (Jan Kara 2016-08-29 15:43:11 -0400 2751) NULL);
b640b2c51b264 (Miao Xie 2017-08-06 00:55:48 -0400 2752) brelse(bh);
e3014d14a81ed (Jan Kara 2016-08-29 15:38:11 -0400 2753) if (bfree + ifree < isize_diff) {
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2754) if (!tried_min_extra_isize && s_min_extra_isize) {
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2755) tried_min_extra_isize++;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2756) new_extra_isize = s_min_extra_isize;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2757) goto retry;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2758) }
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2759) error = -ENOSPC;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2760) goto cleanup;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2761) }
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2762) } else {
e3014d14a81ed (Jan Kara 2016-08-29 15:38:11 -0400 2763) bfree = inode->i_sb->s_blocksize;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2764) }
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2765)
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2766) error = ext4_xattr_make_inode_space(handle, inode, raw_inode,
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2767) isize_diff, ifree, bfree,
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2768) &total_ino);
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2769) if (error) {
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2770) if (error == -ENOSPC && !tried_min_extra_isize &&
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2771) s_min_extra_isize) {
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2772) tried_min_extra_isize++;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2773) new_extra_isize = s_min_extra_isize;
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2774) goto retry;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2775) }
dfa2064b222c9 (Jan Kara 2016-08-29 15:44:11 -0400 2776) goto cleanup;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2777) }
e3014d14a81ed (Jan Kara 2016-08-29 15:38:11 -0400 2778) shift:
e3014d14a81ed (Jan Kara 2016-08-29 15:38:11 -0400 2779) /* Adjust the offsets and shift the remaining entries ahead */
6e0cd088c0102 (Jan Kara 2016-08-29 15:43:11 -0400 2780) ext4_xattr_shift_entries(IFIRST(header), EXT4_I(inode)->i_extra_isize
e3014d14a81ed (Jan Kara 2016-08-29 15:38:11 -0400 2781) - new_extra_isize, (void *)raw_inode +
e3014d14a81ed (Jan Kara 2016-08-29 15:38:11 -0400 2782) EXT4_GOOD_OLD_INODE_SIZE + new_extra_isize,
94405713889d4 (Jan Kara 2016-08-29 15:41:11 -0400 2783) (void *)header, total_ino);
e3014d14a81ed (Jan Kara 2016-08-29 15:38:11 -0400 2784) EXT4_I(inode)->i_extra_isize = new_extra_isize;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2785)
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2786) cleanup:
b640b2c51b264 (Miao Xie 2017-08-06 00:55:48 -0400 2787) if (error && (mnt_count != le16_to_cpu(sbi->s_es->s_mnt_count))) {
cf0a5e818fe21 (Miao Xie 2017-08-06 00:40:01 -0400 2788) ext4_warning(inode->i_sb, "Unable to expand inode %lu. Delete some EAs or run e2fsck.",
cf0a5e818fe21 (Miao Xie 2017-08-06 00:40:01 -0400 2789) inode->i_ino);
cf0a5e818fe21 (Miao Xie 2017-08-06 00:40:01 -0400 2790) mnt_count = le16_to_cpu(sbi->s_es->s_mnt_count);
cf0a5e818fe21 (Miao Xie 2017-08-06 00:40:01 -0400 2791) }
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2792) return error;
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2793) }
6dd4ee7cab7e3 (Kalpak Shah 2007-07-18 09:19:57 -0400 2794)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2795) #define EIA_INCR 16 /* must be 2^n */
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2796) #define EIA_MASK (EIA_INCR - 1)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2797)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2798) /* Add the large xattr @inode into @ea_inode_array for deferred iput().
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2799) * If @ea_inode_array is new or full it will be grown and the old
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2800) * contents copied over.
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2801) */
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2802) static int
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2803) ext4_expand_inode_array(struct ext4_xattr_inode_array **ea_inode_array,
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2804) struct inode *inode)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2805) {
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2806) if (*ea_inode_array == NULL) {
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2807) /*
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2808) * Start with 15 inodes, so it fits into a power-of-two size.
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2809) * If *ea_inode_array is NULL, this is essentially offsetof()
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2810) */
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2811) (*ea_inode_array) =
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2812) kmalloc(offsetof(struct ext4_xattr_inode_array,
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2813) inodes[EIA_MASK]),
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2814) GFP_NOFS);
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2815) if (*ea_inode_array == NULL)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2816) return -ENOMEM;
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2817) (*ea_inode_array)->count = 0;
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2818) } else if (((*ea_inode_array)->count & EIA_MASK) == EIA_MASK) {
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2819) /* expand the array once all 15 + n * 16 slots are full */
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2820) struct ext4_xattr_inode_array *new_array = NULL;
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2821) int count = (*ea_inode_array)->count;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2822)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2823) /* if new_array is NULL, this is essentially offsetof() */
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2824) new_array = kmalloc(
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2825) offsetof(struct ext4_xattr_inode_array,
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2826) inodes[count + EIA_INCR]),
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2827) GFP_NOFS);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2828) if (new_array == NULL)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2829) return -ENOMEM;
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2830) memcpy(new_array, *ea_inode_array,
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2831) offsetof(struct ext4_xattr_inode_array, inodes[count]));
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2832) kfree(*ea_inode_array);
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2833) *ea_inode_array = new_array;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2834) }
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2835) (*ea_inode_array)->inodes[(*ea_inode_array)->count++] = inode;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2836) return 0;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2837) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2838)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2839) /*
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2840) * ext4_xattr_delete_inode()
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2841) *
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2842) * Free extended attribute resources associated with this inode. Traverse
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2843) * all entries and decrement reference on any xattr inodes associated with this
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2844) * inode. This is called immediately before an inode is freed. We have exclusive
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2845) * access to the inode. If an orphan inode is deleted it will also release its
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2846) * references on xattr block and xattr inodes.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2847) */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2848) int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2849) struct ext4_xattr_inode_array **ea_inode_array,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2850) int extra_credits)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2851) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2852) struct buffer_head *bh = NULL;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2853) struct ext4_xattr_ibody_header *header;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 2854) struct ext4_iloc iloc = { .bh = NULL };
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2855) struct ext4_xattr_entry *entry;
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2856) struct inode *ea_inode;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 2857) int error;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 2858)
83448bdfb5973 (Jan Kara 2019-11-05 17:44:29 +0100 2859) error = ext4_journal_ensure_credits(handle, extra_credits,
83448bdfb5973 (Jan Kara 2019-11-05 17:44:29 +0100 2860) ext4_free_metadata_revoke_credits(inode->i_sb, 1));
a413036791d04 (Jan Kara 2019-11-05 17:44:16 +0100 2861) if (error < 0) {
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 2862) EXT4_ERROR_INODE(inode, "ensure credits (error %d)", error);
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 2863) goto cleanup;
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 2864) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2865)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2866) if (ext4_has_feature_ea_inode(inode->i_sb) &&
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2867) ext4_test_inode_state(inode, EXT4_STATE_XATTR)) {
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2868)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2869) error = ext4_get_inode_loc(inode, &iloc);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2870) if (error) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2871) EXT4_ERROR_INODE(inode, "inode loc (error %d)", error);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2872) goto cleanup;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2873) }
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 2874)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2875) error = ext4_journal_get_write_access(handle, iloc.bh);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2876) if (error) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2877) EXT4_ERROR_INODE(inode, "write access (error %d)",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2878) error);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2879) goto cleanup;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2880) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2881)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2882) header = IHDR(inode, ext4_raw_inode(&iloc));
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2883) if (header->h_magic == cpu_to_le32(EXT4_XATTR_MAGIC))
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2884) ext4_xattr_inode_dec_ref_all(handle, inode, iloc.bh,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2885) IFIRST(header),
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2886) false /* block_csum */,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2887) ea_inode_array,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2888) extra_credits,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2889) false /* skip_quota */);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2890) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2891)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2892) if (EXT4_I(inode)->i_file_acl) {
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 2893) bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 2894) if (IS_ERR(bh)) {
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 2895) error = PTR_ERR(bh);
878520ac45f9f (Theodore Ts'o 2019-11-19 21:54:15 -0500 2896) if (error == -EIO) {
54d3adbc29f0c (Theodore Ts'o 2020-03-28 19:33:43 -0400 2897) EXT4_ERROR_INODE_ERR(inode, EIO,
54d3adbc29f0c (Theodore Ts'o 2020-03-28 19:33:43 -0400 2898) "block %llu read error",
54d3adbc29f0c (Theodore Ts'o 2020-03-28 19:33:43 -0400 2899) EXT4_I(inode)->i_file_acl);
878520ac45f9f (Theodore Ts'o 2019-11-19 21:54:15 -0500 2900) }
7159a986b4202 (Dan Carpenter 2019-02-21 11:17:34 -0500 2901) bh = NULL;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2902) goto cleanup;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2903) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2904) error = ext4_xattr_check_block(inode, bh);
de05ca8526796 (Theodore Ts'o 2018-03-30 15:42:25 -0400 2905) if (error)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2906) goto cleanup;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2907)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2908) if (ext4_has_feature_ea_inode(inode->i_sb)) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2909) for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2910) entry = EXT4_XATTR_NEXT(entry)) {
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2911) if (!entry->e_value_inum)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2912) continue;
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2913) error = ext4_xattr_inode_iget(inode,
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2914) le32_to_cpu(entry->e_value_inum),
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2915) le32_to_cpu(entry->e_hash),
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2916) &ea_inode);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2917) if (error)
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2918) continue;
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2919) ext4_xattr_inode_free_quota(inode, ea_inode,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2920) le32_to_cpu(entry->e_value_size));
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2921) iput(ea_inode);
a6d05676047ec (Tahsin Erdogan 2017-08-24 14:25:02 -0400 2922) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2923)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2924) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2925)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2926) ext4_xattr_release_block(handle, inode, bh, ea_inode_array,
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2927) extra_credits);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2928) /*
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2929) * Update i_file_acl value in the same transaction that releases
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2930) * block.
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2931) */
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2932) EXT4_I(inode)->i_file_acl = 0;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2933) error = ext4_mark_inode_dirty(handle, inode);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2934) if (error) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2935) EXT4_ERROR_INODE(inode, "mark inode dirty (error %d)",
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2936) error);
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2937) goto cleanup;
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2938) }
aa75f4d3daaeb (Harshad Shirwadkar 2020-10-15 13:37:57 -0700 2939) ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR);
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 2940) }
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2941) error = 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2942) cleanup:
30a7eb970c3aa (Tahsin Erdogan 2017-06-22 11:42:09 -0400 2943) brelse(iloc.bh);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2944) brelse(bh);
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2945) return error;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2946) }
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2947)
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2948) void ext4_xattr_inode_array_free(struct ext4_xattr_inode_array *ea_inode_array)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2949) {
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2950) int idx;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2951)
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2952) if (ea_inode_array == NULL)
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2953) return;
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 2954)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2955) for (idx = 0; idx < ea_inode_array->count; ++idx)
dec214d00e0d7 (Tahsin Erdogan 2017-06-22 11:44:55 -0400 2956) iput(ea_inode_array->inodes[idx]);
0421a189bc8cd (Tahsin Erdogan 2017-06-22 10:26:31 -0400 2957) kfree(ea_inode_array);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2958) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2959)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2960) /*
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 2961) * ext4_xattr_block_cache_insert()
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2962) *
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 2963) * Create a new entry in the extended attribute block cache, and insert
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2964) * it unless such an entry is already in the cache.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2965) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2966) * Returns 0, or a negative error number on failure.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2967) */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2968) static void
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 2969) ext4_xattr_block_cache_insert(struct mb_cache *ea_block_cache,
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 2970) struct buffer_head *bh)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2971) {
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2972) struct ext4_xattr_header *header = BHDR(bh);
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2973) __u32 hash = le32_to_cpu(header->h_hash);
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2974) int reusable = le32_to_cpu(header->h_refcount) <
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2975) EXT4_XATTR_REFCOUNT_MAX;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2976) int error;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2977)
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 2978) if (!ea_block_cache)
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 2979) return;
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 2980) error = mb_cache_entry_create(ea_block_cache, GFP_NOFS, hash,
6048c64b26097 (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 2981) bh->b_blocknr, reusable);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2982) if (error) {
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2983) if (error == -EBUSY)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2984) ea_bdebug(bh, "already in cache");
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 2985) } else
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2986) ea_bdebug(bh, "inserting [%x]", (int)hash);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2987) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2988)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2989) /*
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2990) * ext4_xattr_cmp()
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2991) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2992) * Compare two extended attribute blocks for equality.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2993) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2994) * Returns 0 if the blocks are equal, 1 if they differ, and
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2995) * a negative error number on errors.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2996) */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 2997) static int
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2998) ext4_xattr_cmp(struct ext4_xattr_header *header1,
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 2999) struct ext4_xattr_header *header2)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3000) {
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 3001) struct ext4_xattr_entry *entry1, *entry2;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3002)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3003) entry1 = ENTRY(header1+1);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3004) entry2 = ENTRY(header2+1);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3005) while (!IS_LAST_ENTRY(entry1)) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3006) if (IS_LAST_ENTRY(entry2))
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3007) return 1;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3008) if (entry1->e_hash != entry2->e_hash ||
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3009) entry1->e_name_index != entry2->e_name_index ||
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3010) entry1->e_name_len != entry2->e_name_len ||
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3011) entry1->e_value_size != entry2->e_value_size ||
e50e5129f384a (Andreas Dilger 2017-06-21 21:10:32 -0400 3012) entry1->e_value_inum != entry2->e_value_inum ||
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3013) memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3014) return 1;
7cec191894e4e (Tahsin Erdogan 2017-06-21 22:14:30 -0400 3015) if (!entry1->e_value_inum &&
7cec191894e4e (Tahsin Erdogan 2017-06-21 22:14:30 -0400 3016) memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3017) (char *)header2 + le16_to_cpu(entry2->e_value_offs),
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3018) le32_to_cpu(entry1->e_value_size)))
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3019) return 1;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3020)
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 3021) entry1 = EXT4_XATTR_NEXT(entry1);
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 3022) entry2 = EXT4_XATTR_NEXT(entry2);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3023) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3024) if (!IS_LAST_ENTRY(entry2))
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3025) return 1;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3026) return 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3027) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3028)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3029) /*
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 3030) * ext4_xattr_block_cache_find()
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3031) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3032) * Find an identical extended attribute block.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3033) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3034) * Returns a pointer to the block found, or NULL if such a block was
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3035) * not found or an error occurred.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3036) */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3037) static struct buffer_head *
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 3038) ext4_xattr_block_cache_find(struct inode *inode,
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 3039) struct ext4_xattr_header *header,
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 3040) struct mb_cache_entry **pce)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3041) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3042) __u32 hash = le32_to_cpu(header->h_hash);
7a2508e1b657c (Jan Kara 2016-02-22 22:35:22 -0500 3043) struct mb_cache_entry *ce;
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 3044) struct mb_cache *ea_block_cache = EA_BLOCK_CACHE(inode);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3045)
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 3046) if (!ea_block_cache)
cdb7ee4c63275 (Tahsin Erdogan 2017-06-22 11:55:14 -0400 3047) return NULL;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3048) if (!header->h_hash)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3049) return NULL; /* never share */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3050) ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 3051) ce = mb_cache_entry_find_first(ea_block_cache, hash);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3052) while (ce) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3053) struct buffer_head *bh;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3054)
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 3055) bh = ext4_sb_bread(inode->i_sb, ce->e_value, REQ_PRIO);
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 3056) if (IS_ERR(bh)) {
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 3057) if (PTR_ERR(bh) == -ENOMEM)
fb265c9cb49e2 (Theodore Ts'o 2018-11-25 17:20:31 -0500 3058) return NULL;
7159a986b4202 (Dan Carpenter 2019-02-21 11:17:34 -0500 3059) bh = NULL;
24676da469f50 (Theodore Ts'o 2010-05-16 21:00:00 -0400 3060) EXT4_ERROR_INODE(inode, "block %lu read error",
c07dfcb45877f (Tahsin Erdogan 2017-06-22 10:29:53 -0400 3061) (unsigned long)ce->e_value);
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 3062) } else if (ext4_xattr_cmp(header, BHDR(bh)) == 0) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3063) *pce = ce;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3064) return bh;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3065) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3066) brelse(bh);
47387409ee2e0 (Tahsin Erdogan 2017-06-22 11:28:55 -0400 3067) ce = mb_cache_entry_find_next(ea_block_cache, ce);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3068) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3069) return NULL;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3070) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3071)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3072) #define NAME_HASH_SHIFT 5
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3073) #define VALUE_HASH_SHIFT 16
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3074)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3075) /*
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 3076) * ext4_xattr_hash_entry()
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3077) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3078) * Compute the hash of an extended attribute.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3079) */
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 3080) static __le32 ext4_xattr_hash_entry(char *name, size_t name_len, __le32 *value,
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 3081) size_t value_count)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3082) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3083) __u32 hash = 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3084)
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 3085) while (name_len--) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3086) hash = (hash << NAME_HASH_SHIFT) ^
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3087) (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3088) *name++;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3089) }
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 3090) while (value_count--) {
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 3091) hash = (hash << VALUE_HASH_SHIFT) ^
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 3092) (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 3093) le32_to_cpu(*value++);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3094) }
b9fc761ea2d82 (Tahsin Erdogan 2017-06-22 11:53:15 -0400 3095) return cpu_to_le32(hash);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3096) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3097)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3098) #undef NAME_HASH_SHIFT
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3099) #undef VALUE_HASH_SHIFT
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3100)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3101) #define BLOCK_HASH_SHIFT 16
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3102)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3103) /*
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 3104) * ext4_xattr_rehash()
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3105) *
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3106) * Re-compute the extended attribute hash value after an entry has changed.
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3107) */
daf8328172dff (Tahsin Erdogan 2017-06-22 11:52:03 -0400 3108) static void ext4_xattr_rehash(struct ext4_xattr_header *header)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3109) {
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 3110) struct ext4_xattr_entry *here;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3111) __u32 hash = 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3112)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3113) here = ENTRY(header+1);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3114) while (!IS_LAST_ENTRY(here)) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3115) if (!here->e_hash) {
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3116) /* Block is not shared if an entry's hash value == 0 */
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3117) hash = 0;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3118) break;
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3119) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3120) hash = (hash << BLOCK_HASH_SHIFT) ^
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3121) (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3122) le32_to_cpu(here->e_hash);
617ba13b31fbf (Mingming Cao 2006-10-11 01:20:53 -0700 3123) here = EXT4_XATTR_NEXT(here);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3124) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3125) header->h_hash = cpu_to_le32(hash);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3126) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3127)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3128) #undef BLOCK_HASH_SHIFT
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3129)
9c191f701ce9f (T Makphaibulchoke 2014-03-18 19:24:49 -0400 3130) #define HASH_BUCKET_BITS 10
9c191f701ce9f (T Makphaibulchoke 2014-03-18 19:24:49 -0400 3131)
7a2508e1b657c (Jan Kara 2016-02-22 22:35:22 -0500 3132) struct mb_cache *
82939d7999dfc (Jan Kara 2016-02-22 11:50:13 -0500 3133) ext4_xattr_create_cache(void)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3134) {
7a2508e1b657c (Jan Kara 2016-02-22 22:35:22 -0500 3135) return mb_cache_create(HASH_BUCKET_BITS);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3136) }
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3137)
7a2508e1b657c (Jan Kara 2016-02-22 22:35:22 -0500 3138) void ext4_xattr_destroy_cache(struct mb_cache *cache)
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3139) {
9c191f701ce9f (T Makphaibulchoke 2014-03-18 19:24:49 -0400 3140) if (cache)
7a2508e1b657c (Jan Kara 2016-02-22 22:35:22 -0500 3141) mb_cache_destroy(cache);
ac27a0ec112a0 (Dave Kleikamp 2006-10-11 01:20:50 -0700 3142) }
9c191f701ce9f (T Makphaibulchoke 2014-03-18 19:24:49 -0400 3143)