All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] btrfs: fix disk_i_size update bug when fallocate() fails
@ 2016-06-22  1:57 Wang Xiaoguang
  2016-06-22  6:24 ` Christoph Hellwig
  0 siblings, 1 reply; 3+ messages in thread
From: Wang Xiaoguang @ 2016-06-22  1:57 UTC (permalink / raw)
  To: linux-btrfs

When doing truncate operation, btrfs_setsize() will first call
truncate_setsize() to set new inode->i_size, but if later
btrfs_truncate() fails, btrfs_setsize() will call
"i_size_write(inode, BTRFS_I(inode)->disk_i_size)" to reset the
inmemory inode size, now bug occurs. It's because for truncate
case btrfs_ordered_update_i_size() directly uses inode->i_size
to update BTRFS_I(inode)->disk_i_size, indeed we should use the
"offset" argument to update disk_i_size. Here is the call graph:
==>btrfs_truncate()
====>btrfs_truncate_inode_items()
======>btrfs_ordered_update_i_size(inode, last_size, NULL);
Here btrfs_ordered_update_i_size()'s offset argument is last_size.

And below test case can reveal this bug:

dd if=/dev/zero of=fs.img bs=$((1024*1024)) count=100
dev=$(losetup --show -f fs.img)
mkdir -p /mnt/mntpoint
mkfs.btrfs  -f $dev
mount $dev /mnt/mntpoint
cd /mnt/mntpoint

echo "workdir is: /mnt/mntpoint"
blocksize=$((128 * 1024))
dd if=/dev/zero of=testfile bs=$blocksize count=1
sync
count=$((17*1024*1024*1024/blocksize))
echo "file size is:" $((count*blocksize))
for ((i = 1; i <= $count; i++)); do
	i=$((i + 1))
	dst_offset=$((blocksize * i))
	xfs_io -f -c "reflink testfile 0 $dst_offset $blocksize"\
		testfile > /dev/null
done
sync

truncate --size 0 testfile
ls -l testfile
du -sh testfile
exit

In this case, truncate operation will fail for enospc reason and
"du -sh testfile" returns value greater than 0, but testfile's
size is 0, we need to reflect correct inode->i_size.

Signed-off-by: Wang Xiaoguang <wangxg.fnst@cn.fujitsu.com>
---
 fs/btrfs/ordered-data.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index e96634a..aca8264 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -968,6 +968,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
 	struct rb_node *prev = NULL;
 	struct btrfs_ordered_extent *test;
 	int ret = 1;
+	u64 orig_offset = offset;
 
 	spin_lock_irq(&tree->lock);
 	if (ordered) {
@@ -983,7 +984,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
 
 	/* truncate file */
 	if (disk_i_size > i_size) {
-		BTRFS_I(inode)->disk_i_size = i_size;
+		BTRFS_I(inode)->disk_i_size = orig_offset;
 		ret = 0;
 		goto out;
 	}
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] btrfs: fix disk_i_size update bug when fallocate() fails
  2016-06-22  1:57 [PATCH] btrfs: fix disk_i_size update bug when fallocate() fails Wang Xiaoguang
@ 2016-06-22  6:24 ` Christoph Hellwig
  2016-06-22  7:28   ` Wang Xiaoguang
  0 siblings, 1 reply; 3+ messages in thread
From: Christoph Hellwig @ 2016-06-22  6:24 UTC (permalink / raw)
  To: Wang Xiaoguang; +Cc: linux-btrfs

On Wed, Jun 22, 2016 at 09:57:01AM +0800, Wang Xiaoguang wrote:
> And below test case can reveal this bug:

Please wire this up for xfstests, thanks!

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] btrfs: fix disk_i_size update bug when fallocate() fails
  2016-06-22  6:24 ` Christoph Hellwig
@ 2016-06-22  7:28   ` Wang Xiaoguang
  0 siblings, 0 replies; 3+ messages in thread
From: Wang Xiaoguang @ 2016-06-22  7:28 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-btrfs

hello,

On 06/22/2016 02:24 PM, Christoph Hellwig wrote:
> On Wed, Jun 22, 2016 at 09:57:01AM +0800, Wang Xiaoguang wrote:
>> And below test case can reveal this bug:
> Please wire this up for xfstests, thanks!
OK.

Regards,
Xiaoguang Wang
>
>




^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-06-22  7:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-22  1:57 [PATCH] btrfs: fix disk_i_size update bug when fallocate() fails Wang Xiaoguang
2016-06-22  6:24 ` Christoph Hellwig
2016-06-22  7:28   ` Wang Xiaoguang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.