Skip to content

block: refactor get_contig_folio_len#485

Closed
blktests-ci[bot] wants to merge 15 commits intolinus-master_basefrom
series/1042135=>linus-master
Closed

block: refactor get_contig_folio_len#485
blktests-ci[bot] wants to merge 15 commits intolinus-master_basefrom
series/1042135=>linus-master

Conversation

@blktests-ci
Copy link

@blktests-ci blktests-ci bot commented Jan 14, 2026

Pull request for series with
subject: block: refactor get_contig_folio_len
version: 1
url: https://patchwork.kernel.org/project/linux-block/list/?series=1042135

@blktests-ci
Copy link
Author

blktests-ci bot commented Jan 14, 2026

Upstream branch: b543459
series: https://patchwork.kernel.org/project/linux-block/list/?series=1042135
version: 1

@blktests-ci
Copy link
Author

blktests-ci bot commented Jan 15, 2026

Upstream branch: 944aacb
series: https://patchwork.kernel.org/project/linux-block/list/?series=1042135
version: 1

@blktests-ci blktests-ci bot force-pushed the series/1042135=>linus-master branch from cd6773c to 879f6ad Compare January 15, 2026 09:01
@blktests-ci blktests-ci bot force-pushed the linus-master_base branch from 8a473ad to fa94b37 Compare January 19, 2026 00:27
@blktests-ci
Copy link
Author

blktests-ci bot commented Jan 19, 2026

Upstream branch: 944aacb
series: https://patchwork.kernel.org/project/linux-block/list/?series=1042135
version: 1

@blktests-ci blktests-ci bot force-pushed the series/1042135=>linus-master branch from 879f6ad to 9a9912f Compare January 19, 2026 00:34
@blktests-ci
Copy link
Author

blktests-ci bot commented Jan 19, 2026

Upstream branch: 944aacb
series: https://patchwork.kernel.org/project/linux-block/list/?series=1043971
version: 1

@blktests-ci blktests-ci bot force-pushed the series/1042135=>linus-master branch from 9a9912f to dffcd4c Compare January 19, 2026 07:52
@blktests-ci
Copy link
Author

blktests-ci bot commented Jan 19, 2026

Upstream branch: 944aacb
series: https://patchwork.kernel.org/project/linux-block/list/?series=1043971
version: 1

@blktests-ci blktests-ci bot force-pushed the series/1042135=>linus-master branch from dffcd4c to 78c9685 Compare January 19, 2026 17:48
@blktests-ci
Copy link
Author

blktests-ci bot commented Jan 19, 2026

Upstream branch: 944aacb
series: https://patchwork.kernel.org/project/linux-block/list/?series=1043971
version: 1

@blktests-ci blktests-ci bot force-pushed the series/1042135=>linus-master branch from 78c9685 to 5f6fd56 Compare January 19, 2026 17:56
@blktests-ci blktests-ci bot force-pushed the linus-master_base branch from fa94b37 to 41a5848 Compare January 21, 2026 04:18
@blktests-ci
Copy link
Author

blktests-ci bot commented Jan 21, 2026

Upstream branch: 6c79021
series: https://patchwork.kernel.org/project/linux-block/list/?series=1043971
version: 1

@blktests-ci blktests-ci bot force-pushed the series/1042135=>linus-master branch from 5f6fd56 to 6439c5c Compare January 21, 2026 04:19
@blktests-ci blktests-ci bot force-pushed the linus-master_base branch from 41a5848 to 30680e5 Compare January 22, 2026 10:04
@blktests-ci
Copy link
Author

blktests-ci bot commented Jan 22, 2026

Upstream branch: a66191c
series: https://patchwork.kernel.org/project/linux-block/list/?series=1043971
version: 1

@blktests-ci blktests-ci bot force-pushed the series/1042135=>linus-master branch from 6439c5c to ad2d493 Compare January 22, 2026 10:04
@blktests-ci
Copy link
Author

blktests-ci bot commented Jan 22, 2026

Upstream branch: a66191c
series: https://patchwork.kernel.org/project/linux-block/list/?series=1043971
version: 1

@blktests-ci blktests-ci bot force-pushed the series/1042135=>linus-master branch from ad2d493 to f6482bf Compare January 22, 2026 11:09
@blktests-ci
Copy link
Author

blktests-ci bot commented Jan 22, 2026

Upstream branch: a66191c
series: https://patchwork.kernel.org/project/linux-block/list/?series=1043971
version: 1

@blktests-ci blktests-ci bot force-pushed the series/1042135=>linus-master branch from f6482bf to 680ed6b Compare January 22, 2026 11:17
@blktests-ci
Copy link
Author

blktests-ci bot commented Jan 22, 2026

Upstream branch: a66191c
series: https://patchwork.kernel.org/project/linux-block/list/?series=1043971
version: 1

