Received: by 2002:a05:6a10:1d13:0:0:0:0 with SMTP id pp19csp216809pxb; Wed, 18 Aug 2021 00:10:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzfHkE+FqRORGowesp7US+K4LbA+jJIBtyQMGDouOrHX/xOrZHMUmb433Xz6ITOcrvnqNmD X-Received: by 2002:a17:906:8493:: with SMTP id m19mr8283027ejx.103.1629270631481; Wed, 18 Aug 2021 00:10:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1629270631; cv=none; d=google.com; s=arc-20160816; b=alYPNoEXmAfl9BvNIw6j4hcZcxAOYYENMLwc8z85QshSkFocGUsphw2Kf9cJkPTW+T 1TG6Sn5SGXovsap8f20LJZBOmg2UNgv2JKeqZ4a87Nokr66CFFr9ZFPDMxC41U4Shd2w yoIQjgTsn/2gphqLWBKalG4bDTnlBRuG7ObQUEl0NjDgDZmm4vCla4ZfjP0B4pXpP3ft yeBzZmOhdMjelyTn68Nsd0XXwm3oMQMx+cPqEm2J/ndY5j+aU2yaagjUzNW4cLBFIWmm SH1Yl+b5QAT9JJAD0EP0bUNTEyzNxq2gaiIq5J/34jWKN4busfZQ0m6fqhbzSoYIwFL8 mBSg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=0RPxWLB8o0RhPAfPJqebpxCETomkYyZf5HL0rGwYPss=; b=sPX36/J+3scD0SJpXsaV9mnwc87HLyhQUM+GW3khh1bt42iaXgm2YaLrn8XFOGxkwk ngNMna4slkIq9lu/jALN2H3ycdEH3jqS7sRXcvK+qobHULzE4eXuCYE42boRniHjUuUd RU9FG8wg5TUEQjUpDMQuUZdm1lPz61suhXmLPNco5DlVUF6Gp30id53Znjq7x0AKDHq8 q/HByrgKVF/zjG2EBZlub4XHsdqci3h7HyUVMlzOhrJAjFEad52Dhi+svzgLGcLACVj4 JD4bJwvgr+HUT2vXHgdL9GM++DkuWrLhRxki/elIDBdxp9tNX4LJzJLE7KLRHvPIHA2q +CSQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ee37si4802213edb.307.2021.08.18.00.10.00; Wed, 18 Aug 2021 00:10:31 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238826AbhHRHID (ORCPT + 99 others); Wed, 18 Aug 2021 03:08:03 -0400 Received: from out30-43.freemail.mail.aliyun.com ([115.124.30.43]:55593 "EHLO out30-43.freemail.mail.aliyun.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238144AbhHRHHy (ORCPT ); Wed, 18 Aug 2021 03:07:54 -0400 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R681e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04426;MF=hsiangkao@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0UjfS-t9_1629270434; Received: from e18g09479.et15sqa.tbsite.net(mailfrom:hsiangkao@linux.alibaba.com fp:SMTPD_---0UjfS-t9_1629270434) by smtp.aliyun-inc.com(127.0.0.1); Wed, 18 Aug 2021 15:07:19 +0800 From: Gao Xiang To: linux-erofs@lists.ozlabs.org, Chao Yu , Liu Bo Cc: LKML , Peng Tao , Eryu Guan , Liu Jiang , Joseph Qi , Gao Xiang Subject: [PATCH 2/2] erofs: support reading chunk-based uncompressed files Date: Wed, 18 Aug 2021 15:07:13 +0800 Message-Id: <20210818070713.4437-2-hsiangkao@linux.alibaba.com> X-Mailer: git-send-email 2.24.4 In-Reply-To: <20210818070713.4437-1-hsiangkao@linux.alibaba.com> References: <20210818070713.4437-1-hsiangkao@linux.alibaba.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add runtime support for chunk-based uncompressed files described in the previous patch. Signed-off-by: Gao Xiang --- fs/erofs/data.c | 90 ++++++++++++++++++++++++++++++++++++++++----- fs/erofs/inode.c | 18 ++++++++- fs/erofs/internal.h | 5 +++ 3 files changed, 102 insertions(+), 11 deletions(-) diff --git a/fs/erofs/data.c b/fs/erofs/data.c index b2a22aabc9bc..78d625709481 100644 --- a/fs/erofs/data.c +++ b/fs/erofs/data.c @@ -2,6 +2,7 @@ /* * Copyright (C) 2017-2018 HUAWEI, Inc. * https://www.huawei.com/ + * Copyright (C) 2021, Alibaba Cloud */ #include "internal.h" #include @@ -37,13 +38,6 @@ static int erofs_map_blocks_flatmode(struct inode *inode, nblocks = DIV_ROUND_UP(inode->i_size, PAGE_SIZE); lastblk = nblocks - tailendpacking; - if (offset >= inode->i_size) { - /* leave out-of-bound access unmapped */ - map->m_flags = 0; - map->m_plen = 0; - goto out; - } - /* there is no hole in flatmode */ map->m_flags = EROFS_MAP_MAPPED; @@ -78,14 +72,90 @@ static int erofs_map_blocks_flatmode(struct inode *inode, goto err_out; } -out: map->m_llen = map->m_plen; - err_out: trace_erofs_map_blocks_flatmode_exit(inode, map, flags, 0); return err; } +static int erofs_map_blocks(struct inode *inode, + struct erofs_map_blocks *map, int flags) +{ + struct super_block *sb = inode->i_sb; + struct erofs_inode *vi = EROFS_I(inode); + struct erofs_inode_chunk_index *idx; + struct page *page; + u64 chunknr; + unsigned int unit; + erofs_off_t pos; + int err = 0; + + if (map->m_la >= inode->i_size) { + /* leave out-of-bound access unmapped */ + map->m_flags = 0; + map->m_plen = 0; + goto out; + } + + if (vi->datalayout != EROFS_INODE_CHUNK_BASED) + return erofs_map_blocks_flatmode(inode, map, flags); + + if (vi->chunkformat & EROFS_CHUNK_FORMAT_INDEXES) + unit = sizeof(*idx); /* chunk index */ + else + unit = 4; /* block map */ + + chunknr = map->m_la >> vi->chunkbits; + pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize + + vi->xattr_isize, unit) + unit * chunknr; + + page = erofs_get_meta_page(inode->i_sb, erofs_blknr(pos)); + if (IS_ERR(page)) + return PTR_ERR(page); + + map->m_la = chunknr << vi->chunkbits; + map->m_plen = min_t(erofs_off_t, 1UL << vi->chunkbits, + roundup(inode->i_size - map->m_la, EROFS_BLKSIZ)); + + /* handle block map */ + if (!(vi->chunkformat & EROFS_CHUNK_FORMAT_INDEXES)) { + __le32 *blkaddr = page_address(page) + erofs_blkoff(pos); + + if (le32_to_cpu(*blkaddr) == EROFS_NULL_ADDR) { + map->m_flags = 0; + } else { + map->m_pa = blknr_to_addr(le32_to_cpu(*blkaddr)); + map->m_flags = EROFS_MAP_MAPPED; + } + goto out_unlock; + } + /* parse chunk indexes */ + idx = page_address(page) + erofs_blkoff(pos); + switch (le32_to_cpu(idx->blkaddr)) { + case EROFS_NULL_ADDR: + map->m_flags = 0; + break; + default: + /* only one device is supported for now */ + if (idx->device_id) { + erofs_err(sb, "invalid device id %u @ %llu for nid %llu", + le32_to_cpu(idx->device_id), + chunknr, vi->nid); + err = -EFSCORRUPTED; + goto out_unlock; + } + map->m_pa = blknr_to_addr(le32_to_cpu(idx->blkaddr)); + map->m_flags = EROFS_MAP_MAPPED; + break; + } +out_unlock: + unlock_page(page); + put_page(page); +out: + map->m_llen = map->m_plen; + return err; +} + static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, unsigned int flags, struct iomap *iomap, struct iomap *srcmap) { @@ -95,7 +165,7 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, map.m_la = offset; map.m_llen = length; - ret = erofs_map_blocks_flatmode(inode, &map, EROFS_GET_BLOCKS_RAW); + ret = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW); if (ret < 0) return ret; diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c index 92728da1d206..036a6cc97d10 100644 --- a/fs/erofs/inode.c +++ b/fs/erofs/inode.c @@ -2,6 +2,7 @@ /* * Copyright (C) 2017-2018 HUAWEI, Inc. * https://www.huawei.com/ + * Copyright (C) 2021, Alibaba Cloud */ #include "xattr.h" @@ -122,7 +123,9 @@ static struct page *erofs_read_inode(struct inode *inode, /* total blocks for compressed files */ if (erofs_inode_is_data_compressed(vi->datalayout)) nblks = le32_to_cpu(die->i_u.compressed_blocks); - + else if (vi->datalayout == EROFS_INODE_CHUNK_BASED) + /* fill chunked inode summary info */ + vi->chunkformat = __le16_to_cpu(die->i_u.c.format); kfree(copied); break; case EROFS_INODE_LAYOUT_COMPACT: @@ -160,6 +163,8 @@ static struct page *erofs_read_inode(struct inode *inode, inode->i_size = le32_to_cpu(dic->i_size); if (erofs_inode_is_data_compressed(vi->datalayout)) nblks = le32_to_cpu(dic->i_u.compressed_blocks); + else if (vi->datalayout == EROFS_INODE_CHUNK_BASED) + vi->chunkformat = __le16_to_cpu(dic->i_u.c.format); break; default: erofs_err(inode->i_sb, @@ -169,6 +174,17 @@ static struct page *erofs_read_inode(struct inode *inode, goto err_out; } + if (vi->datalayout == EROFS_INODE_CHUNK_BASED) { + if (!(vi->chunkformat & EROFS_CHUNK_FORMAT_ALL)) { + erofs_err(inode->i_sb, + "unsupported chunk format %x of nid %llu", + vi->chunkformat, vi->nid); + err = -EOPNOTSUPP; + goto err_out; + } + vi->chunkbits = LOG_BLOCK_SIZE + + (vi->chunkformat & EROFS_CHUNK_FORMAT_BLKBITS_MASK); + } inode->i_mtime.tv_sec = inode->i_ctime.tv_sec; inode->i_atime.tv_sec = inode->i_ctime.tv_sec; inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec; diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 25b094085ca6..0a46e149aadd 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -2,6 +2,7 @@ /* * Copyright (C) 2017-2018 HUAWEI, Inc. * https://www.huawei.com/ + * Copyright (C) 2021, Alibaba Cloud */ #ifndef __EROFS_INTERNAL_H #define __EROFS_INTERNAL_H @@ -260,6 +261,10 @@ struct erofs_inode { union { erofs_blk_t raw_blkaddr; + struct { + unsigned short chunkformat; + unsigned char chunkbits; + }; #ifdef CONFIG_EROFS_FS_ZIP struct { unsigned short z_advise; -- 2.24.4