diff options
| -rw-r--r-- | fs/ext4/ext4_jbd2.h | 4 | ||||
| -rw-r--r-- | fs/ext4/indirect.c | 9 | ||||
| -rw-r--r-- | fs/ext4/inode.c | 26 | ||||
| -rw-r--r-- | fs/ext4/page-io.c | 6 | ||||
| -rw-r--r-- | fs/ext4/super.c | 1 |
5 files changed, 37 insertions, 9 deletions
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h index bb85757689b6..5802fa1dab18 100644 --- a/fs/ext4/ext4_jbd2.h +++ b/fs/ext4/ext4_jbd2.h | |||
| @@ -289,10 +289,10 @@ static inline int ext4_should_order_data(struct inode *inode) | |||
| 289 | 289 | ||
| 290 | static inline int ext4_should_writeback_data(struct inode *inode) | 290 | static inline int ext4_should_writeback_data(struct inode *inode) |
| 291 | { | 291 | { |
| 292 | if (!S_ISREG(inode->i_mode)) | ||
| 293 | return 0; | ||
| 294 | if (EXT4_JOURNAL(inode) == NULL) | 292 | if (EXT4_JOURNAL(inode) == NULL) |
| 295 | return 1; | 293 | return 1; |
| 294 | if (!S_ISREG(inode->i_mode)) | ||
| 295 | return 0; | ||
| 296 | if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA)) | 296 | if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA)) |
| 297 | return 0; | 297 | return 0; |
| 298 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) | 298 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) |
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c index b8602cde5b5a..0962642119c0 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c | |||
| @@ -800,12 +800,17 @@ ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb, | |||
| 800 | } | 800 | } |
| 801 | 801 | ||
| 802 | retry: | 802 | retry: |
| 803 | if (rw == READ && ext4_should_dioread_nolock(inode)) | 803 | if (rw == READ && ext4_should_dioread_nolock(inode)) { |
| 804 | if (unlikely(!list_empty(&ei->i_completed_io_list))) { | ||
| 805 | mutex_lock(&inode->i_mutex); | ||
| 806 | ext4_flush_completed_IO(inode); | ||
| 807 | mutex_unlock(&inode->i_mutex); | ||
| 808 | } | ||
| 804 | ret = __blockdev_direct_IO(rw, iocb, inode, | 809 | ret = __blockdev_direct_IO(rw, iocb, inode, |
| 805 | inode->i_sb->s_bdev, iov, | 810 | inode->i_sb->s_bdev, iov, |
| 806 | offset, nr_segs, | 811 | offset, nr_segs, |
| 807 | ext4_get_block, NULL, NULL, 0); | 812 | ext4_get_block, NULL, NULL, 0); |
| 808 | else { | 813 | } else { |
| 809 | ret = blockdev_direct_IO(rw, iocb, inode, iov, | 814 | ret = blockdev_direct_IO(rw, iocb, inode, iov, |
| 810 | offset, nr_segs, ext4_get_block); | 815 | offset, nr_segs, ext4_get_block); |
| 811 | 816 | ||
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index d47264cafee0..c4da98a959ae 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -120,6 +120,12 @@ void ext4_evict_inode(struct inode *inode) | |||
| 120 | int err; | 120 | int err; |
| 121 | 121 | ||
| 122 | trace_ext4_evict_inode(inode); | 122 | trace_ext4_evict_inode(inode); |
| 123 | |||
| 124 | mutex_lock(&inode->i_mutex); | ||
| 125 | ext4_flush_completed_IO(inode); | ||
| 126 | mutex_unlock(&inode->i_mutex); | ||
| 127 | ext4_ioend_wait(inode); | ||
| 128 | |||
| 123 | if (inode->i_nlink) { | 129 | if (inode->i_nlink) { |
| 124 | /* | 130 | /* |
| 125 | * When journalling data dirty buffers are tracked only in the | 131 | * When journalling data dirty buffers are tracked only in the |
| @@ -983,6 +989,8 @@ static int ext4_journalled_write_end(struct file *file, | |||
| 983 | from = pos & (PAGE_CACHE_SIZE - 1); | 989 | from = pos & (PAGE_CACHE_SIZE - 1); |
| 984 | to = from + len; | 990 | to = from + len; |
| 985 | 991 | ||
| 992 | BUG_ON(!ext4_handle_valid(handle)); | ||
| 993 | |||
| 986 | if (copied < len) { | 994 | if (copied < len) { |
| 987 | if (!PageUptodate(page)) | 995 | if (!PageUptodate(page)) |
| 988 | copied = 0; | 996 | copied = 0; |
| @@ -1283,7 +1291,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, | |||
| 1283 | else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT)) | 1291 | else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT)) |
| 1284 | err = ext4_bio_write_page(&io_submit, page, | 1292 | err = ext4_bio_write_page(&io_submit, page, |
| 1285 | len, mpd->wbc); | 1293 | len, mpd->wbc); |
| 1286 | else | 1294 | else if (buffer_uninit(page_bufs)) { |
| 1295 | ext4_set_bh_endio(page_bufs, inode); | ||
| 1296 | err = block_write_full_page_endio(page, | ||
| 1297 | noalloc_get_block_write, | ||
| 1298 | mpd->wbc, ext4_end_io_buffer_write); | ||
| 1299 | } else | ||
| 1287 | err = block_write_full_page(page, | 1300 | err = block_write_full_page(page, |
| 1288 | noalloc_get_block_write, mpd->wbc); | 1301 | noalloc_get_block_write, mpd->wbc); |
| 1289 | 1302 | ||
| @@ -1699,6 +1712,8 @@ static int __ext4_journalled_writepage(struct page *page, | |||
| 1699 | goto out; | 1712 | goto out; |
| 1700 | } | 1713 | } |
| 1701 | 1714 | ||
| 1715 | BUG_ON(!ext4_handle_valid(handle)); | ||
| 1716 | |||
| 1702 | ret = walk_page_buffers(handle, page_bufs, 0, len, NULL, | 1717 | ret = walk_page_buffers(handle, page_bufs, 0, len, NULL, |
| 1703 | do_journal_get_write_access); | 1718 | do_journal_get_write_access); |
| 1704 | 1719 | ||
| @@ -2668,8 +2683,15 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate) | |||
| 2668 | goto out; | 2683 | goto out; |
| 2669 | } | 2684 | } |
| 2670 | 2685 | ||
| 2671 | io_end->flag = EXT4_IO_END_UNWRITTEN; | 2686 | /* |
| 2687 | * It may be over-defensive here to check EXT4_IO_END_UNWRITTEN now, | ||
| 2688 | * but being more careful is always safe for the future change. | ||
| 2689 | */ | ||
| 2672 | inode = io_end->inode; | 2690 | inode = io_end->inode; |
| 2691 | if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) { | ||
| 2692 | io_end->flag |= EXT4_IO_END_UNWRITTEN; | ||
| 2693 | atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten); | ||
| 2694 | } | ||
| 2673 | 2695 | ||
| 2674 | /* Add the io_end to per-inode completed io list*/ | 2696 | /* Add the io_end to per-inode completed io list*/ |
| 2675 | spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags); | 2697 | spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags); |
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 430c401d0895..78839af7ce29 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
| @@ -334,8 +334,10 @@ submit_and_retry: | |||
| 334 | if ((io_end->num_io_pages >= MAX_IO_PAGES) && | 334 | if ((io_end->num_io_pages >= MAX_IO_PAGES) && |
| 335 | (io_end->pages[io_end->num_io_pages-1] != io_page)) | 335 | (io_end->pages[io_end->num_io_pages-1] != io_page)) |
| 336 | goto submit_and_retry; | 336 | goto submit_and_retry; |
| 337 | if (buffer_uninit(bh)) | 337 | if (buffer_uninit(bh) && !(io_end->flag & EXT4_IO_END_UNWRITTEN)) { |
| 338 | io->io_end->flag |= EXT4_IO_END_UNWRITTEN; | 338 | io_end->flag |= EXT4_IO_END_UNWRITTEN; |
| 339 | atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten); | ||
| 340 | } | ||
| 339 | io->io_end->size += bh->b_size; | 341 | io->io_end->size += bh->b_size; |
| 340 | io->io_next_block++; | 342 | io->io_next_block++; |
| 341 | ret = bio_add_page(io->io_bio, bh->b_page, bh->b_size, bh_offset(bh)); | 343 | ret = bio_add_page(io->io_bio, bh->b_page, bh->b_size, bh_offset(bh)); |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 4687fea0c00f..44d0c8db2239 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -919,7 +919,6 @@ static void ext4_i_callback(struct rcu_head *head) | |||
| 919 | 919 | ||
| 920 | static void ext4_destroy_inode(struct inode *inode) | 920 | static void ext4_destroy_inode(struct inode *inode) |
| 921 | { | 921 | { |
| 922 | ext4_ioend_wait(inode); | ||
| 923 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { | 922 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { |
| 924 | ext4_msg(inode->i_sb, KERN_ERR, | 923 | ext4_msg(inode->i_sb, KERN_ERR, |
| 925 | "Inode %lu (%p): orphan list check failed!", | 924 | "Inode %lu (%p): orphan list check failed!", |
