| From stable-bounces@linux.kernel.org Tue Jun 9 02:26:29 2009 |
| From: "Theodore Ts'o" <tytso@mit.edu> |
| Date: Tue, 2 Jun 2009 08:07:47 -0400 |
| Subject: ext4: Automatically allocate delay allocated blocks on close |
| To: stable@kernel.org |
| Cc: linux-ext4@vger.kernel.org, "Theodore Ts'o" <tytso@mit.edu> |
| Message-ID: <1243944479-20574-6-git-send-email-tytso@mit.edu> |
| |
| From: "Theodore Ts'o" <tytso@mit.edu> |
| |
| (cherry picked from commit 7d8f9f7d150dded7b68e61ca6403a1f166fb4edf) |
| |
| When closing a file that had been previously truncated, force any |
| delay allocated blocks that to be allocated so that if the filesystem |
| is mounted with data=ordered, the data blocks will be pushed out to |
| disk along with the journal commit. Many application programs expect |
| this, so we do this to avoid zero length files if the system crashes |
| unexpectedly. |
| |
| Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| --- |
| fs/ext4/ext4.h | 1 + |
| fs/ext4/file.c | 4 ++++ |
| fs/ext4/inode.c | 3 +++ |
| 3 files changed, 8 insertions(+) |
| |
| --- a/fs/ext4/ext4.h |
| +++ b/fs/ext4/ext4.h |
| @@ -279,6 +279,7 @@ static inline __u32 ext4_mask_flags(umod |
| #define EXT4_STATE_NEW 0x00000002 /* inode is newly created */ |
| #define EXT4_STATE_XATTR 0x00000004 /* has in-inode xattrs */ |
| #define EXT4_STATE_NO_EXPAND 0x00000008 /* No space for expansion */ |
| +#define EXT4_STATE_DA_ALLOC_CLOSE 0x00000010 /* Alloc DA blks on close */ |
| |
| /* Used to pass group descriptor data when online resize is done */ |
| struct ext4_new_group_input { |
| --- a/fs/ext4/file.c |
| +++ b/fs/ext4/file.c |
| @@ -33,6 +33,10 @@ |
| */ |
| static int ext4_release_file(struct inode *inode, struct file *filp) |
| { |
| + if (EXT4_I(inode)->i_state & EXT4_STATE_DA_ALLOC_CLOSE) { |
| + ext4_alloc_da_blocks(inode); |
| + EXT4_I(inode)->i_state &= ~EXT4_STATE_DA_ALLOC_CLOSE; |
| + } |
| /* if we are the last writer on the inode, drop the block reservation */ |
| if ((filp->f_mode & FMODE_WRITE) && |
| (atomic_read(&inode->i_writecount) == 1)) |
| --- a/fs/ext4/inode.c |
| +++ b/fs/ext4/inode.c |
| @@ -3880,6 +3880,9 @@ void ext4_truncate(struct inode *inode) |
| if (!ext4_can_truncate(inode)) |
| return; |
| |
| + if (inode->i_size == 0) |
| + ei->i_state |= EXT4_STATE_DA_ALLOC_CLOSE; |
| + |
| if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { |
| ext4_ext_truncate(inode); |
| return; |