Commit f7ab34ea authored by Theodore Ts'o's avatar Theodore Ts'o

ext3: Add replace-on-truncate hueristics for data=writeback mode

In data=writeback mode, start an asynchronous flush when closing a
file which had been previously truncated down to zero.  This lowers
the probability of data loss in the case of applications that attempt
to replace a file using truncate.
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 512a0043
...@@ -33,6 +33,10 @@ ...@@ -33,6 +33,10 @@
*/ */
static int ext3_release_file (struct inode * inode, struct file * filp) static int ext3_release_file (struct inode * inode, struct file * filp)
{ {
if (EXT3_I(inode)->i_state & EXT3_STATE_FLUSH_ON_CLOSE) {
filemap_flush(inode->i_mapping);
EXT3_I(inode)->i_state &= ~EXT3_STATE_FLUSH_ON_CLOSE;
}
/* if we are the last writer on the inode, drop the block reservation */ /* if we are the last writer on the inode, drop the block reservation */
if ((filp->f_mode & FMODE_WRITE) && if ((filp->f_mode & FMODE_WRITE) &&
(atomic_read(&inode->i_writecount) == 1)) (atomic_read(&inode->i_writecount) == 1))
......
...@@ -2346,6 +2346,9 @@ void ext3_truncate(struct inode *inode) ...@@ -2346,6 +2346,9 @@ void ext3_truncate(struct inode *inode)
if (!ext3_can_truncate(inode)) if (!ext3_can_truncate(inode))
return; return;
if (inode->i_size == 0 && ext3_should_writeback_data(inode))
ei->i_state |= EXT3_STATE_FLUSH_ON_CLOSE;
/* /*
* We have to lock the EOF page here, because lock_page() nests * We have to lock the EOF page here, because lock_page() nests
* outside journal_start(). * outside journal_start().
......
...@@ -208,6 +208,7 @@ static inline __u32 ext3_mask_flags(umode_t mode, __u32 flags) ...@@ -208,6 +208,7 @@ static inline __u32 ext3_mask_flags(umode_t mode, __u32 flags)
#define EXT3_STATE_JDATA 0x00000001 /* journaled data exists */ #define EXT3_STATE_JDATA 0x00000001 /* journaled data exists */
#define EXT3_STATE_NEW 0x00000002 /* inode is newly created */ #define EXT3_STATE_NEW 0x00000002 /* inode is newly created */
#define EXT3_STATE_XATTR 0x00000004 /* has in-inode xattrs */ #define EXT3_STATE_XATTR 0x00000004 /* has in-inode xattrs */
#define EXT3_STATE_FLUSH_ON_CLOSE 0x00000008
/* Used to pass group descriptor data when online resize is done */ /* Used to pass group descriptor data when online resize is done */
struct ext3_new_group_input { struct ext3_new_group_input {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment