Commit 1a67cbe1 authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim
Browse files

f2fs: fix to account compressed blocks in f2fs_compressed_blocks()



por_fsstress reports inconsistent status in orphan inode, the root cause
of this is in f2fs_write_raw_pages() we decrease i_compr_blocks incorrectly
due to wrong calculation in f2fs_compressed_blocks().

So this patch exposes below two functions based on __f2fs_cluster_blocks:
- f2fs_compressed_blocks: get count of compressed blocks in compressed cluster
- f2fs_cluster_blocks: get count of valid blocks (including reserved blocks)
in compressed cluster.

Then use f2fs_compress_blocks() to get correct compressed blocks count in
f2fs_write_raw_pages().

sanity_check_inode: inode (ino=ad80) hash inconsistent i_compr_blocks:2, i_blocks:1, run fsck to fix

Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 50b1203d
Loading
Loading
Loading
Loading
+22 −6
Original line number Diff line number Diff line
@@ -535,8 +535,7 @@ static bool __cluster_may_compress(struct compress_ctx *cc)
	return true;
}

/* return # of compressed block addresses */
static int f2fs_compressed_blocks(struct compress_ctx *cc)
static int __f2fs_cluster_blocks(struct compress_ctx *cc, bool compr)
{
	struct dnode_of_data dn;
	int ret;
@@ -559,15 +558,32 @@ static int f2fs_compressed_blocks(struct compress_ctx *cc)

			blkaddr = data_blkaddr(dn.inode,
					dn.node_page, dn.ofs_in_node + i);
			if (compr) {
				if (__is_valid_data_blkaddr(blkaddr))
					ret++;
			} else {
				if (blkaddr != NULL_ADDR)
					ret++;
			}
		}
	}
fail:
	f2fs_put_dnode(&dn);
	return ret;
}

/* return # of compressed blocks in compressed cluster */
static int f2fs_compressed_blocks(struct compress_ctx *cc)
{
	return __f2fs_cluster_blocks(cc, true);
}

/* return # of valid blocks in compressed cluster */
static int f2fs_cluster_blocks(struct compress_ctx *cc, bool compr)
{
	return __f2fs_cluster_blocks(cc, false);
}

int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index)
{
	struct compress_ctx cc = {
@@ -577,7 +593,7 @@ int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index)
		.cluster_idx = index >> F2FS_I(inode)->i_log_cluster_size,
	};

	return f2fs_compressed_blocks(&cc);
	return f2fs_cluster_blocks(&cc, false);
}

static bool cluster_may_compress(struct compress_ctx *cc)
@@ -626,7 +642,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc,
	bool prealloc;

retry:
	ret = f2fs_compressed_blocks(cc);
	ret = f2fs_cluster_blocks(cc, false);
	if (ret <= 0)
		return ret;