Commit 0bdd0f0b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull gfs2 fix from Andreas Gruenbacher:

 - Don't get stuck writing page onto itself under direct I/O

* tag 'gfs2-v6.4-rc4-fix' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2:
  gfs2: Don't get stuck writing page onto itself under direct I/O
parents 846b065d fa58cc88
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -784,9 +784,13 @@ static inline bool should_fault_in_pages(struct iov_iter *i,
	if (!user_backed_iter(i))
		return false;

	/*
	 * Try to fault in multiple pages initially.  When that doesn't result
	 * in any progress, fall back to a single page.
	 */
	size = PAGE_SIZE;
	offs = offset_in_page(iocb->ki_pos);
	if (*prev_count != count || !*window_size) {
	if (*prev_count != count) {
		size_t nr_dirtied;

		nr_dirtied = max(current->nr_dirtied_pause -
@@ -870,6 +874,7 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
	struct gfs2_inode *ip = GFS2_I(inode);
	size_t prev_count = 0, window_size = 0;
	size_t written = 0;
	bool enough_retries;
	ssize_t ret;

	/*
@@ -913,11 +918,17 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
	if (ret > 0)
		written = ret;

	enough_retries = prev_count == iov_iter_count(from) &&
			 window_size <= PAGE_SIZE;
	if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) {
		gfs2_glock_dq(gh);
		window_size -= fault_in_iov_iter_readable(from, window_size);
		if (window_size)
		if (window_size) {
			if (!enough_retries)
				goto retry;
			/* fall back to buffered I/O */
			ret = 0;
		}
	}
out_unlock:
	if (gfs2_holder_queued(gh))