xfs
[Top] [All Lists]

[PATCH] xfs: fix the wrong new_size/rnew_size at xfs_iext_realloc_direc

To: "xfs@xxxxxxxxxxx" <xfs@xxxxxxxxxxx>
Subject: [PATCH] xfs: fix the wrong new_size/rnew_size at xfs_iext_realloc_direct()
From: Jeff Liu <jeff.liu@xxxxxxxxxx>
Date: Sun, 22 Sep 2013 16:25:15 +0800
Delivered-to: xfs@xxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:11.0) Gecko/20120410 Thunderbird/11.0.1
From: Jie Liu <jeff.liu@xxxxxxxxxx>

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@xxxxxxxxxx>
---
 fs/xfs/xfs_inode_fork.c |    9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/fs/xfs/xfs_inode_fork.c b/fs/xfs/xfs_inode_fork.c
index dfb4226..7c6192a 100644
--- a/fs/xfs/xfs_inode_fork.c
+++ b/fs/xfs/xfs_inode_fork.c
@@ -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);
                }
-- 
1.7.9.5

<Prev in Thread] Current Thread [Next in Thread>