Commit 093f0bac authored by Daeho Jeong's avatar Daeho Jeong Committed by Jaegeuk Kim

f2fs: change fiemap way in printing compression chunk

When we print out a discontinuous compression chunk, it shows like a
continuous chunk now. To show it more correctly, I've changed the way of
printing fiemap info like below. Plus, eliminated NEW_ADDR(-1) in fiemap
info, since it is not in fiemap user api manual.

Let's assume 16KB compression cluster.

<before>
   Logical          Physical         Length           Flags
0:  0000000000000000 00000002c091f000 0000000000004000 1008
1:  0000000000004000 00000002c0920000 0000000000004000 1008
  ...
9:  0000000000034000 0000000f8c623000 0000000000004000 1008
10: 0000000000038000 000000101a6eb000 0000000000004000 1008

<after>
0:  0000000000000000 00000002c091f000 0000000000004000 1008
1:  0000000000004000 00000002c0920000 0000000000004000 1008
  ...
9:  0000000000034000 0000000f8c623000 0000000000001000 1008
10: 0000000000035000 000000101a6ea000 0000000000003000 1008
11: 0000000000038000 000000101a6eb000 0000000000002000 1008
12: 000000000003a000 00000002c3544000 0000000000002000 1008

Flags
0x1000 => FIEMAP_EXTENT_MERGED
0x0008 => FIEMAP_EXTENT_ENCODED
Signed-off-by: default avatarDaeho Jeong <daehojeong@google.com>
Tested-by: default avatarEric Biggers <ebiggers@google.com>
Reviewed-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent b7ec2061
...@@ -1843,8 +1843,9 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, ...@@ -1843,8 +1843,9 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
u64 logical = 0, phys = 0, size = 0; u64 logical = 0, phys = 0, size = 0;
u32 flags = 0; u32 flags = 0;
int ret = 0; int ret = 0;
bool compr_cluster = false; bool compr_cluster = false, compr_appended;
unsigned int cluster_size = F2FS_I(inode)->i_cluster_size; unsigned int cluster_size = F2FS_I(inode)->i_cluster_size;
unsigned int count_in_cluster = 0;
loff_t maxbytes; loff_t maxbytes;
if (fieinfo->fi_flags & FIEMAP_FLAG_CACHE) { if (fieinfo->fi_flags & FIEMAP_FLAG_CACHE) {
...@@ -1892,15 +1893,17 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, ...@@ -1892,15 +1893,17 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
map.m_next_pgofs = &next_pgofs; map.m_next_pgofs = &next_pgofs;
map.m_seg_type = NO_CHECK_TYPE; map.m_seg_type = NO_CHECK_TYPE;
if (compr_cluster) if (compr_cluster) {
map.m_len = cluster_size - 1; map.m_lblk += 1;
map.m_len = cluster_size - count_in_cluster;
}
ret = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_FIEMAP); ret = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_FIEMAP);
if (ret) if (ret)
goto out; goto out;
/* HOLE */ /* HOLE */
if (!(map.m_flags & F2FS_MAP_FLAGS)) { if (!compr_cluster && !(map.m_flags & F2FS_MAP_FLAGS)) {
start_blk = next_pgofs; start_blk = next_pgofs;
if (blks_to_bytes(inode, start_blk) < blks_to_bytes(inode, if (blks_to_bytes(inode, start_blk) < blks_to_bytes(inode,
...@@ -1910,6 +1913,14 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, ...@@ -1910,6 +1913,14 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
flags |= FIEMAP_EXTENT_LAST; flags |= FIEMAP_EXTENT_LAST;
} }
compr_appended = false;
/* In a case of compressed cluster, append this to the last extent */
if (compr_cluster && ((map.m_flags & F2FS_MAP_UNWRITTEN) ||
!(map.m_flags & F2FS_MAP_FLAGS))) {
compr_appended = true;
goto skip_fill;
}
if (size) { if (size) {
flags |= FIEMAP_EXTENT_MERGED; flags |= FIEMAP_EXTENT_MERGED;
if (IS_ENCRYPTED(inode)) if (IS_ENCRYPTED(inode))
...@@ -1926,38 +1937,36 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, ...@@ -1926,38 +1937,36 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
if (start_blk > last_blk) if (start_blk > last_blk)
goto out; goto out;
if (compr_cluster) { skip_fill:
compr_cluster = false;
logical = blks_to_bytes(inode, start_blk - 1);
phys = blks_to_bytes(inode, map.m_pblk);
size = blks_to_bytes(inode, cluster_size);
flags |= FIEMAP_EXTENT_ENCODED;
start_blk += cluster_size - 1;
if (start_blk > last_blk)
goto out;
goto prep_next;
}
if (map.m_pblk == COMPRESS_ADDR) { if (map.m_pblk == COMPRESS_ADDR) {
compr_cluster = true; compr_cluster = true;
start_blk++; count_in_cluster = 1;
goto prep_next; } else if (compr_appended) {
} unsigned int appended_blks = cluster_size -
count_in_cluster + 1;
logical = blks_to_bytes(inode, start_blk); size += blks_to_bytes(inode, appended_blks);
phys = blks_to_bytes(inode, map.m_pblk); start_blk += appended_blks;
size = blks_to_bytes(inode, map.m_len); compr_cluster = false;
flags = 0; } else {
if (map.m_flags & F2FS_MAP_UNWRITTEN) logical = blks_to_bytes(inode, start_blk);
flags = FIEMAP_EXTENT_UNWRITTEN; phys = __is_valid_data_blkaddr(map.m_pblk) ?
blks_to_bytes(inode, map.m_pblk) : 0;
size = blks_to_bytes(inode, map.m_len);
flags = 0;
if (compr_cluster) {
flags = FIEMAP_EXTENT_ENCODED;
count_in_cluster += map.m_len;
if (count_in_cluster == cluster_size) {
compr_cluster = false;
size += blks_to_bytes(inode, 1);
}
} else if (map.m_flags & F2FS_MAP_UNWRITTEN) {
flags = FIEMAP_EXTENT_UNWRITTEN;
}
start_blk += bytes_to_blks(inode, size); start_blk += bytes_to_blks(inode, size);
}
prep_next: prep_next:
cond_resched(); cond_resched();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment