^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2017-2018 HUAWEI, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * https://www.huawei.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Created by Gao Xiang <gaoxiang25@huawei.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "xattr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) struct xattr_iter {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) struct super_block *sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) void *kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) erofs_blk_t blkaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) unsigned int ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static inline void xattr_iter_end(struct xattr_iter *it, bool atomic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /* the only user of kunmap() is 'init_inode_xattrs' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if (!atomic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) kunmap(it->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) kunmap_atomic(it->kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) unlock_page(it->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) put_page(it->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static inline void xattr_iter_end_final(struct xattr_iter *it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (!it->page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) xattr_iter_end(it, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static int init_inode_xattrs(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct erofs_inode *const vi = EROFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct xattr_iter it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct erofs_xattr_ibody_header *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct super_block *sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct erofs_sb_info *sbi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) bool atomic_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* the most case is that xattrs of this inode are initialized. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (test_bit(EROFS_I_EA_INITED_BIT, &vi->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * paired with smp_mb() at the end of the function to ensure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * fields will only be observed after the bit is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) smp_mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (wait_on_bit_lock(&vi->flags, EROFS_I_BL_XATTR_BIT, TASK_KILLABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* someone has initialized xattrs for us? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (test_bit(EROFS_I_EA_INITED_BIT, &vi->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * bypass all xattr operations if ->xattr_isize is not greater than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * sizeof(struct erofs_xattr_ibody_header), in detail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * 1) it is not enough to contain erofs_xattr_ibody_header then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * ->xattr_isize should be 0 (it means no xattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * 2) it is just to contain erofs_xattr_ibody_header, which is on-disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * undefined right now (maybe use later with some new sb feature).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (vi->xattr_isize == sizeof(struct erofs_xattr_ibody_header)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) erofs_err(inode->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) "xattr_isize %d of nid %llu is not supported yet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) vi->xattr_isize, vi->nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) } else if (vi->xattr_isize < sizeof(struct erofs_xattr_ibody_header)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (vi->xattr_isize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) erofs_err(inode->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) "bogus xattr ibody @ nid %llu", vi->nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) DBG_BUGON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ret = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) goto out_unlock; /* xattr ondisk layout error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ret = -ENOATTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) sbi = EROFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) it.blkaddr = erofs_blknr(iloc(sbi, vi->nid) + vi->inode_isize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) it.page = erofs_get_meta_page(sb, it.blkaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (IS_ERR(it.page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ret = PTR_ERR(it.page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* read in shared xattr array (non-atomic, see kmalloc below) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) it.kaddr = kmap(it.page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) atomic_map = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ih = (struct erofs_xattr_ibody_header *)(it.kaddr + it.ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) vi->xattr_shared_count = ih->h_shared_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) vi->xattr_shared_xattrs = kmalloc_array(vi->xattr_shared_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) sizeof(uint), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (!vi->xattr_shared_xattrs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) xattr_iter_end(&it, atomic_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* let's skip ibody header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) it.ofs += sizeof(struct erofs_xattr_ibody_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) for (i = 0; i < vi->xattr_shared_count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (it.ofs >= EROFS_BLKSIZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* cannot be unaligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) DBG_BUGON(it.ofs != EROFS_BLKSIZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) xattr_iter_end(&it, atomic_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) it.page = erofs_get_meta_page(sb, ++it.blkaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (IS_ERR(it.page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) kfree(vi->xattr_shared_xattrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) vi->xattr_shared_xattrs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ret = PTR_ERR(it.page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) it.kaddr = kmap_atomic(it.page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) atomic_map = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) it.ofs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) vi->xattr_shared_xattrs[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) le32_to_cpu(*(__le32 *)(it.kaddr + it.ofs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) it.ofs += sizeof(__le32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) xattr_iter_end(&it, atomic_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* paired with smp_mb() at the beginning of the function. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) smp_mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) set_bit(EROFS_I_EA_INITED_BIT, &vi->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) clear_and_wake_up_bit(EROFS_I_BL_XATTR_BIT, &vi->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * the general idea for these return values is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * if 0 is returned, go on processing the current xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * 1 (> 0) is returned, skip this round to process the next xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * -err (< 0) is returned, an error (maybe ENOXATTR) occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * and need to be handled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct xattr_iter_handlers {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int (*entry)(struct xattr_iter *_it, struct erofs_xattr_entry *entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int (*name)(struct xattr_iter *_it, unsigned int processed, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) unsigned int len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int (*alloc_buffer)(struct xattr_iter *_it, unsigned int value_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) void (*value)(struct xattr_iter *_it, unsigned int processed, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned int len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static inline int xattr_iter_fixup(struct xattr_iter *it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (it->ofs < EROFS_BLKSIZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) xattr_iter_end(it, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) it->blkaddr += erofs_blknr(it->ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) it->page = erofs_get_meta_page(it->sb, it->blkaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (IS_ERR(it->page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int err = PTR_ERR(it->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) it->page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) it->kaddr = kmap_atomic(it->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) it->ofs = erofs_blkoff(it->ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static int inline_xattr_iter_begin(struct xattr_iter *it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct erofs_inode *const vi = EROFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct erofs_sb_info *const sbi = EROFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) unsigned int xattr_header_sz, inline_xattr_ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) xattr_header_sz = inlinexattr_header_size(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (xattr_header_sz >= vi->xattr_isize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) DBG_BUGON(xattr_header_sz > vi->xattr_isize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return -ENOATTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) inline_xattr_ofs = vi->inode_isize + xattr_header_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) it->blkaddr = erofs_blknr(iloc(sbi, vi->nid) + inline_xattr_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) it->ofs = erofs_blkoff(iloc(sbi, vi->nid) + inline_xattr_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) it->page = erofs_get_meta_page(inode->i_sb, it->blkaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (IS_ERR(it->page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return PTR_ERR(it->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) it->kaddr = kmap_atomic(it->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return vi->xattr_isize - xattr_header_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * Regardless of success or failure, `xattr_foreach' will end up with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * `ofs' pointing to the next xattr item rather than an arbitrary position.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static int xattr_foreach(struct xattr_iter *it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) const struct xattr_iter_handlers *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) unsigned int *tlimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct erofs_xattr_entry entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) unsigned int value_sz, processed, slice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* 0. fixup blkaddr, ofs, ipage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) err = xattr_iter_fixup(it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * 1. read xattr entry to the memory,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * since we do EROFS_XATTR_ALIGN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * therefore entry should be in the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) entry = *(struct erofs_xattr_entry *)(it->kaddr + it->ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (tlimit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) unsigned int entry_sz = erofs_xattr_entry_size(&entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /* xattr on-disk corruption: xattr entry beyond xattr_isize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (*tlimit < entry_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) DBG_BUGON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *tlimit -= entry_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) it->ofs += sizeof(struct erofs_xattr_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) value_sz = le16_to_cpu(entry.e_value_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* handle entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) err = op->entry(it, &entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) it->ofs += entry.e_name_len + value_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* 2. handle xattr name (ofs will finally be at the end of name) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) processed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) while (processed < entry.e_name_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (it->ofs >= EROFS_BLKSIZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) DBG_BUGON(it->ofs > EROFS_BLKSIZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) err = xattr_iter_fixup(it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) it->ofs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) slice = min_t(unsigned int, PAGE_SIZE - it->ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) entry.e_name_len - processed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* handle name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) err = op->name(it, processed, it->kaddr + it->ofs, slice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) it->ofs += entry.e_name_len - processed + value_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) it->ofs += slice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) processed += slice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* 3. handle xattr value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) processed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (op->alloc_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) err = op->alloc_buffer(it, value_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) it->ofs += value_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) while (processed < value_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (it->ofs >= EROFS_BLKSIZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) DBG_BUGON(it->ofs > EROFS_BLKSIZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) err = xattr_iter_fixup(it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) it->ofs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) slice = min_t(unsigned int, PAGE_SIZE - it->ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) value_sz - processed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) op->value(it, processed, it->kaddr + it->ofs, slice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) it->ofs += slice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) processed += slice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* xattrs should be 4-byte aligned (on-disk constraint) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) it->ofs = EROFS_XATTR_ALIGN(it->ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return err < 0 ? err : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct getxattr_iter {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct xattr_iter it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) char *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int buffer_size, index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct qstr name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int xattr_entrymatch(struct xattr_iter *_it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct erofs_xattr_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return (it->index != entry->e_name_index ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) it->name.len != entry->e_name_len) ? -ENOATTR : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static int xattr_namematch(struct xattr_iter *_it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) unsigned int processed, char *buf, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return memcmp(buf, it->name.name + processed, len) ? -ENOATTR : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static int xattr_checkbuffer(struct xattr_iter *_it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) unsigned int value_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int err = it->buffer_size < value_sz ? -ERANGE : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) it->buffer_size = value_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return !it->buffer ? 1 : err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static void xattr_copyvalue(struct xattr_iter *_it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) unsigned int processed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) char *buf, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) memcpy(it->buffer + processed, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static const struct xattr_iter_handlers find_xattr_handlers = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .entry = xattr_entrymatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .name = xattr_namematch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .alloc_buffer = xattr_checkbuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .value = xattr_copyvalue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static int inline_getxattr(struct inode *inode, struct getxattr_iter *it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) unsigned int remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ret = inline_xattr_iter_begin(&it->it, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) remaining = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) while (remaining) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) ret = xattr_foreach(&it->it, &find_xattr_handlers, &remaining);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (ret != -ENOATTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) xattr_iter_end_final(&it->it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return ret ? ret : it->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static int shared_getxattr(struct inode *inode, struct getxattr_iter *it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct erofs_inode *const vi = EROFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) struct super_block *const sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) struct erofs_sb_info *const sbi = EROFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int ret = -ENOATTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) for (i = 0; i < vi->xattr_shared_count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) erofs_blk_t blkaddr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) xattrblock_addr(sbi, vi->xattr_shared_xattrs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) it->it.ofs = xattrblock_offset(sbi, vi->xattr_shared_xattrs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (!i || blkaddr != it->it.blkaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) xattr_iter_end(&it->it, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) it->it.page = erofs_get_meta_page(sb, blkaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (IS_ERR(it->it.page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return PTR_ERR(it->it.page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) it->it.kaddr = kmap_atomic(it->it.page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) it->it.blkaddr = blkaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ret = xattr_foreach(&it->it, &find_xattr_handlers, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (ret != -ENOATTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (vi->xattr_shared_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) xattr_iter_end_final(&it->it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return ret ? ret : it->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static bool erofs_xattr_user_list(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return test_opt(&EROFS_SB(dentry->d_sb)->ctx, XATTR_USER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static bool erofs_xattr_trusted_list(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return capable(CAP_SYS_ADMIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) int erofs_getxattr(struct inode *inode, int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) void *buffer, size_t buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct getxattr_iter it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) ret = init_inode_xattrs(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) it.index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) it.name.len = strlen(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (it.name.len > EROFS_NAME_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) it.name.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) it.buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) it.buffer_size = buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) it.it.sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ret = inline_getxattr(inode, &it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (ret == -ENOATTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ret = shared_getxattr(inode, &it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static int erofs_xattr_generic_get(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct dentry *unused, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) const char *name, void *buffer, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct erofs_sb_info *const sbi = EROFS_I_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) switch (handler->flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) case EROFS_XATTR_INDEX_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (!test_opt(&sbi->ctx, XATTR_USER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) case EROFS_XATTR_INDEX_TRUSTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) case EROFS_XATTR_INDEX_SECURITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return erofs_getxattr(inode, handler->flags, name, buffer, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) const struct xattr_handler erofs_xattr_user_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) .prefix = XATTR_USER_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) .flags = EROFS_XATTR_INDEX_USER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) .list = erofs_xattr_user_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) .get = erofs_xattr_generic_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) const struct xattr_handler erofs_xattr_trusted_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .prefix = XATTR_TRUSTED_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) .flags = EROFS_XATTR_INDEX_TRUSTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .list = erofs_xattr_trusted_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .get = erofs_xattr_generic_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) #ifdef CONFIG_EROFS_FS_SECURITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) const struct xattr_handler __maybe_unused erofs_xattr_security_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) .prefix = XATTR_SECURITY_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) .flags = EROFS_XATTR_INDEX_SECURITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) .get = erofs_xattr_generic_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) const struct xattr_handler *erofs_xattr_handlers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) &erofs_xattr_user_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) #ifdef CONFIG_EROFS_FS_POSIX_ACL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) &posix_acl_access_xattr_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) &posix_acl_default_xattr_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) &erofs_xattr_trusted_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) #ifdef CONFIG_EROFS_FS_SECURITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) &erofs_xattr_security_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct listxattr_iter {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct xattr_iter it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) char *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int buffer_size, buffer_ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static int xattr_entrylist(struct xattr_iter *_it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct erofs_xattr_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct listxattr_iter *it =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) container_of(_it, struct listxattr_iter, it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) unsigned int prefix_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) const char *prefix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) const struct xattr_handler *h =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) erofs_xattr_handler(entry->e_name_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (!h || (h->list && !h->list(it->dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) prefix = xattr_prefix(h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) prefix_len = strlen(prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (!it->buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) it->buffer_ofs += prefix_len + entry->e_name_len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (it->buffer_ofs + prefix_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) + entry->e_name_len + 1 > it->buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) memcpy(it->buffer + it->buffer_ofs, prefix, prefix_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) it->buffer_ofs += prefix_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static int xattr_namelist(struct xattr_iter *_it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) unsigned int processed, char *buf, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct listxattr_iter *it =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) container_of(_it, struct listxattr_iter, it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) memcpy(it->buffer + it->buffer_ofs, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) it->buffer_ofs += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static int xattr_skipvalue(struct xattr_iter *_it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) unsigned int value_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct listxattr_iter *it =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) container_of(_it, struct listxattr_iter, it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) it->buffer[it->buffer_ofs++] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static const struct xattr_iter_handlers list_xattr_handlers = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) .entry = xattr_entrylist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) .name = xattr_namelist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) .alloc_buffer = xattr_skipvalue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) .value = NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static int inline_listxattr(struct listxattr_iter *it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) unsigned int remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ret = inline_xattr_iter_begin(&it->it, d_inode(it->dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) remaining = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) while (remaining) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ret = xattr_foreach(&it->it, &list_xattr_handlers, &remaining);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) xattr_iter_end_final(&it->it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return ret ? ret : it->buffer_ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static int shared_listxattr(struct listxattr_iter *it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct inode *const inode = d_inode(it->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct erofs_inode *const vi = EROFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct super_block *const sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct erofs_sb_info *const sbi = EROFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) for (i = 0; i < vi->xattr_shared_count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) erofs_blk_t blkaddr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) xattrblock_addr(sbi, vi->xattr_shared_xattrs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) it->it.ofs = xattrblock_offset(sbi, vi->xattr_shared_xattrs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (!i || blkaddr != it->it.blkaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) xattr_iter_end(&it->it, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) it->it.page = erofs_get_meta_page(sb, blkaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (IS_ERR(it->it.page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return PTR_ERR(it->it.page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) it->it.kaddr = kmap_atomic(it->it.page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) it->it.blkaddr = blkaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ret = xattr_foreach(&it->it, &list_xattr_handlers, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (vi->xattr_shared_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) xattr_iter_end_final(&it->it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return ret ? ret : it->buffer_ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) ssize_t erofs_listxattr(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) char *buffer, size_t buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct listxattr_iter it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ret = init_inode_xattrs(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (ret == -ENOATTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) it.dentry = dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) it.buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) it.buffer_size = buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) it.buffer_ofs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) it.it.sb = dentry->d_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) ret = inline_listxattr(&it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (ret < 0 && ret != -ENOATTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return shared_listxattr(&it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) #ifdef CONFIG_EROFS_FS_POSIX_ACL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) struct posix_acl *erofs_get_acl(struct inode *inode, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct posix_acl *acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) int prefix, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) char *value = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) case ACL_TYPE_ACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) prefix = EROFS_XATTR_INDEX_POSIX_ACL_ACCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) case ACL_TYPE_DEFAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) prefix = EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) rc = erofs_getxattr(inode, prefix, "", NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (rc > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) value = kmalloc(rc, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (!value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) rc = erofs_getxattr(inode, prefix, "", value, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (rc == -ENOATTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) acl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) else if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) acl = ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) acl = posix_acl_from_xattr(&init_user_ns, value, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) kfree(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)