diff options
author | Jiaying Zhang <jiayingz@google.com> | 2010-02-24 09:52:53 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2010-02-24 09:52:53 -0500 |
commit | c8d46e41bc744c8fa0092112af3942fcd46c8b18 (patch) | |
tree | fd8bad55c3c9903b6c798b838396bc832bbf7f4b /fs/ext4/inode.c | |
parent | 73b50c1c92666d326b5fa2c945d46509f2f6d91f (diff) |
ext4: Add flag to files with blocks intentionally past EOF
fallocate() may potentially instantiate blocks past EOF, depending
on the flags used when it is called.
e2fsck currently has a test for blocks past i_size, and it
sometimes trips up - noticeably on xfstests 013 which runs fsstress.
This patch from Jiayang does fix it up - it (along with
e2fsprogs updates and other patches recently from Aneesh) has
survived many fsstress runs in a row.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Jiaying Zhang <jiayingz@google.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ecac8c5a6f5c..edb7edc99f71 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -4456,6 +4456,8 @@ void ext4_truncate(struct inode *inode) | |||
4456 | if (!ext4_can_truncate(inode)) | 4456 | if (!ext4_can_truncate(inode)) |
4457 | return; | 4457 | return; |
4458 | 4458 | ||
4459 | EXT4_I(inode)->i_flags &= ~EXT4_EOFBLOCKS_FL; | ||
4460 | |||
4459 | if (inode->i_size == 0 && !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC)) | 4461 | if (inode->i_size == 0 && !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC)) |
4460 | ext4_set_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE); | 4462 | ext4_set_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE); |
4461 | 4463 | ||
@@ -5305,7 +5307,9 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) | |||
5305 | } | 5307 | } |
5306 | 5308 | ||
5307 | if (S_ISREG(inode->i_mode) && | 5309 | if (S_ISREG(inode->i_mode) && |
5308 | attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) { | 5310 | attr->ia_valid & ATTR_SIZE && |
5311 | (attr->ia_size < inode->i_size || | ||
5312 | (EXT4_I(inode)->i_flags & EXT4_EOFBLOCKS_FL))) { | ||
5309 | handle_t *handle; | 5313 | handle_t *handle; |
5310 | 5314 | ||
5311 | handle = ext4_journal_start(inode, 3); | 5315 | handle = ext4_journal_start(inode, 3); |
@@ -5336,6 +5340,9 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) | |||
5336 | goto err_out; | 5340 | goto err_out; |
5337 | } | 5341 | } |
5338 | } | 5342 | } |
5343 | /* ext4_truncate will clear the flag */ | ||
5344 | if ((EXT4_I(inode)->i_flags & EXT4_EOFBLOCKS_FL)) | ||
5345 | ext4_truncate(inode); | ||
5339 | } | 5346 | } |
5340 | 5347 | ||
5341 | rc = inode_setattr(inode, attr); | 5348 | rc = inode_setattr(inode, attr); |