Skip to content

Commit 9e38291

Browse files
lostjefflehsiangkao
authored andcommitted
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>
1 parent b3bfcb9 commit 9e38291

4 files changed

Lines changed: 73 additions & 3 deletions

File tree

fs/erofs/internal.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ struct erofs_fscache {
117117
char *name;
118118
};
119119

120+
struct erofs_xattr_prefix_item {
121+
struct erofs_xattr_long_prefix *prefix;
122+
u8 infix_len;
123+
};
124+
120125
struct erofs_sb_info {
121126
struct erofs_mount_opts opt; /* options */
122127
#ifdef CONFIG_EROFS_FS_ZIP
@@ -145,6 +150,9 @@ struct erofs_sb_info {
145150
u32 meta_blkaddr;
146151
#ifdef CONFIG_EROFS_FS_XATTR
147152
u32 xattr_blkaddr;
153+
u32 xattr_prefix_start;
154+
u8 xattr_prefix_count;
155+
struct erofs_xattr_prefix_item *xattr_prefixes;
148156
#endif
149157
u16 device_id_mask; /* valid bits of device id to be used */
150158

@@ -440,6 +448,8 @@ extern const struct iomap_ops z_erofs_iomap_report_ops;
440448
#define EROFS_REG_COOKIE_SHARE 0x0001
441449
#define EROFS_REG_COOKIE_NEED_NOEXIST 0x0002
442450

451+
void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
452+
erofs_off_t *offset, int *lengthp);
443453
void erofs_unmap_metabuf(struct erofs_buf *buf);
444454
void erofs_put_metabuf(struct erofs_buf *buf);
445455
void *erofs_bread(struct erofs_buf *buf, erofs_blk_t blkaddr,

fs/erofs/super.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,9 @@ static bool check_layout_compatibility(struct super_block *sb,
126126
return true;
127127
}
128128

129-
#ifdef CONFIG_EROFS_FS_ZIP
130129
/* read variable-sized metadata, offset will be aligned by 4-byte */
131-
static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
132-
erofs_off_t *offset, int *lengthp)
130+
void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
131+
erofs_off_t *offset, int *lengthp)
133132
{
134133
u8 *buffer, *ptr;
135134
int len, i, cnt;
@@ -162,6 +161,7 @@ static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
162161
return buffer;
163162
}
164163

164+
#ifdef CONFIG_EROFS_FS_ZIP
165165
static int erofs_load_compr_cfgs(struct super_block *sb,
166166
struct erofs_super_block *dsb)
167167
{

fs/erofs/xattr.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,62 @@ ssize_t erofs_listxattr(struct dentry *dentry,
610610
return ret;
611611
}
612612

613+
void erofs_xattr_prefixes_cleanup(struct super_block *sb)
614+
{
615+
struct erofs_sb_info *sbi = EROFS_SB(sb);
616+
int i;
617+
618+
if (sbi->xattr_prefixes) {
619+
for (i = 0; i < sbi->xattr_prefix_count; i++)
620+
kfree(sbi->xattr_prefixes[i].prefix);
621+
kfree(sbi->xattr_prefixes);
622+
sbi->xattr_prefixes = NULL;
623+
}
624+
}
625+
626+
int erofs_xattr_prefixes_init(struct super_block *sb)
627+
{
628+
struct erofs_sb_info *sbi = EROFS_SB(sb);
629+
struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
630+
erofs_off_t pos = (erofs_off_t)sbi->xattr_prefix_start << 2;
631+
struct erofs_xattr_prefix_item *pfs;
632+
int ret = 0, i, len;
633+
634+
if (!sbi->xattr_prefix_count)
635+
return 0;
636+
637+
pfs = kzalloc(sbi->xattr_prefix_count * sizeof(*pfs), GFP_KERNEL);
638+
if (!pfs)
639+
return -ENOMEM;
640+
641+
if (erofs_sb_has_fragments(sbi))
642+
buf.inode = sbi->packed_inode;
643+
else
644+
erofs_init_metabuf(&buf, sb);
645+
646+
for (i = 0; i < sbi->xattr_prefix_count; i++) {
647+
void *ptr = erofs_read_metadata(sb, &buf, &pos, &len);
648+
649+
if (IS_ERR(ptr)) {
650+
ret = PTR_ERR(ptr);
651+
break;
652+
} else if (len < sizeof(*pfs->prefix) ||
653+
len > EROFS_NAME_LEN + sizeof(*pfs->prefix)) {
654+
kfree(ptr);
655+
ret = -EFSCORRUPTED;
656+
break;
657+
}
658+
pfs[i].prefix = ptr;
659+
pfs[i].infix_len = len - sizeof(struct erofs_xattr_long_prefix);
660+
}
661+
662+
erofs_put_metabuf(&buf);
663+
sbi->xattr_prefixes = pfs;
664+
if (ret)
665+
erofs_xattr_prefixes_cleanup(sb);
666+
return ret;
667+
}
668+
613669
#ifdef CONFIG_EROFS_FS_POSIX_ACL
614670
struct posix_acl *erofs_get_acl(struct inode *inode, int type, bool rcu)
615671
{

fs/erofs/xattr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,13 @@ static inline const struct xattr_handler *erofs_xattr_handler(unsigned int idx)
4040

4141
extern const struct xattr_handler *erofs_xattr_handlers[];
4242

43+
int erofs_xattr_prefixes_init(struct super_block *sb);
44+
void erofs_xattr_prefixes_cleanup(struct super_block *sb);
4345
int erofs_getxattr(struct inode *, int, const char *, void *, size_t);
4446
ssize_t erofs_listxattr(struct dentry *, char *, size_t);
4547
#else
48+
static inline int erofs_xattr_prefixes_init(struct super_block *sb) { return 0; }
49+
static inline void erofs_xattr_prefixes_cleanup(struct super_block *sb) {}
4650
static inline int erofs_getxattr(struct inode *inode, int index,
4751
const char *name, void *buffer,
4852
size_t buffer_size)

0 commit comments

Comments
 (0)