Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp782347pxf; Wed, 7 Apr 2021 11:22:34 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy86a9fB1L1eFqq1GbKsy300bgoZRxfs/4zYVGWp9PaOjI9xfU12ZbsYsiHk0ZqYMlGtZvc X-Received: by 2002:a05:6402:b26:: with SMTP id bo6mr6384482edb.162.1617819753935; Wed, 07 Apr 2021 11:22:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617819753; cv=none; d=google.com; s=arc-20160816; b=V6hZRXQpoF0W7QmbnmIIggHyWberjVoQChd0U/NAShKSXWDPTf9C8Kb3ZzABJOGhM+ K7fXQ2zkldXPxC4jhj8atdy8DaIdr8dol49id0yzj5CJgdIRUtLxtvit8DTYwd0SSLwr v4o2hs272FnJe+iz36+jO4xWz7tAI2PMuuvqwr6Qmv/ZAU36t8yLeMKaEK2QHGtMksc+ ktUeIRHTrjqjsnPbZ2OsoQnvvw7jsdkp/4MoOZqldoWb271Oqcb44Q7eJZzeWHHi69Qr 5F2Qz0mmlIZavZCY6hnUGifMWuo8aYJEObceD/NAQ5Uki0+34aU05HnZ0wxHGIRIO8DH XizQ== 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 :dkim-signature; bh=9odre37gVCAa8vSYaFvf/7jA6BfeSBfNVbXAUmgq35s=; b=s7lMvy3TM2dZeCqcsYOWYH7dCH0IVIFVJBn/uoaLtvvViyabNSNvxWsRwRjWRgVhh0 Zywh9EdxbIfRrVfgGHdCIp9iEvcZEfB/G6okMC0Sw8SSbcDNSrcbLfLlpGtuk72htukL +Cx1ivIHlC6aRpJRRZ6ZNRqRkKxDnvYB8YWdZuHGrfAr5J+AstF38N89Ye97tXXvoX+1 8fmOxa/Fs0rqOEDgZlytGbic4ICF6AuyCU3NSnYmLn4CP4udi3e4W0t3+QJ5pppVdbwc PodTulpVSIfWsXYGwWLo5qmZm1LEFcn9iw1Ni1PFn7pYBIG6Mg9ZjDLa3DCJ8yl6vY2N 9OCA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=RZdT1FxJ; 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=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id u4si6736858ejz.726.2021.04.07.11.22.10; Wed, 07 Apr 2021 11:22:33 -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; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=RZdT1FxJ; 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=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244193AbhDGEkF (ORCPT + 99 others); Wed, 7 Apr 2021 00:40:05 -0400 Received: from mail.kernel.org ([198.145.29.99]:58842 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239524AbhDGEkA (ORCPT ); Wed, 7 Apr 2021 00:40:00 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id AFD8D61246; Wed, 7 Apr 2021 04:39:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1617770391; bh=xLye+0HHGuYd4pkCBDveDWowvUkzwRHRya3QjrGRvJE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RZdT1FxJIqrziP0EMdqPVDEB8FeLRKcXK2rjrI6WSjcnXkfxzJSgVkCuObQdiMyYi DIzN8YxytxGZj8qmJoJt0ibwaeP1Pf8bar5MEiURGLFghscQmiIfPDUu+r6nhEKU9R auhJev1Mbh5TW1BmJL28YYIJg+xx1IaKFi7LiyHaY+2f7ZmDFlqv5KqZ1c6xg1s5sE OR+vhEbUAyAyD6mWB2M9HQ/zvGfBD9JvMVL9upl9ONNsVWDWW/HKKX27MkLijQZDim +AqU3NKolvj1okPluG+gt+1Mo21uWBMZSTPgaRq+6zmlbZyYcDk0NCBOUxp8bTutPY xa+TuKdl1B8pA== From: Gao Xiang To: linux-erofs@lists.ozlabs.org, Chao Yu , Chao Yu Cc: LKML , Gao Xiang Subject: [PATCH v3 07/10] erofs: support parsing big pcluster compress indexes Date: Wed, 7 Apr 2021 12:39:24 +0800 Message-Id: <20210407043927.10623-8-xiang@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210407043927.10623-1-xiang@kernel.org> References: <20210407043927.10623-1-xiang@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Gao Xiang When INCOMPAT_BIG_PCLUSTER sb feature is enabled, legacy compress indexes will also have the same on-disk header compact indexes to keep per-file configurations instead of leaving it zeroed. If ADVISE_BIG_PCLUSTER is set for a file, CBLKCNT will be loaded for each pcluster in this file by parsing 1st non-head lcluster. Acked-by: Chao Yu Signed-off-by: Gao Xiang --- fs/erofs/zmap.c | 79 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 6 deletions(-) diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index 7fd6bd843471..6c0c47f68b75 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -11,8 +11,10 @@ int z_erofs_fill_inode(struct inode *inode) { struct erofs_inode *const vi = EROFS_I(inode); + struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); - if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) { + if (!erofs_sb_has_big_pcluster(sbi) && + vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) { vi->z_advise = 0; vi->z_algorithmtype[0] = 0; vi->z_algorithmtype[1] = 0; @@ -49,7 +51,8 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags)) goto out_unlock; - DBG_BUGON(vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY); + DBG_BUGON(!erofs_sb_has_big_pcluster(EROFS_SB(sb)) && + vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY); pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize + vi->xattr_isize, 8); @@ -96,7 +99,7 @@ struct z_erofs_maprecorder { u8 type; u16 clusterofs; u16 delta[2]; - erofs_blk_t pblk; + erofs_blk_t pblk, compressedlcs; }; static int z_erofs_reload_indexes(struct z_erofs_maprecorder *m, @@ -159,6 +162,15 @@ static int legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m, case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: m->clusterofs = 1 << vi->z_logical_clusterbits; m->delta[0] = le16_to_cpu(di->di_u.delta[0]); + if (m->delta[0] & Z_EROFS_VLE_DI_D0_CBLKCNT) { + if (!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) { + DBG_BUGON(1); + return -EFSCORRUPTED; + } + m->compressedlcs = m->delta[0] & + ~Z_EROFS_VLE_DI_D0_CBLKCNT; + m->delta[0] = 1; + } m->delta[1] = le16_to_cpu(di->di_u.delta[1]); break; case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: @@ -366,6 +378,58 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m, return 0; } +static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m, + unsigned int initial_lcn) +{ + struct erofs_inode *const vi = EROFS_I(m->inode); + struct erofs_map_blocks *const map = m->map; + const unsigned int lclusterbits = vi->z_logical_clusterbits; + unsigned long lcn; + int err; + + DBG_BUGON(m->type != Z_EROFS_VLE_CLUSTER_TYPE_PLAIN && + m->type != Z_EROFS_VLE_CLUSTER_TYPE_HEAD); + if (!(map->m_flags & EROFS_MAP_ZIPPED) || + !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) { + map->m_plen = 1 << lclusterbits; + return 0; + } + + lcn = m->lcn + 1; + if (m->compressedlcs) + goto out; + if (lcn == initial_lcn) + goto err_bonus_cblkcnt; + + err = z_erofs_load_cluster_from_disk(m, lcn); + if (err) + return err; + + switch (m->type) { + case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: + if (m->delta[0] != 1) + goto err_bonus_cblkcnt; + if (m->compressedlcs) + break; + fallthrough; + default: + erofs_err(m->inode->i_sb, + "cannot found CBLKCNT @ lcn %lu of nid %llu", + lcn, vi->nid); + DBG_BUGON(1); + return -EFSCORRUPTED; + } +out: + map->m_plen = m->compressedlcs << lclusterbits; + return 0; +err_bonus_cblkcnt: + erofs_err(m->inode->i_sb, + "bogus CBLKCNT @ lcn %lu of nid %llu", + lcn, vi->nid); + DBG_BUGON(1); + return -EFSCORRUPTED; +} + int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map, int flags) @@ -377,6 +441,7 @@ int z_erofs_map_blocks_iter(struct inode *inode, }; int err = 0; unsigned int lclusterbits, endoff; + unsigned long initial_lcn; unsigned long long ofs, end; trace_z_erofs_map_blocks_iter_enter(inode, map, flags); @@ -395,10 +460,10 @@ int z_erofs_map_blocks_iter(struct inode *inode, lclusterbits = vi->z_logical_clusterbits; ofs = map->m_la; - m.lcn = ofs >> lclusterbits; + initial_lcn = ofs >> lclusterbits; endoff = ofs & ((1 << lclusterbits) - 1); - err = z_erofs_load_cluster_from_disk(&m, m.lcn); + err = z_erofs_load_cluster_from_disk(&m, initial_lcn); if (err) goto unmap_out; @@ -442,10 +507,12 @@ int z_erofs_map_blocks_iter(struct inode *inode, } map->m_llen = end - map->m_la; - map->m_plen = 1 << lclusterbits; map->m_pa = blknr_to_addr(m.pblk); map->m_flags |= EROFS_MAP_MAPPED; + err = z_erofs_get_extent_compressedlen(&m, initial_lcn); + if (err) + goto out; unmap_out: if (m.kaddr) kunmap_atomic(m.kaddr); -- 2.20.1