Btrfs: fix wrong i_size when truncating a file to a larger size
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> Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
5dbc8fca8e
commit
f4a2f4c548
|
@ -3370,6 +3370,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;
|
||||
|
||||
|
@ -3377,16 +3379,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 {
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue