2023-02-20 02:50:55

by Jingbo Xu

[permalink] [raw]
Subject: [PATCH v3 2/2] erofs: set block size to the on-disk block size

Set the block size to that specified in on-disk superblock.

Also remove the hard constraint of PAGE_SIZE block size for the
uncompressed device backend. This constraint is temporarily remained
for compressed device and fscache backend, as there is more work needed
to handle the condition where the block size is not equal to PAGE_SIZE.

It is worth noting that the on-disk block size is read prior to
erofs_superblock_csum_verify(), as the read block size is needed in the
latter.

Signed-off-by: Jingbo Xu <[email protected]>
---
fs/erofs/erofs_fs.h | 2 +-
fs/erofs/inode.c | 3 ++-
fs/erofs/internal.h | 8 --------
fs/erofs/super.c | 42 +++++++++++++++++++++++++++---------------
4 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h
index dbcd24371002..5c7647d68c07 100644
--- a/fs/erofs/erofs_fs.h
+++ b/fs/erofs/erofs_fs.h
@@ -53,7 +53,7 @@ struct erofs_super_block {
__le32 magic; /* file system magic number */
__le32 checksum; /* crc32c(super_block) */
__le32 feature_compat;
- __u8 blkszbits; /* support block_size == PAGE_SIZE only */
+ __u8 blkszbits; /* filesystem block size */
__u8 sb_extslots; /* superblock size = 128 + sb_extslots * 16 */

__le16 root_nid; /* nid of root directory */
diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c
index de26dac4e07e..0e6ff8a98c68 100644
--- a/fs/erofs/inode.c
+++ b/fs/erofs/inode.c
@@ -291,7 +291,8 @@ static int erofs_fill_inode(struct inode *inode)
}

if (erofs_inode_is_data_compressed(vi->datalayout)) {
- if (!erofs_is_fscache_mode(inode->i_sb))
+ if (!erofs_is_fscache_mode(inode->i_sb) &&
+ inode->i_sb->s_blocksize_bits == PAGE_SHIFT)
err = z_erofs_fill_inode(inode);
else
err = -EOPNOTSUPP;
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index d8019d835405..612543915e9e 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -240,14 +240,6 @@ static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp)
VAL != EROFS_LOCKED_MAGIC);
}

-/* we strictly follow PAGE_SIZE and no buffer head yet */
-#define LOG_BLOCK_SIZE PAGE_SHIFT
-#define EROFS_BLKSIZ (1 << LOG_BLOCK_SIZE)
-
-#if (EROFS_BLKSIZ % 4096 || !EROFS_BLKSIZ)
-#error erofs cannot be used in this platform
-#endif
-
enum erofs_kmap_type {
EROFS_NO_KMAP, /* don't map the buffer */
EROFS_KMAP, /* use kmap_local_page() to map the buffer */
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index c97615c96ef8..89011a4ed274 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -349,6 +349,14 @@ static int erofs_read_superblock(struct super_block *sb)
goto out;
}

+ blkszbits = dsb->blkszbits;
+ sbi->blkszbits = dsb->blkszbits;
+ if (blkszbits < 9 || blkszbits > PAGE_SHIFT) {
+ erofs_err(sb, "blkszbits %u isn't supported on this platform",
+ blkszbits);
+ goto out;
+ }
+
sbi->feature_compat = le32_to_cpu(dsb->feature_compat);
if (erofs_sb_has_sb_chksum(sbi)) {
ret = erofs_superblock_csum_verify(sb, data);
@@ -357,19 +365,11 @@ static int erofs_read_superblock(struct super_block *sb)
}

ret = -EINVAL;
- blkszbits = dsb->blkszbits;
- /* 9(512 bytes) + LOG_SECTORS_PER_BLOCK == LOG_BLOCK_SIZE */
- if (blkszbits != LOG_BLOCK_SIZE) {
- erofs_err(sb, "blkszbits %u isn't supported on this platform",
- blkszbits);
- goto out;
- }
-
if (!check_layout_compatibility(sb, dsb))
goto out;

