summaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorMingming Cao <cmm@us.ibm.com>2009-09-28 21:48:29 +0200
committerTheodore Ts'o <tytso@mit.edu>2009-09-28 21:48:29 +0200
commit8d5d02e6b176565c77ff03604908b1453a22044d (patch)
tree0d29e4f28233f24960c7921c1c0a7608077bf713 /fs/ext4/super.c
parentext4: Use end_io callback to avoid direct I/O fallback to buffered I/O (diff)
downloadlinux-8d5d02e6b176565c77ff03604908b1453a22044d.tar.xz
linux-8d5d02e6b176565c77ff03604908b1453a22044d.zip
ext4: async direct IO for holes and fallocate support
For async direct IO that covers holes or fallocate, the end_io callback function now queued the convertion work on workqueue but don't flush the work rightaway as it might take too long to afford. But when fsync is called after all the data is completed, user expects the metadata also being updated before fsync returns. Thus we need to flush the conversion work when fsync() is called. This patch keep track of a listed of completed async direct io that has a work queued on workqueue. When fsync() is called, it will go through the list and do the conversion. Signed-off-by: Mingming Cao <cmm@us.ibm.com>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 1a03ea98fdd1..f095c60b569e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -687,6 +687,8 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
ei->i_allocated_meta_blocks = 0;
ei->i_delalloc_reserved_flag = 0;
spin_lock_init(&(ei->i_block_reservation_lock));
+ INIT_LIST_HEAD(&ei->i_aio_dio_complete_list);
+ ei->cur_aio_dio = NULL;
return &ei->vfs_inode;
}
@@ -3375,11 +3377,13 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
{
int ret = 0;
tid_t target;
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
trace_ext4_sync_fs(sb, wait);
- if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) {
+ flush_workqueue(sbi->dio_unwritten_wq);
+ if (jbd2_journal_start_commit(sbi->s_journal, &target)) {
if (wait)
- jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target);
+ jbd2_log_wait_commit(sbi->s_journal, target);
}
return ret;
}