ext3: Add replace-on-rename hueristics for data=writeback mode
authorTheodore Ts'o <tytso@mit.edu>
Fri, 3 Apr 2009 05:34:49 +0000 (01:34 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 3 Apr 2009 05:34:49 +0000 (01:34 -0400)
In data=writeback mode, start an asynchronous flush when renaming a
file on top of an already-existing file.  This lowers the probability
of data loss in the case of applications that attempt to replace a
file via using rename().

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
fs/ext3/namei.c

index 4db4ffa1edad2f54c5b5de0d8c80ee26f83bb20b..ab98a66ab8c76b15c0b68f68dfbcf0f0f8d64fd4 100644 (file)
@@ -2265,7 +2265,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
        struct inode * old_inode, * new_inode;
        struct buffer_head * old_bh, * new_bh, * dir_bh;
        struct ext3_dir_entry_2 * old_de, * new_de;
-       int retval;
+       int retval, flush_file = 0;
 
        old_bh = new_bh = dir_bh = NULL;
 
@@ -2401,6 +2401,8 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
                ext3_mark_inode_dirty(handle, new_inode);
                if (!new_inode->i_nlink)
                        ext3_orphan_add(handle, new_inode);
+               if (ext3_should_writeback_data(new_inode))
+                       flush_file = 1;
        }
        retval = 0;
 
@@ -2409,6 +2411,8 @@ end_rename:
        brelse (old_bh);
        brelse (new_bh);
        ext3_journal_stop(handle);
+       if (retval == 0 && flush_file)
+               filemap_flush(old_inode->i_mapping);
        return retval;
 }