[LU-13103] e2fsprogs has problem when calculation block number Created: 27/Dec/19  Updated: 20/Apr/20  Resolved: 20/Apr/20

Status: Resolved
Project: Lustre
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Li Xi Assignee: Wang Shilong (Inactive)
Resolution: Fixed Votes: 0
Labels: None

Severity: 3
Rank (Obsolete): 9223372036854775807

 Description   
static blkcnt_t blocks_from_inode(ext2_filsys fs,
				  struct ext2_inode_large *inode)
{
	blkcnt_t b;

	b = inode->i_blocks;
	if (ext2fs_has_feature_huge_file(fs->super))
		b += ((long long) inode->osd2.linux2.l_i_blocks_hi) << 32;

	if (!ext2fs_has_feature_huge_file(fs->super) ||
	    !(inode->i_flags & EXT4_HUGE_FILE_FL))
		b *= fs->blocksize / 512;
	b *= EXT2FS_CLUSTER_RATIO(fs);

	return b;
}

This is wrong, it should be something like

static blkcnt_t blocks_from_inode(ext2_filsys fs, struct ext2_inode *inode)
{
	blkcnt_t b;

	b = inode->i_blocks;
	if (ext2fs_has_feature_huge_file(fs->super)) {
		b += ((long long) inode->osd2.linux2.l_i_blocks_hi) << 32;
		if (inode->i_flags & EXT4_HUGE_FILE_FL)
			b *= fs->blocksize / 512;
	}
	b *= EXT2FS_CLUSTER_RATIO(fs);

	return b;
}

ext2fs_iblk_add_blocks(), ext2fs_iblk_sub_blocks() and ext2fs_iblk_set() has similar problems.



 Comments   
Comment by Andreas Dilger [ 27/Dec/19 ]

It looks to me that the existing code is correct.

There are two parts to the huge file support. One part is the high 16 bits of the block number. The second part is whether the blocks are in 512-byte sector units (old code) or blocksize units (new code). Only if both the HUGE_FILE feature is enabled in the superblock is the high-bits field available. and only if the inode flag is set is it in units of blocksize. Otherwise it has to be converted from sectors to blocks.

Comment by Li Xi [ 27/Dec/19 ]

Dongyang found following:

Lower 32-bits of "block" count. If the huge_file feature flag is not set on the filesystem, the file consumes i_blocks_lo 512-byte blocks on disk. If huge_file is set and EXT4_HUGE_FILE_FL is NOT set in inode.i_flags, then the file consumes i_blocks_lo + (i_blocks_hi << 32) 512-byte blocks on disk. If huge_file is set and EXT4_HUGE_FILE_FL IS set in inode.i_flags, then this file consumes (i_blocks_lo + i_blocks_hi << 32) filesystem blocks on disk.

Comment by Li Xi [ 27/Dec/19 ]

The problem with current code is, if file system has no huge file feature, or if the file has no huge file flag, the block saved in i_blocks will be consider to having the unit of block size. That is not correct, and causes different values between the 512 block number got from stat(2) and from e2fsprogs utilities.

Comment by Wang Shilong (Inactive) [ 27/Dec/19 ]

btw, above codes have another problem that it b *= EXT2FS_CLUSTER_RATIO(fs), this is not right for i_blocks.

Comment by Andreas Dilger [ 28/Dec/19 ]

Please post an email to linux-ext4@vger.kernel.org with bug report and/or patch. It looks like the code in blocks_from_inode() is specific to FUSE, and that may never have been tested with files over 16TB (since that isn't possible with x86 systems, only with PAGE_SIZE over 4KB). The other places where EXT4_HUGE_FILE_FL are used is converting from a blocks count to store into the inode, while the blocks_from_inode() is converting from inode->i_blocks to the 512-byte sector count, so the logic should be reversed.

I also see that ext2fs_inode_i_blocks() is not taking EXT4_HUGE_FILE_FL into account at all, which is likely confusing/broken as well.

Comment by Gerrit Updater [ 29/Dec/19 ]

Wang Shilong (wshilong@ddn.com) uploaded a new patch: https://review.whamcloud.com/37109
Subject: LU-13103 e2fsprogs: fix to use inode i_blocks correctly
Project: tools/e2fsprogs
Branch: master
Current Patch Set: 1
Commit: 9450605fc9053d553f7f5980bc747c58d70f9483

Comment by Gerrit Updater [ 29/Dec/19 ]

Wang Shilong (wshilong@ddn.com) uploaded a new patch: https://review.whamcloud.com/37110
Subject: LU-13103 e2fsprogs: fix to use inode i_blocks correctly
Project: tools/e2fsprogs
Branch: master-lustre
Current Patch Set: 1
Commit: 5bdf73f1a7055b97342c92d256923a4b32c8ec97

Comment by Wang Shilong (Inactive) [ 20/Apr/20 ]

DY is rebasing e2fsprogs, supposing we will include it soon.

Generated at Sat Feb 10 02:58:24 UTC 2024 using Jira 9.4.14#940014-sha1:734e6822bbf0d45eff9af51f82432957f73aa32c.