Christoph Hellwig added 10 commits February 9, 2026 13:40
Merge bio_release_page into the only remaining caller.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com
Add helpers to implement bounce buffering of data into a bio to implement
direct I/O for cases where direct user access is not possible because
stable in-flight data is required.  These are intended to be used as
easily as bio_iov_iter_get_pages for the zero-copy path.

The write side is trivial and just copies data into the bounce buffer.
The read side is a lot more complex because it needs to perform the copy
from the completion context, and without preserving the iov_iter through
the call chain.  It steals a trick from the integrity data user interface
and uses the first vector in the bio for the bounce buffer data that is
fed to the block I/O stack, and uses the others to record the user
buffer fragments.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com
The "if (dio->error)" in iomap_dio_bio_iter exists to stop submitting
more bios when a completion already return an error.  Commit cfe057f
("iomap_dio_actor(): fix iov_iter bugs") made it revert the iov by
"copied", which is very wrong given that we've already consumed that
range and submitted a bio for it.

Fixes: cfe057f ("iomap_dio_actor(): fix iov_iter bugs")
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Use iov_iter_count to check if we need to continue as that just reads
a field in the iov_iter, and only use bio_iov_vecs_to_alloc to calculate
the actual number of vectors to allocate for the bio.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Factor out a separate helper that builds and submits a single bio.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
…_direct

Refactor the two per-bio completion handlers to share common code using
a new helper.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
There are good arguments for processing the user completions ASAP vs.
freeing resources ASAP, but freeing the bio first here removes potential
use after free hazards when checking flags, and will simplify the
upcoming bounce buffer support.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Match the more descriptive iov_iter terminology instead of encoding
what we do with them for reads only.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Support using the ioend structure to defer I/O completion for direct
reads in addition to writes.  This requires a check for the operation
to not merge reads and writes in iomap_ioend_can_merge.  This support
will be used for bounce buffered direct I/O reads that need to copy
data back to the user address space on read completion.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Add a new flag that request bounce buffering for direct I/O.  This is
needed to provide the stable pages requirement requested by devices
that need to calculate checksums or parity over the data and allows
file systems to properly work with things like T10 protection
information.  The implementation just calls out to the new bio bounce
buffering helpers to allocate a bounce buffer, which is used for
I/O and to copy to/from it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
@blktests-ci
Copy link
Author

blktests-ci bot commented Feb 9, 2026

Upstream branch: 05f7e89
series: https://patchwork.kernel.org/project/linux-block/list/?series=1043971
version: 1

…pages

Fix direct I/O on devices that require stable pages by asking iomap
to bounce buffer.  To support this, ioends are used for direct reads
in this case to provide a user context for copying data back from the
bounce buffer.

This fixes qemu when used on devices using T10 protection information
and probably other cases like iSCSI using data digests.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
@blktests-ci blktests-ci bot force-pushed the series/1042135=>linus-master branch from f5c0eb8 to a9a8172 Compare February 9, 2026 04:40
@blktests-ci blktests-ci bot force-pushed the linus-master_base branch from 30e5c22 to 519f160 Compare February 12, 2026 00:34
@blktests-ci
Copy link
Author

blktests-ci bot commented Feb 12, 2026

Upstream branch: c22e26b
series: https://patchwork.kernel.org/project/linux-block/list/?series=1043971
version: 1

Pull request is NOT updated. Failed to apply https://patchwork.kernel.org/project/linux-block/list/?series=1043971
error message:

Cmd('git') failed due to: exit code(128)
  cmdline: git am --3way
  stdout: 'Applying: block: refactor get_contig_folio_len
Using index info to reconstruct a base tree...
M	block/bio.c
Falling back to patching base and 3-way merge...
Auto-merging block/bio.c
CONFLICT (content): Merge conflict in block/bio.c
Patch failed at 0001 block: refactor get_contig_folio_len'
  stderr: 'error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"'

conflict:

diff --cc block/bio.c
index b291b9aaeee1,18dfdaba0c73..000000000000
--- a/block/bio.c
+++ b/block/bio.c
@@@ -1206,6 -1172,114 +1206,117 @@@ void bio_iov_bvec_set(struct bio *bio, 
  	bio_set_flag(bio, BIO_CLONED);
  }
  
