zmap.c (1758047057dbe329be712a31b79db7151b5871f8) | zmap.c (ab92184ff8f12979f3d3dd5ed601ed85770d81ba) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2018-2019 HUAWEI, Inc. 4 * https://www.huawei.com/ 5 */ 6#include "internal.h" 7#include <asm/unaligned.h> 8#include <trace/events/erofs.h> 9 | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2018-2019 HUAWEI, Inc. 4 * https://www.huawei.com/ 5 */ 6#include "internal.h" 7#include <asm/unaligned.h> 8#include <trace/events/erofs.h> 9 |
10static int z_erofs_do_map_blocks(struct inode *inode, 11 struct erofs_map_blocks *map, 12 int flags); 13 |
|
10int z_erofs_fill_inode(struct inode *inode) 11{ 12 struct erofs_inode *const vi = EROFS_I(inode); 13 struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); 14 15 if (!erofs_sb_has_big_pcluster(sbi) && | 14int z_erofs_fill_inode(struct inode *inode) 15{ 16 struct erofs_inode *const vi = EROFS_I(inode); 17 struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); 18 19 if (!erofs_sb_has_big_pcluster(sbi) && |
20 !erofs_sb_has_ztailpacking(sbi) && |
|
16 vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) { 17 vi->z_advise = 0; 18 vi->z_algorithmtype[0] = 0; 19 vi->z_algorithmtype[1] = 0; 20 vi->z_logical_clusterbits = LOG_BLOCK_SIZE; 21 set_bit(EROFS_I_Z_INITED_BIT, &vi->flags); 22 } 23 inode->i_mapping->a_ops = &z_erofs_aops; --- 22 unchanged lines hidden (view full) --- 46 if (wait_on_bit_lock(&vi->flags, EROFS_I_BL_Z_BIT, TASK_KILLABLE)) 47 return -ERESTARTSYS; 48 49 err = 0; 50 if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags)) 51 goto out_unlock; 52 53 DBG_BUGON(!erofs_sb_has_big_pcluster(EROFS_SB(sb)) && | 21 vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) { 22 vi->z_advise = 0; 23 vi->z_algorithmtype[0] = 0; 24 vi->z_algorithmtype[1] = 0; 25 vi->z_logical_clusterbits = LOG_BLOCK_SIZE; 26 set_bit(EROFS_I_Z_INITED_BIT, &vi->flags); 27 } 28 inode->i_mapping->a_ops = &z_erofs_aops; --- 22 unchanged lines hidden (view full) --- 51 if (wait_on_bit_lock(&vi->flags, EROFS_I_BL_Z_BIT, TASK_KILLABLE)) 52 return -ERESTARTSYS; 53 54 err = 0; 55 if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags)) 56 goto out_unlock; 57 58 DBG_BUGON(!erofs_sb_has_big_pcluster(EROFS_SB(sb)) && |
59 !erofs_sb_has_ztailpacking(EROFS_SB(sb)) && |
|
54 vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY); 55 56 pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize + 57 vi->xattr_isize, 8); 58 page = erofs_get_meta_page(sb, erofs_blknr(pos)); 59 if (IS_ERR(page)) { 60 err = PTR_ERR(page); 61 goto out_unlock; --- 27 unchanged lines hidden (view full) --- 89 if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION && 90 !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^ 91 !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { 92 erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu", 93 vi->nid); 94 err = -EFSCORRUPTED; 95 goto unmap_done; 96 } | 60 vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY); 61 62 pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize + 63 vi->xattr_isize, 8); 64 page = erofs_get_meta_page(sb, erofs_blknr(pos)); 65 if (IS_ERR(page)) { 66 err = PTR_ERR(page); 67 goto out_unlock; --- 27 unchanged lines hidden (view full) --- 95 if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION && 96 !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^ 97 !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { 98 erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu", 99 vi->nid); 100 err = -EFSCORRUPTED; 101 goto unmap_done; 102 } |
97 /* paired with smp_mb() at the beginning of the function */ 98 smp_mb(); 99 set_bit(EROFS_I_Z_INITED_BIT, &vi->flags); | |
100unmap_done: 101 kunmap_atomic(kaddr); 102 unlock_page(page); 103 put_page(page); | 103unmap_done: 104 kunmap_atomic(kaddr); 105 unlock_page(page); 106 put_page(page); |
107 if (err) 108 goto out_unlock; 109 110 if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER) { 111 struct erofs_map_blocks map = { .mpage = NULL }; 112 113 vi->z_idata_size = le16_to_cpu(h->h_idata_size); 114 err = z_erofs_do_map_blocks(inode, &map, 115 EROFS_GET_BLOCKS_FINDTAIL); 116 if (map.mpage) 117 put_page(map.mpage); 118 119 if (!map.m_plen || 120 erofs_blkoff(map.m_pa) + map.m_plen > EROFS_BLKSIZ) { 121 erofs_err(sb, "invalid tail-packing pclustersize %llu", 122 map.m_plen); 123 err = -EFSCORRUPTED; 124 } 125 if (err < 0) 126 goto out_unlock; 127 } 128 /* paired with smp_mb() at the beginning of the function */ 129 smp_mb(); 130 set_bit(EROFS_I_Z_INITED_BIT, &vi->flags); |
|
104out_unlock: 105 clear_and_wake_up_bit(EROFS_I_BL_Z_BIT, &vi->flags); 106 return err; 107} 108 109struct z_erofs_maprecorder { 110 struct inode *inode; 111 struct erofs_map_blocks *map; 112 void *kaddr; 113 114 unsigned long lcn; 115 /* compression extent information gathered */ 116 u8 type, headtype; 117 u16 clusterofs; 118 u16 delta[2]; 119 erofs_blk_t pblk, compressedlcs; | 131out_unlock: 132 clear_and_wake_up_bit(EROFS_I_BL_Z_BIT, &vi->flags); 133 return err; 134} 135 136struct z_erofs_maprecorder { 137 struct inode *inode; 138 struct erofs_map_blocks *map; 139 void *kaddr; 140 141 unsigned long lcn; 142 /* compression extent information gathered */ 143 u8 type, headtype; 144 u16 clusterofs; 145 u16 delta[2]; 146 erofs_blk_t pblk, compressedlcs; |
147 erofs_off_t nextpackoff; |
|
120}; 121 122static int z_erofs_reload_indexes(struct z_erofs_maprecorder *m, 123 erofs_blk_t eblk) 124{ 125 struct super_block *const sb = m->inode->i_sb; 126 struct erofs_map_blocks *const map = m->map; 127 struct page *mpage = map->mpage; --- 36 unchanged lines hidden (view full) --- 164 struct z_erofs_vle_decompressed_index *di; 165 unsigned int advise, type; 166 int err; 167 168 err = z_erofs_reload_indexes(m, erofs_blknr(pos)); 169 if (err) 170 return err; 171 | 148}; 149 150static int z_erofs_reload_indexes(struct z_erofs_maprecorder *m, 151 erofs_blk_t eblk) 152{ 153 struct super_block *const sb = m->inode->i_sb; 154 struct erofs_map_blocks *const map = m->map; 155 struct page *mpage = map->mpage; --- 36 unchanged lines hidden (view full) --- 192 struct z_erofs_vle_decompressed_index *di; 193 unsigned int advise, type; 194 int err; 195 196 err = z_erofs_reload_indexes(m, erofs_blknr(pos)); 197 if (err) 198 return err; 199 |
200 m->nextpackoff = pos + sizeof(struct z_erofs_vle_decompressed_index); |
|
172 m->lcn = lcn; 173 di = m->kaddr + erofs_blkoff(pos); 174 175 advise = le16_to_cpu(di->di_advise); 176 type = (advise >> Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT) & 177 ((1 << Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) - 1); 178 switch (type) { 179 case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: --- 58 unchanged lines hidden (view full) --- 238 /* vcnt - 1 (Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) item */ 239 if (!(lo & Z_EROFS_VLE_DI_D0_CBLKCNT)) 240 d1 += lo - 1; 241 return d1; 242} 243 244static int unpack_compacted_index(struct z_erofs_maprecorder *m, 245 unsigned int amortizedshift, | 201 m->lcn = lcn; 202 di = m->kaddr + erofs_blkoff(pos); 203 204 advise = le16_to_cpu(di->di_advise); 205 type = (advise >> Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT) & 206 ((1 << Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) - 1); 207 switch (type) { 208 case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: --- 58 unchanged lines hidden (view full) --- 267 /* vcnt - 1 (Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) item */ 268 if (!(lo & Z_EROFS_VLE_DI_D0_CBLKCNT)) 269 d1 += lo - 1; 270 return d1; 271} 272 273static int unpack_compacted_index(struct z_erofs_maprecorder *m, 274 unsigned int amortizedshift, |
246 unsigned int eofs, bool lookahead) | 275 erofs_off_t pos, bool lookahead) |
247{ 248 struct erofs_inode *const vi = EROFS_I(m->inode); 249 const unsigned int lclusterbits = vi->z_logical_clusterbits; 250 const unsigned int lomask = (1 << lclusterbits) - 1; | 276{ 277 struct erofs_inode *const vi = EROFS_I(m->inode); 278 const unsigned int lclusterbits = vi->z_logical_clusterbits; 279 const unsigned int lomask = (1 << lclusterbits) - 1; |
251 unsigned int vcnt, base, lo, encodebits, nblk; | 280 unsigned int vcnt, base, lo, encodebits, nblk, eofs; |
252 int i; 253 u8 *in, type; 254 bool big_pcluster; 255 256 if (1 << amortizedshift == 4) 257 vcnt = 2; 258 else if (1 << amortizedshift == 2 && lclusterbits == 12) 259 vcnt = 16; 260 else 261 return -EOPNOTSUPP; 262 | 281 int i; 282 u8 *in, type; 283 bool big_pcluster; 284 285 if (1 << amortizedshift == 4) 286 vcnt = 2; 287 else if (1 << amortizedshift == 2 && lclusterbits == 12) 288 vcnt = 16; 289 else 290 return -EOPNOTSUPP; 291 |
292 /* it doesn't equal to round_up(..) */ 293 m->nextpackoff = round_down(pos, vcnt << amortizedshift) + 294 (vcnt << amortizedshift); |
|
263 big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1; 264 encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt; | 295 big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1; 296 encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt; |
297 eofs = erofs_blkoff(pos); |
|
265 base = round_down(eofs, vcnt << amortizedshift); 266 in = m->kaddr + base; 267 268 i = (eofs - base) >> amortizedshift; 269 270 lo = decode_compactedbits(lclusterbits, lomask, 271 in, encodebits * i, &type); 272 m->type = type; --- 121 unchanged lines hidden (view full) --- 394 pos += compacted_2b * 2; 395 lcn -= compacted_2b; 396 amortizedshift = 2; 397out: 398 pos += lcn * (1 << amortizedshift); 399 err = z_erofs_reload_indexes(m, erofs_blknr(pos)); 400 if (err) 401 return err; | 298 base = round_down(eofs, vcnt << amortizedshift); 299 in = m->kaddr + base; 300 301 i = (eofs - base) >> amortizedshift; 302 303 lo = decode_compactedbits(lclusterbits, lomask, 304 in, encodebits * i, &type); 305 m->type = type; --- 121 unchanged lines hidden (view full) --- 427 pos += compacted_2b * 2; 428 lcn -= compacted_2b; 429 amortizedshift = 2; 430out: 431 pos += lcn * (1 << amortizedshift); 432 err = z_erofs_reload_indexes(m, erofs_blknr(pos)); 433 if (err) 434 return err; |
402 return unpack_compacted_index(m, amortizedshift, erofs_blkoff(pos), 403 lookahead); | 435 return unpack_compacted_index(m, amortizedshift, pos, lookahead); |
404} 405 406static int z_erofs_load_cluster_from_disk(struct z_erofs_maprecorder *m, 407 unsigned int lcn, bool lookahead) 408{ 409 const unsigned int datamode = EROFS_I(m->inode)->datalayout; 410 411 if (datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY) --- 166 unchanged lines hidden (view full) --- 578 } 579 lcn += m->delta[1]; 580 } while (m->delta[1]); 581 582 map->m_llen = (lcn << lclusterbits) + m->clusterofs - map->m_la; 583 return 0; 584} 585 | 436} 437 438static int z_erofs_load_cluster_from_disk(struct z_erofs_maprecorder *m, 439 unsigned int lcn, bool lookahead) 440{ 441 const unsigned int datamode = EROFS_I(m->inode)->datalayout; 442 443 if (datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY) --- 166 unchanged lines hidden (view full) --- 610 } 611 lcn += m->delta[1]; 612 } while (m->delta[1]); 613 614 map->m_llen = (lcn << lclusterbits) + m->clusterofs - map->m_la; 615 return 0; 616} 617 |
586int z_erofs_map_blocks_iter(struct inode *inode, 587 struct erofs_map_blocks *map, 588 int flags) | 618static int z_erofs_do_map_blocks(struct inode *inode, 619 struct erofs_map_blocks *map, 620 int flags) |
589{ 590 struct erofs_inode *const vi = EROFS_I(inode); | 621{ 622 struct erofs_inode *const vi = EROFS_I(inode); |
623 bool ztailpacking = vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER; |
|
591 struct z_erofs_maprecorder m = { 592 .inode = inode, 593 .map = map, 594 }; 595 int err = 0; 596 unsigned int lclusterbits, endoff; 597 unsigned long initial_lcn; 598 unsigned long long ofs, end; 599 | 624 struct z_erofs_maprecorder m = { 625 .inode = inode, 626 .map = map, 627 }; 628 int err = 0; 629 unsigned int lclusterbits, endoff; 630 unsigned long initial_lcn; 631 unsigned long long ofs, end; 632 |
600 trace_z_erofs_map_blocks_iter_enter(inode, map, flags); 601 602 /* when trying to read beyond EOF, leave it unmapped */ 603 if (map->m_la >= inode->i_size) { 604 map->m_llen = map->m_la + 1 - inode->i_size; 605 map->m_la = inode->i_size; 606 map->m_flags = 0; 607 goto out; 608 } 609 610 err = z_erofs_fill_inode_lazy(inode); 611 if (err) 612 goto out; 613 | |
614 lclusterbits = vi->z_logical_clusterbits; | 633 lclusterbits = vi->z_logical_clusterbits; |
615 ofs = map->m_la; | 634 ofs = flags & EROFS_GET_BLOCKS_FINDTAIL ? inode->i_size - 1 : map->m_la; |
616 initial_lcn = ofs >> lclusterbits; 617 endoff = ofs & ((1 << lclusterbits) - 1); 618 619 err = z_erofs_load_cluster_from_disk(&m, initial_lcn, false); 620 if (err) 621 goto unmap_out; 622 | 635 initial_lcn = ofs >> lclusterbits; 636 endoff = ofs & ((1 << lclusterbits) - 1); 637 638 err = z_erofs_load_cluster_from_disk(&m, initial_lcn, false); 639 if (err) 640 goto unmap_out; 641 |
642 if (ztailpacking && (flags & EROFS_GET_BLOCKS_FINDTAIL)) 643 vi->z_idataoff = m.nextpackoff; 644 |
|
623 map->m_flags = EROFS_MAP_MAPPED | EROFS_MAP_ENCODED; 624 end = (m.lcn + 1ULL) << lclusterbits; 625 626 switch (m.type) { 627 case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: 628 case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1: 629 case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2: 630 if (endoff >= m.clusterofs) { --- 23 unchanged lines hidden (view full) --- 654 erofs_err(inode->i_sb, 655 "unknown type %u @ offset %llu of nid %llu", 656 m.type, ofs, vi->nid); 657 err = -EOPNOTSUPP; 658 goto unmap_out; 659 } 660 661 map->m_llen = end - map->m_la; | 645 map->m_flags = EROFS_MAP_MAPPED | EROFS_MAP_ENCODED; 646 end = (m.lcn + 1ULL) << lclusterbits; 647 648 switch (m.type) { 649 case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: 650 case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1: 651 case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2: 652 if (endoff >= m.clusterofs) { --- 23 unchanged lines hidden (view full) --- 676 erofs_err(inode->i_sb, 677 "unknown type %u @ offset %llu of nid %llu", 678 m.type, ofs, vi->nid); 679 err = -EOPNOTSUPP; 680 goto unmap_out; 681 } 682 683 map->m_llen = end - map->m_la; |
662 map->m_pa = blknr_to_addr(m.pblk); | |
663 | 684 |
664 err = z_erofs_get_extent_compressedlen(&m, initial_lcn); 665 if (err) 666 goto out; | 685 if (flags & EROFS_GET_BLOCKS_FINDTAIL) 686 vi->z_tailextent_headlcn = m.lcn; 687 if (ztailpacking && m.lcn == vi->z_tailextent_headlcn) { 688 map->m_flags |= EROFS_MAP_META; 689 map->m_pa = vi->z_idataoff; 690 map->m_plen = vi->z_idata_size; 691 } else { 692 map->m_pa = blknr_to_addr(m.pblk); 693 err = z_erofs_get_extent_compressedlen(&m, initial_lcn); 694 if (err) 695 goto out; 696 } |
667 668 if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN) 669 map->m_algorithmformat = Z_EROFS_COMPRESSION_SHIFTED; 670 else if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2) 671 map->m_algorithmformat = vi->z_algorithmtype[1]; 672 else 673 map->m_algorithmformat = vi->z_algorithmtype[0]; 674 --- 9 unchanged lines hidden (view full) --- 684 if (m.kaddr) 685 kunmap_atomic(m.kaddr); 686 687out: 688 erofs_dbg("%s, m_la %llu m_pa %llu m_llen %llu m_plen %llu m_flags 0%o", 689 __func__, map->m_la, map->m_pa, 690 map->m_llen, map->m_plen, map->m_flags); 691 | 697 698 if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN) 699 map->m_algorithmformat = Z_EROFS_COMPRESSION_SHIFTED; 700 else if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2) 701 map->m_algorithmformat = vi->z_algorithmtype[1]; 702 else 703 map->m_algorithmformat = vi->z_algorithmtype[0]; 704 --- 9 unchanged lines hidden (view full) --- 714 if (m.kaddr) 715 kunmap_atomic(m.kaddr); 716 717out: 718 erofs_dbg("%s, m_la %llu m_pa %llu m_llen %llu m_plen %llu m_flags 0%o", 719 __func__, map->m_la, map->m_pa, 720 map->m_llen, map->m_plen, map->m_flags); 721 |
722 return err; 723} 724 725int z_erofs_map_blocks_iter(struct inode *inode, 726 struct erofs_map_blocks *map, 727 int flags) 728{ 729 int err = 0; 730 731 trace_z_erofs_map_blocks_iter_enter(inode, map, flags); 732 733 /* when trying to read beyond EOF, leave it unmapped */ 734 if (map->m_la >= inode->i_size) { 735 map->m_llen = map->m_la + 1 - inode->i_size; 736 map->m_la = inode->i_size; 737 map->m_flags = 0; 738 goto out; 739 } 740 741 err = z_erofs_fill_inode_lazy(inode); 742 if (err) 743 goto out; 744 745 err = z_erofs_do_map_blocks(inode, map, flags); 746out: |
|
692 trace_z_erofs_map_blocks_iter_exit(inode, map, flags, err); 693 694 /* aggressively BUG_ON iff CONFIG_EROFS_FS_DEBUG is on */ 695 DBG_BUGON(err < 0 && err != -ENOMEM); 696 return err; 697} 698 699static int z_erofs_iomap_begin_report(struct inode *inode, loff_t offset, --- 36 unchanged lines hidden --- | 747 trace_z_erofs_map_blocks_iter_exit(inode, map, flags, err); 748 749 /* aggressively BUG_ON iff CONFIG_EROFS_FS_DEBUG is on */ 750 DBG_BUGON(err < 0 && err != -ENOMEM); 751 return err; 752} 753 754static int z_erofs_iomap_begin_report(struct inode *inode, loff_t offset, --- 36 unchanged lines hidden --- |