linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2/2] Btrfs: fix wrong i_size when truncating a file to a larger size
@ 2011-12-14  7:15 Miao Xie
  2011-12-14 16:51 ` Chris Mason
  0 siblings, 1 reply; 4+ messages in thread
From: Miao Xie @ 2011-12-14  7:15 UTC (permalink / raw)
  To: Linux Btrfs

Btrfsck report error 100 after the 83th case of xfstests was run, it means
the i_size of the file is wrong.

The reason of this bug is that:
Btrfs increased i_size of the file at the beginning, but it failed to expand
the file, and failed to update the i_size to the old size because there is no
enough space in the file system, so we found a wrong i_size.

This patch fixes this bug by updating the i_size just when we pass the file
expanding and get enough space to update i-node.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
 fs/btrfs/inode.c |   18 ++++++++++++------
 1 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 960818b..f1c4bce 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3373,6 +3373,8 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
 
 static int btrfs_setsize(struct inode *inode, loff_t newsize)
 {
+	struct btrfs_root *root = BTRFS_I(inode)->root;
+	struct btrfs_trans_handle *trans;
 	loff_t oldsize = i_size_read(inode);
 	int ret;
 
@@ -3380,16 +3382,20 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize)
 		return 0;
 
 	if (newsize > oldsize) {
-		i_size_write(inode, newsize);
-		btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL);
 		truncate_pagecache(inode, oldsize, newsize);
 		ret = btrfs_cont_expand(inode, oldsize, newsize);
-		if (ret) {
-			btrfs_setsize(inode, oldsize);
+		if (ret)
 			return ret;
-		}
 
-		mark_inode_dirty(inode);
+		trans = btrfs_start_transaction(root, 1);
+		if (IS_ERR(trans))
+			return PTR_ERR(trans);
+
+		i_size_write(inode, newsize);
+		btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL);
+		ret = btrfs_update_inode(trans, root, inode);
+
+		btrfs_end_transaction_throttle(trans, root);
 	} else {
 
 		/*
-- 
1.7.6.4

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

* Re: [PATCH 2/2] Btrfs: fix wrong i_size when truncating a file to a larger size
  2011-12-14  7:15 [PATCH 2/2] Btrfs: fix wrong i_size when truncating a file to a larger size Miao Xie
@ 2011-12-14 16:51 ` Chris Mason
  2011-12-15  6:02   ` Miao Xie
  2011-12-15  9:55   ` [PATCH V2 " Miao Xie
  0 siblings, 2 replies; 4+ messages in thread
From: Chris Mason @ 2011-12-14 16:51 UTC (permalink / raw)
  To: Miao Xie; +Cc: Linux Btrfs

On Wed, Dec 14, 2011 at 03:15:53PM +0800, Miao Xie wrote:
> Btrfsck report error 100 after the 83th case of xfstests was run, it means
> the i_size of the file is wrong.
> 
> The reason of this bug is that:
> Btrfs increased i_size of the file at the beginning, but it failed to expand
> the file, and failed to update the i_size to the old size because there is no
> enough space in the file system, so we found a wrong i_size.
> 
> This patch fixes this bug by updating the i_size just when we pass the file
> expanding and get enough space to update i-node.

Hmmm, have you tested this one with fsx-linux?  It should be ok to call
truncate_pagecache before bumping i_size in this case, since we
shouldn't have pages past i_size.

But, truncate_pagecache does expect i_size to be accurate before the
call.

-chris

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

* Re: [PATCH 2/2] Btrfs: fix wrong i_size when truncating a file to a larger size
  2011-12-14 16:51 ` Chris Mason
@ 2011-12-15  6:02   ` Miao Xie
  2011-12-15  9:55   ` [PATCH V2 " Miao Xie
  1 sibling, 0 replies; 4+ messages in thread
From: Miao Xie @ 2011-12-15  6:02 UTC (permalink / raw)
  To: Chris Mason, Linux Btrfs

On Wed, 14 Dec 2011 11:51:47 -0500, Chris Mason wrote:
> On Wed, Dec 14, 2011 at 03:15:53PM +0800, Miao Xie wrote:
>> Btrfsck report error 100 after the 83th case of xfstests was run, it means
>> the i_size of the file is wrong.
>>
>> The reason of this bug is that:
>> Btrfs increased i_size of the file at the beginning, but it failed to expand
>> the file, and failed to update the i_size to the old size because there is no
>> enough space in the file system, so we found a wrong i_size.
>>
>> This patch fixes this bug by updating the i_size just when we pass the file
>> expanding and get enough space to update i-node.
> 
> Hmmm, have you tested this one with fsx-linux?  It should be ok to call
> truncate_pagecache before bumping i_size in this case, since we
> shouldn't have pages past i_size.

Yes, I have tested it. Everything is OK.

> But, truncate_pagecache does expect i_size to be accurate before the
> call.

OK, I will modify my patch.

Thanks for your comment.
Miao

> 
> -chris
> 


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

* [PATCH V2 2/2] Btrfs: fix wrong i_size when truncating a file to a larger size
  2011-12-14 16:51 ` Chris Mason
  2011-12-15  6:02   ` Miao Xie
@ 2011-12-15  9:55   ` Miao Xie
  1 sibling, 0 replies; 4+ messages in thread
From: Miao Xie @ 2011-12-15  9:55 UTC (permalink / raw)
  To: Chris Mason, Linux Btrfs

Btrfsck report error 100 after the 83th case of xfstests was run, it means
the i_size of the file is wrong.

The reason of this bug is that:
Btrfs increased i_size of the file at the beginning, but it failed to expand
the file, and failed to update the i_size to the old size because there is no
enough space in the file system, so we found a wrong i_size.

This patch fixes this bug by updating the i_size just when we pass the file
expanding.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
Changes v1 -> v2:
- make i_size be accurate before truncate_pagecache() is called
  (use truncate_setsize())
---
 fs/btrfs/inode.c |   20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 960818b..21051fc 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3373,6 +3373,8 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
 
 static int btrfs_setsize(struct inode *inode, loff_t newsize)
 {
+	struct btrfs_root *root = BTRFS_I(inode)->root;
+	struct btrfs_trans_handle *trans;
 	loff_t oldsize = i_size_read(inode);
 	int ret;
 
@@ -3380,16 +3382,22 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize)
 		return 0;
 
 	if (newsize > oldsize) {
-		i_size_write(inode, newsize);
-		btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL);
-		truncate_pagecache(inode, oldsize, newsize);
 		ret = btrfs_cont_expand(inode, oldsize, newsize);
-		if (ret) {
-			btrfs_setsize(inode, oldsize);
+		if (ret)
 			return ret;
+
+		truncate_setsize(inode, newsize);
+
+		trans = btrfs_start_transaction(root, 1);
+		if (IS_ERR(trans)) {
+			truncate_setsize(inode, oldsize);
+			return PTR_ERR(trans);
 		}
 
-		mark_inode_dirty(inode);
+		btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL);
+		ret = btrfs_update_inode(trans, root, inode);
+
+		btrfs_end_transaction_throttle(trans, root);
 	} else {
 
 		/*
-- 
1.7.6.4

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

end of thread, other threads:[~2011-12-15  9:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-14  7:15 [PATCH 2/2] Btrfs: fix wrong i_size when truncating a file to a larger size Miao Xie
2011-12-14 16:51 ` Chris Mason
2011-12-15  6:02   ` Miao Xie
2011-12-15  9:55   ` [PATCH V2 " Miao Xie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).