++<<<<<<< HEAD
++=======
+ static unsigned int get_contig_folio_len(struct page **pages,
+ 					 unsigned int *num_pages, size_t left,
+ 					 size_t offset)
+ {
+ 	struct folio *folio = page_folio(pages[0]);
+ 	size_t contig_sz = min_t(size_t, PAGE_SIZE - offset, left);
+ 	unsigned int max_pages, i;
+ 	size_t folio_offset, len;
+ 
+ 	folio_offset = PAGE_SIZE * folio_page_idx(folio, pages[0]) + offset;
+ 	len = min(folio_size(folio) - folio_offset, left);
+ 
+ 	/*
+ 	 * We might COW a single page in the middle of a large folio, so we have
+ 	 * to check that all pages belong to the same folio.
+ 	 */
+ 	left -= contig_sz;
+ 	max_pages = DIV_ROUND_UP(offset + len, PAGE_SIZE);
+ 	for (i = 1; i < max_pages; i++) {
+ 		size_t next = min_t(size_t, PAGE_SIZE, left);
+ 
+ 		if (page_folio(pages[i]) != folio ||
+ 		    pages[i] != pages[i - 1] + 1)
+ 			break;
+ 		contig_sz += next;
+ 		left -= next;
+ 	}
+ 
+ 	*num_pages = i;
+ 	return contig_sz;
+ }
+ 
+ #define PAGE_PTRS_PER_BVEC     (sizeof(struct bio_vec) / sizeof(struct page *))
+ 
+ /**
+  * __bio_iov_iter_get_pages - pin user or kernel pages and add them to a bio
+  * @bio: bio to add pages to
+  * @iter: iov iterator describing the region to be mapped
+  *
+  * Extracts pages from *iter and appends them to @bio's bvec array.  The pages
+  * will have to be cleaned up in the way indicated by the BIO_PAGE_PINNED flag.
+  * For a multi-segment *iter, this function only adds pages from the next
+  * non-empty segment of the iov iterator.
+  */
+ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+ {
+ 	iov_iter_extraction_t extraction_flags = 0;
+ 	unsigned short nr_pages = bio->bi_max_vecs - bio->bi_vcnt;
+ 	unsigned short entries_left = bio->bi_max_vecs - bio->bi_vcnt;
+ 	struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt;
+ 	struct page **pages = (struct page **)bv;
+ 	ssize_t size;
+ 	unsigned int i = 0;
+ 	size_t offset, left, len;
+ 	int ret = 0;
+ 
+ 	/*
+ 	 * Move page array up in the allocated memory for the bio vecs as far as
+ 	 * possible so that we can start filling biovecs from the beginning
+ 	 * without overwriting the temporary page array.
+ 	 */
+ 	BUILD_BUG_ON(PAGE_PTRS_PER_BVEC < 2);
+ 	pages += entries_left * (PAGE_PTRS_PER_BVEC - 1);
+ 
+ 	if (bio->bi_bdev && blk_queue_pci_p2pdma(bio->bi_bdev->bd_disk->queue))
+ 		extraction_flags |= ITER_ALLOW_P2PDMA;
+ 
+ 	size = iov_iter_extract_pages(iter, &pages,
+ 				      UINT_MAX - bio->bi_iter.bi_size,
+ 				      nr_pages, extraction_flags, &offset);
+ 	if (unlikely(size <= 0))
+ 		return size ? size : -EFAULT;
+ 
+ 	nr_pages = DIV_ROUND_UP(offset + size, PAGE_SIZE);
+ 	for (left = size; left > 0; left -= len) {
+ 		unsigned int old_vcnt = bio->bi_vcnt;
+ 		unsigned int nr_to_add;
+ 
+ 		len = get_contig_folio_len(&pages[i], &nr_to_add, left, offset);
+ 		if (!bio_add_page(bio, pages[i], len, offset)) {
+ 			WARN_ON_ONCE(1);
+ 			ret = -EINVAL;
+ 			goto out;
+ 		}
+ 
+ 		if (bio_flagged(bio, BIO_PAGE_PINNED)) {
+ 			/*
+ 			 * We're adding another fragment of a page that already
+ 			 * was part of the last segment.  Undo our pin as the
+ 			 * page was pinned when an earlier fragment of it was
+ 			 * added to the bio and __bio_release_pages expects a
+ 			 * single pin per page.
+ 			 */
+ 			if (offset && bio->bi_vcnt == old_vcnt)
+ 				unpin_user_folio(page_folio(pages[i]), 1);
+ 		}
+ 		i += nr_to_add;
+ 		offset = 0;
+ 	}
+ 
+ 	iov_iter_revert(iter, left);
+ out:
+ 	while (i < nr_pages)
+ 		bio_release_page(bio, pages[i++]);
+ 
+ 	return ret;
+ }
+ 
++>>>>>>> block: refactor get_contig_folio_len
  /*
   * Aligns the bio size to the len_align_mask, releasing excessive bio vecs that
   * __bio_iov_iter_get_pages may have inserted, and reverts the trimmed length

@blktests-ci blktests-ci bot force-pushed the linus-master_base branch 9 times, most recently from e1fefe2 to f714aad Compare February 18, 2026 05:50
@blktests-ci
Copy link
Author

blktests-ci bot commented Feb 18, 2026

At least one diff in series https://patchwork.kernel.org/project/linux-block/list/?series=1042135 irrelevant now for [{'archived': False, 'project': 241}] search patterns

@blktests-ci blktests-ci bot closed this Feb 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments