29b24f6ca112d drivers/staging/erofs/zmap.c (Gao Xiang 2019-07-31 23:57:31 +0800 1) // SPDX-License-Identifier: GPL-2.0-only
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 2) /*
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 3) * Copyright (C) 2018-2019 HUAWEI, Inc.
592e7cd00bb9d fs/erofs/zmap.c (Alexander A. Klimov 2020-07-13 15:09:44 +0200 4) * https://www.huawei.com/
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 5) * Created by Gao Xiang <gaoxiang25@huawei.com>
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 6) */
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 7) #include "internal.h"
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 8) #include <asm/unaligned.h>
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 9) #include <trace/events/erofs.h>
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 10)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 11) int z_erofs_fill_inode(struct inode *inode)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 12) {
a5876e24f13f1 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:08:56 +0800 13) struct erofs_inode *const vi = EROFS_I(inode);
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 14) struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 15)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 16) if (!erofs_sb_has_big_pcluster(sbi) &&
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 17) vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 18) vi->z_advise = 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 19) vi->z_algorithmtype[0] = 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 20) vi->z_algorithmtype[1] = 0;
eace994a116c9 drivers/staging/erofs/zmap.c (Gao Xiang 2019-07-31 23:57:48 +0800 21) vi->z_logical_clusterbits = LOG_BLOCK_SIZE;
a5876e24f13f1 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:08:56 +0800 22) set_bit(EROFS_I_Z_INITED_BIT, &vi->flags);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 23) }
0c638f70d7310 fs/erofs/zmap.c (Gao Xiang 2019-11-08 11:37:33 +0800 24) inode->i_mapping->a_ops = &z_erofs_aops;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 25) return 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 26) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 27)
0c638f70d7310 fs/erofs/zmap.c (Gao Xiang 2019-11-08 11:37:33 +0800 28) static int z_erofs_fill_inode_lazy(struct inode *inode)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 29) {
a5876e24f13f1 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:08:56 +0800 30) struct erofs_inode *const vi = EROFS_I(inode);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 31) struct super_block *const sb = inode->i_sb;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 32) int err;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 33) erofs_off_t pos;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 34) struct page *page;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 35) void *kaddr;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 36) struct z_erofs_map_header *h;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 37)
ce06312918131 fs/erofs/zmap.c (Gao Xiang 2021-02-09 21:06:18 +0800 38) if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags)) {
ce06312918131 fs/erofs/zmap.c (Gao Xiang 2021-02-09 21:06:18 +0800 39) /*
ce06312918131 fs/erofs/zmap.c (Gao Xiang 2021-02-09 21:06:18 +0800 40) * paired with smp_mb() at the end of the function to ensure
ce06312918131 fs/erofs/zmap.c (Gao Xiang 2021-02-09 21:06:18 +0800 41) * fields will only be observed after the bit is set.
ce06312918131 fs/erofs/zmap.c (Gao Xiang 2021-02-09 21:06:18 +0800 42) */
ce06312918131 fs/erofs/zmap.c (Gao Xiang 2021-02-09 21:06:18 +0800 43) smp_mb();
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 44) return 0;
ce06312918131 fs/erofs/zmap.c (Gao Xiang 2021-02-09 21:06:18 +0800 45) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 46)
a5876e24f13f1 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:08:56 +0800 47) if (wait_on_bit_lock(&vi->flags, EROFS_I_BL_Z_BIT, TASK_KILLABLE))
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 48) return -ERESTARTSYS;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 49)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 50) err = 0;
a5876e24f13f1 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:08:56 +0800 51) if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags))
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 52) goto out_unlock;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 53)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 54) DBG_BUGON(!erofs_sb_has_big_pcluster(EROFS_SB(sb)) &&
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 55) vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 56)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 57) pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize +
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 58) vi->xattr_isize, 8);
e655b5b3a29c5 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:03 +0800 59) page = erofs_get_meta_page(sb, erofs_blknr(pos));
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 60) if (IS_ERR(page)) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 61) err = PTR_ERR(page);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 62) goto out_unlock;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 63) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 64)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 65) kaddr = kmap_atomic(page);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 66)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 67) h = kaddr + erofs_blkoff(pos);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 68) vi->z_advise = le16_to_cpu(h->h_advise);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 69) vi->z_algorithmtype[0] = h->h_algorithmtype & 15;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 70) vi->z_algorithmtype[1] = h->h_algorithmtype >> 4;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 71)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 72) if (vi->z_algorithmtype[0] >= Z_EROFS_COMPRESSION_MAX) {
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 73) erofs_err(sb, "unknown compression format %u for nid %llu, please upgrade kernel",
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 74) vi->z_algorithmtype[0], vi->nid);
ff784a78af117 drivers/staging/erofs/zmap.c (Gao Xiang 2019-08-14 18:37:05 +0800 75) err = -EOPNOTSUPP;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 76) goto unmap_done;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 77) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 78)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 79) vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7);
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 80) if (!erofs_sb_has_big_pcluster(EROFS_SB(sb)) &&
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 81) vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 |
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 82) Z_EROFS_ADVISE_BIG_PCLUSTER_2)) {
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 83) erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu",
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 84) vi->nid);
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 85) err = -EFSCORRUPTED;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 86) goto unmap_done;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 87) }
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 88) if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION &&
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 89) !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 90) !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) {
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 91) erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu",
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 92) vi->nid);
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 93) err = -EFSCORRUPTED;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 94) goto unmap_done;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 95) }
ce06312918131 fs/erofs/zmap.c (Gao Xiang 2021-02-09 21:06:18 +0800 96) /* paired with smp_mb() at the beginning of the function */
ce06312918131 fs/erofs/zmap.c (Gao Xiang 2021-02-09 21:06:18 +0800 97) smp_mb();
a5876e24f13f1 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:08:56 +0800 98) set_bit(EROFS_I_Z_INITED_BIT, &vi->flags);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 99) unmap_done:
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 100) kunmap_atomic(kaddr);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 101) unlock_page(page);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 102) put_page(page);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 103) out_unlock:
a5876e24f13f1 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:08:56 +0800 104) clear_and_wake_up_bit(EROFS_I_BL_Z_BIT, &vi->flags);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 105) return err;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 106) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 107)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 108) struct z_erofs_maprecorder {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 109) struct inode *inode;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 110) struct erofs_map_blocks *map;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 111) void *kaddr;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 112)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 113) unsigned long lcn;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 114) /* compression extent information gathered */
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 115) u8 type;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 116) u16 clusterofs;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 117) u16 delta[2];
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 118) erofs_blk_t pblk, compressedlcs;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 119) };
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 120)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 121) static int z_erofs_reload_indexes(struct z_erofs_maprecorder *m,
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 122) erofs_blk_t eblk)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 123) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 124) struct super_block *const sb = m->inode->i_sb;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 125) struct erofs_map_blocks *const map = m->map;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 126) struct page *mpage = map->mpage;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 127)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 128) if (mpage) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 129) if (mpage->index == eblk) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 130) if (!m->kaddr)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 131) m->kaddr = kmap_atomic(mpage);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 132) return 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 133) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 134)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 135) if (m->kaddr) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 136) kunmap_atomic(m->kaddr);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 137) m->kaddr = NULL;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 138) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 139) put_page(mpage);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 140) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 141)
e655b5b3a29c5 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:03 +0800 142) mpage = erofs_get_meta_page(sb, eblk);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 143) if (IS_ERR(mpage)) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 144) map->mpage = NULL;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 145) return PTR_ERR(mpage);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 146) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 147) m->kaddr = kmap_atomic(mpage);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 148) unlock_page(mpage);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 149) map->mpage = mpage;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 150) return 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 151) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 152)
0c638f70d7310 fs/erofs/zmap.c (Gao Xiang 2019-11-08 11:37:33 +0800 153) static int legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m,
0c638f70d7310 fs/erofs/zmap.c (Gao Xiang 2019-11-08 11:37:33 +0800 154) unsigned long lcn)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 155) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 156) struct inode *const inode = m->inode;
a5876e24f13f1 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:08:56 +0800 157) struct erofs_inode *const vi = EROFS_I(inode);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 158) const erofs_off_t ibase = iloc(EROFS_I_SB(inode), vi->nid);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 159) const erofs_off_t pos =
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 160) Z_EROFS_VLE_LEGACY_INDEX_ALIGN(ibase + vi->inode_isize +
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 161) vi->xattr_isize) +
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 162) lcn * sizeof(struct z_erofs_vle_decompressed_index);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 163) struct z_erofs_vle_decompressed_index *di;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 164) unsigned int advise, type;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 165) int err;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 166)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 167) err = z_erofs_reload_indexes(m, erofs_blknr(pos));
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 168) if (err)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 169) return err;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 170)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 171) m->lcn = lcn;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 172) di = m->kaddr + erofs_blkoff(pos);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 173)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 174) advise = le16_to_cpu(di->di_advise);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 175) type = (advise >> Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT) &
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 176) ((1 << Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) - 1);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 177) switch (type) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 178) case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 179) m->clusterofs = 1 << vi->z_logical_clusterbits;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 180) m->delta[0] = le16_to_cpu(di->di_u.delta[0]);
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 181) if (m->delta[0] & Z_EROFS_VLE_DI_D0_CBLKCNT) {
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 182) if (!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) {
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 183) DBG_BUGON(1);
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 184) return -EFSCORRUPTED;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 185) }
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 186) m->compressedlcs = m->delta[0] &
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 187) ~Z_EROFS_VLE_DI_D0_CBLKCNT;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 188) m->delta[0] = 1;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 189) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 190) m->delta[1] = le16_to_cpu(di->di_u.delta[1]);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 191) break;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 192) case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 193) case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 194) m->clusterofs = le16_to_cpu(di->di_clusterofs);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 195) m->pblk = le32_to_cpu(di->di_u.blkaddr);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 196) break;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 197) default:
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 198) DBG_BUGON(1);
382329a9d8553 drivers/staging/erofs/zmap.c (Gao Xiang 2019-08-14 18:37:04 +0800 199) return -EOPNOTSUPP;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 200) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 201) m->type = type;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 202) return 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 203) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 204)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 205) static unsigned int decode_compactedbits(unsigned int lobits,
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 206) unsigned int lomask,
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 207) u8 *in, unsigned int pos, u8 *type)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 208) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 209) const unsigned int v = get_unaligned_le32(in + pos / 8) >> (pos & 7);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 210) const unsigned int lo = v & lomask;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 211)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 212) *type = (v >> lobits) & 3;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 213) return lo;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 214) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 215)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 216) static int unpack_compacted_index(struct z_erofs_maprecorder *m,
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 217) unsigned int amortizedshift,
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 218) unsigned int eofs)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 219) {
a5876e24f13f1 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:08:56 +0800 220) struct erofs_inode *const vi = EROFS_I(m->inode);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 221) const unsigned int lclusterbits = vi->z_logical_clusterbits;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 222) const unsigned int lomask = (1 << lclusterbits) - 1;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 223) unsigned int vcnt, base, lo, encodebits, nblk;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 224) int i;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 225) u8 *in, type;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 226) bool big_pcluster;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 227)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 228) if (1 << amortizedshift == 4)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 229) vcnt = 2;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 230) else if (1 << amortizedshift == 2 && lclusterbits == 12)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 231) vcnt = 16;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 232) else
ff784a78af117 drivers/staging/erofs/zmap.c (Gao Xiang 2019-08-14 18:37:05 +0800 233) return -EOPNOTSUPP;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 234)
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 235) big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 236) encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 237) base = round_down(eofs, vcnt << amortizedshift);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 238) in = m->kaddr + base;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 239)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 240) i = (eofs - base) >> amortizedshift;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 241)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 242) lo = decode_compactedbits(lclusterbits, lomask,
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 243) in, encodebits * i, &type);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 244) m->type = type;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 245) if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 246) m->clusterofs = 1 << lclusterbits;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 247) if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT) {
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 248) if (!big_pcluster) {
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 249) DBG_BUGON(1);
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 250) return -EFSCORRUPTED;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 251) }
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 252) m->compressedlcs = lo & ~Z_EROFS_VLE_DI_D0_CBLKCNT;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 253) m->delta[0] = 1;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 254) return 0;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 255) } else if (i + 1 != (int)vcnt) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 256) m->delta[0] = lo;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 257) return 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 258) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 259) /*
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 260) * since the last lcluster in the pack is special,
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 261) * of which lo saves delta[1] rather than delta[0].
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 262) * Hence, get delta[0] by the previous lcluster indirectly.
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 263) */
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 264) lo = decode_compactedbits(lclusterbits, lomask,
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 265) in, encodebits * (i - 1), &type);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 266) if (type != Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 267) lo = 0;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 268) else if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT)
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 269) lo = 1;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 270) m->delta[0] = lo + 1;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 271) return 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 272) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 273) m->clusterofs = lo;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 274) m->delta[0] = 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 275) /* figout out blkaddr (pblk) for HEAD lclusters */
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 276) if (!big_pcluster) {
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 277) nblk = 1;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 278) while (i > 0) {
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 279) --i;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 280) lo = decode_compactedbits(lclusterbits, lomask,
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 281) in, encodebits * i, &type);
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 282) if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD)
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 283) i -= lo;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 284)
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 285) if (i >= 0)
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 286) ++nblk;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 287) }
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 288) } else {
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 289) nblk = 0;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 290) while (i > 0) {
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 291) --i;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 292) lo = decode_compactedbits(lclusterbits, lomask,
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 293) in, encodebits * i, &type);
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 294) if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) {
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 295) if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT) {
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 296) --i;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 297) nblk += lo & ~Z_EROFS_VLE_DI_D0_CBLKCNT;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 298) continue;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 299) }
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 300) /* bigpcluster shouldn't have plain d0 == 1 */
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 301) if (lo <= 1) {
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 302) DBG_BUGON(1);
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 303) return -EFSCORRUPTED;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 304) }
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 305) i -= lo - 2;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 306) continue;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 307) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 308) ++nblk;
b86269f438923 fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:25 +0800 309) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 310) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 311) in += (vcnt << amortizedshift) - sizeof(__le32);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 312) m->pblk = le32_to_cpu(*(__le32 *)in) + nblk;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 313) return 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 314) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 315)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 316) static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m,
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 317) unsigned long lcn)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 318) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 319) struct inode *const inode = m->inode;
a5876e24f13f1 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:08:56 +0800 320) struct erofs_inode *const vi = EROFS_I(inode);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 321) const unsigned int lclusterbits = vi->z_logical_clusterbits;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 322) const erofs_off_t ebase = ALIGN(iloc(EROFS_I_SB(inode), vi->nid) +
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 323) vi->inode_isize + vi->xattr_isize, 8) +
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 324) sizeof(struct z_erofs_map_header);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 325) const unsigned int totalidx = DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 326) unsigned int compacted_4b_initial, compacted_2b;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 327) unsigned int amortizedshift;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 328) erofs_off_t pos;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 329) int err;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 330)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 331) if (lclusterbits != 12)
ff784a78af117 drivers/staging/erofs/zmap.c (Gao Xiang 2019-08-14 18:37:05 +0800 332) return -EOPNOTSUPP;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 333)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 334) if (lcn >= totalidx)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 335) return -EINVAL;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 336)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 337) m->lcn = lcn;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 338) /* used to align to 32-byte (compacted_2b) alignment */
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 339) compacted_4b_initial = (32 - ebase % 32) / 4;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 340) if (compacted_4b_initial == 32 / 4)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 341) compacted_4b_initial = 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 342)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 343) if (vi->z_advise & Z_EROFS_ADVISE_COMPACTED_2B)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 344) compacted_2b = rounddown(totalidx - compacted_4b_initial, 16);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 345) else
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 346) compacted_2b = 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 347)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 348) pos = ebase;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 349) if (lcn < compacted_4b_initial) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 350) amortizedshift = 2;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 351) goto out;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 352) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 353) pos += compacted_4b_initial * 4;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 354) lcn -= compacted_4b_initial;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 355)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 356) if (lcn < compacted_2b) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 357) amortizedshift = 1;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 358) goto out;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 359) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 360) pos += compacted_2b * 2;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 361) lcn -= compacted_2b;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 362) amortizedshift = 2;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 363) out:
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 364) pos += lcn * (1 << amortizedshift);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 365) err = z_erofs_reload_indexes(m, erofs_blknr(pos));
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 366) if (err)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 367) return err;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 368) return unpack_compacted_index(m, amortizedshift, erofs_blkoff(pos));
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 369) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 370)
0c638f70d7310 fs/erofs/zmap.c (Gao Xiang 2019-11-08 11:37:33 +0800 371) static int z_erofs_load_cluster_from_disk(struct z_erofs_maprecorder *m,
0c638f70d7310 fs/erofs/zmap.c (Gao Xiang 2019-11-08 11:37:33 +0800 372) unsigned int lcn)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 373) {
a5876e24f13f1 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:08:56 +0800 374) const unsigned int datamode = EROFS_I(m->inode)->datalayout;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 375)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 376) if (datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY)
0c638f70d7310 fs/erofs/zmap.c (Gao Xiang 2019-11-08 11:37:33 +0800 377) return legacy_load_cluster_from_disk(m, lcn);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 378)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 379) if (datamode == EROFS_INODE_FLAT_COMPRESSION)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 380) return compacted_load_cluster_from_disk(m, lcn);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 381)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 382) return -EINVAL;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 383) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 384)
0c638f70d7310 fs/erofs/zmap.c (Gao Xiang 2019-11-08 11:37:33 +0800 385) static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
0c638f70d7310 fs/erofs/zmap.c (Gao Xiang 2019-11-08 11:37:33 +0800 386) unsigned int lookback_distance)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 387) {
a5876e24f13f1 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:08:56 +0800 388) struct erofs_inode *const vi = EROFS_I(m->inode);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 389) struct erofs_map_blocks *const map = m->map;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 390) const unsigned int lclusterbits = vi->z_logical_clusterbits;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 391) unsigned long lcn = m->lcn;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 392) int err;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 393)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 394) if (lcn < lookback_distance) {
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 395) erofs_err(m->inode->i_sb,
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 396) "bogus lookback distance @ nid %llu", vi->nid);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 397) DBG_BUGON(1);
a6b9b1d5eae61 drivers/staging/erofs/zmap.c (Gao Xiang 2019-08-14 18:37:03 +0800 398) return -EFSCORRUPTED;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 399) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 400)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 401) /* load extent head logical cluster if needed */
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 402) lcn -= lookback_distance;
0c638f70d7310 fs/erofs/zmap.c (Gao Xiang 2019-11-08 11:37:33 +0800 403) err = z_erofs_load_cluster_from_disk(m, lcn);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 404) if (err)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 405) return err;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 406)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 407) switch (m->type) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 408) case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
8d8a09b093d70 fs/erofs/zmap.c (Gao Xiang 2019-08-30 00:38:27 +0800 409) if (!m->delta[0]) {
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 410) erofs_err(m->inode->i_sb,
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 411) "invalid lookback distance 0 @ nid %llu",
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 412) vi->nid);
598bb8913d015 drivers/staging/erofs/zmap.c (Gao Xiang 2019-08-19 18:34:26 +0800 413) DBG_BUGON(1);
598bb8913d015 drivers/staging/erofs/zmap.c (Gao Xiang 2019-08-19 18:34:26 +0800 414) return -EFSCORRUPTED;
598bb8913d015 drivers/staging/erofs/zmap.c (Gao Xiang 2019-08-19 18:34:26 +0800 415) }
0c638f70d7310 fs/erofs/zmap.c (Gao Xiang 2019-11-08 11:37:33 +0800 416) return z_erofs_extent_lookback(m, m->delta[0]);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 417) case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 418) map->m_flags &= ~EROFS_MAP_ZIPPED;
df561f6688fef fs/erofs/zmap.c (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 419) fallthrough;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 420) case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 421) map->m_la = (lcn << lclusterbits) | m->clusterofs;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 422) break;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 423) default:
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 424) erofs_err(m->inode->i_sb,
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 425) "unknown type %u @ lcn %lu of nid %llu",
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 426) m->type, lcn, vi->nid);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 427) DBG_BUGON(1);
382329a9d8553 drivers/staging/erofs/zmap.c (Gao Xiang 2019-08-14 18:37:04 +0800 428) return -EOPNOTSUPP;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 429) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 430) return 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 431) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 432)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 433) static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 434) unsigned int initial_lcn)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 435) {
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 436) struct erofs_inode *const vi = EROFS_I(m->inode);
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 437) struct erofs_map_blocks *const map = m->map;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 438) const unsigned int lclusterbits = vi->z_logical_clusterbits;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 439) unsigned long lcn;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 440) int err;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 441)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 442) DBG_BUGON(m->type != Z_EROFS_VLE_CLUSTER_TYPE_PLAIN &&
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 443) m->type != Z_EROFS_VLE_CLUSTER_TYPE_HEAD);
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 444) if (!(map->m_flags & EROFS_MAP_ZIPPED) ||
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 445) !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) {
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 446) map->m_plen = 1 << lclusterbits;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 447) return 0;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 448) }
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 449)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 450) lcn = m->lcn + 1;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 451) if (m->compressedlcs)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 452) goto out;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 453)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 454) err = z_erofs_load_cluster_from_disk(m, lcn);
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 455) if (err)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 456) return err;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 457)
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 458) /*
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 459) * If the 1st NONHEAD lcluster has already been handled initially w/o
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 460) * valid compressedlcs, which means at least it mustn't be CBLKCNT, or
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 461) * an internal implemenatation error is detected.
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 462) *
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 463) * The following code can also handle it properly anyway, but let's
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 464) * BUG_ON in the debugging mode only for developers to notice that.
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 465) */
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 466) DBG_BUGON(lcn == initial_lcn &&
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 467) m->type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD);
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 468)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 469) switch (m->type) {
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 470) case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 471) case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 472) /*
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 473) * if the 1st NONHEAD lcluster is actually PLAIN or HEAD type
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 474) * rather than CBLKCNT, it's a 1 lcluster-sized pcluster.
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 475) */
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 476) m->compressedlcs = 1;
0852b6ca941ef fs/erofs/zmap.c (Gao Xiang 2021-05-10 14:47:15 +0800 477) break;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 478) case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 479) if (m->delta[0] != 1)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 480) goto err_bonus_cblkcnt;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 481) if (m->compressedlcs)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 482) break;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 483) fallthrough;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 484) default:
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 485) erofs_err(m->inode->i_sb,
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 486) "cannot found CBLKCNT @ lcn %lu of nid %llu",
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 487) lcn, vi->nid);
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 488) DBG_BUGON(1);
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 489) return -EFSCORRUPTED;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 490) }
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 491) out:
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 492) map->m_plen = m->compressedlcs << lclusterbits;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 493) return 0;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 494) err_bonus_cblkcnt:
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 495) erofs_err(m->inode->i_sb,
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 496) "bogus CBLKCNT @ lcn %lu of nid %llu",
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 497) lcn, vi->nid);
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 498) DBG_BUGON(1);
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 499) return -EFSCORRUPTED;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 500) }
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 501)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 502) int z_erofs_map_blocks_iter(struct inode *inode,
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 503) struct erofs_map_blocks *map,
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 504) int flags)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 505) {
a5876e24f13f1 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:08:56 +0800 506) struct erofs_inode *const vi = EROFS_I(inode);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 507) struct z_erofs_maprecorder m = {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 508) .inode = inode,
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 509) .map = map,
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 510) };
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 511) int err = 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 512) unsigned int lclusterbits, endoff;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 513) unsigned long initial_lcn;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 514) unsigned long long ofs, end;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 515)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 516) trace_z_erofs_map_blocks_iter_enter(inode, map, flags);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 517)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 518) /* when trying to read beyond EOF, leave it unmapped */
8d8a09b093d70 fs/erofs/zmap.c (Gao Xiang 2019-08-30 00:38:27 +0800 519) if (map->m_la >= inode->i_size) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 520) map->m_llen = map->m_la + 1 - inode->i_size;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 521) map->m_la = inode->i_size;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 522) map->m_flags = 0;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 523) goto out;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 524) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 525)
0c638f70d7310 fs/erofs/zmap.c (Gao Xiang 2019-11-08 11:37:33 +0800 526) err = z_erofs_fill_inode_lazy(inode);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 527) if (err)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 528) goto out;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 529)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 530) lclusterbits = vi->z_logical_clusterbits;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 531) ofs = map->m_la;
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 532) initial_lcn = ofs >> lclusterbits;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 533) endoff = ofs & ((1 << lclusterbits) - 1);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 534)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 535) err = z_erofs_load_cluster_from_disk(&m, initial_lcn);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 536) if (err)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 537) goto unmap_out;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 538)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 539) map->m_flags = EROFS_MAP_ZIPPED; /* by default, compressed */
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 540) end = (m.lcn + 1ULL) << lclusterbits;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 541)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 542) switch (m.type) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 543) case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 544) if (endoff >= m.clusterofs)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 545) map->m_flags &= ~EROFS_MAP_ZIPPED;
df561f6688fef fs/erofs/zmap.c (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 546) fallthrough;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 547) case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 548) if (endoff >= m.clusterofs) {
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 549) map->m_la = (m.lcn << lclusterbits) | m.clusterofs;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 550) break;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 551) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 552) /* m.lcn should be >= 1 if endoff < m.clusterofs */
8d8a09b093d70 fs/erofs/zmap.c (Gao Xiang 2019-08-30 00:38:27 +0800 553) if (!m.lcn) {
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 554) erofs_err(inode->i_sb,
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 555) "invalid logical cluster 0 at nid %llu",
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 556) vi->nid);
a6b9b1d5eae61 drivers/staging/erofs/zmap.c (Gao Xiang 2019-08-14 18:37:03 +0800 557) err = -EFSCORRUPTED;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 558) goto unmap_out;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 559) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 560) end = (m.lcn << lclusterbits) | m.clusterofs;
b6a76183dea8d drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:58 +0800 561) map->m_flags |= EROFS_MAP_FULL_MAPPED;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 562) m.delta[0] = 1;
df561f6688fef fs/erofs/zmap.c (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 563) fallthrough;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 564) case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
fe6adcce7e297 fs/erofs/zmap.c (Ruiqi Gong 2021-03-31 05:39:20 -0400 565) /* get the corresponding first chunk */
0c638f70d7310 fs/erofs/zmap.c (Gao Xiang 2019-11-08 11:37:33 +0800 566) err = z_erofs_extent_lookback(&m, m.delta[0]);
8d8a09b093d70 fs/erofs/zmap.c (Gao Xiang 2019-08-30 00:38:27 +0800 567) if (err)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 568) goto unmap_out;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 569) break;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 570) default:
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 571) erofs_err(inode->i_sb,
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 572) "unknown type %u @ offset %llu of nid %llu",
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 573) m.type, ofs, vi->nid);
382329a9d8553 drivers/staging/erofs/zmap.c (Gao Xiang 2019-08-14 18:37:04 +0800 574) err = -EOPNOTSUPP;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 575) goto unmap_out;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 576) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 577)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 578) map->m_llen = end - map->m_la;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 579) map->m_pa = blknr_to_addr(m.pblk);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 580) map->m_flags |= EROFS_MAP_MAPPED;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 581)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 582) err = z_erofs_get_extent_compressedlen(&m, initial_lcn);
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 583) if (err)
cec6e93beadfd fs/erofs/zmap.c (Gao Xiang 2021-04-07 12:39:24 +0800 584) goto out;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 585) unmap_out:
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 586) if (m.kaddr)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 587) kunmap_atomic(m.kaddr);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 588)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 589) out:
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 590) erofs_dbg("%s, m_la %llu m_pa %llu m_llen %llu m_plen %llu m_flags 0%o",
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 591) __func__, map->m_la, map->m_pa,
4f761fa253b49 fs/erofs/zmap.c (Gao Xiang 2019-09-04 10:09:09 +0800 592) map->m_llen, map->m_plen, map->m_flags);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 593)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 594) trace_z_erofs_map_blocks_iter_exit(inode, map, flags, err);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 595)
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 596) /* aggressively BUG_ON iff CONFIG_EROFS_FS_DEBUG is on */
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 597) DBG_BUGON(err < 0 && err != -ENOMEM);
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 598) return err;
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 599) }
152a333a58956 drivers/staging/erofs/zmap.c (Gao Xiang 2019-06-24 15:22:52 +0800 600)