Commit f0b65f39 authored by Al Viro's avatar Al Viro
Browse files

iov_iter: replace iov_iter_copy_from_user_atomic() with iterator-advancing variant



Replacement is called copy_page_from_iter_atomic(); unlike the old primitive the
callers do *not* need to do iov_iter_advance() after it.  In case when they end
up consuming less than they'd been given they need to do iov_iter_revert() on
everything they had not consumed.  That, however, needs to be done only on slow
paths.

All in-tree callers converted.  And that kills the last user of iterate_all_kinds()

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent e4f8df86
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -890,3 +890,12 @@ been called or returned with non -EIOCBQUEUED code.

mnt_want_write_file() can now only be paired with mnt_drop_write_file(),
whereas previously it could be paired with mnt_drop_write() as well.

---

**mandatory**

iov_iter_copy_from_user_atomic() is gone; use copy_page_from_iter_atomic().
The difference is copy_page_from_iter_atomic() advances the iterator and
you don't need iov_iter_advance() after it.  However, if you decide to use
only a part of obtained data, you should do iov_iter_revert().
+11 −12
Original line number Diff line number Diff line
@@ -398,7 +398,7 @@ static noinline int btrfs_copy_from_user(loff_t pos, size_t write_bytes,
		/*
		 * Copy data from userspace to the current page
		 */
		copied = iov_iter_copy_from_user_atomic(page, i, offset, count);
		copied = copy_page_from_iter_atomic(page, offset, count, i);

		/* Flush processor's dcache for this page */
		flush_dcache_page(page);
@@ -412,20 +412,19 @@ static noinline int btrfs_copy_from_user(loff_t pos, size_t write_bytes,
		 * The rest of the btrfs_file_write code will fall
		 * back to page at a time copies after we return 0.
		 */
		if (!PageUptodate(page) && copied < count)
		if (unlikely(copied < count)) {
			if (!PageUptodate(page)) {
				iov_iter_revert(i, copied);
				copied = 0;
			}
			if (!copied)
				break;
		}

		iov_iter_advance(i, copied);
		write_bytes -= copied;
		total_copied += copied;

		/* Return to btrfs_file_write_iter to fault page */
		if (unlikely(copied == 0))
			break;

		if (copied < PAGE_SIZE - offset) {
		offset += copied;
		} else {
		if (offset == PAGE_SIZE) {
			pg++;
			offset = 0;
		}
+1 −2
Original line number Diff line number Diff line
@@ -1171,10 +1171,9 @@ static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia,
		if (mapping_writably_mapped(mapping))
			flush_dcache_page(page);

		tmp = iov_iter_copy_from_user_atomic(page, ii, offset, bytes);
		tmp = copy_page_from_iter_atomic(page, offset, bytes, ii);
		flush_dcache_page(page);

		iov_iter_advance(ii, tmp);
		if (!tmp) {
			unlock_page(page);
			put_page(page);
+7 −7
Original line number Diff line number Diff line
@@ -785,13 +785,15 @@ iomap_write_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
		if (mapping_writably_mapped(inode->i_mapping))
			flush_dcache_page(page);

		copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
		copied = copy_page_from_iter_atomic(page, offset, bytes, i);

		status = iomap_write_end(inode, pos, bytes, copied, page, iomap,
				srcmap);

		cond_resched();
		if (unlikely(copied != status))
			iov_iter_revert(i, copied - status);

		cond_resched();
		if (unlikely(status == 0)) {
			/*
			 * A short copy made iomap_write_end() reject the
@@ -803,11 +805,9 @@ iomap_write_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
				bytes = copied;
			goto again;
		}
		copied = status;
		iov_iter_advance(i, copied);
		pos += copied;
		written += copied;
		length -= copied;
		pos += status;
		written += status;
		length -= status;

		balance_dirty_pages_ratelimited(inode->i_mapping);
	} while (iov_iter_count(i) && length);
+1 −3
Original line number Diff line number Diff line
@@ -1690,9 +1690,7 @@ static size_t ntfs_copy_from_user_iter(struct page **pages, unsigned nr_pages,
		len = PAGE_SIZE - ofs;
		if (len > bytes)
			len = bytes;
		copied = iov_iter_copy_from_user_atomic(*pages, i, ofs,
				len);
		iov_iter_advance(i, copied);
		copied = copy_page_from_iter_atomic(*pages, ofs, len, i);
		total += copied;
		bytes -= copied;
		if (!bytes)
Loading