sbi->sb_size = 128 + dsb->sb_extslots * EROFS_SB_EXTSLOT_SIZE;
- if (sbi->sb_size > EROFS_BLKSIZ) {
+ if (sbi->sb_size > PAGE_SIZE - EROFS_SUPER_OFFSET) {
erofs_err(sb, "invalid sb_extslots %u (more than a fs block)",
sbi->sb_size);
goto out;
@@ -736,8 +736,8 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)

sbi->blkszbits = PAGE_SHIFT;
if (erofs_is_fscache_mode(sb)) {
- sb->s_blocksize = EROFS_BLKSIZ;
- sb->s_blocksize_bits = LOG_BLOCK_SIZE;
+ sb->s_blocksize = PAGE_SIZE;
+ sb->s_blocksize_bits = PAGE_SHIFT;

err = erofs_fscache_register_fs(sb);
if (err)
@@ -747,8 +747,8 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
if (err)
return err;
} else {
- if (!sb_set_blocksize(sb, EROFS_BLKSIZ)) {
- erofs_err(sb, "failed to set erofs blksize");
+ if (!sb_set_blocksize(sb, PAGE_SIZE)) {
+ errorfc(fc, "failed to set initial blksize");
return -EINVAL;
}

@@ -761,12 +761,24 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
if (err)
return err;

- if (test_opt(&sbi->opt, DAX_ALWAYS)) {
- BUILD_BUG_ON(EROFS_BLKSIZ != PAGE_SIZE);
+ if (sb->s_blocksize_bits != sbi->blkszbits) {
+ if (erofs_is_fscache_mode(sb)) {
+ errorfc(fc, "unsupported blksize for fscache mode");
+ return -EINVAL;
+ }
+ if (!sb_set_blocksize(sb, 1 << sbi->blkszbits)) {
+ errorfc(fc, "failed to set erofs blksize");
+ return -EINVAL;
+ }
+ }

+ if (test_opt(&sbi->opt, DAX_ALWAYS)) {
if (!sbi->dax_dev) {
errorfc(fc, "DAX unsupported by block device. Turning off DAX.");
clear_opt(&sbi->opt, DAX_ALWAYS);
+ } else if (sbi->blkszbits != PAGE_SHIFT) {
+ errorfc(fc, "unsupported blocksize for DAX");
+ clear_opt(&sbi->opt, DAX_ALWAYS);
}
}

--
2.19.1.6.gb485710b



2023-03-02 13:23:55

by Gao Xiang

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] erofs: set block size to the on-disk block size

Hi Jingbo,

On 2023/2/20 10:50, Jingbo Xu wrote:
> Set the block size to that specified in on-disk superblock.
>
> Also remove the hard constraint of PAGE_SIZE block size for the
> uncompressed device backend. This constraint is temporarily remained
> for compressed device and fscache backend, as there is more work needed
> to handle the condition where the block size is not equal to PAGE_SIZE.
>
> It is worth noting that the on-disk block size is read prior to
> erofs_superblock_csum_verify(), as the read block size is needed in the
> latter.
>
> Signed-off-by: Jingbo Xu <[email protected]>
> ---
> fs/erofs/erofs_fs.h | 2 +-
> fs/erofs/inode.c | 3 ++-
> fs/erofs/internal.h | 8 --------
> fs/erofs/super.c | 42 +++++++++++++++++++++++++++---------------
> 4 files changed, 30 insertions(+), 25 deletions(-)
>
> diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h
> index dbcd24371002..5c7647d68c07 100644
> --- a/fs/erofs/erofs_fs.h
> +++ b/fs/erofs/erofs_fs.h
> @@ -53,7 +53,7 @@ struct erofs_super_block {
> __le32 magic; /* file system magic number */
> __le32 checksum; /* crc32c(super_block) */
> __le32 feature_compat;
> - __u8 blkszbits; /* support block_size == PAGE_SIZE only */
> + __u8 blkszbits; /* filesystem block size */
> __u8 sb_extslots; /* superblock size = 128 + sb_extslots * 16 */
>
> __le16 root_nid; /* nid of root directory */

Due to we already support < page_size blocks, laterly, we'd consider
refer to tar data blobs (which is 512-byte aligned) for OCI
containers.

So we will have another use case is to use 512-byte block size, but
in that case, dir block size is too small.

So I'd like to add a reserved bit
__u8 dirblkbits;

for this.

> diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c
> index de26dac4e07e..0e6ff8a98c68 100644
> --- a/fs/erofs/inode.c
> +++ b/fs/erofs/inode.c
> @@ -291,7 +291,8 @@ static int erofs_fill_inode(struct inode *inode)
> }
>
> if (erofs_inode_is_data_compressed(vi->datalayout)) {
> - if (!erofs_is_fscache_mode(inode->i_sb))
> + if (!erofs_is_fscache_mode(inode->i_sb) &&
> + inode->i_sb->s_blocksize_bits == PAGE_SHIFT)
> err = z_erofs_fill_inode(inode);
> else
> err = -EOPNOTSUPP;
> diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
> index d8019d835405..612543915e9e 100644
> --- a/fs/erofs/internal.h
> +++ b/fs/erofs/internal.h
> @@ -240,14 +240,6 @@ static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp)
> VAL != EROFS_LOCKED_MAGIC);
> }
>
> -/* we strictly follow PAGE_SIZE and no buffer head yet */
> -#define LOG_BLOCK_SIZE PAGE_SHIFT
> -#define EROFS_BLKSIZ (1 << LOG_BLOCK_SIZE)
> -
> -#if (EROFS_BLKSIZ % 4096 || !EROFS_BLKSIZ)
> -#error erofs cannot be used in this platform
> -#endif
> -
> enum erofs_kmap_type {
> EROFS_NO_KMAP, /* don't map the buffer */
> EROFS_KMAP, /* use kmap_local_page() to map the buffer */
> diff --git a/fs/erofs/super.c b/fs/erofs/super.c
> index c97615c96ef8..89011a4ed274 100644
> --- a/fs/erofs/super.c
> +++ b/fs/erofs/super.c
> @@ -349,6 +349,14 @@ static int erofs_read_superblock(struct super_block *sb)
> goto out;
> }
>
> + blkszbits = dsb->blkszbits;
> + sbi->blkszbits = dsb->blkszbits;
> + if (blkszbits < 9 || blkszbits > PAGE_SHIFT) {
> + erofs_err(sb, "blkszbits %u isn't supported on this platform",
> + blkszbits);
> + goto out;
> + }

Also,
if (blkszbits != PAGE_SHIFT && dsb->dirblkbits) {
erofs_err("dirblkbits %u isn't supported", dsb->dirblkbits);
goto out;
}

Thanks,
Gao Xiang