Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c063d8a6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* '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
parents 79058c4b dccaf33f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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)
+7 −2
Original line number Diff line number Diff line
@@ -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);

+24 −2
Original line number Diff line number Diff line
@@ -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);
+4 −2
Original line number Diff line number Diff line
@@ -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));
+0 −1
Original line number Diff line number Diff line
@@ -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!",