All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yue Hu <huyue2@yulong.com>
To: linux-erofs@lists.ozlabs.org
Cc: huyue2@yulong.com, geshifei@yulong.com, zhangwen@yulong.com,
	shaojunjun@yulong.com
Subject: [RFC PATCH 2/2] erofs-utils: fuse: support tail-packing inline compressed data
Date: Mon, 25 Oct 2021 20:30:44 +0800	[thread overview]
Message-ID: <c7855cbdd82f62fbc84d36d9fb3c892cfa569128.1635162978.git.huyue2@yulong.com> (raw)
In-Reply-To: <cover.1635162978.git.huyue2@yulong.com>

Add tail-packing inline compressed data support for erofsfuse.

Signed-off-by: Yue Hu <huyue2@yulong.com>
---
 lib/zmap.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 90 insertions(+), 5 deletions(-)

diff --git a/lib/zmap.c b/lib/zmap.c
index 1084faa..de79f03 100644
--- a/lib/zmap.c
+++ b/lib/zmap.c
@@ -442,6 +442,66 @@ err_bonus_cblkcnt:
 	return -EFSCORRUPTED;
 }
 
+static erofs_off_t compacted_inline_data_addr(struct erofs_inode *vi)
+{
+	const erofs_off_t ebase = round_up(iloc(vi->nid) + vi->inode_isize +
+					   vi->xattr_isize, 8) +
+					   sizeof(struct z_erofs_map_header);
+	const unsigned int totalidx = DIV_ROUND_UP(vi->i_size, EROFS_BLKSIZ);
+	unsigned int compacted_4b_initial, compacted_4b_end;
+	unsigned int compacted_2b;
+	erofs_off_t addr;
+
+	compacted_4b_initial = (32 - ebase % 32) / 4;
+	if (compacted_4b_initial == 32 / 4)
+		compacted_4b_initial = 0;
+
+	if (compacted_4b_initial > totalidx) {
+		compacted_4b_initial = 0;
+		compacted_2b = 0;
+	} else if (vi->z_advise & Z_EROFS_ADVISE_COMPACTED_2B) {
+		compacted_2b = rounddown(totalidx - compacted_4b_initial, 16);
+	} else
+		compacted_2b = 0;
+
+	compacted_4b_end = totalidx - compacted_4b_initial - compacted_2b;
+
+	addr = ebase;
+	addr += compacted_4b_initial * 4;
+	addr += compacted_2b * 2;
+	if (compacted_4b_end > 1)
+		addr += (compacted_4b_end/2) * 8;
+	if (compacted_4b_end % 2)
+		addr += 8;
+
+	return addr;
+}
+
+static erofs_off_t legacy_inline_data_addr(struct erofs_inode *vi)
+{
+	const erofs_off_t ibase = iloc(vi->nid);
+	const unsigned int totalidx = DIV_ROUND_UP(vi->i_size, EROFS_BLKSIZ);
+	erofs_off_t addr;
+
+	addr = Z_EROFS_VLE_LEGACY_INDEX_ALIGN(ibase + vi->inode_isize +
+					     vi->xattr_isize) +
+		totalidx * sizeof(struct z_erofs_vle_decompressed_index);
+	return addr;
+}
+
+static erofs_off_t z_erofs_inline_data_addr(struct erofs_inode *vi)
+{
+	const unsigned int datamode = vi->datalayout;
+
+	if (datamode == EROFS_INODE_FLAT_COMPRESSION)
+		return compacted_inline_data_addr(vi);
+
+	if (datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY)
+		return legacy_inline_data_addr(vi);
+
+	return -EINVAL;
+}
+
 int z_erofs_map_blocks_iter(struct erofs_inode *vi,
 			    struct erofs_map_blocks *map)
 {
@@ -454,6 +514,7 @@ int z_erofs_map_blocks_iter(struct erofs_inode *vi,
 	unsigned int lclusterbits, endoff;
 	unsigned long initial_lcn;
 	unsigned long long ofs, end;
+	bool tailpacking;
 
 	/* when trying to read beyond EOF, leave it unmapped */
 	if (map->m_la >= vi->i_size) {
@@ -467,6 +528,8 @@ int z_erofs_map_blocks_iter(struct erofs_inode *vi,
 	if (err)
 		goto out;
 
+	tailpacking = vi->z_advise & Z_EROFS_ADVISE_TAILPACKING;
+
 	lclusterbits = vi->z_logical_clusterbits;
 	ofs = map->m_la;
 	initial_lcn = ofs >> lclusterbits;
@@ -478,6 +541,9 @@ int z_erofs_map_blocks_iter(struct erofs_inode *vi,
 
 	map->m_flags = EROFS_MAP_ZIPPED;	/* by default, compressed */
 	end = (m.lcn + 1ULL) << lclusterbits;
+
+	map->m_flags &= ~EROFS_MAP_META;
+
 	switch (m.type) {
 	case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
 		if (endoff >= m.clusterofs)
@@ -485,6 +551,16 @@ int z_erofs_map_blocks_iter(struct erofs_inode *vi,
 	case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
 		if (endoff >= m.clusterofs) {
 			map->m_la = (m.lcn << lclusterbits) | m.clusterofs;
+			if (tailpacking &&
+			    end == round_up(vi->i_size, 1<<lclusterbits)) {
+				end = vi->i_size;
+				map->m_flags |= EROFS_MAP_META;
+			}
+			if (tailpacking &&
+			    end == round_down(vi->i_size, 1<<lclusterbits) &&
+			    vi->i_size - map->m_la <= EROFS_BLKSIZ) {
+				map->m_flags |= EROFS_MAP_META;
+			}
 			break;
 		}
 		/* m.lcn should be >= 1 if endoff < m.clusterofs */
@@ -495,7 +571,10 @@ int z_erofs_map_blocks_iter(struct erofs_inode *vi,
 			goto out;
 		}
 		end = (m.lcn << lclusterbits) | m.clusterofs;
-		map->m_flags |= EROFS_MAP_FULL_MAPPED;
+		if (tailpacking && end == vi->i_size)
+			map->m_flags |= EROFS_MAP_META;
+		else
+			map->m_flags |= EROFS_MAP_FULL_MAPPED;
 		m.delta[0] = 1;
 	case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
 		/* get the correspoinding first chunk */
@@ -511,11 +590,17 @@ int z_erofs_map_blocks_iter(struct erofs_inode *vi,
 	}
 
 	map->m_llen = end - map->m_la;
-	map->m_pa = blknr_to_addr(m.pblk);
 
-	err = z_erofs_get_extent_compressedlen(&m, initial_lcn);
-	if (err)
-		goto out;
+	if (map->m_flags & EROFS_MAP_META) {
+		map->m_pa = z_erofs_inline_data_addr(vi);
+		map->m_plen = EROFS_BLKSIZ;
+	} else {
+		map->m_pa = blknr_to_addr(m.pblk);
+
+		err = z_erofs_get_extent_compressedlen(&m, initial_lcn);
+		if (err)
+			goto out;
+	}
 	map->m_flags |= EROFS_MAP_MAPPED;
 
 out:
-- 
2.29.0




      parent reply	other threads:[~2021-10-25 12:34 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-25 12:30 [RFC PATCH 0/2] erofs-utils: compression inline feature Yue Hu
2021-10-25 12:30 ` [RFC PATCH 1/2] erofs-utils: support tail-packing inline compressed data Yue Hu
2021-10-26 12:00   ` Gao Xiang
2021-10-27  1:58     ` Yue Hu
2021-10-27  7:21       ` Yue Hu
2021-10-27  7:34         ` Gao Xiang
2021-10-27  8:02           ` Yue Hu
2021-10-25 12:30 ` Yue Hu [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c7855cbdd82f62fbc84d36d9fb3c892cfa569128.1635162978.git.huyue2@yulong.com \
    --to=huyue2@yulong.com \
    --cc=geshifei@yulong.com \
    --cc=linux-erofs@lists.ozlabs.org \
    --cc=shaojunjun@yulong.com \
    --cc=zhangwen@yulong.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.