mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
f2fs: describe xattr block layout dynamically
The usable capacity of dedicated on-disk extended attribute blocks and inline xattr regions scales with the filesystem block size. Parameterize VALID_XATTR_BLOCK_SIZE and MAX_INLINE_XATTR_SIZE to calculate usable xattr limits dynamically from sbi->blocksize rather than hardcoding PAGE_SIZE or DEF_ADDRS_PER_INODE. Update mount option consistency validation for inline_xattr_size to evaluate allowed boundaries dynamically against the runtime block size. Signed-off-by: Kelvin Zhang <zhangxp1998@gmail.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
87f9a4888f
commit
48747bfe30
|
|
@ -337,12 +337,13 @@ static bool sanity_check_inode(struct inode *inode, struct folio *node_folio)
|
|||
}
|
||||
|
||||
if (f2fs_sb_has_flexible_inline_xattr(sbi) &&
|
||||
(fi->i_inline_xattr_size > MAX_INLINE_XATTR_SIZE ||
|
||||
(fi->i_inline_xattr_size > MAX_INLINE_XATTR_SIZE(i_blocksize(inode)) ||
|
||||
(f2fs_has_inline_xattr(inode) &&
|
||||
fi->i_inline_xattr_size < MIN_INLINE_XATTR_SIZE))) {
|
||||
f2fs_warn(sbi, "%s: inode (ino=%llx) has corrupted i_inline_xattr_size: %d, min: %zu, max: %lu",
|
||||
f2fs_warn(sbi, "%s: inode (ino=%llx) has corrupted i_inline_xattr_size: %d, min: %zu, max: %zu",
|
||||
__func__, inode->i_ino, fi->i_inline_xattr_size,
|
||||
MIN_INLINE_XATTR_SIZE, MAX_INLINE_XATTR_SIZE);
|
||||
MIN_INLINE_XATTR_SIZE,
|
||||
(size_t)MAX_INLINE_XATTR_SIZE(i_blocksize(inode)));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2919,7 +2919,7 @@ int f2fs_recover_xattr_data(struct inode *inode, struct folio *folio)
|
|||
/* 3: update and set xattr node page dirty */
|
||||
if (folio) {
|
||||
memcpy(F2FS_NODE(xfolio), F2FS_NODE(folio),
|
||||
VALID_XATTR_BLOCK_SIZE);
|
||||
VALID_XATTR_BLOCK_SIZE(inode));
|
||||
folio_mark_dirty(xfolio);
|
||||
}
|
||||
f2fs_folio_put(xfolio, true);
|
||||
|
|
|
|||
|
|
@ -855,9 +855,11 @@ static int f2fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||
break;
|
||||
case Opt_inline_xattr_size:
|
||||
if (result.int_32 < MIN_INLINE_XATTR_SIZE ||
|
||||
result.int_32 > MAX_INLINE_XATTR_SIZE) {
|
||||
result.int_32 >
|
||||
MAX_INLINE_XATTR_SIZE(F2FS_MAX_BLKSIZE)) {
|
||||
f2fs_err(NULL, "inline xattr size is out of range: %u ~ %u",
|
||||
(u32)MIN_INLINE_XATTR_SIZE, (u32)MAX_INLINE_XATTR_SIZE);
|
||||
(u32)MIN_INLINE_XATTR_SIZE,
|
||||
(u32)MAX_INLINE_XATTR_SIZE(F2FS_MAX_BLKSIZE));
|
||||
return -EINVAL;
|
||||
}
|
||||
ctx_set_opt(ctx, F2FS_MOUNT_INLINE_XATTR_SIZE);
|
||||
|
|
@ -1596,6 +1598,8 @@ static int f2fs_check_opt_consistency(struct fs_context *fc,
|
|||
}
|
||||
|
||||
if (ctx_test_opt(ctx, F2FS_MOUNT_INLINE_XATTR_SIZE)) {
|
||||
int min_size, max_size;
|
||||
|
||||
if (!f2fs_sb_has_extra_attr(sbi) ||
|
||||
!f2fs_sb_has_flexible_inline_xattr(sbi)) {
|
||||
f2fs_err(sbi, "extra_attr or flexible_inline_xattr feature is off");
|
||||
|
|
@ -1605,6 +1609,15 @@ static int f2fs_check_opt_consistency(struct fs_context *fc,
|
|||
f2fs_err(sbi, "inline_xattr_size option should be set with inline_xattr option");
|
||||
return -EINVAL;
|
||||
}
|
||||
min_size = MIN_INLINE_XATTR_SIZE;
|
||||
max_size = MAX_INLINE_XATTR_SIZE(sbi->blocksize);
|
||||
|
||||
if (F2FS_OPTION(sbi).inline_xattr_size < min_size ||
|
||||
F2FS_OPTION(sbi).inline_xattr_size > max_size) {
|
||||
f2fs_err(sbi, "inline xattr size is out of range: %d ~ %d",
|
||||
min_size, max_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx_test_opt(ctx, F2FS_MOUNT_ATGC) &&
|
||||
|
|
|
|||
|
|
@ -310,7 +310,8 @@ static int read_xattr_block(struct inode *inode, void *txattr_addr)
|
|||
return PTR_ERR(xfolio);
|
||||
|
||||
xattr_addr = folio_address(xfolio);
|
||||
memcpy(txattr_addr + inline_size, xattr_addr, VALID_XATTR_BLOCK_SIZE);
|
||||
memcpy(txattr_addr + inline_size, xattr_addr,
|
||||
VALID_XATTR_BLOCK_SIZE(inode));
|
||||
f2fs_folio_put(xfolio, true);
|
||||
|
||||
return 0;
|
||||
|
|
@ -393,7 +394,7 @@ static int read_all_xattrs(struct inode *inode, struct folio *ifolio,
|
|||
{
|
||||
struct f2fs_xattr_header *header;
|
||||
nid_t xnid = F2FS_I(inode)->i_xattr_nid;
|
||||
unsigned int size = VALID_XATTR_BLOCK_SIZE;
|
||||
unsigned int size = VALID_XATTR_BLOCK_SIZE(inode);
|
||||
unsigned int inline_size = inline_xattr_size(inode);
|
||||
void *txattr_addr;
|
||||
int err;
|
||||
|
|
@ -502,7 +503,8 @@ static inline int write_all_xattrs(struct inode *inode, __u32 hsize,
|
|||
|
||||
if (inline_size)
|
||||
memcpy(inline_addr, txattr_addr, inline_size);
|
||||
memcpy(xattr_addr, txattr_addr + inline_size, VALID_XATTR_BLOCK_SIZE);
|
||||
memcpy(xattr_addr, txattr_addr + inline_size,
|
||||
VALID_XATTR_BLOCK_SIZE(inode));
|
||||
|
||||
if (inline_size)
|
||||
folio_mark_dirty(ifolio ? ifolio : in_folio);
|
||||
|
|
|
|||
|
|
@ -71,21 +71,22 @@ struct f2fs_xattr_entry {
|
|||
for (entry = XATTR_FIRST_ENTRY(addr);\
|
||||
!IS_XATTR_LAST_ENTRY(entry);\
|
||||
entry = XATTR_NEXT_ENTRY(entry))
|
||||
#define VALID_XATTR_BLOCK_SIZE (PAGE_SIZE - sizeof(struct node_footer))
|
||||
#define VALID_XATTR_BLOCK_SIZE(i) (i_blocksize(i) - \
|
||||
sizeof(struct node_footer))
|
||||
#define XATTR_PADDING_SIZE (sizeof(__u32))
|
||||
#define XATTR_SIZE(i) ((F2FS_I(i)->i_xattr_nid ? \
|
||||
VALID_XATTR_BLOCK_SIZE : 0) + \
|
||||
VALID_XATTR_BLOCK_SIZE(i) : 0) + \
|
||||
(inline_xattr_size(i)))
|
||||
#define MIN_OFFSET(i) XATTR_ALIGN(inline_xattr_size(i) + \
|
||||
VALID_XATTR_BLOCK_SIZE)
|
||||
VALID_XATTR_BLOCK_SIZE(i))
|
||||
|
||||
#define MAX_VALUE_LEN(i) (MIN_OFFSET(i) - \
|
||||
sizeof(struct f2fs_xattr_header) - \
|
||||
sizeof(struct f2fs_xattr_entry))
|
||||
|
||||
#define MIN_INLINE_XATTR_SIZE (sizeof(struct f2fs_xattr_header) / sizeof(__le32))
|
||||
#define MAX_INLINE_XATTR_SIZE \
|
||||
(F2FS_DEF_ADDRS_PER_INODE(F2FS_BLKSIZE) - \
|
||||
#define MAX_INLINE_XATTR_SIZE(blocksize) \
|
||||
(F2FS_DEF_ADDRS_PER_INODE(blocksize) - \
|
||||
F2FS_TOTAL_EXTRA_ATTR_SIZE / sizeof(__le32) - \
|
||||
DEF_INLINE_RESERVED_SIZE - \
|
||||
MIN_INLINE_DENTRY_SIZE / sizeof(__le32))
|
||||
|
|
|
|||
|
|
@ -15,7 +15,10 @@
|
|||
#define F2FS_MIN_LOG_SECTOR_SIZE 9 /* 9 bits for 512 bytes */
|
||||
#define F2FS_MAX_LOG_SECTOR_SIZE PAGE_SHIFT /* Max is Block Size */
|
||||
#define F2FS_LOG_SECTORS_PER_BLOCK (PAGE_SHIFT - 9) /* log number for sector/blk */
|
||||
#define F2FS_MIN_LOG_BLOCKSIZE 12
|
||||
#define F2FS_MIN_BLKSIZE 4096UL
|
||||
#define F2FS_BLKSIZE PAGE_SIZE /* support only block == page */
|
||||
#define F2FS_MAX_BLKSIZE PAGE_SIZE
|
||||
#define F2FS_BLKSIZE_BITS PAGE_SHIFT /* bits for F2FS_BLKSIZE */
|
||||
#define F2FS_MAX_EXTENSION 64 /* # of extension entries */
|
||||
#define F2FS_EXTENSION_LEN 8 /* max size of extension */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user