aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/ext4.h2
-rw-r--r--fs/ext4/inode.c4
-rw-r--r--fs/ext4/page-io.c12
3 files changed, 14 insertions, 4 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 167ff564bbfa..3b83cd604796 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2617,7 +2617,7 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp,
2617extern int __init ext4_init_pageio(void); 2617extern int __init ext4_init_pageio(void);
2618extern void ext4_add_complete_io(ext4_io_end_t *io_end); 2618extern void ext4_add_complete_io(ext4_io_end_t *io_end);
2619extern void ext4_exit_pageio(void); 2619extern void ext4_exit_pageio(void);
2620extern void ext4_ioend_wait(struct inode *); 2620extern void ext4_ioend_shutdown(struct inode *);
2621extern void ext4_free_io_end(ext4_io_end_t *io); 2621extern void ext4_free_io_end(ext4_io_end_t *io);
2622extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags); 2622extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags);
2623extern void ext4_end_io_work(struct work_struct *work); 2623extern void ext4_end_io_work(struct work_struct *work);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 65bbc9339aca..ea5f24ffa60c 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -185,8 +185,6 @@ void ext4_evict_inode(struct inode *inode)
185 185
186 trace_ext4_evict_inode(inode); 186 trace_ext4_evict_inode(inode);
187 187
188 ext4_ioend_wait(inode);
189
190 if (inode->i_nlink) { 188 if (inode->i_nlink) {
191 /* 189 /*
192 * When journalling data dirty buffers are tracked only in the 190 * When journalling data dirty buffers are tracked only in the
@@ -216,6 +214,7 @@ void ext4_evict_inode(struct inode *inode)
216 filemap_write_and_wait(&inode->i_data); 214 filemap_write_and_wait(&inode->i_data);
217 } 215 }
218 truncate_inode_pages(&inode->i_data, 0); 216 truncate_inode_pages(&inode->i_data, 0);
217 ext4_ioend_shutdown(inode);
219 goto no_delete; 218 goto no_delete;
220 } 219 }
221 220
@@ -225,6 +224,7 @@ void ext4_evict_inode(struct inode *inode)
225 if (ext4_should_order_data(inode)) 224 if (ext4_should_order_data(inode))
226 ext4_begin_ordered_truncate(inode, 0); 225 ext4_begin_ordered_truncate(inode, 0);
227 truncate_inode_pages(&inode->i_data, 0); 226 truncate_inode_pages(&inode->i_data, 0);
227 ext4_ioend_shutdown(inode);
228 228
229 if (is_bad_inode(inode)) 229 if (is_bad_inode(inode))
230 goto no_delete; 230 goto no_delete;
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 809b31003ecc..047a6de04a0a 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -50,11 +50,21 @@ void ext4_exit_pageio(void)
50 kmem_cache_destroy(io_page_cachep); 50 kmem_cache_destroy(io_page_cachep);
51} 51}
52 52
53void ext4_ioend_wait(struct inode *inode) 53/*
54 * This function is called by ext4_evict_inode() to make sure there is
55 * no more pending I/O completion work left to do.
56 */
57void ext4_ioend_shutdown(struct inode *inode)
54{ 58{
55 wait_queue_head_t *wq = ext4_ioend_wq(inode); 59 wait_queue_head_t *wq = ext4_ioend_wq(inode);
56 60
57 wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0)); 61 wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0));
62 /*
63 * We need to make sure the work structure is finished being
64 * used before we let the inode get destroyed.
65 */
66 if (work_pending(&EXT4_I(inode)->i_unwritten_work))
67 cancel_work_sync(&EXT4_I(inode)->i_unwritten_work);
58} 68}
59 69
60static void put_io_page(struct ext4_io_page *io_page) 70static void put_io_page(struct ext4_io_page *io_page)