Btrfs: fix reported number of inode blocks after buffered append writes
The patch from commita7e3b975a0
("Btrfs: fix reported number of inode blocks") introduced a regression where if we do a buffered write starting at position equal to or greater than the file's size and then stat(2) the file before writeback is triggered, the number of used blocks does not change (unless there's a prealloc/unwritten extent). Example: $ xfs_io -f -c "pwrite -S 0xab 0 64K" foobar $ du -h foobar 0 foobar $ sync $ du -h foobar 64K foobar The first version of that patch didn't had this regression and the second version, which was the one committed, was made only to address some performance regression detected by the intel test robots using fs_mark. This fixes the regression by setting the new delaloc bit in the range, and doing it at btrfs_dirty_pages() while setting the regular dealloc bit as well, so that this way we set both bits at once avoiding navigation of the inode's io tree twice. Doing it at btrfs_dirty_pages() is also the most meaninful place, as we should set the new dellaloc bit when if we set the delalloc bit, which happens only if we copied bytes into the pages at __btrfs_buffered_write(). This was making some of LTP's du tests fail, which can be quickly run using a command line like the following: $ ./runltp -q -p -l /ltp.log -f commands -s du -d /mnt Fixes:a7e3b975a0
("Btrfs: fix reported number of inode blocks") Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:

committed by
David Sterba

parent
f48bf66b66
commit
e3b8a48585
@@ -968,7 +968,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
|
||||
btrfs_test_inode_set_ops(inode);
|
||||
|
||||
/* [BTRFS_MAX_EXTENT_SIZE] */
|
||||
ret = btrfs_set_extent_delalloc(inode, 0, BTRFS_MAX_EXTENT_SIZE - 1,
|
||||
ret = btrfs_set_extent_delalloc(inode, 0, BTRFS_MAX_EXTENT_SIZE - 1, 0,
|
||||
NULL, 0);
|
||||
if (ret) {
|
||||
test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
|
||||
@@ -984,7 +984,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
|
||||
/* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */
|
||||
ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE,
|
||||
BTRFS_MAX_EXTENT_SIZE + sectorsize - 1,
|
||||
NULL, 0);
|
||||
0, NULL, 0);
|
||||
if (ret) {
|
||||
test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
|
||||
goto out;
|
||||
@@ -1018,7 +1018,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
|
||||
ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE >> 1,
|
||||
(BTRFS_MAX_EXTENT_SIZE >> 1)
|
||||
+ sectorsize - 1,
|
||||
NULL, 0);
|
||||
0, NULL, 0);
|
||||
if (ret) {
|
||||
test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
|
||||
goto out;
|
||||
@@ -1036,7 +1036,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
|
||||
ret = btrfs_set_extent_delalloc(inode,
|
||||
BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize,
|
||||
(BTRFS_MAX_EXTENT_SIZE << 1) + 3 * sectorsize - 1,
|
||||
NULL, 0);
|
||||
0, NULL, 0);
|
||||
if (ret) {
|
||||
test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
|
||||
goto out;
|
||||
@@ -1053,7 +1053,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
|
||||
*/
|
||||
ret = btrfs_set_extent_delalloc(inode,
|
||||
BTRFS_MAX_EXTENT_SIZE + sectorsize,
|
||||
BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL, 0);
|
||||
BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, 0, NULL, 0);
|
||||
if (ret) {
|
||||
test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
|
||||
goto out;
|
||||
@@ -1089,7 +1089,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
|
||||
*/
|
||||
ret = btrfs_set_extent_delalloc(inode,
|
||||
BTRFS_MAX_EXTENT_SIZE + sectorsize,
|
||||
BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL, 0);
|
||||
BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, 0, NULL, 0);
|
||||
if (ret) {
|
||||
test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
|
||||
goto out;
|
||||
|
Reference in New Issue
Block a user