mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-18 16:44:27 +08:00
erofs: add helpers to load long xattr name prefixes
Long xattr name prefixes will be scanned upon mounting and the in-memory long xattr name prefix array will be initialized accordingly. Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com> Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com> Acked-by: Chao Yu <chao@kernel.org> Link: https://lore.kernel.org/r/20230407141710.113882-6-jefflexu@linux.alibaba.com Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
This commit is contained in:
parent
b3bfcb9dbf
commit
9e38291461
@ -117,6 +117,11 @@ struct erofs_fscache {
|
||||
char *name;
|
||||
};
|
||||
|
||||
struct erofs_xattr_prefix_item {
|
||||
struct erofs_xattr_long_prefix *prefix;
|
||||
u8 infix_len;
|
||||
};
|
||||
|
||||
struct erofs_sb_info {
|
||||
struct erofs_mount_opts opt; /* options */
|
||||
#ifdef CONFIG_EROFS_FS_ZIP
|
||||
@ -145,6 +150,9 @@ struct erofs_sb_info {
|
||||
u32 meta_blkaddr;
|
||||
#ifdef CONFIG_EROFS_FS_XATTR
|
||||
u32 xattr_blkaddr;
|
||||
u32 xattr_prefix_start;
|
||||
u8 xattr_prefix_count;
|
||||
struct erofs_xattr_prefix_item *xattr_prefixes;
|
||||
#endif
|
||||
u16 device_id_mask; /* valid bits of device id to be used */
|
||||
|
||||
@ -440,6 +448,8 @@ extern const struct iomap_ops z_erofs_iomap_report_ops;
|
||||
#define EROFS_REG_COOKIE_SHARE 0x0001
|
||||
#define EROFS_REG_COOKIE_NEED_NOEXIST 0x0002
|
||||
|
||||
void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
|
||||
erofs_off_t *offset, int *lengthp);
|
||||
void erofs_unmap_metabuf(struct erofs_buf *buf);
|
||||
void erofs_put_metabuf(struct erofs_buf *buf);
|
||||
void *erofs_bread(struct erofs_buf *buf, erofs_blk_t blkaddr,
|
||||
|
@ -126,10 +126,9 @@ static bool check_layout_compatibility(struct super_block *sb,
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EROFS_FS_ZIP
|
||||
/* read variable-sized metadata, offset will be aligned by 4-byte */
|
||||
static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
|
||||
erofs_off_t *offset, int *lengthp)
|
||||
void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
|
||||
erofs_off_t *offset, int *lengthp)
|
||||
{
|
||||
u8 *buffer, *ptr;
|
||||
int len, i, cnt;
|
||||
@ -162,6 +161,7 @@ static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EROFS_FS_ZIP
|
||||
static int erofs_load_compr_cfgs(struct super_block *sb,
|
||||
struct erofs_super_block *dsb)
|
||||
{
|
||||
|
@ -610,6 +610,62 @@ ssize_t erofs_listxattr(struct dentry *dentry,
|
||||
return ret;
|
||||
}
|
||||
|
||||
void erofs_xattr_prefixes_cleanup(struct super_block *sb)
|
||||
{
|
||||
struct erofs_sb_info *sbi = EROFS_SB(sb);
|
||||
int i;
|
||||
|
||||
if (sbi->xattr_prefixes) {
|
||||
for (i = 0; i < sbi->xattr_prefix_count; i++)
|
||||
kfree(sbi->xattr_prefixes[i].prefix);
|
||||
kfree(sbi->xattr_prefixes);
|
||||
sbi->xattr_prefixes = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int erofs_xattr_prefixes_init(struct super_block *sb)
|
||||
{
|
||||
struct erofs_sb_info *sbi = EROFS_SB(sb);
|
||||
struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
|
||||
erofs_off_t pos = (erofs_off_t)sbi->xattr_prefix_start << 2;
|
||||
struct erofs_xattr_prefix_item *pfs;
|
||||
int ret = 0, i, len;
|
||||
|
||||
if (!sbi->xattr_prefix_count)
|
||||
return 0;
|
||||
|
||||
pfs = kzalloc(sbi->xattr_prefix_count * sizeof(*pfs), GFP_KERNEL);
|
||||
if (!pfs)
|
||||
return -ENOMEM;
|
||||
|
||||
if (erofs_sb_has_fragments(sbi))
|
||||
buf.inode = sbi->packed_inode;
|
||||
else
|
||||
erofs_init_metabuf(&buf, sb);
|
||||
|
||||
for (i = 0; i < sbi->xattr_prefix_count; i++) {
|
||||
void *ptr = erofs_read_metadata(sb, &buf, &pos, &len);
|
||||
|
||||
if (IS_ERR(ptr)) {
|
||||
ret = PTR_ERR(ptr);
|
||||
break;
|
||||
} else if (len < sizeof(*pfs->prefix) ||
|
||||
len > EROFS_NAME_LEN + sizeof(*pfs->prefix)) {
|
||||
kfree(ptr);
|
||||
ret = -EFSCORRUPTED;
|
||||
break;
|
||||
}
|
||||
pfs[i].prefix = ptr;
|
||||
pfs[i].infix_len = len - sizeof(struct erofs_xattr_long_prefix);
|
||||
}
|
||||
|
||||
erofs_put_metabuf(&buf);
|
||||
sbi->xattr_prefixes = pfs;
|
||||
if (ret)
|
||||
erofs_xattr_prefixes_cleanup(sb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EROFS_FS_POSIX_ACL
|
||||
struct posix_acl *erofs_get_acl(struct inode *inode, int type, bool rcu)
|
||||
{
|
||||
|
@ -40,9 +40,13 @@ static inline const struct xattr_handler *erofs_xattr_handler(unsigned int idx)
|
||||
|
||||
extern const struct xattr_handler *erofs_xattr_handlers[];
|
||||
|
||||
int erofs_xattr_prefixes_init(struct super_block *sb);
|
||||
void erofs_xattr_prefixes_cleanup(struct super_block *sb);
|
||||
int erofs_getxattr(struct inode *, int, const char *, void *, size_t);
|
||||
ssize_t erofs_listxattr(struct dentry *, char *, size_t);
|
||||
#else
|
||||
static inline int erofs_xattr_prefixes_init(struct super_block *sb) { return 0; }
|
||||
static inline void erofs_xattr_prefixes_cleanup(struct super_block *sb) {}
|
||||
static inline int erofs_getxattr(struct inode *inode, int index,
|
||||
const char *name, void *buffer,
|
||||
size_t buffer_size)
|
||||
|
Loading…
Reference in New Issue
Block a user