mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 07:01:57 +00:00
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: flush any pending end_io requests before DIO reads w/dioread_nolock ext4: fix nomblk_io_submit option so it correctly converts uninit blocks ext4: Resolve the hang of direct i/o read in handling EXT4_IO_END_UNWRITTEN. ext4: call ext4_ioend_wait and ext4_flush_completed_IO in ext4_evict_inode ext4: Fix ext4_should_writeback_data() for no-journal mode
This commit is contained in:
commit
c063d8a60f
@ -289,10 +289,10 @@ static inline int ext4_should_order_data(struct inode *inode)
|
||||
|
||||
static inline int ext4_should_writeback_data(struct inode *inode)
|
||||
{
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
return 0;
|
||||
if (EXT4_JOURNAL(inode) == NULL)
|
||||
return 1;
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
return 0;
|
||||
if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA))
|
||||
return 0;
|
||||
if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
|
||||
|
@ -800,12 +800,17 @@ ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
|
||||
}
|
||||
|
||||
retry:
|
||||
if (rw == READ && ext4_should_dioread_nolock(inode))
|
||||
if (rw == READ && ext4_should_dioread_nolock(inode)) {
|
||||
if (unlikely(!list_empty(&ei->i_completed_io_list))) {
|
||||
mutex_lock(&inode->i_mutex);
|
||||
ext4_flush_completed_IO(inode);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
}
|
||||
ret = __blockdev_direct_IO(rw, iocb, inode,
|
||||
inode->i_sb->s_bdev, iov,
|
||||
offset, nr_segs,
|
||||
ext4_get_block, NULL, NULL, 0);
|
||||
else {
|
||||
} else {
|
||||
ret = blockdev_direct_IO(rw, iocb, inode, iov,
|
||||
offset, nr_segs, ext4_get_block);
|
||||
|
||||
|
@ -120,6 +120,12 @@ void ext4_evict_inode(struct inode *inode)
|
||||
int err;
|
||||
|
||||
trace_ext4_evict_inode(inode);
|
||||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
ext4_flush_completed_IO(inode);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
ext4_ioend_wait(inode);
|
||||
|
||||
if (inode->i_nlink) {
|
||||
/*
|
||||
* When journalling data dirty buffers are tracked only in the
|
||||
@ -983,6 +989,8 @@ static int ext4_journalled_write_end(struct file *file,
|
||||
from = pos & (PAGE_CACHE_SIZE - 1);
|
||||
to = from + len;
|
||||
|
||||
BUG_ON(!ext4_handle_valid(handle));
|
||||
|
||||
if (copied < len) {
|
||||
if (!PageUptodate(page))
|
||||
copied = 0;
|
||||
@ -1283,7 +1291,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
|
||||
else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT))
|
||||
err = ext4_bio_write_page(&io_submit, page,
|
||||
len, mpd->wbc);
|
||||
else
|
||||
else if (buffer_uninit(page_bufs)) {
|
||||
ext4_set_bh_endio(page_bufs, inode);
|
||||
err = block_write_full_page_endio(page,
|
||||
noalloc_get_block_write,
|
||||
mpd->wbc, ext4_end_io_buffer_write);
|
||||
} else
|
||||
err = block_write_full_page(page,
|
||||
noalloc_get_block_write, mpd->wbc);
|
||||
|
||||
@ -1699,6 +1712,8 @@ static int __ext4_journalled_writepage(struct page *page,
|
||||
goto out;
|
||||
}
|
||||
|
||||
BUG_ON(!ext4_handle_valid(handle));
|
||||
|
||||
ret = walk_page_buffers(handle, page_bufs, 0, len, NULL,
|
||||
do_journal_get_write_access);
|
||||
|
||||
@ -2668,8 +2683,15 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
|
||||
goto out;
|
||||
}
|
||||
|
||||
io_end->flag = EXT4_IO_END_UNWRITTEN;
|
||||
/*
|
||||
* It may be over-defensive here to check EXT4_IO_END_UNWRITTEN now,
|
||||
* but being more careful is always safe for the future change.
|
||||
*/
|
||||
inode = io_end->inode;
|
||||
if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) {
|
||||
io_end->flag |= EXT4_IO_END_UNWRITTEN;
|
||||
atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten);
|
||||
}
|
||||
|
||||
/* Add the io_end to per-inode completed io list*/
|
||||
spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
|
||||
|
@ -334,8 +334,10 @@ submit_and_retry:
|
||||
if ((io_end->num_io_pages >= MAX_IO_PAGES) &&
|
||||
(io_end->pages[io_end->num_io_pages-1] != io_page))
|
||||
goto submit_and_retry;
|
||||
if (buffer_uninit(bh))
|
||||
io->io_end->flag |= EXT4_IO_END_UNWRITTEN;
|
||||
if (buffer_uninit(bh) && !(io_end->flag & EXT4_IO_END_UNWRITTEN)) {
|
||||
io_end->flag |= EXT4_IO_END_UNWRITTEN;
|
||||
atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten);
|
||||
}
|
||||
io->io_end->size += bh->b_size;
|
||||
io->io_next_block++;
|
||||
ret = bio_add_page(io->io_bio, bh->b_page, bh->b_size, bh_offset(bh));
|
||||
|
@ -919,7 +919,6 @@ static void ext4_i_callback(struct rcu_head *head)
|
||||
|
||||
static void ext4_destroy_inode(struct inode *inode)
|
||||
{
|
||||
ext4_ioend_wait(inode);
|
||||
if (!list_empty(&(EXT4_I(inode)->i_orphan))) {
|
||||
ext4_msg(inode->i_sb, KERN_ERR,
|
||||
"Inode %lu (%p): orphan list check failed!",
|
||||
|
Loading…
Reference in New Issue
Block a user