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