aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/page-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/page-io.c')
-rw-r--r--fs/ext4/page-io.c85
1 files changed, 26 insertions, 59 deletions
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 0016fbca2a40..809b31003ecc 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -23,6 +23,7 @@
23#include <linux/workqueue.h> 23#include <linux/workqueue.h>
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/mm.h>
26 27
27#include "ext4_jbd2.h" 28#include "ext4_jbd2.h"
28#include "xattr.h" 29#include "xattr.h"
@@ -73,8 +74,6 @@ void ext4_free_io_end(ext4_io_end_t *io)
73 BUG_ON(!list_empty(&io->list)); 74 BUG_ON(!list_empty(&io->list));
74 BUG_ON(io->flag & EXT4_IO_END_UNWRITTEN); 75 BUG_ON(io->flag & EXT4_IO_END_UNWRITTEN);
75 76
76 if (io->page)
77 put_page(io->page);
78 for (i = 0; i < io->num_io_pages; i++) 77 for (i = 0; i < io->num_io_pages; i++)
79 put_io_page(io->pages[i]); 78 put_io_page(io->pages[i]);
80 io->num_io_pages = 0; 79 io->num_io_pages = 0;
@@ -103,14 +102,13 @@ static int ext4_end_io(ext4_io_end_t *io)
103 "(inode %lu, offset %llu, size %zd, error %d)", 102 "(inode %lu, offset %llu, size %zd, error %d)",
104 inode->i_ino, offset, size, ret); 103 inode->i_ino, offset, size, ret);
105 } 104 }
106 if (io->iocb)
107 aio_complete(io->iocb, io->result, 0);
108
109 if (io->flag & EXT4_IO_END_DIRECT)
110 inode_dio_done(inode);
111 /* Wake up anyone waiting on unwritten extent conversion */ 105 /* Wake up anyone waiting on unwritten extent conversion */
112 if (atomic_dec_and_test(&EXT4_I(inode)->i_unwritten)) 106 if (atomic_dec_and_test(&EXT4_I(inode)->i_unwritten))
113 wake_up_all(ext4_ioend_wq(inode)); 107 wake_up_all(ext4_ioend_wq(inode));
108 if (io->flag & EXT4_IO_END_DIRECT)
109 inode_dio_done(inode);
110 if (io->iocb)
111 aio_complete(io->iocb, io->result, 0);
114 return ret; 112 return ret;
115} 113}
116 114
@@ -119,7 +117,6 @@ static void dump_completed_IO(struct inode *inode)
119#ifdef EXT4FS_DEBUG 117#ifdef EXT4FS_DEBUG
120 struct list_head *cur, *before, *after; 118 struct list_head *cur, *before, *after;
121 ext4_io_end_t *io, *io0, *io1; 119 ext4_io_end_t *io, *io0, *io1;
122 unsigned long flags;
123 120
124 if (list_empty(&EXT4_I(inode)->i_completed_io_list)) { 121 if (list_empty(&EXT4_I(inode)->i_completed_io_list)) {
125 ext4_debug("inode %lu completed_io list is empty\n", 122 ext4_debug("inode %lu completed_io list is empty\n",
@@ -152,26 +149,20 @@ void ext4_add_complete_io(ext4_io_end_t *io_end)
152 wq = EXT4_SB(io_end->inode->i_sb)->dio_unwritten_wq; 149 wq = EXT4_SB(io_end->inode->i_sb)->dio_unwritten_wq;
153 150
154 spin_lock_irqsave(&ei->i_completed_io_lock, flags); 151 spin_lock_irqsave(&ei->i_completed_io_lock, flags);
155 if (list_empty(&ei->i_completed_io_list)) { 152 if (list_empty(&ei->i_completed_io_list))
156 io_end->flag |= EXT4_IO_END_QUEUED; 153 queue_work(wq, &ei->i_unwritten_work);
157 queue_work(wq, &io_end->work);
158 }
159 list_add_tail(&io_end->list, &ei->i_completed_io_list); 154 list_add_tail(&io_end->list, &ei->i_completed_io_list);
160 spin_unlock_irqrestore(&ei->i_completed_io_lock, flags); 155 spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
161} 156}
162 157
163static int ext4_do_flush_completed_IO(struct inode *inode, 158static int ext4_do_flush_completed_IO(struct inode *inode)
164 ext4_io_end_t *work_io)
165{ 159{
166 ext4_io_end_t *io; 160 ext4_io_end_t *io;
167 struct list_head unwritten, complete, to_free; 161 struct list_head unwritten;
168 unsigned long flags; 162 unsigned long flags;
169 struct ext4_inode_info *ei = EXT4_I(inode); 163 struct ext4_inode_info *ei = EXT4_I(inode);
170 int err, ret = 0; 164 int err, ret = 0;
171 165
172 INIT_LIST_HEAD(&complete);
173 INIT_LIST_HEAD(&to_free);
174
175 spin_lock_irqsave(&ei->i_completed_io_lock, flags); 166 spin_lock_irqsave(&ei->i_completed_io_lock, flags);
176 dump_completed_IO(inode); 167 dump_completed_IO(inode);
177 list_replace_init(&ei->i_completed_io_list, &unwritten); 168 list_replace_init(&ei->i_completed_io_list, &unwritten);
@@ -185,32 +176,7 @@ static int ext4_do_flush_completed_IO(struct inode *inode,
185 err = ext4_end_io(io); 176 err = ext4_end_io(io);
186 if (unlikely(!ret && err)) 177 if (unlikely(!ret && err))
187 ret = err; 178 ret = err;
188
189 list_add_tail(&io->list, &complete);
190 }
191 spin_lock_irqsave(&ei->i_completed_io_lock, flags);
192 while (!list_empty(&complete)) {
193 io = list_entry(complete.next, ext4_io_end_t, list);
194 io->flag &= ~EXT4_IO_END_UNWRITTEN; 179 io->flag &= ~EXT4_IO_END_UNWRITTEN;
195 /* end_io context can not be destroyed now because it still
196 * used by queued worker. Worker thread will destroy it later */
197 if (io->flag & EXT4_IO_END_QUEUED)
198 list_del_init(&io->list);
199 else
200 list_move(&io->list, &to_free);
201 }
202 /* If we are called from worker context, it is time to clear queued
203 * flag, and destroy it's end_io if it was converted already */
204 if (work_io) {
205 work_io->flag &= ~EXT4_IO_END_QUEUED;
206 if (!(work_io->flag & EXT4_IO_END_UNWRITTEN))
207 list_add_tail(&work_io->list, &to_free);
208 }
209 spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
210
211 while (!list_empty(&to_free)) {
212 io = list_entry(to_free.next, ext4_io_end_t, list);
213 list_del_init(&io->list);
214 ext4_free_io_end(io); 180 ext4_free_io_end(io);
215 } 181 }
216 return ret; 182 return ret;
@@ -219,10 +185,11 @@ static int ext4_do_flush_completed_IO(struct inode *inode,
219/* 185/*
220 * work on completed aio dio IO, to convert unwritten extents to extents 186 * work on completed aio dio IO, to convert unwritten extents to extents
221 */ 187 */
222static void ext4_end_io_work(struct work_struct *work) 188void ext4_end_io_work(struct work_struct *work)
223{ 189{
224 ext4_io_end_t *io = container_of(work, ext4_io_end_t, work); 190 struct ext4_inode_info *ei = container_of(work, struct ext4_inode_info,
225 ext4_do_flush_completed_IO(io->inode, io); 191 i_unwritten_work);
192 ext4_do_flush_completed_IO(&ei->vfs_inode);
226} 193}
227 194
228int ext4_flush_unwritten_io(struct inode *inode) 195int ext4_flush_unwritten_io(struct inode *inode)
@@ -230,7 +197,7 @@ int ext4_flush_unwritten_io(struct inode *inode)
230 int ret; 197 int ret;
231 WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex) && 198 WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex) &&
232 !(inode->i_state & I_FREEING)); 199 !(inode->i_state & I_FREEING));
233 ret = ext4_do_flush_completed_IO(inode, NULL); 200 ret = ext4_do_flush_completed_IO(inode);
234 ext4_unwritten_wait(inode); 201 ext4_unwritten_wait(inode);
235 return ret; 202 return ret;
236} 203}
@@ -241,7 +208,6 @@ ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
241 if (io) { 208 if (io) {
242 atomic_inc(&EXT4_I(inode)->i_ioend_count); 209 atomic_inc(&EXT4_I(inode)->i_ioend_count);
243 io->inode = inode; 210 io->inode = inode;
244 INIT_WORK(&io->work, ext4_end_io_work);
245 INIT_LIST_HEAD(&io->list); 211 INIT_LIST_HEAD(&io->list);
246 } 212 }
247 return io; 213 return io;
@@ -382,14 +348,6 @@ static int io_submit_add_bh(struct ext4_io_submit *io,
382 unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr); 348 unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
383 } 349 }
384 350
385 if (!buffer_mapped(bh) || buffer_delay(bh)) {
386 if (!buffer_mapped(bh))
387 clear_buffer_dirty(bh);
388 if (io->io_bio)
389 ext4_io_submit(io);
390 return 0;
391 }
392
393 if (io->io_bio && bh->b_blocknr != io->io_next_block) { 351 if (io->io_bio && bh->b_blocknr != io->io_next_block) {
394submit_and_retry: 352submit_and_retry:
395 ext4_io_submit(io); 353 ext4_io_submit(io);
@@ -436,7 +394,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
436 394
437 io_page = kmem_cache_alloc(io_page_cachep, GFP_NOFS); 395 io_page = kmem_cache_alloc(io_page_cachep, GFP_NOFS);
438 if (!io_page) { 396 if (!io_page) {
439 set_page_dirty(page); 397 redirty_page_for_writepage(wbc, page);
440 unlock_page(page); 398 unlock_page(page);
441 return -ENOMEM; 399 return -ENOMEM;
442 } 400 }
@@ -468,7 +426,15 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
468 set_buffer_uptodate(bh); 426 set_buffer_uptodate(bh);
469 continue; 427 continue;
470 } 428 }
471 clear_buffer_dirty(bh); 429 if (!buffer_dirty(bh) || buffer_delay(bh) ||
430 !buffer_mapped(bh) || buffer_unwritten(bh)) {
431 /* A hole? We can safely clear the dirty bit */
432 if (!buffer_mapped(bh))
433 clear_buffer_dirty(bh);
434 if (io->io_bio)
435 ext4_io_submit(io);
436 continue;
437 }
472 ret = io_submit_add_bh(io, io_page, inode, wbc, bh); 438 ret = io_submit_add_bh(io, io_page, inode, wbc, bh);
473 if (ret) { 439 if (ret) {
474 /* 440 /*
@@ -476,9 +442,10 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
476 * we can do but mark the page as dirty, and 442 * we can do but mark the page as dirty, and
477 * better luck next time. 443 * better luck next time.
478 */ 444 */
479 set_page_dirty(page); 445 redirty_page_for_writepage(wbc, page);
480 break; 446 break;
481 } 447 }
448 clear_buffer_dirty(bh);
482 } 449 }
483 unlock_page(page); 450 unlock_page(page);
484 /* 451 /*