>From 55bde5feb7aa94812b82de615db4effee12bc196 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 16 Jun 2016 10:22:50 +0200 Subject: [PATCH 1/2] Revert "ext4: remove i_ioend_count" This reverts commit 600be30a8bc1d405f791e01dbef84679e14529b8. --- fs/ext4/ext4.h | 7 ++++++- fs/ext4/inode.c | 3 +++ fs/ext4/page-io.c | 4 ++++ fs/ext4/super.c | 1 + 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index b84aa1ca480a..d64fc259590f 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1063,8 +1063,13 @@ struct ext4_inode_info { * transaction reserved */ struct list_head i_rsv_conversion_list; - struct work_struct i_rsv_conversion_work; + /* + * Completed IOs that need unwritten extents handling and don't have + * transaction reserved + */ + atomic_t i_ioend_count; /* Number of outstanding io_end structs */ atomic_t i_unwritten; /* Nr. of inflight conversions pending */ + struct work_struct i_rsv_conversion_work; spinlock_t i_block_reservation_lock; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index f7140ca66e3b..cb00e5949bc3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -216,6 +216,7 @@ void ext4_evict_inode(struct inode *inode) } truncate_inode_pages_final(&inode->i_data); + WARN_ON(atomic_read(&EXT4_I(inode)->i_ioend_count)); goto no_delete; } @@ -227,6 +228,8 @@ void ext4_evict_inode(struct inode *inode) ext4_begin_ordered_truncate(inode, 0); truncate_inode_pages_final(&inode->i_data); + WARN_ON(atomic_read(&EXT4_I(inode)->i_ioend_count)); + /* * Protect us against freezing - iput() caller didn't have to have any * protection against it diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 2a01df9cc1c3..cc5f529e328e 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -129,6 +129,9 @@ static void ext4_release_io_end(ext4_io_end_t *io_end) BUG_ON(io_end->flag & EXT4_IO_END_UNWRITTEN); WARN_ON(io_end->handle); + if (atomic_dec_and_test(&EXT4_I(io_end->inode)->i_ioend_count)) + wake_up_all(ext4_ioend_wq(io_end->inode)); + for (bio = io_end->bio; bio; bio = next_bio) { next_bio = bio->bi_private; ext4_finish_bio(bio); @@ -253,6 +256,7 @@ ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags) { ext4_io_end_t *io = kmem_cache_zalloc(io_end_cachep, flags); if (io) { + atomic_inc(&EXT4_I(inode)->i_ioend_count); io->inode = inode; INIT_LIST_HEAD(&io->list); atomic_set(&io->count, 1); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 3822a5aedc61..221ec29afde6 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -943,6 +943,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) spin_lock_init(&ei->i_completed_io_lock); ei->i_sync_tid = 0; ei->i_datasync_tid = 0; + atomic_set(&ei->i_ioend_count, 0); atomic_set(&ei->i_unwritten, 0); INIT_WORK(&ei->i_rsv_conversion_work, ext4_end_io_rsv_work); #ifdef CONFIG_EXT4_FS_ENCRYPTION -- 2.6.6