On 2019/6/21 0:07, Gao Xiang wrote: > This patch introduces new compacted compression indexes. > > In contract to legacy compression indexes that > each 4k logical cluster has an 8-byte index, > compacted ondisk compression indexes will have > amortized 2 bytes for each 4k logical cluster (compacted 2B) > amortized 4 bytes for each 4k logical cluster (compacted 4B) > > In detail, several continuous clusters will be encoded in > a compacted pack with cluster types, offsets, and one blkaddr > at the end of the pack to leave 4-byte margin for better > decoding performance, as illustrated below: > _____________________________________________ > |___@_____ encoded bits __________|_ blkaddr _| > 0 . amortized * vcnt > . . > . . amortized * vcnt - 4 > . . > .___________________. > |_type_|_clusterofs_| > > Note that compacted 2 / 4B should be aligned with 32 / 8 bytes > in order to avoid each pack crossing page boundary. > > Signed-off-by: Gao Xiang <gaoxiang25@xxxxxxxxxx> > --- > drivers/staging/erofs/data.c | 4 +-- > drivers/staging/erofs/erofs_fs.h | 57 +++++++++++++++++++++++++------ > drivers/staging/erofs/inode.c | 5 +-- > drivers/staging/erofs/internal.h | 11 ++---- > drivers/staging/erofs/unzip_vle.c | 8 ++--- > 5 files changed, 56 insertions(+), 29 deletions(-) > > diff --git a/drivers/staging/erofs/data.c b/drivers/staging/erofs/data.c > index 746685f90564..cc31c3e5984c 100644 > --- a/drivers/staging/erofs/data.c > +++ b/drivers/staging/erofs/data.c > @@ -124,7 +124,7 @@ static int erofs_map_blocks_flatmode(struct inode *inode, > trace_erofs_map_blocks_flatmode_enter(inode, map, flags); > > nblocks = DIV_ROUND_UP(inode->i_size, PAGE_SIZE); > - lastblk = nblocks - is_inode_layout_inline(inode); > + lastblk = nblocks - is_inode_flat_inline(inode); > > if (unlikely(offset >= inode->i_size)) { > /* leave out-of-bound access unmapped */ > @@ -139,7 +139,7 @@ static int erofs_map_blocks_flatmode(struct inode *inode, > 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; > - } else if (is_inode_layout_inline(inode)) { > + } else if (is_inode_flat_inline(inode)) { > /* 2 - inode inline B: inode, [xattrs], inline last blk... */ > struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); > > diff --git a/drivers/staging/erofs/erofs_fs.h b/drivers/staging/erofs/erofs_fs.h > index 8ddb2b3e7d39..a05139f1df60 100644 > --- a/drivers/staging/erofs/erofs_fs.h > +++ b/drivers/staging/erofs/erofs_fs.h > @@ -49,19 +49,29 @@ struct erofs_super_block { > * erofs inode data mapping: > * 0 - inode plain without inline data A: > * inode, [xattrs], ... | ... | no-holed data > - * 1 - inode VLE compression B: > + * 1 - inode VLE compression B (legacy): > * inode, [xattrs], extents ... | ... > * 2 - inode plain with inline data C: > * inode, [xattrs], last_inline_data, ... | ... | no-holed data > - * 3~7 - reserved > + * 3 - inode compression D: > + * inode, [xattrs], map_header, extents ... | ... > + * 4~7 - reserved > */ > enum { > - EROFS_INODE_LAYOUT_PLAIN, > - EROFS_INODE_LAYOUT_COMPRESSION, > - EROFS_INODE_LAYOUT_INLINE, > + EROFS_INODE_FLAT_PLAIN, > + EROFS_INODE_FLAT_COMPRESSION_LEGACY, > + EROFS_INODE_FLAT_INLINE, > + EROFS_INODE_FLAT_COMPRESSION, > EROFS_INODE_LAYOUT_MAX > }; > > +static bool erofs_inode_is_data_compressed(unsigned int datamode) > +{ > + if (datamode == EROFS_INODE_FLAT_COMPRESSION) > + return true; > + return datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY; > +} > + > /* bit definitions of inode i_advise */ > #define EROFS_I_VERSION_BITS 1 > #define EROFS_I_DATA_MAPPING_BITS 3 > @@ -176,11 +186,37 @@ struct erofs_xattr_entry { > sizeof(struct erofs_xattr_entry) + \ > (entry)->e_name_len + le16_to_cpu((entry)->e_value_size)) > > -/* have to be aligned with 8 bytes on disk */ > -struct erofs_extent_header { > - __le32 eh_checksum; > - __le32 eh_reserved[3]; > -} __packed; > +/* available compression algorithm types */ > +enum { > + Z_EROFS_COMPRESSION_LZ4, > + Z_EROFS_COMPRESSION_MAX > +}; > + > +/* > + * bit 0 : COMPACTED_2B indexes (0 - off; 1 - on) > + * e.g. for 4k logical cluster size, 4B if compacted 2B is off; > + * (4B) + 2B + (4B) if compacted 2B is on. > + */ > +#define Z_EROFS_ADVISE_COMPACTED_2B_BIT 0 > + > +#define Z_EROFS_ADVISE_COMPACTED_2B (1 << Z_EROFS_ADVISE_COMPACTED_2B_BIT) > + > +struct z_erofs_map_header { > + __le32 h_reserved1; > + __le16 h_advise; > + /* > + * bit 0-3 : algorithm type of head 1 (logical cluster type 01); > + * bit 4-7 : algorithm type of head 2 (logical cluster type 11). > + */ > + __u8 h_algorithmtype; > + /* > + * bit 0-2 : logical cluster bits - 12, e.g. 0 for 4096; > + * bit 3-4 : (physical - logical) cluster bits of head 1: > + * For example, if logical clustersize = 4096, 1 for 8192. > + * bit 5-7 : (physical - logical) cluster bits of head 2. > + */ > + __u8 h_clusterbits; > +}; > > /* > * Z_EROFS Variable-sized Logical Extent cluster type: > @@ -270,7 +306,6 @@ static inline void erofs_check_ondisk_layout_definitions(void) > BUILD_BUG_ON(sizeof(struct erofs_inode_v2) != 64); > BUILD_BUG_ON(sizeof(struct erofs_xattr_ibody_header) != 12); > BUILD_BUG_ON(sizeof(struct erofs_xattr_entry) != 4); > - BUILD_BUG_ON(sizeof(struct erofs_extent_header) != 16); > BUILD_BUG_ON(sizeof(struct z_erofs_vle_decompressed_index) != 8); > BUILD_BUG_ON(sizeof(struct erofs_dirent) != 12); > > diff --git a/drivers/staging/erofs/inode.c b/drivers/staging/erofs/inode.c > index e51348f7e838..3539290b8e45 100644 > --- a/drivers/staging/erofs/inode.c > +++ b/drivers/staging/erofs/inode.c > @@ -127,12 +127,9 @@ static int fill_inline_data(struct inode *inode, void *data, > { > struct erofs_vnode *vi = EROFS_V(inode); > struct erofs_sb_info *sbi = EROFS_I_SB(inode); > - const int mode = vi->datamode; > - > - DBG_BUGON(mode >= EROFS_INODE_LAYOUT_MAX); > > /* should be inode inline C */ > - if (mode != EROFS_INODE_LAYOUT_INLINE) > + if (!is_inode_flat_inline(inode)) > return 0; > > /* fast symlink (following ext4) */ > diff --git a/drivers/staging/erofs/internal.h b/drivers/staging/erofs/internal.h > index 1666cceecb3c..c851d0be6cf6 100644 > --- a/drivers/staging/erofs/internal.h > +++ b/drivers/staging/erofs/internal.h > @@ -382,19 +382,14 @@ static inline unsigned long inode_datablocks(struct inode *inode) > return DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ); > } > > -static inline bool is_inode_layout_plain(struct inode *inode) > -{ > - return EROFS_V(inode)->datamode == EROFS_INODE_LAYOUT_PLAIN; > -} > - > static inline bool is_inode_layout_compression(struct inode *inode) > { > - return EROFS_V(inode)->datamode == EROFS_INODE_LAYOUT_COMPRESSION; > + return erofs_inode_is_data_compressed(EROFS_V(inode)->datamode); > } > > -static inline bool is_inode_layout_inline(struct inode *inode) > +static inline bool is_inode_flat_inline(struct inode *inode) > { > - return EROFS_V(inode)->datamode == EROFS_INODE_LAYOUT_INLINE; > + return EROFS_V(inode)->datamode == EROFS_INODE_FLAT_INLINE; > } > > extern const struct super_operations erofs_sops; > diff --git a/drivers/staging/erofs/unzip_vle.c b/drivers/staging/erofs/unzip_vle.c > index f3d0d2c03939..0db9bc50f67c 100644 > --- a/drivers/staging/erofs/unzip_vle.c > +++ b/drivers/staging/erofs/unzip_vle.c > @@ -1643,8 +1643,8 @@ vle_extent_blkaddr(struct inode *inode, pgoff_t index) > struct erofs_vnode *vi = EROFS_V(inode); > > unsigned int ofs = Z_EROFS_VLE_EXTENT_ALIGN(vi->inode_isize + > - vi->xattr_isize) + sizeof(struct erofs_extent_header) + > - index * sizeof(struct z_erofs_vle_decompressed_index); > + vi->xattr_isize) + > + 16 + index * sizeof(struct z_erofs_vle_decompressed_index); > > return erofs_blknr(iloc(sbi, vi->nid) + ofs); > } > @@ -1656,8 +1656,8 @@ vle_extent_blkoff(struct inode *inode, pgoff_t index) > struct erofs_vnode *vi = EROFS_V(inode); > > unsigned int ofs = Z_EROFS_VLE_EXTENT_ALIGN(vi->inode_isize + > - vi->xattr_isize) + sizeof(struct erofs_extent_header) + > - index * sizeof(struct z_erofs_vle_decompressed_index); > + vi->xattr_isize) + > + 16 + index * sizeof(struct z_erofs_vle_decompressed_index); We can add one macro to wrap above offset (16) for better readability, anyway, this patch looks good to me. :) Reviewed-by: Chao Yu <yuchao0@xxxxxxxxxx> Thanks, > > return erofs_blkoff(iloc(sbi, vi->nid) + ofs); > } > _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel