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