29b24f6ca112d drivers/staging/erofs/data.c (Gao Xiang 2019-07-31 23:57:31 +0800 1) // SPDX-License-Identifier: GPL-2.0-only
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 2) /*
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 3) * Copyright (C) 2017-2018 HUAWEI, Inc.
592e7cd00bb9d fs/erofs/data.c (Alexander A. Klimov 2020-07-13 15:09:44 +0200 4) * https://www.huawei.com/
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 5) * Created by Gao Xiang <gaoxiang25@huawei.com>
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 6) */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 7) #include "internal.h"
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 8) #include <linux/prefetch.h>
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 9)
13f06f48f7bf8 drivers/staging/erofs/data.c (Chao Yu 2018-07-26 20:21:55 +0800 10) #include <trace/events/erofs.h>
13f06f48f7bf8 drivers/staging/erofs/data.c (Chao Yu 2018-07-26 20:21:55 +0800 11)
99634bf388db0 fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:05 +0800 12) static void erofs_readendio(struct bio *bio)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 13) {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 14) struct bio_vec *bvec;
14a56ec65bab3 drivers/staging/erofs/data.c (Gao Xiang 2019-03-25 11:40:09 +0800 15) blk_status_t err = bio->bi_status;
6dc4f100c175d drivers/staging/erofs/data.c (Ming Lei 2019-02-15 19:13:19 +0800 16) struct bvec_iter_all iter_all;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 17)
2b070cfe582b8 drivers/staging/erofs/data.c (Christoph Hellwig 2019-04-25 09:03:00 +0200 18) bio_for_each_segment_all(bvec, bio, iter_all) {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 19) struct page *page = bvec->bv_page;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 20)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 21) /* page is already locked */
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 22) DBG_BUGON(PageUptodate(page));
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 23)
8d8a09b093d70 fs/erofs/data.c (Gao Xiang 2019-08-30 00:38:27 +0800 24) if (err)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 25) SetPageError(page);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 26) else
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 27) SetPageUptodate(page);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 28)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 29) unlock_page(page);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 30) /* page could be reclaimed now */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 31) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 32) bio_put(bio);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 33) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 34)
e655b5b3a29c5 fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:03 +0800 35) struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 36) {
55252ab72b774 fs/erofs/data.c (Gao Xiang 2019-09-22 02:43:55 +0800 37) struct address_space *const mapping = sb->s_bdev->bd_inode->i_mapping;
55252ab72b774 fs/erofs/data.c (Gao Xiang 2019-09-22 02:43:55 +0800 38) struct page *page;
6e78901a9f233 drivers/staging/erofs/data.c (Gao Xiang 2018-08-21 22:49:30 +0800 39)
55252ab72b774 fs/erofs/data.c (Gao Xiang 2019-09-22 02:43:55 +0800 40) page = read_cache_page_gfp(mapping, blkaddr,
618f40ea026bd fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:12 +0800 41) mapping_gfp_constraint(mapping, ~__GFP_FS));
55252ab72b774 fs/erofs/data.c (Gao Xiang 2019-09-22 02:43:55 +0800 42) /* should already be PageUptodate */
55252ab72b774 fs/erofs/data.c (Gao Xiang 2019-09-22 02:43:55 +0800 43) if (!IS_ERR(page))
55252ab72b774 fs/erofs/data.c (Gao Xiang 2019-09-22 02:43:55 +0800 44) lock_page(page);
55252ab72b774 fs/erofs/data.c (Gao Xiang 2019-09-22 02:43:55 +0800 45) return page;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 46) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 47)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 48) static int erofs_map_blocks_flatmode(struct inode *inode,
f0950b02a74ca drivers/staging/erofs/data.c (Bhagyashri P. Dighole 2018-11-05 19:48:38 +0000 49) struct erofs_map_blocks *map,
f0950b02a74ca drivers/staging/erofs/data.c (Bhagyashri P. Dighole 2018-11-05 19:48:38 +0000 50) int flags)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 51) {
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 52) int err = 0;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 53) erofs_blk_t nblocks, lastblk;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 54) u64 offset = map->m_la;
a5876e24f13f1 fs/erofs/data.c (Gao Xiang 2019-09-04 10:08:56 +0800 55) struct erofs_inode *vi = EROFS_I(inode);
8a76568225dea fs/erofs/data.c (Gao Xiang 2019-09-04 10:08:54 +0800 56) bool tailendpacking = (vi->datalayout == EROFS_INODE_FLAT_INLINE);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 57)
13f06f48f7bf8 drivers/staging/erofs/data.c (Chao Yu 2018-07-26 20:21:55 +0800 58) trace_erofs_map_blocks_flatmode_enter(inode, map, flags);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 59)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 60) nblocks = DIV_ROUND_UP(inode->i_size, PAGE_SIZE);
8a76568225dea fs/erofs/data.c (Gao Xiang 2019-09-04 10:08:54 +0800 61) lastblk = nblocks - tailendpacking;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 62)
8d8a09b093d70 fs/erofs/data.c (Gao Xiang 2019-08-30 00:38:27 +0800 63) if (offset >= inode->i_size) {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 64) /* leave out-of-bound access unmapped */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 65) map->m_flags = 0;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 66) map->m_plen = 0;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 67) goto out;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 68) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 69)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 70) /* there is no hole in flatmode */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 71) map->m_flags = EROFS_MAP_MAPPED;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 72)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 73) if (offset < blknr_to_addr(lastblk)) {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 74) map->m_pa = blknr_to_addr(vi->raw_blkaddr) + map->m_la;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 75) map->m_plen = blknr_to_addr(lastblk) - offset;
8a76568225dea fs/erofs/data.c (Gao Xiang 2019-09-04 10:08:54 +0800 76) } else if (tailendpacking) {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 77) /* 2 - inode inline B: inode, [xattrs], inline last blk... */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 78) struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 79)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 80) map->m_pa = iloc(sbi, vi->nid) + vi->inode_isize +
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 81) vi->xattr_isize + erofs_blkoff(map->m_la);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 82) map->m_plen = inode->i_size - offset;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 83)
a6b9b1d5eae61 drivers/staging/erofs/data.c (Gao Xiang 2019-08-14 18:37:03 +0800 84) /* inline data should be located in one meta block */
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 85) if (erofs_blkoff(map->m_pa) + map->m_plen > PAGE_SIZE) {
4f761fa253b49 fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:09 +0800 86) erofs_err(inode->i_sb,
4f761fa253b49 fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:09 +0800 87) "inline data cross block boundary @ nid %llu",
4f761fa253b49 fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:09 +0800 88) vi->nid);
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 89) DBG_BUGON(1);
a6b9b1d5eae61 drivers/staging/erofs/data.c (Gao Xiang 2019-08-14 18:37:03 +0800 90) err = -EFSCORRUPTED;
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 91) goto err_out;
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 92) }
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 93)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 94) map->m_flags |= EROFS_MAP_META;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 95) } else {
4f761fa253b49 fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:09 +0800 96) erofs_err(inode->i_sb,
4f761fa253b49 fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:09 +0800 97) "internal error @ nid: %llu (size %llu), m_la 0x%llx",
4f761fa253b49 fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:09 +0800 98) vi->nid, inode->i_size, map->m_la);
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 99) DBG_BUGON(1);
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 100) err = -EIO;
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 101) goto err_out;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 102) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 103)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 104) out:
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 105) map->m_llen = map->m_plen;
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 106)
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 107) err_out:
13f06f48f7bf8 drivers/staging/erofs/data.c (Chao Yu 2018-07-26 20:21:55 +0800 108) trace_erofs_map_blocks_flatmode_exit(inode, map, flags, 0);
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 109) return err;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 110) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 111)
f0950b02a74ca drivers/staging/erofs/data.c (Bhagyashri P. Dighole 2018-11-05 19:48:38 +0000 112) static inline struct bio *erofs_read_raw_page(struct bio *bio,
f0950b02a74ca drivers/staging/erofs/data.c (Bhagyashri P. Dighole 2018-11-05 19:48:38 +0000 113) struct address_space *mapping,
f0950b02a74ca drivers/staging/erofs/data.c (Bhagyashri P. Dighole 2018-11-05 19:48:38 +0000 114) struct page *page,
f0950b02a74ca drivers/staging/erofs/data.c (Bhagyashri P. Dighole 2018-11-05 19:48:38 +0000 115) erofs_off_t *last_block,
f0950b02a74ca drivers/staging/erofs/data.c (Bhagyashri P. Dighole 2018-11-05 19:48:38 +0000 116) unsigned int nblocks,
9f377622a484d fs/erofs/data.c (Gao Xiang 2021-03-06 12:04:38 +0800 117) unsigned int *eblks,
f0950b02a74ca drivers/staging/erofs/data.c (Bhagyashri P. Dighole 2018-11-05 19:48:38 +0000 118) bool ra)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 119) {
14a56ec65bab3 drivers/staging/erofs/data.c (Gao Xiang 2019-03-25 11:40:09 +0800 120) struct inode *const inode = mapping->host;
14a56ec65bab3 drivers/staging/erofs/data.c (Gao Xiang 2019-03-25 11:40:09 +0800 121) struct super_block *const sb = inode->i_sb;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 122) erofs_off_t current_block = (erofs_off_t)page->index;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 123) int err;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 124)
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 125) DBG_BUGON(!nblocks);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 126)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 127) if (PageUptodate(page)) {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 128) err = 0;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 129) goto has_updated;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 130) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 131)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 132) /* note that for readpage case, bio also equals to NULL */
d1ab82443bed2 drivers/staging/erofs/data.c (Bhagyashri P. Dighole 2018-11-05 19:49:05 +0000 133) if (bio &&
9f377622a484d fs/erofs/data.c (Gao Xiang 2021-03-06 12:04:38 +0800 134) (*last_block + 1 != current_block || !*eblks)) {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 135) submit_bio_retry:
94e4e153b1c25 fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:04 +0800 136) submit_bio(bio);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 137) bio = NULL;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 138) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 139)
d1ab82443bed2 drivers/staging/erofs/data.c (Bhagyashri P. Dighole 2018-11-05 19:49:05 +0000 140) if (!bio) {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 141) struct erofs_map_blocks map = {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 142) .m_la = blknr_to_addr(current_block),
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 143) };
55441958bb8d1 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:22:00 +0800 144) erofs_blk_t blknr;
7dd68b147d60e drivers/staging/erofs/data.c (Thomas Weißschuh 2018-09-10 21:41:14 +0200 145) unsigned int blkoff;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 146)
8137824eddd2e fs/erofs/data.c (Yue Hu 2021-03-25 15:10:08 +0800 147) err = erofs_map_blocks_flatmode(inode, &map, EROFS_GET_BLOCKS_RAW);
8d8a09b093d70 fs/erofs/data.c (Gao Xiang 2019-08-30 00:38:27 +0800 148) if (err)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 149) goto err_out;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 150)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 151) /* zero out the holed page */
8d8a09b093d70 fs/erofs/data.c (Gao Xiang 2019-08-30 00:38:27 +0800 152) if (!(map.m_flags & EROFS_MAP_MAPPED)) {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 153) zero_user_segment(page, 0, PAGE_SIZE);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 154) SetPageUptodate(page);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 155)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 156) /* imply err = 0, see erofs_map_blocks */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 157) goto has_updated;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 158) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 159)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 160) /* for RAW access mode, m_plen must be equal to m_llen */
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 161) DBG_BUGON(map.m_plen != map.m_llen);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 162)
55441958bb8d1 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:22:00 +0800 163) blknr = erofs_blknr(map.m_pa);
55441958bb8d1 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:22:00 +0800 164) blkoff = erofs_blkoff(map.m_pa);
55441958bb8d1 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:22:00 +0800 165)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 166) /* deal with inline page */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 167) if (map.m_flags & EROFS_MAP_META) {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 168) void *vsrc, *vto;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 169) struct page *ipage;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 170)
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 171) DBG_BUGON(map.m_plen > PAGE_SIZE);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 172)
e655b5b3a29c5 fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:03 +0800 173) ipage = erofs_get_meta_page(inode->i_sb, blknr);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 174)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 175) if (IS_ERR(ipage)) {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 176) err = PTR_ERR(ipage);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 177) goto err_out;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 178) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 179)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 180) vsrc = kmap_atomic(ipage);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 181) vto = kmap_atomic(page);
55441958bb8d1 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:22:00 +0800 182) memcpy(vto, vsrc + blkoff, map.m_plen);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 183) memset(vto + map.m_plen, 0, PAGE_SIZE - map.m_plen);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 184) kunmap_atomic(vto);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 185) kunmap_atomic(vsrc);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 186) flush_dcache_page(page);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 187)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 188) SetPageUptodate(page);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 189) /* TODO: could we unlock the page earlier? */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 190) unlock_page(ipage);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 191) put_page(ipage);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 192)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 193) /* imply err = 0, see erofs_map_blocks */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 194) goto has_updated;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 195) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 196)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 197) /* pa must be block-aligned for raw reading */
9141b60cf6a53 drivers/staging/erofs/data.c (Chen Gong 2018-09-18 22:27:28 +0800 198) DBG_BUGON(erofs_blkoff(map.m_pa));
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 199)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 200) /* max # of continuous pages */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 201) if (nblocks > DIV_ROUND_UP(map.m_plen, PAGE_SIZE))
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 202) nblocks = DIV_ROUND_UP(map.m_plen, PAGE_SIZE);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 203)
9f377622a484d fs/erofs/data.c (Gao Xiang 2021-03-06 12:04:38 +0800 204) *eblks = bio_max_segs(nblocks);
9f377622a484d fs/erofs/data.c (Gao Xiang 2021-03-06 12:04:38 +0800 205) bio = bio_alloc(GFP_NOIO, *eblks);
618f40ea026bd fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:12 +0800 206)
618f40ea026bd fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:12 +0800 207) bio->bi_end_io = erofs_readendio;
618f40ea026bd fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:12 +0800 208) bio_set_dev(bio, sb->s_bdev);
618f40ea026bd fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:12 +0800 209) bio->bi_iter.bi_sector = (sector_t)blknr <<
618f40ea026bd fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:12 +0800 210) LOG_SECTORS_PER_BLOCK;
6ea5aad32dd8b fs/erofs/data.c (Gao Xiang 2020-09-19 15:27:30 +0800 211) bio->bi_opf = REQ_OP_READ | (ra ? REQ_RAHEAD : 0);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 212) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 213)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 214) err = bio_add_page(bio, page, PAGE_SIZE, 0);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 215) /* out of the extent or bio is full */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 216) if (err < PAGE_SIZE)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 217) goto submit_bio_retry;
9f377622a484d fs/erofs/data.c (Gao Xiang 2021-03-06 12:04:38 +0800 218) --*eblks;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 219) *last_block = current_block;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 220) return bio;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 221)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 222) err_out:
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 223) /* for sync reading, set page error immediately */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 224) if (!ra) {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 225) SetPageError(page);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 226) ClearPageUptodate(page);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 227) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 228) has_updated:
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 229) unlock_page(page);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 230)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 231) /* if updated manually, continuous pages has a gap */
d1ab82443bed2 drivers/staging/erofs/data.c (Bhagyashri P. Dighole 2018-11-05 19:49:05 +0000 232) if (bio)
94e4e153b1c25 fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:04 +0800 233) submit_bio(bio);
8d8a09b093d70 fs/erofs/data.c (Gao Xiang 2019-08-30 00:38:27 +0800 234) return err ? ERR_PTR(err) : NULL;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 235) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 236)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 237) /*
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 238) * since we dont have write or truncate flows, so no inode
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 239) * locking needs to be held at the moment.
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 240) */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 241) static int erofs_raw_access_readpage(struct file *file, struct page *page)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 242) {
3f649ab728cda fs/erofs/data.c (Kees Cook 2020-06-03 13:09:38 -0700 243) erofs_off_t last_block;
9f377622a484d fs/erofs/data.c (Gao Xiang 2021-03-06 12:04:38 +0800 244) unsigned int eblks;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 245) struct bio *bio;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 246)
13f06f48f7bf8 drivers/staging/erofs/data.c (Chao Yu 2018-07-26 20:21:55 +0800 247) trace_erofs_readpage(page, true);
13f06f48f7bf8 drivers/staging/erofs/data.c (Chao Yu 2018-07-26 20:21:55 +0800 248)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 249) bio = erofs_read_raw_page(NULL, page->mapping,
9f377622a484d fs/erofs/data.c (Gao Xiang 2021-03-06 12:04:38 +0800 250) page, &last_block, 1, &eblks, false);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 251)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 252) if (IS_ERR(bio))
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 253) return PTR_ERR(bio);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 254)
9f377622a484d fs/erofs/data.c (Gao Xiang 2021-03-06 12:04:38 +0800 255) if (bio)
9f377622a484d fs/erofs/data.c (Gao Xiang 2021-03-06 12:04:38 +0800 256) submit_bio(bio);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 257) return 0;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 258) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 259)
0c07a9f91ec03 fs/erofs/data.c (Matthew Wilcox (Oracle) 2020-06-01 21:47:09 -0700 260) static void erofs_raw_access_readahead(struct readahead_control *rac)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 261) {
3f649ab728cda fs/erofs/data.c (Kees Cook 2020-06-03 13:09:38 -0700 262) erofs_off_t last_block;
9f377622a484d fs/erofs/data.c (Gao Xiang 2021-03-06 12:04:38 +0800 263) unsigned int eblks;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 264) struct bio *bio = NULL;
0c07a9f91ec03 fs/erofs/data.c (Matthew Wilcox (Oracle) 2020-06-01 21:47:09 -0700 265) struct page *page;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 266)
0c07a9f91ec03 fs/erofs/data.c (Matthew Wilcox (Oracle) 2020-06-01 21:47:09 -0700 267) trace_erofs_readpages(rac->mapping->host, readahead_index(rac),
0c07a9f91ec03 fs/erofs/data.c (Matthew Wilcox (Oracle) 2020-06-01 21:47:09 -0700 268) readahead_count(rac), true);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 269)
0c07a9f91ec03 fs/erofs/data.c (Matthew Wilcox (Oracle) 2020-06-01 21:47:09 -0700 270) while ((page = readahead_page(rac))) {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 271) prefetchw(&page->flags);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 272)
0c07a9f91ec03 fs/erofs/data.c (Matthew Wilcox (Oracle) 2020-06-01 21:47:09 -0700 273) bio = erofs_read_raw_page(bio, rac->mapping, page, &last_block,
9f377622a484d fs/erofs/data.c (Gao Xiang 2021-03-06 12:04:38 +0800 274) readahead_count(rac), &eblks, true);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 275)
0c07a9f91ec03 fs/erofs/data.c (Matthew Wilcox (Oracle) 2020-06-01 21:47:09 -0700 276) /* all the page errors are ignored when readahead */
0c07a9f91ec03 fs/erofs/data.c (Matthew Wilcox (Oracle) 2020-06-01 21:47:09 -0700 277) if (IS_ERR(bio)) {
0c07a9f91ec03 fs/erofs/data.c (Matthew Wilcox (Oracle) 2020-06-01 21:47:09 -0700 278) pr_err("%s, readahead error at page %lu of nid %llu\n",
0c07a9f91ec03 fs/erofs/data.c (Matthew Wilcox (Oracle) 2020-06-01 21:47:09 -0700 279) __func__, page->index,
0c07a9f91ec03 fs/erofs/data.c (Matthew Wilcox (Oracle) 2020-06-01 21:47:09 -0700 280) EROFS_I(rac->mapping->host)->nid);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 281)
0c07a9f91ec03 fs/erofs/data.c (Matthew Wilcox (Oracle) 2020-06-01 21:47:09 -0700 282) bio = NULL;
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 283) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 284)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 285) put_page(page);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 286) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 287)
8d8a09b093d70 fs/erofs/data.c (Gao Xiang 2019-08-30 00:38:27 +0800 288) if (bio)
94e4e153b1c25 fs/erofs/data.c (Gao Xiang 2019-09-04 10:09:04 +0800 289) submit_bio(bio);
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 290) }
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 291)
9da681e017a36 drivers/staging/erofs/data.c (Chao Yu 2019-07-16 17:32:56 +0800 292) static sector_t erofs_bmap(struct address_space *mapping, sector_t block)
9da681e017a36 drivers/staging/erofs/data.c (Chao Yu 2019-07-16 17:32:56 +0800 293) {
9da681e017a36 drivers/staging/erofs/data.c (Chao Yu 2019-07-16 17:32:56 +0800 294) struct inode *inode = mapping->host;
d8b3df8b10484 fs/erofs/data.c (Huang Jianan 2020-12-09 19:57:40 +0800 295) struct erofs_map_blocks map = {
d8b3df8b10484 fs/erofs/data.c (Huang Jianan 2020-12-09 19:57:40 +0800 296) .m_la = blknr_to_addr(block),
d8b3df8b10484 fs/erofs/data.c (Huang Jianan 2020-12-09 19:57:40 +0800 297) };
9da681e017a36 drivers/staging/erofs/data.c (Chao Yu 2019-07-16 17:32:56 +0800 298)
a5876e24f13f1 fs/erofs/data.c (Gao Xiang 2019-09-04 10:08:56 +0800 299) if (EROFS_I(inode)->datalayout == EROFS_INODE_FLAT_INLINE) {
9da681e017a36 drivers/staging/erofs/data.c (Chao Yu 2019-07-16 17:32:56 +0800 300) erofs_blk_t blks = i_size_read(inode) >> LOG_BLOCK_SIZE;
9da681e017a36 drivers/staging/erofs/data.c (Chao Yu 2019-07-16 17:32:56 +0800 301)
9da681e017a36 drivers/staging/erofs/data.c (Chao Yu 2019-07-16 17:32:56 +0800 302) if (block >> LOG_SECTORS_PER_BLOCK >= blks)
9da681e017a36 drivers/staging/erofs/data.c (Chao Yu 2019-07-16 17:32:56 +0800 303) return 0;
9da681e017a36 drivers/staging/erofs/data.c (Chao Yu 2019-07-16 17:32:56 +0800 304) }
9da681e017a36 drivers/staging/erofs/data.c (Chao Yu 2019-07-16 17:32:56 +0800 305)
8137824eddd2e fs/erofs/data.c (Yue Hu 2021-03-25 15:10:08 +0800 306) if (!erofs_map_blocks_flatmode(inode, &map, EROFS_GET_BLOCKS_RAW))
d8b3df8b10484 fs/erofs/data.c (Huang Jianan 2020-12-09 19:57:40 +0800 307) return erofs_blknr(map.m_pa);
d8b3df8b10484 fs/erofs/data.c (Huang Jianan 2020-12-09 19:57:40 +0800 308)
d8b3df8b10484 fs/erofs/data.c (Huang Jianan 2020-12-09 19:57:40 +0800 309) return 0;
9da681e017a36 drivers/staging/erofs/data.c (Chao Yu 2019-07-16 17:32:56 +0800 310) }
9da681e017a36 drivers/staging/erofs/data.c (Chao Yu 2019-07-16 17:32:56 +0800 311)
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 312) /* for uncompressed (aligned) files and raw access for other files */
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 313) const struct address_space_operations erofs_raw_access_aops = {
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 314) .readpage = erofs_raw_access_readpage,
0c07a9f91ec03 fs/erofs/data.c (Matthew Wilcox (Oracle) 2020-06-01 21:47:09 -0700 315) .readahead = erofs_raw_access_readahead,
9da681e017a36 drivers/staging/erofs/data.c (Chao Yu 2019-07-16 17:32:56 +0800 316) .bmap = erofs_bmap,
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 317) };
81781b02f9845 drivers/staging/erofs/data.c (Gao Xiang 2018-07-26 20:21:47 +0800 318)