xfs: fix the wrong new_size/rnew_size at xfs_iext_realloc_direct()

At xfs_iext_realloc_direct(), the new_size is changed by adding
if_bytes if originally the extent records are stored at the inline
extent buffer, and we have to switch from it to a direct extent
list for those new allocated extents, this is wrong. e.g,

Create a file with three extents which was showing as following,

xfs_io -f -c "truncate 100m" /xfs/testme

for i in $(seq 0 5 10); do
	offset=$(($i * $((1 << 20))))
	xfs_io -c "pwrite $offset 1m" /xfs/testme
done

Inline
------
irec:	if_bytes	bytes_diff	new_size
1st	0		16		16
2nd	16		16		32

Switching
---------						rnew_size
3rd	32		16		48 + 32 = 80	roundup=128

In this case, the desired value of new_size should be 48, and then
it will be roundup to 64 and be assigned to rnew_size.

However, this issue has been covered by resetting the if_bytes to
the new_size which is calculated at the begnning of xfs_iext_add()
before leaving out this function, and in turn make the rnew_size
correctly again. Hence, this can not be detected via xfstestes.

This patch fix above problem and revise the new_size comments at
xfs_iext_realloc_direct() to make it more readable.  Also, fix the
comments while switching from the inline extent buffer to a direct
extent list to reflect this change.

Signed-off-by: Jie Liu <jeff.liu@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
This commit is contained in:
Jie Liu 2013-09-22 16:25:15 +08:00 committed by Ben Myers
parent 0799a3e808
commit 17ec81c15f
1 changed files with 2 additions and 7 deletions

View File

@ -1359,7 +1359,7 @@ xfs_iext_remove_indirect(
void
xfs_iext_realloc_direct(
xfs_ifork_t *ifp, /* inode fork pointer */
int new_size) /* new size of extents */
int new_size) /* new size of extents after adding */
{
int rnew_size; /* real new size of extents */
@ -1397,13 +1397,8 @@ xfs_iext_realloc_direct(
rnew_size - ifp->if_real_bytes);
}
}
/*
* Switch from the inline extent buffer to a direct
* extent list. Be sure to include the inline extent
* bytes in new_size.
*/
/* Switch from the inline extent buffer to a direct extent list */
else {
new_size += ifp->if_bytes;
if (!is_power_of_2(new_size)) {
rnew_size = roundup_pow_of_two(new_size);
}