erofs: fix long xattr name prefix placement

Currently, xattr name prefixes are forcibly placed into the packed
inode if the fragments feature is enabled, and users have no option
to put them in plain form directly on disk.

This is inflexible. First, as mentioned above, users should be able
to store unwrapped long xattr name prefixes unconditionally
(COMPAT_PLAIN_XATTR_PFX). Second, since we now have the new metabox
inode to store metadata, it should be used when available instead
of the packed inode.

Fixes: 414091322c63 ("erofs: implement metadata compression")
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>

Gao Xiang 1fcf686d 181993bb

+16 -6
+5 -3
fs/erofs/erofs_fs.h
··· 12 /* to allow for x86 boot sectors and other oddities. */ 13 #define EROFS_SUPER_OFFSET 1024 14 15 - #define EROFS_FEATURE_COMPAT_SB_CHKSUM 0x00000001 16 - #define EROFS_FEATURE_COMPAT_MTIME 0x00000002 17 - #define EROFS_FEATURE_COMPAT_XATTR_FILTER 0x00000004 18 #define EROFS_FEATURE_COMPAT_SHARED_EA_IN_METABOX 0x00000008 19 20 /* 21 * Any bits that aren't in EROFS_ALL_FEATURE_INCOMPAT should
··· 12 /* to allow for x86 boot sectors and other oddities. */ 13 #define EROFS_SUPER_OFFSET 1024 14 15 + #define EROFS_FEATURE_COMPAT_SB_CHKSUM 0x00000001 16 + #define EROFS_FEATURE_COMPAT_MTIME 0x00000002 17 + #define EROFS_FEATURE_COMPAT_XATTR_FILTER 0x00000004 18 #define EROFS_FEATURE_COMPAT_SHARED_EA_IN_METABOX 0x00000008 19 + #define EROFS_FEATURE_COMPAT_PLAIN_XATTR_PFX 0x00000010 20 + 21 22 /* 23 * Any bits that aren't in EROFS_ALL_FEATURE_INCOMPAT should
+1
fs/erofs/internal.h
··· 234 EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM) 235 EROFS_FEATURE_FUNCS(xattr_filter, compat, COMPAT_XATTR_FILTER) 236 EROFS_FEATURE_FUNCS(shared_ea_in_metabox, compat, COMPAT_SHARED_EA_IN_METABOX) 237 238 static inline u64 erofs_nid_to_ino64(struct erofs_sb_info *sbi, erofs_nid_t nid) 239 {
··· 234 EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM) 235 EROFS_FEATURE_FUNCS(xattr_filter, compat, COMPAT_XATTR_FILTER) 236 EROFS_FEATURE_FUNCS(shared_ea_in_metabox, compat, COMPAT_SHARED_EA_IN_METABOX) 237 + EROFS_FEATURE_FUNCS(plain_xattr_pfx, compat, COMPAT_PLAIN_XATTR_PFX) 238 239 static inline u64 erofs_nid_to_ino64(struct erofs_sb_info *sbi, erofs_nid_t nid) 240 {
+10 -3
fs/erofs/xattr.c
··· 482 erofs_off_t pos = (erofs_off_t)sbi->xattr_prefix_start << 2; 483 struct erofs_xattr_prefix_item *pfs; 484 int ret = 0, i, len; 485 486 if (!sbi->xattr_prefix_count) 487 return 0; ··· 491 if (!pfs) 492 return -ENOMEM; 493 494 - if (sbi->packed_inode) 495 - buf.mapping = sbi->packed_inode->i_mapping; 496 - else 497 (void)erofs_init_metabuf(&buf, sb, false); 498 499 for (i = 0; i < sbi->xattr_prefix_count; i++) {
··· 482 erofs_off_t pos = (erofs_off_t)sbi->xattr_prefix_start << 2; 483 struct erofs_xattr_prefix_item *pfs; 484 int ret = 0, i, len; 485 + bool plain = erofs_sb_has_plain_xattr_pfx(sbi); 486 487 if (!sbi->xattr_prefix_count) 488 return 0; ··· 490 if (!pfs) 491 return -ENOMEM; 492 493 + if (!plain) { 494 + if (erofs_sb_has_metabox(sbi)) 495 + (void)erofs_init_metabuf(&buf, sb, true); 496 + else if (sbi->packed_inode) 497 + buf.mapping = sbi->packed_inode->i_mapping; 498 + else 499 + plain = true; 500 + } 501 + if (plain) 502 (void)erofs_init_metabuf(&buf, sb, false); 503 504 for (i = 0; i < sbi->xattr_prefix_count; i++) {