Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1763190AbZANPNE (ORCPT ); Wed, 14 Jan 2009 10:13:04 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1757906AbZANPMd (ORCPT ); Wed, 14 Jan 2009 10:12:33 -0500 Received: from styx.suse.cz ([82.119.242.94]:56986 "EHLO mail.suse.cz" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753024AbZANPMa (ORCPT ); Wed, 14 Jan 2009 10:12:30 -0500 From: Jan Kara To: linux-ext4@vger.kernel.org Cc: Andrew Morton , linux-kernel@vger.kernel.org, Jan Kara , pavel@suse.cz Subject: [PATCH 2/2] ext2: Add blk_issue_flush() to syncing paths Date: Wed, 14 Jan 2009 16:12:28 +0100 Message-Id: <1231945948-23676-2-git-send-email-jack@suse.cz> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1231945948-23676-1-git-send-email-jack@suse.cz> References: <1231945948-23676-1-git-send-email-jack@suse.cz> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3951 Lines: 140 To be really safe that the data hit the platter, we should also flush drive's writeback caches on fsync and for O_SYNC files or O_DIRSYNC inodes. Signed-off-by: Jan Kara CC: pavel@suse.cz --- fs/ext2/dir.c | 5 ++++- fs/ext2/fsync.c | 7 +++++-- fs/ext2/inode.c | 7 +++++++ fs/ext2/xattr.c | 6 +++++- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 2999d72..d6cb59f 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -25,6 +25,7 @@ #include #include #include +#include /* for blkdev_issue_flush() */ typedef struct ext2_dir_entry_2 ext2_dirent; @@ -97,8 +98,10 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len) if (IS_DIRSYNC(dir)) { err = write_one_page(page, 1); - if (!err) + if (!err) { err = ext2_sync_inode(dir); + blkdev_issue_flush(dir->i_sb->s_bdev, NULL); + } } else { unlock_page(page); } diff --git a/fs/ext2/fsync.c b/fs/ext2/fsync.c index fc66c93..9cd1838 100644 --- a/fs/ext2/fsync.c +++ b/fs/ext2/fsync.c @@ -24,6 +24,7 @@ #include "ext2.h" #include /* for sync_mapping_buffers() */ +#include /* for blkdev_issue_flush() */ /* @@ -39,12 +40,14 @@ int ext2_sync_file(struct file *file, struct dentry *dentry, int datasync) ret = sync_mapping_buffers(inode->i_mapping); if (!(inode->i_state & I_DIRTY)) - return ret; + goto out; if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) - return ret; + goto out; err = ext2_sync_inode(inode); if (ret == 0) ret = err; +out: + blkdev_issue_flush(inode->i_sb->s_bdev, NULL); return ret; } diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 23fff2f..49b479e 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -33,6 +33,7 @@ #include #include #include +#include /* for blkdev_issue_flush() */ #include "ext2.h" #include "acl.h" #include "xip.h" @@ -68,9 +69,14 @@ void ext2_delete_inode (struct inode * inode) mark_inode_dirty(inode); ext2_update_inode(inode, inode_needs_sync(inode)); + /* Make sure inode deletion really gets to disk. Disk write caches + * are flushed either in ext2_truncate() or we do it explicitly */ inode->i_size = 0; if (inode->i_blocks) ext2_truncate (inode); + else if (inode_needs_sync(inode)) + blkdev_issue_flush(inode->i_sb->s_bdev, NULL); + ext2_free_inode (inode); return; @@ -1104,6 +1110,7 @@ do_indirects: if (inode_needs_sync(inode)) { sync_mapping_buffers(inode->i_mapping); ext2_sync_inode (inode); + blkdev_issue_flush(inode->i_sb->s_bdev, NULL); } else { mark_inode_dirty(inode); } diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 987a526..d480216 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -60,6 +60,7 @@ #include #include #include +#include /* for blkdev_issue_flush() */ #include "ext2.h" #include "xattr.h" #include "acl.h" @@ -702,6 +703,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, DQUOT_FREE_BLOCK(inode, 1); goto cleanup; } + blkdev_issue_flush(sb->s_bdev, NULL); } else mark_inode_dirty(inode); @@ -792,8 +794,10 @@ ext2_xattr_delete_inode(struct inode *inode) le32_to_cpu(HDR(bh)->h_refcount)); unlock_buffer(bh); mark_buffer_dirty(bh); - if (IS_SYNC(inode)) + if (IS_SYNC(inode)) { sync_dirty_buffer(bh); + blkdev_issue_flush(inode->i_sb->s_bdev, NULL); + } DQUOT_FREE_BLOCK(inode, 1); } EXT2_I(inode)->i_file_acl = 0; -- 1.6.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/