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

Commit 1bdd3dbf authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'io_uring-20190323' of git://git.kernel.dk/linux-block

Pull io_uring fixes and improvements from Jens Axboe:
 "The first five in this series are heavily inspired by the work Al did
  on the aio side to fix the races there.

  The last two re-introduce a feature that was in io_uring before it got
  merged, but which I pulled since we didn't have a good way to have
  BVEC iters that already have a stable reference. These aren't
  necessarily related to block, it's just how io_uring pins fixed
  buffers"

* tag 'io_uring-20190323' of git://git.kernel.dk/linux-block:
  block: add BIO_NO_PAGE_REF flag
  iov_iter: add ITER_BVEC_FLAG_NO_REF flag
  io_uring: mark me as the maintainer
  io_uring: retry bulk slab allocs as single allocs
  io_uring: fix poll races
  io_uring: fix fget/fput handling
  io_uring: add prepped flag
  io_uring: make io_read/write return an integer
  io_uring: use regular request ref counts
parents 2335cbe6 399254aa
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -8096,6 +8096,16 @@ F: include/linux/iommu.h
F:	include/linux/of_iommu.h
F:	include/linux/iova.h

IO_URING
M:	Jens Axboe <axboe@kernel.dk>
L:	linux-block@vger.kernel.org
L:	linux-fsdevel@vger.kernel.org
T:	git git://git.kernel.dk/linux-block
T:	git git://git.kernel.dk/liburing
S:	Maintained
F:	fs/io_uring.c
F:	include/uapi/linux/io_uring.h

IP MASQUERADING
M:	Juanjo Ciarlante <jjciarla@raiz.uncu.edu.ar>
S:	Maintained
+24 −19
Original line number Diff line number Diff line
@@ -849,20 +849,14 @@ static int __bio_iov_bvec_add_pages(struct bio *bio, struct iov_iter *iter)
	size = bio_add_page(bio, bv->bv_page, len,
				bv->bv_offset + iter->iov_offset);
	if (size == len) {
		if (!bio_flagged(bio, BIO_NO_PAGE_REF)) {
			struct page *page;
			int i;

		/*
		 * For the normal O_DIRECT case, we could skip grabbing this
		 * reference and then not have to put them again when IO
		 * completes. But this breaks some in-kernel users, like
		 * splicing to/from a loop device, where we release the pipe
		 * pages unconditionally. If we can fix that case, we can
		 * get rid of the get here and the need to call
		 * bio_release_pages() at IO completion time.
		 */
			mp_bvec_for_each_page(page, bv, i)
				get_page(page);
		}

		iov_iter_advance(iter, size);
		return 0;
	}
@@ -925,10 +919,12 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
 * This takes either an iterator pointing to user memory, or one pointing to
 * kernel pages (BVEC iterator). If we're adding user pages, we pin them and
 * map them into the kernel. On IO completion, the caller should put those
 * pages. For now, when adding kernel pages, we still grab a reference to the
 * page. This isn't strictly needed for the common case, but some call paths
 * end up releasing pages from eg a pipe and we can't easily control these.
 * See comment in __bio_iov_bvec_add_pages().
 * pages. If we're adding kernel pages, and the caller told us it's safe to
 * do so, we just have to add the pages to the bio directly. We don't grab an
 * extra reference to those pages (the user should already have that), and we
 * don't put the page on IO completion. The caller needs to check if the bio is
 * flagged BIO_NO_PAGE_REF on IO completion. If it isn't, then pages should be
 * released.
 *
 * The function tries, but does not guarantee, to pin as many pages as
 * fit into the bio, or are requested in *iter, whatever is smaller. If
@@ -940,6 +936,13 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
	const bool is_bvec = iov_iter_is_bvec(iter);
	unsigned short orig_vcnt = bio->bi_vcnt;

	/*
	 * If this is a BVEC iter, then the pages are kernel pages. Don't
	 * release them on IO completion, if the caller asked us to.
	 */
	if (is_bvec && iov_iter_bvec_no_ref(iter))
		bio_set_flag(bio, BIO_NO_PAGE_REF);

	do {
		int ret;

@@ -1696,6 +1699,7 @@ static void bio_dirty_fn(struct work_struct *work)
		next = bio->bi_private;

		bio_set_pages_dirty(bio);
		if (!bio_flagged(bio, BIO_NO_PAGE_REF))
			bio_release_pages(bio);
		bio_put(bio);
	}
@@ -1713,6 +1717,7 @@ void bio_check_pages_dirty(struct bio *bio)
			goto defer;
	}

	if (!bio_flagged(bio, BIO_NO_PAGE_REF))
		bio_release_pages(bio);
	bio_put(bio);
	return;
+7 −5
Original line number Diff line number Diff line
@@ -336,12 +336,14 @@ static void blkdev_bio_end_io(struct bio *bio)
	if (should_dirty) {
		bio_check_pages_dirty(bio);
	} else {
		if (!bio_flagged(bio, BIO_NO_PAGE_REF)) {
			struct bvec_iter_all iter_all;
			struct bio_vec *bvec;
			int i;
		struct bvec_iter_all iter_all;

			bio_for_each_segment_all(bvec, bio, i, iter_all)
				put_page(bvec->bv_page);
		}
		bio_put(bio);
	}
}
+216 −223

File changed.

Preview size limit exceeded, changes collapsed.

+7 −5
Original line number Diff line number Diff line
@@ -1589,12 +1589,14 @@ static void iomap_dio_bio_end_io(struct bio *bio)
	if (should_dirty) {
		bio_check_pages_dirty(bio);
	} else {
		if (!bio_flagged(bio, BIO_NO_PAGE_REF)) {
			struct bvec_iter_all iter_all;
			struct bio_vec *bvec;
			int i;
		struct bvec_iter_all iter_all;

			bio_for_each_segment_all(bvec, bio, i, iter_all)
				put_page(bvec->bv_page);
		}
		bio_put(bio);
	}
}
Loading