diff --git a/src/dragonball/dbs_virtio_devices/src/vsock/mod.rs b/src/dragonball/dbs_virtio_devices/src/vsock/mod.rs index ab675a0cbf..433ef46589 100644 --- a/src/dragonball/dbs_virtio_devices/src/vsock/mod.rs +++ b/src/dragonball/dbs_virtio_devices/src/vsock/mod.rs @@ -14,7 +14,7 @@ mod packet; use std::os::unix::io::AsRawFd; -use vm_memory::GuestMemoryError; +use vm_memory::{GuestAddress, GuestMemoryError}; pub use self::defs::{NUM_QUEUES, QUEUE_SIZES}; pub use self::device::Vsock; @@ -136,6 +136,9 @@ pub enum VsockError { /// Encountered an unexpected read-only virtio descriptor. #[error("Encountered an unexpected read-only virtio descriptor")] UnwritableDescriptor, + /// Overflow occurred during an arithmetic operation. + #[error("Overflow occurred during an arithmetic operation, base({0:?}) + offset({0:?})")] + Overflow(GuestAddress, usize), } type Result = std::result::Result; diff --git a/src/dragonball/dbs_virtio_devices/src/vsock/packet.rs b/src/dragonball/dbs_virtio_devices/src/vsock/packet.rs index c25df09a20..095b8e5aef 100644 --- a/src/dragonball/dbs_virtio_devices/src/vsock/packet.rs +++ b/src/dragonball/dbs_virtio_devices/src/vsock/packet.rs @@ -18,7 +18,7 @@ use std::ops::{Deref, DerefMut}; use virtio_queue::{Descriptor, DescriptorChain}; -use vm_memory::GuestMemory; +use vm_memory::{Address, GuestMemory}; use super::defs; use super::{Result, VsockError}; @@ -190,15 +190,25 @@ pub struct BufWrapper { impl BufWrapper { /// Create the data wrapper from a virtq descriptor. - pub fn from_virtq_desc(desc: &Descriptor, mem: &M) -> Result { + /// Add offset and size, to support different forms of descriptor. + pub fn from_virtq_desc( + desc: &Descriptor, + mem: &M, + offset: usize, + size: usize, + ) -> Result { // Check the guest provided pointer and data size. mem.checked_offset(desc.addr(), desc.len() as usize) .ok_or_else(|| VsockError::GuestMemoryBounds(desc.addr().0, desc.len() as usize))?; Ok(Self::from_fat_ptr_unchecked( - mem.get_host_address(desc.addr()) - .map_err(VsockError::GuestMemory)?, - desc.len() as usize, + mem.get_host_address( + desc.addr() + .checked_add(offset as u64) + .ok_or(VsockError::Overflow(desc.addr(), offset))?, + ) + .map_err(VsockError::GuestMemory)?, + size, )) } @@ -265,23 +275,48 @@ impl VsockPacket { return Ok(Self { hdr, buf: None }); } - let buf_desc = desc_chain.next().ok_or(VsockError::BufDescMissing)?; + if desc.has_next() { + let buf_desc = desc_chain.next().ok_or(VsockError::BufDescMissing)?; - // All TX buffers must be readable. - if buf_desc.is_write_only() { - return Err(VsockError::UnreadableDescriptor); + // All TX buffers must be readable. + if buf_desc.is_write_only() { + return Err(VsockError::UnreadableDescriptor); + } + + // The data descriptor should be large enough to hold the data length + // indicated by the header. + if buf_desc.len() < hdr.len { + return Err(VsockError::BufDescTooSmall); + } + + Ok(Self { + hdr, + buf: Some(BufWrapper::from_virtq_desc( + &buf_desc, + desc_chain.memory(), + 0, + buf_desc.len() as usize, + )?), + }) + } else { + let buf_size = desc.len() as usize - VSOCK_PKT_HDR_SIZE; + + // The data descriptor should be large enough to hold the data length + // indicated by the header. + if buf_size < hdr.len as usize { + return Err(VsockError::BufDescTooSmall); + } + + Ok(Self { + hdr, + buf: Some(BufWrapper::from_virtq_desc( + &desc, + desc_chain.memory(), + VSOCK_PKT_HDR_SIZE, + buf_size, + )?), + }) } - - // The data descriptor should be large enough to hold the data length - // indicated by the header. - if buf_desc.len() < hdr.len { - return Err(VsockError::BufDescTooSmall); - } - - Ok(Self { - hdr, - buf: Some(BufWrapper::from_virtq_desc(&buf_desc, desc_chain.memory())?), - }) } /// Create the packet wrapper from an RX virtq chain head. @@ -301,15 +336,34 @@ impl VsockPacket { let hdr = HdrWrapper::from_virtq_desc(&desc, desc_chain.memory())?; - let buf_desc = desc_chain.next().ok_or(VsockError::BufDescMissing)?; - if !buf_desc.is_write_only() { - return Err(VsockError::UnwritableDescriptor); - } + if desc.has_next() { + let buf_desc = desc_chain.next().ok_or(VsockError::BufDescMissing)?; + if !buf_desc.is_write_only() { + return Err(VsockError::UnwritableDescriptor); + } - Ok(Self { - hdr, - buf: Some(BufWrapper::from_virtq_desc(&buf_desc, desc_chain.memory())?), - }) + Ok(Self { + hdr, + buf: Some(BufWrapper::from_virtq_desc( + &buf_desc, + desc_chain.memory(), + 0, + buf_desc.len() as usize, + )?), + }) + } else { + let buf_size = desc.len() as usize - VSOCK_PKT_HDR_SIZE; + + Ok(Self { + hdr, + buf: Some(BufWrapper::from_virtq_desc( + &desc, + desc_chain.memory(), + VSOCK_PKT_HDR_SIZE, + buf_size, + )?), + }) + } } /// Provides in-place, byte-slice, access to the vsock packet header. @@ -575,11 +629,12 @@ mod tests { // Test case: // - packet header advertises some data length; and // - the data descriptor is missing. + // This will be treated as single descriptor now. { create_context!(test_ctx, handler_ctx); set_pkt_len(1024, &handler_ctx.guest_txvq.dtable(0), &test_ctx.mem); handler_ctx.guest_txvq.dtable(0).flags().store(0); - expect_asm_error!(tx, test_ctx, handler_ctx, VsockError::BufDescMissing); + expect_asm_error!(tx, test_ctx, handler_ctx, VsockError::BufDescTooSmall); } // Test case: error on write-only buf descriptor. @@ -641,6 +696,7 @@ mod tests { } // Test case: RX descriptor chain is missing the packet buffer descriptor. + // This will be treated as single descriptor now. { create_context!(test_ctx, handler_ctx); handler_ctx @@ -648,7 +704,14 @@ mod tests { .dtable(0) .flags() .store(VIRTQ_DESC_F_WRITE); - expect_asm_error!(rx, test_ctx, handler_ctx, VsockError::BufDescMissing); + let pkt = VsockPacket::from_rx_virtq_head( + &mut handler_ctx.queues[RXQ_EVENT as usize] + .queue_mut() + .pop_descriptor_chain(&test_ctx.mem) + .unwrap(), + ) + .unwrap(); + assert_eq!(pkt.buf(), Some(vec![]).as_deref()); } } diff --git a/tools/packaging/kernel/kata_config_version b/tools/packaging/kernel/kata_config_version index a2ecc456eb..bb79365350 100644 --- a/tools/packaging/kernel/kata_config_version +++ b/tools/packaging/kernel/kata_config_version @@ -1 +1 @@ -154 +155 diff --git a/tools/packaging/kernel/patches/6.1.x/0001-erofs-get-rid-of-erofs_inode_datablocks.patch b/tools/packaging/kernel/patches/6.1.x/0001-erofs-get-rid-of-erofs_inode_datablocks.patch deleted file mode 100644 index 567f3f5aae..0000000000 --- a/tools/packaging/kernel/patches/6.1.x/0001-erofs-get-rid-of-erofs_inode_datablocks.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 50cbaf0848fb52dbeb0a687671ccaf50af53e270 Mon Sep 17 00:00:00 2001 -From: Gao Xiang -Date: Sat, 4 Feb 2023 17:30:35 +0800 -Subject: [PATCH 1/4] erofs: get rid of erofs_inode_datablocks() - -erofs_inode_datablocks() has the only one caller, let's just get -rid of it entirely. No logic changes. - -Reviewed-by: Yue Hu -Reviewed-by: Jingbo Xu -Reviewed-by: Chao Yu -Signed-off-by: Gao Xiang -Link: https://lore.kernel.org/r/20230204093040.97967-1-hsiangkao@linux.alibaba.com ---- - fs/erofs/internal.h | 6 ------ - fs/erofs/namei.c | 18 +++++------------- - 2 files changed, 5 insertions(+), 19 deletions(-) - -diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h -index d8d09fc3ed65..53e05d314181 100644 ---- a/fs/erofs/internal.h -+++ b/fs/erofs/internal.h -@@ -347,12 +347,6 @@ static inline erofs_off_t erofs_iloc(struct inode *inode) - (EROFS_I(inode)->nid << sbi->islotbits); - } - --static inline unsigned long erofs_inode_datablocks(struct inode *inode) --{ -- /* since i_size cannot be changed */ -- return DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ); --} -- - static inline unsigned int erofs_bitrange(unsigned int value, unsigned int bit, - unsigned int bits) - { -diff --git a/fs/erofs/namei.c b/fs/erofs/namei.c -index 0dc34721080c..6ecea7b19882 100644 ---- a/fs/erofs/namei.c -+++ b/fs/erofs/namei.c -@@ -5,7 +5,6 @@ - * Copyright (C) 2022, Alibaba Cloud - */ - #include "xattr.h" -- - #include - - struct erofs_qstr { -@@ -87,19 +86,13 @@ static struct erofs_dirent *find_target_dirent(struct erofs_qstr *name, - return ERR_PTR(-ENOENT); - } - --static void *find_target_block_classic(struct erofs_buf *target, -- struct inode *dir, -- struct erofs_qstr *name, -- int *_ndirents) -+static void *erofs_find_target_block(struct erofs_buf *target, -+ struct inode *dir, struct erofs_qstr *name, int *_ndirents) - { -- unsigned int startprfx, endprfx; -- int head, back; -+ int head = 0, back = DIV_ROUND_UP(dir->i_size, EROFS_BLKSIZ) - 1; -+ unsigned int startprfx = 0, endprfx = 0; - void *candidate = ERR_PTR(-ENOENT); - -- startprfx = endprfx = 0; -- head = 0; -- back = erofs_inode_datablocks(dir) - 1; -- - while (head <= back) { - const int mid = head + (back - head) / 2; - struct erofs_buf buf = __EROFS_BUF_INITIALIZER; -@@ -180,8 +173,7 @@ int erofs_namei(struct inode *dir, const struct qstr *name, erofs_nid_t *nid, - qn.end = name->name + name->len; - - ndirents = 0; -- -- de = find_target_block_classic(&buf, dir, &qn, &ndirents); -+ de = erofs_find_target_block(&buf, dir, &qn, &ndirents); - if (IS_ERR(de)) - return PTR_ERR(de); - --- -2.41.0 - diff --git a/tools/packaging/kernel/patches/6.1.x/0005-erofs-support-flattened-block-device-for-multi-blob-.patch b/tools/packaging/kernel/patches/6.1.x/0001-erofs-support-flattened-block-device-for-multi-blob-.patch similarity index 100% rename from tools/packaging/kernel/patches/6.1.x/0005-erofs-support-flattened-block-device-for-multi-blob-.patch rename to tools/packaging/kernel/patches/6.1.x/0001-erofs-support-flattened-block-device-for-multi-blob-.patch diff --git a/tools/packaging/kernel/patches/6.1.x/0002-erofs-get-rid-of-z_erofs_do_map_blocks-forward-decla.patch b/tools/packaging/kernel/patches/6.1.x/0002-erofs-get-rid-of-z_erofs_do_map_blocks-forward-decla.patch deleted file mode 100644 index 6cdbc11b0d..0000000000 --- a/tools/packaging/kernel/patches/6.1.x/0002-erofs-get-rid-of-z_erofs_do_map_blocks-forward-decla.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 9d64681a2e4f148f52e59aaee91e3f44e4a8caea Mon Sep 17 00:00:00 2001 -From: Gao Xiang -Date: Sat, 4 Feb 2023 17:30:39 +0800 -Subject: [PATCH 2/4] erofs: get rid of z_erofs_do_map_blocks() forward - declaration - -The code can be neater without forward declarations. Let's -get rid of z_erofs_do_map_blocks() forward declaration. - -Reviewed-by: Yue Hu -Reviewed-by: Chao Yu -Signed-off-by: Gao Xiang -Link: https://lore.kernel.org/r/20230204093040.97967-5-hsiangkao@linux.alibaba.com ---- - fs/erofs/zmap.c | 242 ++++++++++++++++++++++++------------------------ - 1 file changed, 119 insertions(+), 123 deletions(-) - -diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c -index 0337b70b2dac..7455c16e36ef 100644 ---- a/fs/erofs/zmap.c -+++ b/fs/erofs/zmap.c -@@ -7,10 +7,6 @@ - #include - #include - --static int z_erofs_do_map_blocks(struct inode *inode, -- struct erofs_map_blocks *map, -- int flags); -- - int z_erofs_fill_inode(struct inode *inode) - { - struct erofs_inode *const vi = EROFS_I(inode); -@@ -29,125 +25,6 @@ int z_erofs_fill_inode(struct inode *inode) - return 0; - } - --static int z_erofs_fill_inode_lazy(struct inode *inode) --{ -- struct erofs_inode *const vi = EROFS_I(inode); -- struct super_block *const sb = inode->i_sb; -- int err, headnr; -- erofs_off_t pos; -- struct erofs_buf buf = __EROFS_BUF_INITIALIZER; -- void *kaddr; -- struct z_erofs_map_header *h; -- -- if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags)) { -- /* -- * paired with smp_mb() at the end of the function to ensure -- * fields will only be observed after the bit is set. -- */ -- smp_mb(); -- return 0; -- } -- -- if (wait_on_bit_lock(&vi->flags, EROFS_I_BL_Z_BIT, TASK_KILLABLE)) -- return -ERESTARTSYS; -- -- err = 0; -- if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags)) -- goto out_unlock; -- -- pos = ALIGN(erofs_iloc(inode) + vi->inode_isize + vi->xattr_isize, 8); -- kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP); -- if (IS_ERR(kaddr)) { -- err = PTR_ERR(kaddr); -- goto out_unlock; -- } -- -- h = kaddr + erofs_blkoff(pos); -- /* -- * if the highest bit of the 8-byte map header is set, the whole file -- * is stored in the packed inode. The rest bits keeps z_fragmentoff. -- */ -- if (h->h_clusterbits >> Z_EROFS_FRAGMENT_INODE_BIT) { -- vi->z_advise = Z_EROFS_ADVISE_FRAGMENT_PCLUSTER; -- vi->z_fragmentoff = le64_to_cpu(*(__le64 *)h) ^ (1ULL << 63); -- vi->z_tailextent_headlcn = 0; -- goto done; -- } -- vi->z_advise = le16_to_cpu(h->h_advise); -- vi->z_algorithmtype[0] = h->h_algorithmtype & 15; -- vi->z_algorithmtype[1] = h->h_algorithmtype >> 4; -- -- headnr = 0; -- if (vi->z_algorithmtype[0] >= Z_EROFS_COMPRESSION_MAX || -- vi->z_algorithmtype[++headnr] >= Z_EROFS_COMPRESSION_MAX) { -- erofs_err(sb, "unknown HEAD%u format %u for nid %llu, please upgrade kernel", -- headnr + 1, vi->z_algorithmtype[headnr], vi->nid); -- err = -EOPNOTSUPP; -- goto out_put_metabuf; -- } -- -- vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7); -- if (!erofs_sb_has_big_pcluster(EROFS_SB(sb)) && -- vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 | -- Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { -- erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu", -- vi->nid); -- err = -EFSCORRUPTED; -- goto out_put_metabuf; -- } -- if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION && -- !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^ -- !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { -- erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu", -- vi->nid); -- err = -EFSCORRUPTED; -- goto out_put_metabuf; -- } -- -- if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER) { -- struct erofs_map_blocks map = { -- .buf = __EROFS_BUF_INITIALIZER -- }; -- -- vi->z_idata_size = le16_to_cpu(h->h_idata_size); -- err = z_erofs_do_map_blocks(inode, &map, -- EROFS_GET_BLOCKS_FINDTAIL); -- erofs_put_metabuf(&map.buf); -- -- if (!map.m_plen || -- erofs_blkoff(map.m_pa) + map.m_plen > EROFS_BLKSIZ) { -- erofs_err(sb, "invalid tail-packing pclustersize %llu", -- map.m_plen); -- err = -EFSCORRUPTED; -- } -- if (err < 0) -- goto out_put_metabuf; -- } -- -- if (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER && -- !(h->h_clusterbits >> Z_EROFS_FRAGMENT_INODE_BIT)) { -- struct erofs_map_blocks map = { -- .buf = __EROFS_BUF_INITIALIZER -- }; -- -- vi->z_fragmentoff = le32_to_cpu(h->h_fragmentoff); -- err = z_erofs_do_map_blocks(inode, &map, -- EROFS_GET_BLOCKS_FINDTAIL); -- erofs_put_metabuf(&map.buf); -- if (err < 0) -- goto out_put_metabuf; -- } --done: -- /* paired with smp_mb() at the beginning of the function */ -- smp_mb(); -- set_bit(EROFS_I_Z_INITED_BIT, &vi->flags); --out_put_metabuf: -- erofs_put_metabuf(&buf); --out_unlock: -- clear_and_wake_up_bit(EROFS_I_BL_Z_BIT, &vi->flags); -- return err; --} -- - struct z_erofs_maprecorder { - struct inode *inode; - struct erofs_map_blocks *map; -@@ -729,6 +606,125 @@ static int z_erofs_do_map_blocks(struct inode *inode, - return err; - } - -+static int z_erofs_fill_inode_lazy(struct inode *inode) -+{ -+ struct erofs_inode *const vi = EROFS_I(inode); -+ struct super_block *const sb = inode->i_sb; -+ int err, headnr; -+ erofs_off_t pos; -+ struct erofs_buf buf = __EROFS_BUF_INITIALIZER; -+ void *kaddr; -+ struct z_erofs_map_header *h; -+ -+ if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags)) { -+ /* -+ * paired with smp_mb() at the end of the function to ensure -+ * fields will only be observed after the bit is set. -+ */ -+ smp_mb(); -+ return 0; -+ } -+ -+ if (wait_on_bit_lock(&vi->flags, EROFS_I_BL_Z_BIT, TASK_KILLABLE)) -+ return -ERESTARTSYS; -+ -+ err = 0; -+ if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags)) -+ goto out_unlock; -+ -+ pos = ALIGN(erofs_iloc(inode) + vi->inode_isize + vi->xattr_isize, 8); -+ kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP); -+ if (IS_ERR(kaddr)) { -+ err = PTR_ERR(kaddr); -+ goto out_unlock; -+ } -+ -+ h = kaddr + erofs_blkoff(pos); -+ /* -+ * if the highest bit of the 8-byte map header is set, the whole file -+ * is stored in the packed inode. The rest bits keeps z_fragmentoff. -+ */ -+ if (h->h_clusterbits >> Z_EROFS_FRAGMENT_INODE_BIT) { -+ vi->z_advise = Z_EROFS_ADVISE_FRAGMENT_PCLUSTER; -+ vi->z_fragmentoff = le64_to_cpu(*(__le64 *)h) ^ (1ULL << 63); -+ vi->z_tailextent_headlcn = 0; -+ goto done; -+ } -+ vi->z_advise = le16_to_cpu(h->h_advise); -+ vi->z_algorithmtype[0] = h->h_algorithmtype & 15; -+ vi->z_algorithmtype[1] = h->h_algorithmtype >> 4; -+ -+ headnr = 0; -+ if (vi->z_algorithmtype[0] >= Z_EROFS_COMPRESSION_MAX || -+ vi->z_algorithmtype[++headnr] >= Z_EROFS_COMPRESSION_MAX) { -+ erofs_err(sb, "unknown HEAD%u format %u for nid %llu, please upgrade kernel", -+ headnr + 1, vi->z_algorithmtype[headnr], vi->nid); -+ err = -EOPNOTSUPP; -+ goto out_put_metabuf; -+ } -+ -+ vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7); -+ if (!erofs_sb_has_big_pcluster(EROFS_SB(sb)) && -+ vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 | -+ Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { -+ erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu", -+ vi->nid); -+ err = -EFSCORRUPTED; -+ goto out_put_metabuf; -+ } -+ if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION && -+ !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^ -+ !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { -+ erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu", -+ vi->nid); -+ err = -EFSCORRUPTED; -+ goto out_put_metabuf; -+ } -+ -+ if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER) { -+ struct erofs_map_blocks map = { -+ .buf = __EROFS_BUF_INITIALIZER -+ }; -+ -+ vi->z_idata_size = le16_to_cpu(h->h_idata_size); -+ err = z_erofs_do_map_blocks(inode, &map, -+ EROFS_GET_BLOCKS_FINDTAIL); -+ erofs_put_metabuf(&map.buf); -+ -+ if (!map.m_plen || -+ erofs_blkoff(map.m_pa) + map.m_plen > EROFS_BLKSIZ) { -+ erofs_err(sb, "invalid tail-packing pclustersize %llu", -+ map.m_plen); -+ err = -EFSCORRUPTED; -+ } -+ if (err < 0) -+ goto out_put_metabuf; -+ } -+ -+ if (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER && -+ !(h->h_clusterbits >> Z_EROFS_FRAGMENT_INODE_BIT)) { -+ struct erofs_map_blocks map = { -+ .buf = __EROFS_BUF_INITIALIZER -+ }; -+ -+ vi->z_fragmentoff = le32_to_cpu(h->h_fragmentoff); -+ err = z_erofs_do_map_blocks(inode, &map, -+ EROFS_GET_BLOCKS_FINDTAIL); -+ erofs_put_metabuf(&map.buf); -+ if (err < 0) -+ goto out_put_metabuf; -+ } -+done: -+ /* paired with smp_mb() at the beginning of the function */ -+ smp_mb(); -+ set_bit(EROFS_I_Z_INITED_BIT, &vi->flags); -+out_put_metabuf: -+ erofs_put_metabuf(&buf); -+out_unlock: -+ clear_and_wake_up_bit(EROFS_I_BL_Z_BIT, &vi->flags); -+ return err; -+} -+ - int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map, - int flags) - { --- -2.41.0 - diff --git a/tools/packaging/kernel/patches/6.1.x/0003-erofs-avoid-hardcoded-blocksize-for-subpage-block-su.patch b/tools/packaging/kernel/patches/6.1.x/0003-erofs-avoid-hardcoded-blocksize-for-subpage-block-su.patch deleted file mode 100644 index 1994f71502..0000000000 --- a/tools/packaging/kernel/patches/6.1.x/0003-erofs-avoid-hardcoded-blocksize-for-subpage-block-su.patch +++ /dev/null @@ -1,989 +0,0 @@ -From 403da9bc5e35428aabafaf9301f2708be4679257 Mon Sep 17 00:00:00 2001 -From: Jingbo Xu -Date: Mon, 13 Mar 2023 21:53:08 +0800 -Subject: [PATCH 3/4] erofs: avoid hardcoded blocksize for subpage block - support - -As the first step of converting hardcoded blocksize to that specified in -on-disk superblock, convert all call sites of hardcoded blocksize to -sb->s_blocksize except for: - -1) use sbi->blkszbits instead of sb->s_blocksize in -erofs_superblock_csum_verify() since sb->s_blocksize has not been -updated with the on-disk blocksize yet when the function is called. - -2) use inode->i_blkbits instead of sb->s_blocksize in erofs_bread(), -since the inode operated on may be an anonymous inode in fscache mode. -Currently the anonymous inode is allocated from an anonymous mount -maintained in erofs, while in the near future we may allocate anonymous -inodes from a generic API directly and thus have no access to the -anonymous inode's i_sb. Thus we keep the block size in i_blkbits for -anonymous inodes in fscache mode. - -Be noted that this patch only gets rid of the hardcoded blocksize, in -preparation for actually setting the on-disk block size in the following -patch. The hard limit of constraining the block size to PAGE_SIZE still -exists until the next patch. - -Signed-off-by: Jingbo Xu -Reviewed-by: Gao Xiang -Reviewed-by: Yue Hu -Reviewed-by: Chao Yu -Link: https://lore.kernel.org/r/20230313135309.75269-2-jefflexu@linux.alibaba.com -[ Gao Xiang: fold a patch to fix incorrect truncated offsets. ] -Link: https://lore.kernel.org/r/20230413035734.15457-1-zhujia.zj@bytedance.com -Signed-off-by: Gao Xiang - - Conflicts: - fs/erofs/fscache.c - fs/erofs/zmap.c ---- - fs/erofs/data.c | 50 +++++++++++++++++++----------------- - fs/erofs/decompressor.c | 6 ++--- - fs/erofs/decompressor_lzma.c | 4 +-- - fs/erofs/dir.c | 22 ++++++++-------- - fs/erofs/fscache.c | 4 +-- - fs/erofs/inode.c | 20 ++++++++------- - fs/erofs/internal.h | 20 +++++---------- - fs/erofs/namei.c | 14 +++++----- - fs/erofs/super.c | 27 +++++++++++-------- - fs/erofs/xattr.c | 40 ++++++++++++++--------------- - fs/erofs/xattr.h | 10 ++++---- - fs/erofs/zdata.c | 18 +++++++------ - fs/erofs/zmap.c | 29 +++++++++++---------- - include/trace/events/erofs.h | 4 +-- - 14 files changed, 136 insertions(+), 132 deletions(-) - -diff --git a/fs/erofs/data.c b/fs/erofs/data.c -index b32801d716f8..d4606c2573ce 100644 ---- a/fs/erofs/data.c -+++ b/fs/erofs/data.c -@@ -29,11 +29,15 @@ void erofs_put_metabuf(struct erofs_buf *buf) - buf->page = NULL; - } - -+/* -+ * Derive the block size from inode->i_blkbits to make compatible with -+ * anonymous inode in fscache mode. -+ */ - void *erofs_bread(struct erofs_buf *buf, struct inode *inode, - erofs_blk_t blkaddr, enum erofs_kmap_type type) - { -+ erofs_off_t offset = (erofs_off_t)blkaddr << inode->i_blkbits; - struct address_space *const mapping = inode->i_mapping; -- erofs_off_t offset = blknr_to_addr(blkaddr); - pgoff_t index = offset >> PAGE_SHIFT; - struct page *page = buf->page; - struct folio *folio; -@@ -84,33 +88,32 @@ static int erofs_map_blocks_flatmode(struct inode *inode, - erofs_blk_t nblocks, lastblk; - u64 offset = map->m_la; - struct erofs_inode *vi = EROFS_I(inode); -+ struct super_block *sb = inode->i_sb; - bool tailendpacking = (vi->datalayout == EROFS_INODE_FLAT_INLINE); - -- nblocks = DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ); -+ nblocks = erofs_iblks(inode); - lastblk = nblocks - tailendpacking; - - /* there is no hole in flatmode */ - map->m_flags = EROFS_MAP_MAPPED; -- if (offset < blknr_to_addr(lastblk)) { -- map->m_pa = blknr_to_addr(vi->raw_blkaddr) + map->m_la; -- map->m_plen = blknr_to_addr(lastblk) - offset; -+ if (offset < erofs_pos(sb, lastblk)) { -+ map->m_pa = erofs_pos(sb, vi->raw_blkaddr) + map->m_la; -+ map->m_plen = erofs_pos(sb, lastblk) - offset; - } else if (tailendpacking) { - map->m_pa = erofs_iloc(inode) + vi->inode_isize + -- vi->xattr_isize + erofs_blkoff(offset); -+ vi->xattr_isize + erofs_blkoff(sb, offset); - map->m_plen = inode->i_size - offset; - - /* inline data should be located in the same meta block */ -- if (erofs_blkoff(map->m_pa) + map->m_plen > EROFS_BLKSIZ) { -- erofs_err(inode->i_sb, -- "inline data cross block boundary @ nid %llu", -+ if (erofs_blkoff(sb, map->m_pa) + map->m_plen > sb->s_blocksize) { -+ erofs_err(sb, "inline data cross block boundary @ nid %llu", - vi->nid); - DBG_BUGON(1); - return -EFSCORRUPTED; - } - map->m_flags |= EROFS_MAP_META; - } else { -- erofs_err(inode->i_sb, -- "internal error @ nid: %llu (size %llu), m_la 0x%llx", -+ erofs_err(sb, "internal error @ nid: %llu (size %llu), m_la 0x%llx", - vi->nid, inode->i_size, map->m_la); - DBG_BUGON(1); - return -EIO; -@@ -154,29 +157,29 @@ int erofs_map_blocks(struct inode *inode, - pos = ALIGN(erofs_iloc(inode) + vi->inode_isize + - vi->xattr_isize, unit) + unit * chunknr; - -- kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP); -+ kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(sb, pos), EROFS_KMAP); - if (IS_ERR(kaddr)) { - err = PTR_ERR(kaddr); - goto out; - } - map->m_la = chunknr << vi->chunkbits; - map->m_plen = min_t(erofs_off_t, 1UL << vi->chunkbits, -- roundup(inode->i_size - map->m_la, EROFS_BLKSIZ)); -+ round_up(inode->i_size - map->m_la, sb->s_blocksize)); - - /* handle block map */ - if (!(vi->chunkformat & EROFS_CHUNK_FORMAT_INDEXES)) { -- __le32 *blkaddr = kaddr + erofs_blkoff(pos); -+ __le32 *blkaddr = kaddr + erofs_blkoff(sb, pos); - - if (le32_to_cpu(*blkaddr) == EROFS_NULL_ADDR) { - map->m_flags = 0; - } else { -- map->m_pa = blknr_to_addr(le32_to_cpu(*blkaddr)); -+ map->m_pa = erofs_pos(sb, le32_to_cpu(*blkaddr)); - map->m_flags = EROFS_MAP_MAPPED; - } - goto out_unlock; - } - /* parse chunk indexes */ -- idx = kaddr + erofs_blkoff(pos); -+ idx = kaddr + erofs_blkoff(sb, pos); - switch (le32_to_cpu(idx->blkaddr)) { - case EROFS_NULL_ADDR: - map->m_flags = 0; -@@ -184,7 +187,7 @@ int erofs_map_blocks(struct inode *inode, - default: - map->m_deviceid = le16_to_cpu(idx->device_id) & - EROFS_SB(sb)->device_id_mask; -- map->m_pa = blknr_to_addr(le32_to_cpu(idx->blkaddr)); -+ map->m_pa = erofs_pos(sb, le32_to_cpu(idx->blkaddr)); - map->m_flags = EROFS_MAP_MAPPED; - break; - } -@@ -228,8 +231,8 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map) - - if (!dif->mapped_blkaddr) - continue; -- startoff = blknr_to_addr(dif->mapped_blkaddr); -- length = blknr_to_addr(dif->blocks); -+ startoff = erofs_pos(sb, dif->mapped_blkaddr); -+ length = erofs_pos(sb, dif->blocks); - - if (map->m_pa >= startoff && - map->m_pa < startoff + length) { -@@ -250,6 +253,7 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, - unsigned int flags, struct iomap *iomap, struct iomap *srcmap) - { - int ret; -+ struct super_block *sb = inode->i_sb; - struct erofs_map_blocks map; - struct erofs_map_dev mdev; - -@@ -264,7 +268,7 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, - .m_deviceid = map.m_deviceid, - .m_pa = map.m_pa, - }; -- ret = erofs_map_dev(inode->i_sb, &mdev); -+ ret = erofs_map_dev(sb, &mdev); - if (ret) - return ret; - -@@ -290,11 +294,11 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, - struct erofs_buf buf = __EROFS_BUF_INITIALIZER; - - iomap->type = IOMAP_INLINE; -- ptr = erofs_read_metabuf(&buf, inode->i_sb, -- erofs_blknr(mdev.m_pa), EROFS_KMAP); -+ ptr = erofs_read_metabuf(&buf, sb, -+ erofs_blknr(sb, mdev.m_pa), EROFS_KMAP); - if (IS_ERR(ptr)) - return PTR_ERR(ptr); -- iomap->inline_data = ptr + erofs_blkoff(mdev.m_pa); -+ iomap->inline_data = ptr + erofs_blkoff(sb, mdev.m_pa); - iomap->private = buf.base; - } else { - iomap->type = IOMAP_MAPPED; -diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c -index 51b7ac7166d9..7021e2cf6146 100644 ---- a/fs/erofs/decompressor.c -+++ b/fs/erofs/decompressor.c -@@ -42,7 +42,7 @@ int z_erofs_load_lz4_config(struct super_block *sb, - if (!sbi->lz4.max_pclusterblks) { - sbi->lz4.max_pclusterblks = 1; /* reserved case */ - } else if (sbi->lz4.max_pclusterblks > -- Z_EROFS_PCLUSTER_MAX_SIZE / EROFS_BLKSIZ) { -+ erofs_blknr(sb, Z_EROFS_PCLUSTER_MAX_SIZE)) { - erofs_err(sb, "too large lz4 pclusterblks %u", - sbi->lz4.max_pclusterblks); - return -EINVAL; -@@ -221,13 +221,13 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_lz4_decompress_ctx *ctx, - support_0padding = true; - ret = z_erofs_fixup_insize(rq, headpage + rq->pageofs_in, - min_t(unsigned int, rq->inputsize, -- EROFS_BLKSIZ - rq->pageofs_in)); -+ rq->sb->s_blocksize - rq->pageofs_in)); - if (ret) { - kunmap_atomic(headpage); - return ret; - } - may_inplace = !((rq->pageofs_in + rq->inputsize) & -- (EROFS_BLKSIZ - 1)); -+ (rq->sb->s_blocksize - 1)); - } - - inputmargin = rq->pageofs_in; -diff --git a/fs/erofs/decompressor_lzma.c b/fs/erofs/decompressor_lzma.c -index 5cd612a8f858..2fd49091c1bb 100644 ---- a/fs/erofs/decompressor_lzma.c -+++ b/fs/erofs/decompressor_lzma.c -@@ -166,8 +166,8 @@ int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq, - /* 1. get the exact LZMA compressed size */ - kin = kmap(*rq->in); - err = z_erofs_fixup_insize(rq, kin + rq->pageofs_in, -- min_t(unsigned int, rq->inputsize, -- EROFS_BLKSIZ - rq->pageofs_in)); -+ min_t(unsigned int, rq->inputsize, -+ rq->sb->s_blocksize - rq->pageofs_in)); - if (err) { - kunmap(*rq->in); - return err; -diff --git a/fs/erofs/dir.c b/fs/erofs/dir.c -index ecf28f66b97d..966a88cc529e 100644 ---- a/fs/erofs/dir.c -+++ b/fs/erofs/dir.c -@@ -67,9 +67,11 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx) - { - struct inode *dir = file_inode(f); - struct erofs_buf buf = __EROFS_BUF_INITIALIZER; -+ struct super_block *sb = dir->i_sb; -+ unsigned long bsz = sb->s_blocksize; - const size_t dirsize = i_size_read(dir); -- unsigned int i = ctx->pos / EROFS_BLKSIZ; -- unsigned int ofs = ctx->pos % EROFS_BLKSIZ; -+ unsigned int i = erofs_blknr(sb, ctx->pos); -+ unsigned int ofs = erofs_blkoff(sb, ctx->pos); - int err = 0; - bool initial = true; - -@@ -79,32 +81,28 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx) - - de = erofs_bread(&buf, dir, i, EROFS_KMAP); - if (IS_ERR(de)) { -- erofs_err(dir->i_sb, -- "fail to readdir of logical block %u of nid %llu", -+ erofs_err(sb, "fail to readdir of logical block %u of nid %llu", - i, EROFS_I(dir)->nid); - err = PTR_ERR(de); - break; - } - - nameoff = le16_to_cpu(de->nameoff); -- if (nameoff < sizeof(struct erofs_dirent) || -- nameoff >= EROFS_BLKSIZ) { -- erofs_err(dir->i_sb, -- "invalid de[0].nameoff %u @ nid %llu", -+ if (nameoff < sizeof(struct erofs_dirent) || nameoff >= bsz) { -+ erofs_err(sb, "invalid de[0].nameoff %u @ nid %llu", - nameoff, EROFS_I(dir)->nid); - err = -EFSCORRUPTED; - break; - } - -- maxsize = min_t(unsigned int, -- dirsize - ctx->pos + ofs, EROFS_BLKSIZ); -+ maxsize = min_t(unsigned int, dirsize - ctx->pos + ofs, bsz); - - /* search dirents at the arbitrary position */ - if (initial) { - initial = false; - - ofs = roundup(ofs, sizeof(struct erofs_dirent)); -- ctx->pos = blknr_to_addr(i) + ofs; -+ ctx->pos = erofs_pos(sb, i) + ofs; - if (ofs >= nameoff) - goto skip_this; - } -@@ -114,7 +112,7 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx) - if (err) - break; - skip_this: -- ctx->pos = blknr_to_addr(i) + maxsize; -+ ctx->pos = erofs_pos(sb, i) + maxsize; - ++i; - ofs = 0; - } -diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c -index 076cf8a149ef..a1ecd44e3987 100644 ---- a/fs/erofs/fscache.c -+++ b/fs/erofs/fscache.c -@@ -282,8 +282,8 @@ static int erofs_fscache_data_read(struct address_space *mapping, - void *src; - - /* For tail packing layout, the offset may be non-zero. */ -- offset = erofs_blkoff(map.m_pa); -- blknr = erofs_blknr(map.m_pa); -+ offset = erofs_blkoff(sb, map.m_pa); -+ blknr = erofs_blknr(sb, map.m_pa); - size = map.m_llen; - - src = erofs_read_metabuf(&buf, sb, blknr, EROFS_KMAP); -diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c -index e090bcd46db1..efbaa4ef63cb 100644 ---- a/fs/erofs/inode.c -+++ b/fs/erofs/inode.c -@@ -23,8 +23,8 @@ static void *erofs_read_inode(struct erofs_buf *buf, - unsigned int ifmt; - int err; - -- blkaddr = erofs_blknr(inode_loc); -- *ofs = erofs_blkoff(inode_loc); -+ blkaddr = erofs_blknr(sb, inode_loc); -+ *ofs = erofs_blkoff(sb, inode_loc); - - erofs_dbg("%s, reading inode nid %llu at %u of blkaddr %u", - __func__, vi->nid, *ofs, blkaddr); -@@ -58,11 +58,11 @@ static void *erofs_read_inode(struct erofs_buf *buf, - case EROFS_INODE_LAYOUT_EXTENDED: - vi->inode_isize = sizeof(struct erofs_inode_extended); - /* check if the extended inode acrosses block boundary */ -- if (*ofs + vi->inode_isize <= EROFS_BLKSIZ) { -+ if (*ofs + vi->inode_isize <= sb->s_blocksize) { - *ofs += vi->inode_isize; - die = (struct erofs_inode_extended *)dic; - } else { -- const unsigned int gotten = EROFS_BLKSIZ - *ofs; -+ const unsigned int gotten = sb->s_blocksize - *ofs; - - copied = kmalloc(vi->inode_isize, GFP_NOFS); - if (!copied) { -@@ -176,7 +176,7 @@ static void *erofs_read_inode(struct erofs_buf *buf, - err = -EOPNOTSUPP; - goto err_out; - } -- vi->chunkbits = LOG_BLOCK_SIZE + -+ vi->chunkbits = sb->s_blocksize_bits + - (vi->chunkformat & EROFS_CHUNK_FORMAT_BLKBITS_MASK); - } - inode->i_mtime.tv_sec = inode->i_ctime.tv_sec; -@@ -189,11 +189,12 @@ static void *erofs_read_inode(struct erofs_buf *buf, - (vi->datalayout == EROFS_INODE_FLAT_PLAIN || - vi->datalayout == EROFS_INODE_CHUNK_BASED)) - inode->i_flags |= S_DAX; -+ - if (!nblks) - /* measure inode.i_blocks as generic filesystems */ -- inode->i_blocks = roundup(inode->i_size, EROFS_BLKSIZ) >> 9; -+ inode->i_blocks = round_up(inode->i_size, sb->s_blocksize) >> 9; - else -- inode->i_blocks = nblks << LOG_SECTORS_PER_BLOCK; -+ inode->i_blocks = nblks << (sb->s_blocksize_bits - 9); - return kaddr; - - bogusimode: -@@ -211,11 +212,12 @@ static int erofs_fill_symlink(struct inode *inode, void *kaddr, - unsigned int m_pofs) - { - struct erofs_inode *vi = EROFS_I(inode); -+ unsigned int bsz = i_blocksize(inode); - char *lnk; - - /* if it cannot be handled with fast symlink scheme */ - if (vi->datalayout != EROFS_INODE_FLAT_INLINE || -- inode->i_size >= EROFS_BLKSIZ || inode->i_size < 0) { -+ inode->i_size >= bsz || inode->i_size < 0) { - inode->i_op = &erofs_symlink_iops; - return 0; - } -@@ -226,7 +228,7 @@ static int erofs_fill_symlink(struct inode *inode, void *kaddr, - - m_pofs += vi->xattr_isize; - /* inline symlink data shouldn't cross block boundary */ -- if (m_pofs + inode->i_size > EROFS_BLKSIZ) { -+ if (m_pofs + inode->i_size > bsz) { - kfree(lnk); - erofs_err(inode->i_sb, - "inline data cross block boundary @ nid %llu", -diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h -index 53e05d314181..08628c64210e 100644 ---- a/fs/erofs/internal.h -+++ b/fs/erofs/internal.h -@@ -145,8 +145,8 @@ struct erofs_sb_info { - #endif - u16 device_id_mask; /* valid bits of device id to be used */ - -- /* inode slot unit size in bit shift */ -- unsigned char islotbits; -+ unsigned char islotbits; /* inode slot unit size in bit shift */ -+ unsigned char blkszbits; - - u32 sb_size; /* total superblock size */ - u32 build_time_nsec; -@@ -241,13 +241,6 @@ static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp) - - /* we strictly follow PAGE_SIZE and no buffer head yet */ - #define LOG_BLOCK_SIZE PAGE_SHIFT -- --#undef LOG_SECTORS_PER_BLOCK --#define LOG_SECTORS_PER_BLOCK (PAGE_SHIFT - 9) -- --#undef SECTORS_PER_BLOCK --#define SECTORS_PER_BLOCK (1 << SECTORS_PER_BLOCK) -- - #define EROFS_BLKSIZ (1 << LOG_BLOCK_SIZE) - - #if (EROFS_BLKSIZ % 4096 || !EROFS_BLKSIZ) -@@ -269,9 +262,10 @@ struct erofs_buf { - - #define ROOT_NID(sb) ((sb)->root_nid) - --#define erofs_blknr(addr) ((addr) / EROFS_BLKSIZ) --#define erofs_blkoff(addr) ((addr) % EROFS_BLKSIZ) --#define blknr_to_addr(nr) ((erofs_off_t)(nr) * EROFS_BLKSIZ) -+#define erofs_blknr(sb, addr) ((addr) >> (sb)->s_blocksize_bits) -+#define erofs_blkoff(sb, addr) ((addr) & ((sb)->s_blocksize - 1)) -+#define erofs_pos(sb, blk) ((erofs_off_t)(blk) << (sb)->s_blocksize_bits) -+#define erofs_iblks(i) (round_up((i)->i_size, i_blocksize(i)) >> (i)->i_blkbits) - - #define EROFS_FEATURE_FUNCS(name, compat, feature) \ - static inline bool erofs_sb_has_##name(struct erofs_sb_info *sbi) \ -@@ -343,7 +337,7 @@ static inline erofs_off_t erofs_iloc(struct inode *inode) - { - struct erofs_sb_info *sbi = EROFS_I_SB(inode); - -- return blknr_to_addr(sbi->meta_blkaddr) + -+ return erofs_pos(inode->i_sb, sbi->meta_blkaddr) + - (EROFS_I(inode)->nid << sbi->islotbits); - } - -diff --git a/fs/erofs/namei.c b/fs/erofs/namei.c -index 6ecea7b19882..cf56a8acafbb 100644 ---- a/fs/erofs/namei.c -+++ b/fs/erofs/namei.c -@@ -89,7 +89,8 @@ static struct erofs_dirent *find_target_dirent(struct erofs_qstr *name, - static void *erofs_find_target_block(struct erofs_buf *target, - struct inode *dir, struct erofs_qstr *name, int *_ndirents) - { -- int head = 0, back = DIV_ROUND_UP(dir->i_size, EROFS_BLKSIZ) - 1; -+ unsigned int bsz = i_blocksize(dir); -+ int head = 0, back = erofs_iblks(dir) - 1; - unsigned int startprfx = 0, endprfx = 0; - void *candidate = ERR_PTR(-ENOENT); - -@@ -100,8 +101,7 @@ static void *erofs_find_target_block(struct erofs_buf *target, - - de = erofs_bread(&buf, dir, mid, EROFS_KMAP); - if (!IS_ERR(de)) { -- const int nameoff = nameoff_from_disk(de->nameoff, -- EROFS_BLKSIZ); -+ const int nameoff = nameoff_from_disk(de->nameoff, bsz); - const int ndirents = nameoff / sizeof(*de); - int diff; - unsigned int matched; -@@ -121,11 +121,10 @@ static void *erofs_find_target_block(struct erofs_buf *target, - - dname.name = (u8 *)de + nameoff; - if (ndirents == 1) -- dname.end = (u8 *)de + EROFS_BLKSIZ; -+ dname.end = (u8 *)de + bsz; - else - dname.end = (u8 *)de + -- nameoff_from_disk(de[1].nameoff, -- EROFS_BLKSIZ); -+ nameoff_from_disk(de[1].nameoff, bsz); - - /* string comparison without already matched prefix */ - diff = erofs_dirnamecmp(name, &dname, &matched); -@@ -178,7 +177,8 @@ int erofs_namei(struct inode *dir, const struct qstr *name, erofs_nid_t *nid, - return PTR_ERR(de); - - if (ndirents) -- de = find_target_dirent(&qn, (u8 *)de, EROFS_BLKSIZ, ndirents); -+ de = find_target_dirent(&qn, (u8 *)de, i_blocksize(dir), -+ ndirents); - - if (!IS_ERR(de)) { - *nid = le64_to_cpu(de->nid); -diff --git a/fs/erofs/super.c b/fs/erofs/super.c -index bd8bf8fc2f5d..b07c9d1deaf8 100644 ---- a/fs/erofs/super.c -+++ b/fs/erofs/super.c -@@ -53,18 +53,21 @@ void _erofs_info(struct super_block *sb, const char *function, - - static int erofs_superblock_csum_verify(struct super_block *sb, void *sbdata) - { -+ size_t len = 1 << EROFS_SB(sb)->blkszbits; - struct erofs_super_block *dsb; - u32 expected_crc, crc; - -- dsb = kmemdup(sbdata + EROFS_SUPER_OFFSET, -- EROFS_BLKSIZ - EROFS_SUPER_OFFSET, GFP_KERNEL); -+ if (len > EROFS_SUPER_OFFSET) -+ len -= EROFS_SUPER_OFFSET; -+ -+ dsb = kmemdup(sbdata + EROFS_SUPER_OFFSET, len, GFP_KERNEL); - if (!dsb) - return -ENOMEM; - - expected_crc = le32_to_cpu(dsb->checksum); - dsb->checksum = 0; - /* to allow for x86 boot sectors and other oddities. */ -- crc = crc32c(~0, dsb, EROFS_BLKSIZ - EROFS_SUPER_OFFSET); -+ crc = crc32c(~0, dsb, len); - kfree(dsb); - - if (crc != expected_crc) { -@@ -133,11 +136,11 @@ static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf, - int len, i, cnt; - - *offset = round_up(*offset, 4); -- ptr = erofs_read_metabuf(buf, sb, erofs_blknr(*offset), EROFS_KMAP); -+ ptr = erofs_read_metabuf(buf, sb, erofs_blknr(sb, *offset), EROFS_KMAP); - if (IS_ERR(ptr)) - return ptr; - -- len = le16_to_cpu(*(__le16 *)&ptr[erofs_blkoff(*offset)]); -+ len = le16_to_cpu(*(__le16 *)&ptr[erofs_blkoff(sb, *offset)]); - if (!len) - len = U16_MAX + 1; - buffer = kmalloc(len, GFP_KERNEL); -@@ -147,14 +150,15 @@ static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf, - *lengthp = len; - - for (i = 0; i < len; i += cnt) { -- cnt = min(EROFS_BLKSIZ - (int)erofs_blkoff(*offset), len - i); -- ptr = erofs_read_metabuf(buf, sb, erofs_blknr(*offset), -+ cnt = min_t(int, sb->s_blocksize - erofs_blkoff(sb, *offset), -+ len - i); -+ ptr = erofs_read_metabuf(buf, sb, erofs_blknr(sb, *offset), - EROFS_KMAP); - if (IS_ERR(ptr)) { - kfree(buffer); - return ptr; - } -- memcpy(buffer + i, ptr + erofs_blkoff(*offset), cnt); -+ memcpy(buffer + i, ptr + erofs_blkoff(sb, *offset), cnt); - *offset += cnt; - } - return buffer; -@@ -229,10 +233,10 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb, - struct block_device *bdev; - void *ptr; - -- ptr = erofs_read_metabuf(buf, sb, erofs_blknr(*pos), EROFS_KMAP); -+ ptr = erofs_read_metabuf(buf, sb, erofs_blknr(sb, *pos), EROFS_KMAP); - if (IS_ERR(ptr)) - return PTR_ERR(ptr); -- dis = ptr + erofs_blkoff(*pos); -+ dis = ptr + erofs_blkoff(sb, *pos); - - if (!dif->path) { - if (!dis->tag[0]) { -@@ -724,6 +728,7 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) - sbi->domain_id = ctx->domain_id; - ctx->domain_id = NULL; - -+ sbi->blkszbits = PAGE_SHIFT; - if (erofs_is_fscache_mode(sb)) { - sb->s_blocksize = EROFS_BLKSIZ; - sb->s_blocksize_bits = LOG_BLOCK_SIZE; -@@ -1059,7 +1064,7 @@ static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf) - id = huge_encode_dev(sb->s_bdev->bd_dev); - - buf->f_type = sb->s_magic; -- buf->f_bsize = EROFS_BLKSIZ; -+ buf->f_bsize = sb->s_blocksize; - buf->f_blocks = sbi->total_blocks; - buf->f_bfree = buf->f_bavail = 0; - -diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c -index a2776abf3698..7c09ad1beb83 100644 ---- a/fs/erofs/xattr.c -+++ b/fs/erofs/xattr.c -@@ -68,8 +68,8 @@ static int init_inode_xattrs(struct inode *inode) - } - - it.buf = __EROFS_BUF_INITIALIZER; -- it.blkaddr = erofs_blknr(erofs_iloc(inode) + vi->inode_isize); -- it.ofs = erofs_blkoff(erofs_iloc(inode) + vi->inode_isize); -+ it.blkaddr = erofs_blknr(sb, erofs_iloc(inode) + vi->inode_isize); -+ it.ofs = erofs_blkoff(sb, erofs_iloc(inode) + vi->inode_isize); - - /* read in shared xattr array (non-atomic, see kmalloc below) */ - it.kaddr = erofs_read_metabuf(&it.buf, sb, it.blkaddr, EROFS_KMAP); -@@ -92,9 +92,9 @@ static int init_inode_xattrs(struct inode *inode) - it.ofs += sizeof(struct erofs_xattr_ibody_header); - - for (i = 0; i < vi->xattr_shared_count; ++i) { -- if (it.ofs >= EROFS_BLKSIZ) { -+ if (it.ofs >= sb->s_blocksize) { - /* cannot be unaligned */ -- DBG_BUGON(it.ofs != EROFS_BLKSIZ); -+ DBG_BUGON(it.ofs != sb->s_blocksize); - - it.kaddr = erofs_read_metabuf(&it.buf, sb, ++it.blkaddr, - EROFS_KMAP); -@@ -139,15 +139,15 @@ struct xattr_iter_handlers { - - static inline int xattr_iter_fixup(struct xattr_iter *it) - { -- if (it->ofs < EROFS_BLKSIZ) -+ if (it->ofs < it->sb->s_blocksize) - return 0; - -- it->blkaddr += erofs_blknr(it->ofs); -+ it->blkaddr += erofs_blknr(it->sb, it->ofs); - it->kaddr = erofs_read_metabuf(&it->buf, it->sb, it->blkaddr, - EROFS_KMAP_ATOMIC); - if (IS_ERR(it->kaddr)) - return PTR_ERR(it->kaddr); -- it->ofs = erofs_blkoff(it->ofs); -+ it->ofs = erofs_blkoff(it->sb, it->ofs); - return 0; - } - -@@ -165,8 +165,8 @@ static int inline_xattr_iter_begin(struct xattr_iter *it, - - inline_xattr_ofs = vi->inode_isize + xattr_header_sz; - -- it->blkaddr = erofs_blknr(erofs_iloc(inode) + inline_xattr_ofs); -- it->ofs = erofs_blkoff(erofs_iloc(inode) + inline_xattr_ofs); -+ it->blkaddr = erofs_blknr(it->sb, erofs_iloc(inode) + inline_xattr_ofs); -+ it->ofs = erofs_blkoff(it->sb, erofs_iloc(inode) + inline_xattr_ofs); - it->kaddr = erofs_read_metabuf(&it->buf, inode->i_sb, it->blkaddr, - EROFS_KMAP_ATOMIC); - if (IS_ERR(it->kaddr)) -@@ -222,8 +222,8 @@ static int xattr_foreach(struct xattr_iter *it, - processed = 0; - - while (processed < entry.e_name_len) { -- if (it->ofs >= EROFS_BLKSIZ) { -- DBG_BUGON(it->ofs > EROFS_BLKSIZ); -+ if (it->ofs >= it->sb->s_blocksize) { -+ DBG_BUGON(it->ofs > it->sb->s_blocksize); - - err = xattr_iter_fixup(it); - if (err) -@@ -231,7 +231,7 @@ static int xattr_foreach(struct xattr_iter *it, - it->ofs = 0; - } - -- slice = min_t(unsigned int, EROFS_BLKSIZ - it->ofs, -+ slice = min_t(unsigned int, it->sb->s_blocksize - it->ofs, - entry.e_name_len - processed); - - /* handle name */ -@@ -257,8 +257,8 @@ static int xattr_foreach(struct xattr_iter *it, - } - - while (processed < value_sz) { -- if (it->ofs >= EROFS_BLKSIZ) { -- DBG_BUGON(it->ofs > EROFS_BLKSIZ); -+ if (it->ofs >= it->sb->s_blocksize) { -+ DBG_BUGON(it->ofs > it->sb->s_blocksize); - - err = xattr_iter_fixup(it); - if (err) -@@ -266,7 +266,7 @@ static int xattr_foreach(struct xattr_iter *it, - it->ofs = 0; - } - -- slice = min_t(unsigned int, EROFS_BLKSIZ - it->ofs, -+ slice = min_t(unsigned int, it->sb->s_blocksize - it->ofs, - value_sz - processed); - op->value(it, processed, it->kaddr + it->ofs, slice); - it->ofs += slice; -@@ -352,15 +352,14 @@ static int shared_getxattr(struct inode *inode, struct getxattr_iter *it) - { - struct erofs_inode *const vi = EROFS_I(inode); - struct super_block *const sb = inode->i_sb; -- struct erofs_sb_info *const sbi = EROFS_SB(sb); - unsigned int i; - int ret = -ENOATTR; - - for (i = 0; i < vi->xattr_shared_count; ++i) { - erofs_blk_t blkaddr = -- xattrblock_addr(sbi, vi->xattr_shared_xattrs[i]); -+ xattrblock_addr(sb, vi->xattr_shared_xattrs[i]); - -- it->it.ofs = xattrblock_offset(sbi, vi->xattr_shared_xattrs[i]); -+ it->it.ofs = xattrblock_offset(sb, vi->xattr_shared_xattrs[i]); - it->it.kaddr = erofs_read_metabuf(&it->it.buf, sb, blkaddr, - EROFS_KMAP_ATOMIC); - if (IS_ERR(it->it.kaddr)) -@@ -564,15 +563,14 @@ static int shared_listxattr(struct listxattr_iter *it) - struct inode *const inode = d_inode(it->dentry); - struct erofs_inode *const vi = EROFS_I(inode); - struct super_block *const sb = inode->i_sb; -- struct erofs_sb_info *const sbi = EROFS_SB(sb); - unsigned int i; - int ret = 0; - - for (i = 0; i < vi->xattr_shared_count; ++i) { - erofs_blk_t blkaddr = -- xattrblock_addr(sbi, vi->xattr_shared_xattrs[i]); -+ xattrblock_addr(sb, vi->xattr_shared_xattrs[i]); - -- it->it.ofs = xattrblock_offset(sbi, vi->xattr_shared_xattrs[i]); -+ it->it.ofs = xattrblock_offset(sb, vi->xattr_shared_xattrs[i]); - it->it.kaddr = erofs_read_metabuf(&it->it.buf, sb, blkaddr, - EROFS_KMAP_ATOMIC); - if (IS_ERR(it->it.kaddr)) -diff --git a/fs/erofs/xattr.h b/fs/erofs/xattr.h -index 0a43c9ee9f8f..f7a21aaa9755 100644 ---- a/fs/erofs/xattr.h -+++ b/fs/erofs/xattr.h -@@ -19,21 +19,21 @@ static inline unsigned int inlinexattr_header_size(struct inode *inode) - sizeof(u32) * EROFS_I(inode)->xattr_shared_count; - } - --static inline erofs_blk_t xattrblock_addr(struct erofs_sb_info *sbi, -+static inline erofs_blk_t xattrblock_addr(struct super_block *sb, - unsigned int xattr_id) - { - #ifdef CONFIG_EROFS_FS_XATTR -- return sbi->xattr_blkaddr + -- xattr_id * sizeof(__u32) / EROFS_BLKSIZ; -+ return EROFS_SB(sb)->xattr_blkaddr + -+ xattr_id * sizeof(__u32) / sb->s_blocksize; - #else - return 0; - #endif - } - --static inline unsigned int xattrblock_offset(struct erofs_sb_info *sbi, -+static inline unsigned int xattrblock_offset(struct super_block *sb, - unsigned int xattr_id) - { -- return (xattr_id * sizeof(__u32)) % EROFS_BLKSIZ; -+ return (xattr_id * sizeof(__u32)) % sb->s_blocksize; - } - - #ifdef CONFIG_EROFS_FS_XATTR -diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c -index 1b91ac5be961..85d78804b1e9 100644 ---- a/fs/erofs/zdata.c -+++ b/fs/erofs/zdata.c -@@ -652,7 +652,7 @@ static int z_erofs_register_pcluster(struct z_erofs_decompress_frontend *fe) - - if (ztailpacking) { - pcl->obj.index = 0; /* which indicates ztailpacking */ -- pcl->pageofs_in = erofs_blkoff(map->m_pa); -+ pcl->pageofs_in = erofs_blkoff(fe->inode->i_sb, map->m_pa); - pcl->tailpacking_size = map->m_plen; - } else { - pcl->obj.index = map->m_pa >> PAGE_SHIFT; -@@ -767,6 +767,7 @@ static int z_erofs_read_fragment(struct inode *inode, erofs_off_t pos, - struct page *page, unsigned int pageofs, - unsigned int len) - { -+ struct super_block *sb = inode->i_sb; - struct inode *packed_inode = EROFS_I_SB(inode)->packed_inode; - struct erofs_buf buf = __EROFS_BUF_INITIALIZER; - u8 *src, *dst; -@@ -778,16 +779,16 @@ static int z_erofs_read_fragment(struct inode *inode, erofs_off_t pos, - pos += EROFS_I(inode)->z_fragmentoff; - for (i = 0; i < len; i += cnt) { - cnt = min_t(unsigned int, len - i, -- EROFS_BLKSIZ - erofs_blkoff(pos)); -+ sb->s_blocksize - erofs_blkoff(sb, pos)); - src = erofs_bread(&buf, packed_inode, -- erofs_blknr(pos), EROFS_KMAP); -+ erofs_blknr(sb, pos), EROFS_KMAP); - if (IS_ERR(src)) { - erofs_put_metabuf(&buf); - return PTR_ERR(src); - } - - dst = kmap_local_page(page); -- memcpy(dst + pageofs + i, src + erofs_blkoff(pos), cnt); -+ memcpy(dst + pageofs + i, src + erofs_blkoff(sb, pos), cnt); - kunmap_local(dst); - pos += cnt; - } -@@ -842,7 +843,8 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe, - void *mp; - - mp = erofs_read_metabuf(&fe->map.buf, inode->i_sb, -- erofs_blknr(map->m_pa), EROFS_NO_KMAP); -+ erofs_blknr(inode->i_sb, map->m_pa), -+ EROFS_NO_KMAP); - if (IS_ERR(mp)) { - err = PTR_ERR(mp); - erofs_err(inode->i_sb, -@@ -1527,11 +1529,11 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f, - - /* no device id here, thus it will always succeed */ - mdev = (struct erofs_map_dev) { -- .m_pa = blknr_to_addr(pcl->obj.index), -+ .m_pa = erofs_pos(sb, pcl->obj.index), - }; - (void)erofs_map_dev(sb, &mdev); - -- cur = erofs_blknr(mdev.m_pa); -+ cur = erofs_blknr(sb, mdev.m_pa); - end = cur + pcl->pclusterpages; - - do { -@@ -1565,7 +1567,7 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f, - - last_bdev = mdev.m_bdev; - bio->bi_iter.bi_sector = (sector_t)cur << -- LOG_SECTORS_PER_BLOCK; -+ (sb->s_blocksize_bits - 9); - bio->bi_private = q[JQ_SUBMIT]; - if (f->readahead) - bio->bi_opf |= REQ_RAHEAD; -diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c -index 7455c16e36ef..eff47d06c38f 100644 ---- a/fs/erofs/zmap.c -+++ b/fs/erofs/zmap.c -@@ -18,7 +18,7 @@ int z_erofs_fill_inode(struct inode *inode) - vi->z_advise = 0; - vi->z_algorithmtype[0] = 0; - vi->z_algorithmtype[1] = 0; -- vi->z_logical_clusterbits = LOG_BLOCK_SIZE; -+ vi->z_logical_clusterbits = inode->i_sb->s_blocksize_bits; - set_bit(EROFS_I_Z_INITED_BIT, &vi->flags); - } - inode->i_mapping->a_ops = &z_erofs_aops; -@@ -53,13 +53,13 @@ static int legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m, - unsigned int advise, type; - - m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb, -- erofs_blknr(pos), EROFS_KMAP_ATOMIC); -+ erofs_blknr(inode->i_sb, pos), EROFS_KMAP); - if (IS_ERR(m->kaddr)) - return PTR_ERR(m->kaddr); - - m->nextpackoff = pos + sizeof(struct z_erofs_vle_decompressed_index); - m->lcn = lcn; -- di = m->kaddr + erofs_blkoff(pos); -+ di = m->kaddr + erofs_blkoff(inode->i_sb, pos); - - advise = le16_to_cpu(di->di_advise); - type = (advise >> Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT) & -@@ -160,7 +160,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, - (vcnt << amortizedshift); - big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1; - encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt; -- eofs = erofs_blkoff(pos); -+ eofs = erofs_blkoff(m->inode->i_sb, pos); - base = round_down(eofs, vcnt << amortizedshift); - in = m->kaddr + base; - -@@ -252,7 +252,7 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m, - struct erofs_inode *const vi = EROFS_I(inode); - const erofs_off_t ebase = sizeof(struct z_erofs_map_header) + - ALIGN(erofs_iloc(inode) + vi->inode_isize + vi->xattr_isize, 8); -- const unsigned int totalidx = DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ); -+ unsigned int totalidx = erofs_iblks(inode); - unsigned int compacted_4b_initial, compacted_2b; - unsigned int amortizedshift; - erofs_off_t pos; -@@ -290,7 +290,7 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m, - out: - pos += lcn * (1 << amortizedshift); - m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb, -- erofs_blknr(pos), EROFS_KMAP_ATOMIC); -+ erofs_blknr(inode->i_sb, pos), EROFS_KMAP); - if (IS_ERR(m->kaddr)) - return PTR_ERR(m->kaddr); - return unpack_compacted_index(m, amortizedshift, pos, lookahead); -@@ -360,6 +360,7 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m, - static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m, - unsigned int initial_lcn) - { -+ struct super_block *sb = m->inode->i_sb; - struct erofs_inode *const vi = EROFS_I(m->inode); - struct erofs_map_blocks *const map = m->map; - const unsigned int lclusterbits = vi->z_logical_clusterbits; -@@ -406,7 +407,7 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m, - * if the 1st NONHEAD lcluster is actually PLAIN or HEAD type - * rather than CBLKCNT, it's a 1 lcluster-sized pcluster. - */ -- m->compressedblks = 1 << (lclusterbits - LOG_BLOCK_SIZE); -+ m->compressedblks = 1 << (lclusterbits - sb->s_blocksize_bits); - break; - case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: - if (m->delta[0] != 1) -@@ -422,7 +423,7 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m, - return -EFSCORRUPTED; - } - out: -- map->m_plen = (u64)m->compressedblks << LOG_BLOCK_SIZE; -+ map->m_plen = erofs_pos(sb, m->compressedblks); - return 0; - err_bonus_cblkcnt: - erofs_err(m->inode->i_sb, -@@ -565,7 +566,7 @@ static int z_erofs_do_map_blocks(struct inode *inode, - } else if (fragment && m.lcn == vi->z_tailextent_headlcn) { - map->m_flags |= EROFS_MAP_FRAGMENT; - } else { -- map->m_pa = blknr_to_addr(m.pblk); -+ map->m_pa = erofs_pos(inode->i_sb, m.pblk); - err = z_erofs_get_extent_compressedlen(&m, initial_lcn); - if (err) - goto unmap_out; -@@ -592,7 +593,7 @@ static int z_erofs_do_map_blocks(struct inode *inode, - if ((flags & EROFS_GET_BLOCKS_FIEMAP) || - ((flags & EROFS_GET_BLOCKS_READMORE) && - map->m_algorithmformat == Z_EROFS_COMPRESSION_LZMA && -- map->m_llen >= EROFS_BLKSIZ)) { -+ map->m_llen >= i_blocksize(inode))) { - err = z_erofs_get_extent_decompressedlen(&m); - if (!err) - map->m_flags |= EROFS_MAP_FULL_MAPPED; -@@ -633,13 +634,13 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) - goto out_unlock; - - pos = ALIGN(erofs_iloc(inode) + vi->inode_isize + vi->xattr_isize, 8); -- kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP); -+ kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(sb, pos), EROFS_KMAP); - if (IS_ERR(kaddr)) { - err = PTR_ERR(kaddr); - goto out_unlock; - } - -- h = kaddr + erofs_blkoff(pos); -+ h = kaddr + erofs_blkoff(sb, pos); - /* - * if the highest bit of the 8-byte map header is set, the whole file - * is stored in the packed inode. The rest bits keeps z_fragmentoff. -@@ -663,7 +664,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) - goto out_put_metabuf; - } - -- vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7); -+ vi->z_logical_clusterbits = sb->s_blocksize_bits + (h->h_clusterbits & 7); - if (!erofs_sb_has_big_pcluster(EROFS_SB(sb)) && - vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 | - Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { -@@ -692,7 +693,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) - erofs_put_metabuf(&map.buf); - - if (!map.m_plen || -- erofs_blkoff(map.m_pa) + map.m_plen > EROFS_BLKSIZ) { -+ erofs_blkoff(sb, map.m_pa) + map.m_plen > sb->s_blocksize) { - erofs_err(sb, "invalid tail-packing pclustersize %llu", - map.m_plen); - err = -EFSCORRUPTED; -diff --git a/include/trace/events/erofs.h b/include/trace/events/erofs.h -index e095d36db939..01d0b8927376 100644 ---- a/include/trace/events/erofs.h -+++ b/include/trace/events/erofs.h -@@ -66,8 +66,8 @@ TRACE_EVENT(erofs_fill_inode, - TP_fast_assign( - __entry->dev = inode->i_sb->s_dev; - __entry->nid = EROFS_I(inode)->nid; -- __entry->blkaddr = erofs_blknr(erofs_iloc(inode)); -- __entry->ofs = erofs_blkoff(erofs_iloc(inode)); -+ __entry->blkaddr = erofs_blknr(inode->i_sb, erofs_iloc(inode)); -+ __entry->ofs = erofs_blkoff(inode->i_sb, erofs_iloc(inode)); - ), - - TP_printk("dev = (%d,%d), nid = %llu, blkaddr %u ofs %u", --- -2.41.0 - diff --git a/tools/packaging/kernel/patches/6.1.x/0004-erofs-set-block-size-to-the-on-disk-block-size.patch b/tools/packaging/kernel/patches/6.1.x/0004-erofs-set-block-size-to-the-on-disk-block-size.patch deleted file mode 100644 index 247fc6a440..0000000000 --- a/tools/packaging/kernel/patches/6.1.x/0004-erofs-set-block-size-to-the-on-disk-block-size.patch +++ /dev/null @@ -1,229 +0,0 @@ -From 51183ae95d33249589b30a708271e1e902f8ad0e Mon Sep 17 00:00:00 2001 -From: Jingbo Xu -Date: Mon, 13 Mar 2023 21:53:09 +0800 -Subject: [PATCH 4/4] 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. - -Besides, later we are going to make erofs refer to tar data blobs (which -is 512-byte aligned) for OCI containers, where the block size is 512 -bytes. In this case, the 512-byte block size may not be adequate for a -directory to contain enough dirents. To fix this, we are also going to -introduce directory block size independent on the block size. - -Due to we have already supported block size smaller than PAGE_SIZE now, -disable all these images with such separated directory block size until -we supported this feature later. - -Signed-off-by: Jingbo Xu -Reviewed-by: Gao Xiang -Reviewed-by: Yue Hu -Reviewed-by: Chao Yu -Link: https://lore.kernel.org/r/20230313135309.75269-3-jefflexu@linux.alibaba.com -[ Gao Xiang: update documentation. ] -Signed-off-by: Gao Xiang ---- - Documentation/filesystems/erofs.rst | 10 +++++-- - fs/erofs/erofs_fs.h | 5 ++-- - fs/erofs/inode.c | 3 +- - fs/erofs/internal.h | 10 +------ - fs/erofs/super.c | 45 +++++++++++++++++++---------- - 5 files changed, 43 insertions(+), 30 deletions(-) - -diff --git a/Documentation/filesystems/erofs.rst b/Documentation/filesystems/erofs.rst -index 05e03d54af1a..df681e4391c0 100644 ---- a/Documentation/filesystems/erofs.rst -+++ b/Documentation/filesystems/erofs.rst -@@ -34,8 +34,14 @@ Here is the main features of EROFS: - - - Little endian on-disk design; - -- - 4KiB block size and 32-bit block addresses, therefore 16TiB address space -- at most for now; -+ - Block-based distribution and file-based distribution over fscache are -+ supported; -+ -+ - Support multiple devices to refer to external blobs, which can be used -+ for container images; -+ -+ - 32-bit block addresses for each device, therefore 16TiB address space at -+ most with 4KiB block size for now; - - - Two inode layouts for different requirements: - -diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h -index dbcd24371002..44876a97cabd 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 in bit shift */ - __u8 sb_extslots; /* superblock size = 128 + sb_extslots * 16 */ - - __le16 root_nid; /* nid of root directory */ -@@ -75,7 +75,8 @@ struct erofs_super_block { - } __packed u1; - __le16 extra_devices; /* # of devices besides the primary device */ - __le16 devt_slotoff; /* startoff = devt_slotoff * devt_slotsize */ -- __u8 reserved[6]; -+ __u8 dirblkbits; /* directory block size in bit shift */ -+ __u8 reserved[5]; - __le64 packed_nid; /* nid of the special packed inode */ - __u8 reserved2[24]; - }; -diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c -index efbaa4ef63cb..8fc41fd1620c 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 08628c64210e..1c03daf83a68 100644 ---- a/fs/erofs/internal.h -+++ b/fs/erofs/internal.h -@@ -146,7 +146,7 @@ struct erofs_sb_info { - u16 device_id_mask; /* valid bits of device id to be used */ - - unsigned char islotbits; /* inode slot unit size in bit shift */ -- unsigned char blkszbits; -+ unsigned char blkszbits; /* filesystem block size in bit shift */ - - u32 sb_size; /* total superblock size */ - u32 build_time_nsec; -@@ -239,14 +239,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() to map the buffer */ -diff --git a/fs/erofs/super.c b/fs/erofs/super.c -index b07c9d1deaf8..b073b38c1c77 100644 ---- a/fs/erofs/super.c -+++ b/fs/erofs/super.c -@@ -334,7 +334,6 @@ static int erofs_read_superblock(struct super_block *sb) - struct erofs_sb_info *sbi; - struct erofs_buf buf = __EROFS_BUF_INITIALIZER; - struct erofs_super_block *dsb; -- unsigned int blkszbits; - void *data; - int ret; - -@@ -353,6 +352,16 @@ static int erofs_read_superblock(struct super_block *sb) - goto out; - } - -+ sbi->blkszbits = dsb->blkszbits; -+ if (sbi->blkszbits < 9 || sbi->blkszbits > PAGE_SHIFT) { -+ erofs_err(sb, "blkszbits %u isn't supported", sbi->blkszbits); -+ goto out; -+ } -+ if (dsb->dirblkbits) { -+ erofs_err(sb, "dirblkbits %u isn't supported", dsb->dirblkbits); -+ 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); -@@ -361,19 +370,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; -@@ -730,8 +731,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) -@@ -741,8 +742,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; - } - -@@ -755,12 +756,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.41.0 - diff --git a/versions.yaml b/versions.yaml index 0e98219863..304de7c66a 100644 --- a/versions.yaml +++ b/versions.yaml @@ -210,7 +210,7 @@ assets: kernel-dragonball-experimental: description: "Linux kernel with Dragonball VMM optimizations like upcall" url: "https://cdn.kernel.org/pub/linux/kernel/v6.x/" - version: "v6.1.62" + version: "v6.1.140" externals: description: "Third-party projects used by the system"