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;
        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;
        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;
        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;
        }
 
                        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) {
                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;
 
                .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;
 
                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;
 
                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;
                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;
 
        /* 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;
 
 {
        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;
 
 
                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;
                }
                if (err)
                        break;
 skip_this:
-               ctx->pos = blknr_to_addr(i) + maxsize;
+               ctx->pos = erofs_pos(sb, i) + maxsize;
                ++i;
                ofs = 0;
        }
 
                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);
        inode->i_size = OFFSET_MAX;
        inode->i_mapping->a_ops = &erofs_fscache_meta_aops;
        mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
+       inode->i_blkbits = EROFS_SB(sb)->blkszbits;
        inode->i_private = ctx;
 
        ctx->cookie = cookie;
 
        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);
        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) {
                        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;
        if (test_opt(&sbi->opt, DAX_ALWAYS) && S_ISREG(inode->i_mode) &&
            vi->datalayout == EROFS_INODE_FLAT_PLAIN)
                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:
                              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;
        }
 
        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",
 
 #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;
 
 /* 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)
 
 #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) \
 {
        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);
 }
 
 
 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);
 
 
                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;
 
                        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);
                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);
 
 
 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) {
        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);
        *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;
        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]) {
        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;
                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;
 
 
        }
 
        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);
        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);
 
 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);
        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;
 }
 
 
        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);
        if (IS_ERR(it->kaddr))
        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)
                        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 */
        }
 
        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)
                        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;
 {
        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);
                if (IS_ERR(it->it.kaddr))
        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);
                if (IS_ERR(it->it.kaddr))
 
                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
 
 
        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;
                                 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;
        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;
        }
                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,
 
                /* 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 {
 
                                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;
 
                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;
        unsigned int advise, type;
 
        m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb,
-                                     erofs_blknr(pos), EROFS_KMAP);
+                                     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) &
                         (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;
 
        const unsigned int lclusterbits = vi->z_logical_clusterbits;
        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;
 out:
        pos += lcn * (1 << amortizedshift);
        m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb,
-                                     erofs_blknr(pos), EROFS_KMAP);
+                                     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);
 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;
                 * 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)
                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,
        } 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;
        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;
                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.
                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)) {
                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;
 
        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",