Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1706169 > unrolled thread

[PATCH v3 00/49] block: support multipage bvec

Started byMing Lei <ming.lei@redhat.com>
First post2017-08-08 10:50 +0200
Last post2017-08-10 13:20 +0200
Articles 20 on this page of 61 — 5 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v3 00/49] block: support multipage bvec Ming Lei <ming.lei@redhat.com> - 2017-08-08 10:50 +0200
    [PATCH v3 10/49] dm: limit the max bio size as BIO_MAX_PAGES * PAGE_SIZE Ming Lei <ming.lei@redhat.com> - 2017-08-08 10:50 +0200
      Re: [PATCH v3 10/49] dm: limit the max bio size as BIO_MAX_PAGES *  PAGE_SIZE Christoph Hellwig <hch@infradead.org> - 2017-08-10 13:30 +0200
    [PATCH v3 13/49] btrfs: comment on direct access bvec table Ming Lei <ming.lei@redhat.com> - 2017-08-08 10:50 +0200
    [PATCH v3 08/49] block: comment on bio_alloc_pages() Ming Lei <ming.lei@redhat.com> - 2017-08-08 10:50 +0200
    [PATCH v3 09/49] block: comment on bio_iov_iter_get_pages() Ming Lei <ming.lei@redhat.com> - 2017-08-08 10:50 +0200
      Re: [PATCH v3 09/49] block: comment on bio_iov_iter_get_pages() Christoph Hellwig <hch@infradead.org> - 2017-08-10 13:30 +0200
    [PATCH v3 07/49] bcache: comment on direct access to bvec table Ming Lei <ming.lei@redhat.com> - 2017-08-08 10:50 +0200
      Re: [PATCH v3 07/49] bcache: comment on direct access to bvec table Coly Li <i@coly.li> - 2017-08-08 14:40 +0200
      Re: [PATCH v3 07/49] bcache: comment on direct access to bvec table Christoph Hellwig <hch@infradead.org> - 2017-08-10 13:30 +0200
    [PATCH v3 05/49] fs/buffer: comment on direct access to bvec table Ming Lei <ming.lei@redhat.com> - 2017-08-08 10:50 +0200
      Re: [PATCH v3 05/49] fs/buffer: comment on direct access to bvec  table Christoph Hellwig <hch@infradead.org> - 2017-08-10 13:20 +0200
    [PATCH v3 12/49] btrfs: avoid to access bvec table directly for a cloned bio Ming Lei <ming.lei@redhat.com> - 2017-08-08 10:50 +0200
    [PATCH v3 03/49] kernel/power/swap.c: comment on direct access to bvec table Ming Lei <ming.lei@redhat.com> - 2017-08-08 10:50 +0200
    [PATCH v3 02/49] block: loop: comment on direct access to bvec table Ming Lei <ming.lei@redhat.com> - 2017-08-08 10:50 +0200
    [PATCH v3 16/49] block: bounce: don't access bio->bi_io_vec in copy_to_high_bio_irq Ming Lei <ming.lei@redhat.com> - 2017-08-08 10:50 +0200
    [PATCH v3 15/49] bvec_iter: introduce BVEC_ITER_ALL_INIT Ming Lei <ming.lei@redhat.com> - 2017-08-08 10:50 +0200
    [PATCH v3 41/49] xfs: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
      Re: [PATCH v3 41/49] xfs: convert to bio_for_each_segment_all_sp() "Darrick J. Wong" <darrick.wong@oracle.com> - 2017-08-08 18:40 +0200
    [PATCH v3 48/49] block: enable multipage bvecs Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 33/49] bcache: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
      Re: [PATCH v3 33/49] bcache: convert to bio_for_each_segment_all_sp() Coly Li <i@coly.li> - 2017-08-08 14:40 +0200
    [PATCH v3 49/49] block: bio: pass segments to bio if bio_add_page() is bypassed Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 25/49] block: use bio_for_each_segment_mp() to map sg Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 37/49] fs/mpage: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
      Re: [PATCH v3 37/49] fs/mpage: convert to  bio_for_each_segment_all_sp() Christoph Hellwig <hch@infradead.org> - 2017-08-10 14:20 +0200
    [PATCH v3 28/49] block: introduce bvec_get_last_page() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 34/49] md: raid1: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 26/49] block: introduce bvec_for_each_sp_bvec() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 44/49] exofs: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 35/49] dm-crypt: don't clear bvec->bv_page in crypt_free_buffer_pages() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 42/49] gfs2: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 32/49] block: convert to singe/multi page version of bio_for_each_segment_all() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 39/49] fs/iomap: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 29/49] fs/buffer.c: use bvec iterator to truncate the bio Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 21/49] blk-merge: compute bio->bi_seg_front_size efficiently Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
      Re: [PATCH v3 21/49] blk-merge: compute bio->bi_seg_front_size  efficiently Christoph Hellwig <hch@infradead.org> - 2017-08-10 14:30 +0200
    [PATCH v3 24/49] block: use bio_for_each_segment_mp() to compute segments count Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 43/49] f2fs: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 23/49] block: blk-merge: remove unnecessary check Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
      Re: [PATCH v3 23/49] block: blk-merge: remove unnecessary check Christoph Hellwig <hch@infradead.org> - 2017-08-10 14:20 +0200
    [PATCH v3 27/49] block: bio: introduce single/multi page version of bio_for_each_segment_all() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 46/49] fs/btrfs: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
      Re: [PATCH v3 46/49] fs/btrfs: convert to bio_for_each_segment_all_sp() Filipe Manana <fdmanana@gmail.com> - 2017-08-08 11:10 +0200
    [PATCH v3 38/49] fs/block: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 18/49] block: introduce multipage/single page bvec helpers Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
      Re: [PATCH v3 18/49] block: introduce multipage/single page bvec  helpers Christoph Hellwig <hch@infradead.org> - 2017-08-10 14:10 +0200
    [PATCH v3 47/49] fs/direct-io: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 31/49] block: deal with dirtying pages for multipage bvec Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 20/49] block: introduce bio_for_each_segment_mp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
      Re: [PATCH v3 20/49] block: introduce bio_for_each_segment_mp() Christoph Hellwig <hch@infradead.org> - 2017-08-10 14:30 +0200
    [PATCH v3 45/49] fs: crypto: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 40/49] ext4: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 22/49] block: blk-merge: try to make front segments in full size Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
      Re: [PATCH v3 22/49] block: blk-merge: try to make front segments in  full size Christoph Hellwig <hch@infradead.org> - 2017-08-10 14:30 +0200
    [PATCH v3 30/49] btrfs: use bvec_get_last_page to get bio's last page Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 36/49] dm-crypt: convert to bio_for_each_segment_all_sp() Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
    [PATCH v3 19/49] block: implement sp version of bvec iterator helpers Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:00 +0200
      Re: [PATCH v3 19/49] block: implement sp version of bvec iterator  helpers Christoph Hellwig <hch@infradead.org> - 2017-08-10 14:10 +0200
    [PATCH v3 04/49] mm: page_io.c: comment on direct access to bvec table Ming Lei <ming.lei@redhat.com> - 2017-08-08 11:10 +0200
      Re: [PATCH v3 04/49] mm: page_io.c: comment on direct access to bvec  table Christoph Hellwig <hch@infradead.org> - 2017-08-10 13:20 +0200

Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →


#1708549 — Re: [PATCH v3 23/49] block: blk-merge: remove unnecessary check

FromChristoph Hellwig <hch@infradead.org>
Date2017-08-10 14:20 +0200
SubjectRe: [PATCH v3 23/49] block: blk-merge: remove unnecessary check
Message-ID<ucUBv-5tj-101@gated-at.bofh.it>
In reply to#1706206
Looks good, and another candidate for a prep series:

Reviewed-by: Christoph Hellwig <hch@lst.de>

[toc] | [prev] | [next] | [standalone]


#1706207 — [PATCH v3 27/49] block: bio: introduce single/multi page version of bio_for_each_segment_all()

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:00 +0200
Subject[PATCH v3 27/49] block: bio: introduce single/multi page version of bio_for_each_segment_all()
Message-ID<uc8wP-5yr-57@gated-at.bofh.it>
In reply to#1706169
This patches introduce bio_for_each_segment_all_sp() and
bio_for_each_segment_all_mp().

bio_for_each_segment_all_sp() is for replacing bio_for_each_segment_all()
in case that the returned bvec has to be single page bvec.

bio_for_each_segment_all_mp() is for replacing bio_for_each_segment_all()
in case that user wants to update the returned bvec via the pointer.

Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 include/linux/bio.h       | 24 ++++++++++++++++++++++++
 include/linux/blk_types.h |  6 ++++++
 2 files changed, 30 insertions(+)

diff --git a/include/linux/bio.h b/include/linux/bio.h
index ac8248558ab4..cd43b4b80472 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -232,6 +232,30 @@ static inline bool bio_rewind_iter(struct bio *bio, struct bvec_iter *iter,
 #define bio_for_each_segment_mp(bvl, bio, iter)				\
 	__bio_for_each_segment_mp(bvl, bio, iter, (bio)->bi_iter)
 
+/*
+ * This helper returns each bvec stored in bvec table directly,
+ * so the returned bvec points to one multipage bvec in the table
+ * and caller can update the bvec via the returnd pointer.
+ */
+#define bio_for_each_segment_all_mp(bvl, bio, i)                       \
+	bio_for_each_segment_all((bvl), (bio), (i))
+
+/*
+ * This helper returns singlepage bvec to caller, and the sp bvec
+ * is generated in-flight from multipage bvec stored in bvec table.
+ * So we can _not_ change the bvec stored in bio->bi_io_vec[] via
+ * this helper.
+ *
+ * If someone need to update bvec in the table, please use
+ * bio_for_each_segment_all_mp() and make sure it is correctly used
+ * since the bvec points to one multipage bvec.
+ */
+#define bio_for_each_segment_all_sp(bvl, bio, i, bi)			\
+	for ((bi).iter = BVEC_ITER_ALL_INIT, i = 0, bvl = &(bi).bv;	\
+	     (bi).iter.bi_idx < (bio)->bi_vcnt &&			\
+		(((bi).bv = bio_iter_iovec((bio), (bi).iter)), 1);	\
+	     bio_advance_iter((bio), &(bi).iter, (bi).bv.bv_len), i++)
+
 #define bio_iter_last(bvec, iter) ((iter).bi_size == (bvec).bv_len)
 
 static inline unsigned bio_segments(struct bio *bio)
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index d2eb87c84d82..99b47b7204fe 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -119,6 +119,12 @@ struct bio {
 
 #define BIO_RESET_BYTES		offsetof(struct bio, bi_max_vecs)
 
+/* this iter is only for implementing bio_for_each_segment_rd() */
+struct bvec_iter_all {
+	struct bvec_iter	iter;
+	struct bio_vec		bv;      /* in-flight singlepage bvec */
+};
+
 /*
  * bio flags
  */
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1706208 — [PATCH v3 46/49] fs/btrfs: convert to bio_for_each_segment_all_sp()

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:00 +0200
Subject[PATCH v3 46/49] fs/btrfs: convert to bio_for_each_segment_all_sp()
Message-ID<uc8wP-5yr-59@gated-at.bofh.it>
In reply to#1706169
Cc: Chris Mason <clm@fb.com>
Cc: Josef Bacik <jbacik@fb.com>
Cc: David Sterba <dsterba@suse.com>
Cc: linux-btrfs@vger.kernel.org
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 fs/btrfs/compression.c |  3 ++-
 fs/btrfs/disk-io.c     |  3 ++-
 fs/btrfs/extent_io.c   | 12 ++++++++----
 fs/btrfs/inode.c       |  6 ++++--
 fs/btrfs/raid56.c      |  1 +
 5 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 28746588f228..55f251a83d0b 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -147,13 +147,14 @@ static void end_compressed_bio_read(struct bio *bio)
 	} else {
 		int i;
 		struct bio_vec *bvec;
+		struct bvec_iter_all bia;
 
 		/*
 		 * we have verified the checksum already, set page
 		 * checked so the end_io handlers know about it
 		 */
 		ASSERT(!bio_flagged(bio, BIO_CLONED));
-		bio_for_each_segment_all(bvec, cb->orig_bio, i)
+		bio_for_each_segment_all_sp(bvec, cb->orig_bio, i, bia)
 			SetPageChecked(bvec->bv_page);
 
 		bio_endio(cb->orig_bio);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 080e2ebb8aa0..a9cd75e6383d 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -963,9 +963,10 @@ static blk_status_t btree_csum_one_bio(struct bio *bio)
 	struct bio_vec *bvec;
 	struct btrfs_root *root;
 	int i, ret = 0;
+	struct bvec_iter_all bia;
 
 	ASSERT(!bio_flagged(bio, BIO_CLONED));
-	bio_for_each_segment_all(bvec, bio, i) {
+	bio_for_each_segment_all_sp(bvec, bio, i, bia) {
 		root = BTRFS_I(bvec->bv_page->mapping->host)->root;
 		ret = csum_dirty_buffer(root->fs_info, bvec->bv_page);
 		if (ret)
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index c8f6a8657bf2..4de9cfd1c385 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2359,8 +2359,9 @@ static unsigned int get_bio_pages(struct bio *bio)
 {
 	unsigned i;
 	struct bio_vec *bv;
+	struct bvec_iter_all bia;
 
-	bio_for_each_segment_all(bv, bio, i)
+	bio_for_each_segment_all_sp(bv, bio, i, bia)
 		;
 
 	return i;
@@ -2463,9 +2464,10 @@ static void end_bio_extent_writepage(struct bio *bio)
 	u64 start;
 	u64 end;
 	int i;
+	struct bvec_iter_all bia;
 
 	ASSERT(!bio_flagged(bio, BIO_CLONED));
-	bio_for_each_segment_all(bvec, bio, i) {
+	bio_for_each_segment_all_sp(bvec, bio, i, bia) {
 		struct page *page = bvec->bv_page;
 		struct inode *inode = page->mapping->host;
 		struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
@@ -2534,9 +2536,10 @@ static void end_bio_extent_readpage(struct bio *bio)
 	int mirror;
 	int ret;
 	int i;
+	struct bvec_iter_all bia;
 
 	ASSERT(!bio_flagged(bio, BIO_CLONED));
-	bio_for_each_segment_all(bvec, bio, i) {
+	bio_for_each_segment_all_sp(bvec, bio, i, bia) {
 		struct page *page = bvec->bv_page;
 		struct inode *inode = page->mapping->host;
 		struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
@@ -3693,9 +3696,10 @@ static void end_bio_extent_buffer_writepage(struct bio *bio)
 	struct bio_vec *bvec;
 	struct extent_buffer *eb;
 	int i, done;
+	struct bvec_iter_all bia;
 
 	ASSERT(!bio_flagged(bio, BIO_CLONED));
-	bio_for_each_segment_all(bvec, bio, i) {
+	bio_for_each_segment_all_sp(bvec, bio, i, bia) {
 		struct page *page = bvec->bv_page;
 
 		eb = (struct extent_buffer *)page->private;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 084ed99dd308..eeb2ff662ec4 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8047,6 +8047,7 @@ static void btrfs_retry_endio_nocsum(struct bio *bio)
 	struct bio_vec *bvec;
 	struct extent_io_tree *io_tree, *failure_tree;
 	int i;
+	struct bvec_iter_all bia;
 
 	if (bio->bi_status)
 		goto end;
@@ -8064,7 +8065,7 @@ static void btrfs_retry_endio_nocsum(struct bio *bio)
 
 	done->uptodate = 1;
 	ASSERT(!bio_flagged(bio, BIO_CLONED));
-	bio_for_each_segment_all(bvec, bio, i)
+	bio_for_each_segment_all_sp(bvec, bio, i, bia)
 		clean_io_failure(BTRFS_I(inode)->root->fs_info, failure_tree,
 				 io_tree, done->start, bvec->bv_page,
 				 btrfs_ino(BTRFS_I(inode)), 0);
@@ -8143,6 +8144,7 @@ static void btrfs_retry_endio(struct bio *bio)
 	int uptodate;
 	int ret;
 	int i;
+	struct bvec_iter_all bia;
 
 	if (bio->bi_status)
 		goto end;
@@ -8162,7 +8164,7 @@ static void btrfs_retry_endio(struct bio *bio)
 	failure_tree = &BTRFS_I(inode)->io_failure_tree;
 
 	ASSERT(!bio_flagged(bio, BIO_CLONED));
-	bio_for_each_segment_all(bvec, bio, i) {
+	bio_for_each_segment_all_sp(bvec, bio, i, bia) {
 		ret = __readpage_endio_check(inode, io_bio, i, bvec->bv_page,
 					     bvec->bv_offset, done->start,
 					     bvec->bv_len);
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c
index 208638384cd2..9247226a2efd 100644
--- a/fs/btrfs/raid56.c
+++ b/fs/btrfs/raid56.c
@@ -1365,6 +1365,7 @@ static int find_logical_bio_stripe(struct btrfs_raid_bio *rbio,
 	u64 logical = bio->bi_iter.bi_sector;
 	u64 stripe_start;
 	int i;
+	struct bvec_iter_all bia;
 
 	logical <<= 9;
 
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1706232 — Re: [PATCH v3 46/49] fs/btrfs: convert to bio_for_each_segment_all_sp()

FromFilipe Manana <fdmanana@gmail.com>
Date2017-08-08 11:10 +0200
SubjectRe: [PATCH v3 46/49] fs/btrfs: convert to bio_for_each_segment_all_sp()
Message-ID<uc8Gv-5Tu-27@gated-at.bofh.it>
In reply to#1706208
On Tue, Aug 8, 2017 at 9:45 AM, Ming Lei <ming.lei@redhat.com> wrote:
> Cc: Chris Mason <clm@fb.com>
> Cc: Josef Bacik <jbacik@fb.com>
> Cc: David Sterba <dsterba@suse.com>
> Cc: linux-btrfs@vger.kernel.org
> Signed-off-by: Ming Lei <ming.lei@redhat.com>

Can you please add some meaningful changelog? E.g., why is this
conversion needed.

> ---
>  fs/btrfs/compression.c |  3 ++-
>  fs/btrfs/disk-io.c     |  3 ++-
>  fs/btrfs/extent_io.c   | 12 ++++++++----
>  fs/btrfs/inode.c       |  6 ++++--
>  fs/btrfs/raid56.c      |  1 +
>  5 files changed, 17 insertions(+), 8 deletions(-)
>
> diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
> index 28746588f228..55f251a83d0b 100644
> --- a/fs/btrfs/compression.c
> +++ b/fs/btrfs/compression.c
> @@ -147,13 +147,14 @@ static void end_compressed_bio_read(struct bio *bio)
>         } else {
>                 int i;
>                 struct bio_vec *bvec;
> +               struct bvec_iter_all bia;
>
>                 /*
>                  * we have verified the checksum already, set page
>                  * checked so the end_io handlers know about it
>                  */
>                 ASSERT(!bio_flagged(bio, BIO_CLONED));
> -               bio_for_each_segment_all(bvec, cb->orig_bio, i)
> +               bio_for_each_segment_all_sp(bvec, cb->orig_bio, i, bia)
>                         SetPageChecked(bvec->bv_page);
>
>                 bio_endio(cb->orig_bio);
> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> index 080e2ebb8aa0..a9cd75e6383d 100644
> --- a/fs/btrfs/disk-io.c
> +++ b/fs/btrfs/disk-io.c
> @@ -963,9 +963,10 @@ static blk_status_t btree_csum_one_bio(struct bio *bio)
>         struct bio_vec *bvec;
>         struct btrfs_root *root;
>         int i, ret = 0;
> +       struct bvec_iter_all bia;
>
>         ASSERT(!bio_flagged(bio, BIO_CLONED));
> -       bio_for_each_segment_all(bvec, bio, i) {
> +       bio_for_each_segment_all_sp(bvec, bio, i, bia) {
>                 root = BTRFS_I(bvec->bv_page->mapping->host)->root;
>                 ret = csum_dirty_buffer(root->fs_info, bvec->bv_page);
>                 if (ret)
> diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
> index c8f6a8657bf2..4de9cfd1c385 100644
> --- a/fs/btrfs/extent_io.c
> +++ b/fs/btrfs/extent_io.c
> @@ -2359,8 +2359,9 @@ static unsigned int get_bio_pages(struct bio *bio)
>  {
>         unsigned i;
>         struct bio_vec *bv;
> +       struct bvec_iter_all bia;
>
> -       bio_for_each_segment_all(bv, bio, i)
> +       bio_for_each_segment_all_sp(bv, bio, i, bia)
>                 ;
>
>         return i;
> @@ -2463,9 +2464,10 @@ static void end_bio_extent_writepage(struct bio *bio)
>         u64 start;
>         u64 end;
>         int i;
> +       struct bvec_iter_all bia;
>
>         ASSERT(!bio_flagged(bio, BIO_CLONED));
> -       bio_for_each_segment_all(bvec, bio, i) {
> +       bio_for_each_segment_all_sp(bvec, bio, i, bia) {
>                 struct page *page = bvec->bv_page;
>                 struct inode *inode = page->mapping->host;
>                 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
> @@ -2534,9 +2536,10 @@ static void end_bio_extent_readpage(struct bio *bio)
>         int mirror;
>         int ret;
>         int i;
> +       struct bvec_iter_all bia;
>
>         ASSERT(!bio_flagged(bio, BIO_CLONED));
> -       bio_for_each_segment_all(bvec, bio, i) {
> +       bio_for_each_segment_all_sp(bvec, bio, i, bia) {
>                 struct page *page = bvec->bv_page;
>                 struct inode *inode = page->mapping->host;
>                 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
> @@ -3693,9 +3696,10 @@ static void end_bio_extent_buffer_writepage(struct bio *bio)
>         struct bio_vec *bvec;
>         struct extent_buffer *eb;
>         int i, done;
> +       struct bvec_iter_all bia;
>
>         ASSERT(!bio_flagged(bio, BIO_CLONED));
> -       bio_for_each_segment_all(bvec, bio, i) {
> +       bio_for_each_segment_all_sp(bvec, bio, i, bia) {
>                 struct page *page = bvec->bv_page;
>
>                 eb = (struct extent_buffer *)page->private;
> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
> index 084ed99dd308..eeb2ff662ec4 100644
> --- a/fs/btrfs/inode.c
> +++ b/fs/btrfs/inode.c
> @@ -8047,6 +8047,7 @@ static void btrfs_retry_endio_nocsum(struct bio *bio)
>         struct bio_vec *bvec;
>         struct extent_io_tree *io_tree, *failure_tree;
>         int i;
> +       struct bvec_iter_all bia;
>
>         if (bio->bi_status)
>                 goto end;
> @@ -8064,7 +8065,7 @@ static void btrfs_retry_endio_nocsum(struct bio *bio)
>
>         done->uptodate = 1;
>         ASSERT(!bio_flagged(bio, BIO_CLONED));
> -       bio_for_each_segment_all(bvec, bio, i)
> +       bio_for_each_segment_all_sp(bvec, bio, i, bia)
>                 clean_io_failure(BTRFS_I(inode)->root->fs_info, failure_tree,
>                                  io_tree, done->start, bvec->bv_page,
>                                  btrfs_ino(BTRFS_I(inode)), 0);
> @@ -8143,6 +8144,7 @@ static void btrfs_retry_endio(struct bio *bio)
>         int uptodate;
>         int ret;
>         int i;
> +       struct bvec_iter_all bia;
>
>         if (bio->bi_status)
>                 goto end;
> @@ -8162,7 +8164,7 @@ static void btrfs_retry_endio(struct bio *bio)
>         failure_tree = &BTRFS_I(inode)->io_failure_tree;
>
>         ASSERT(!bio_flagged(bio, BIO_CLONED));
> -       bio_for_each_segment_all(bvec, bio, i) {
> +       bio_for_each_segment_all_sp(bvec, bio, i, bia) {
>                 ret = __readpage_endio_check(inode, io_bio, i, bvec->bv_page,
>                                              bvec->bv_offset, done->start,
>                                              bvec->bv_len);
> diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c
> index 208638384cd2..9247226a2efd 100644
> --- a/fs/btrfs/raid56.c
> +++ b/fs/btrfs/raid56.c
> @@ -1365,6 +1365,7 @@ static int find_logical_bio_stripe(struct btrfs_raid_bio *rbio,
>         u64 logical = bio->bi_iter.bi_sector;
>         u64 stripe_start;
>         int i;
> +       struct bvec_iter_all bia;

Unused variable.

Thanks.

>
>         logical <<= 9;
>
> --
> 2.9.4
>



-- 
Filipe David Manana,

“Whether you think you can, or you think you can't — you're right.”

[toc] | [prev] | [next] | [standalone]


#1706209 — [PATCH v3 38/49] fs/block: convert to bio_for_each_segment_all_sp()

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:00 +0200
Subject[PATCH v3 38/49] fs/block: convert to bio_for_each_segment_all_sp()
Message-ID<uc8wP-5yr-61@gated-at.bofh.it>
In reply to#1706169
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 fs/block_dev.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/block_dev.c b/fs/block_dev.c
index 9941dc8342df..489d103ae11b 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -209,6 +209,7 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
 	ssize_t ret;
 	blk_qc_t qc;
 	int i;
+	struct bvec_iter_all bia;
 
 	if ((pos | iov_iter_alignment(iter)) &
 	    (bdev_logical_block_size(bdev) - 1))
@@ -254,7 +255,7 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
 	}
 	__set_current_state(TASK_RUNNING);
 
-	bio_for_each_segment_all(bvec, &bio, i) {
+	bio_for_each_segment_all_sp(bvec, &bio, i, bia) {
 		if (should_dirty && !PageCompound(bvec->bv_page))
 			set_page_dirty_lock(bvec->bv_page);
 		put_page(bvec->bv_page);
@@ -321,8 +322,9 @@ static void blkdev_bio_end_io(struct bio *bio)
 	} else {
 		struct bio_vec *bvec;
 		int i;
+		struct bvec_iter_all bia;
 
-		bio_for_each_segment_all(bvec, bio, i)
+		bio_for_each_segment_all_sp(bvec, bio, i, bia)
 			put_page(bvec->bv_page);
 		bio_put(bio);
 	}
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1706211 — [PATCH v3 18/49] block: introduce multipage/single page bvec helpers

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:00 +0200
Subject[PATCH v3 18/49] block: introduce multipage/single page bvec helpers
Message-ID<uc8wP-5yr-65@gated-at.bofh.it>
In reply to#1706169
This patch introduces helpers which are suffixed with _mp
and _sp for the multipage bvec/segment support.

The helpers with _mp suffix are the interfaces for treating
one bvec/segment as real multipage one, for example, .bv_len
is the total length of the multipage segment.

The helpers with _sp suffix are interfaces for supporting
current bvec iterator which is thought as singlepage only
by drivers, fs, dm and etc. These _sp helpers are introduced
to build singlepage bvec in flight, so users of bio/bvec
iterator still can work well and needn't change even though
we store multipage into bvec.

Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 include/linux/bvec.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 53 insertions(+), 3 deletions(-)

diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index fe7a22dd133b..1eaf7ca5cab3 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -25,6 +25,42 @@
 #include <linux/errno.h>
 
 /*
+ * What is multipage bvecs(segment)?
+ *
+ * - bvec stored in bio->bi_io_vec is always multipage style vector
+ *
+ * - bvec(struct bio_vec) represents one physically contiguous I/O
+ *   buffer, now the buffer may include more than one pages since
+ *   multipage(mp) bvec is supported, and all these pages represented
+ *   by one bvec is physically contiguous. Before mp support, at most
+ *   one page can be included in one bvec, we call it singlepage(sp)
+ *   bvec.
+ *
+ * - .bv_page of th bvec represents the 1st page in the mp segment
+ *
+ * - .bv_offset of the bvec represents offset of the buffer in the bvec
+ *
+ * The effect on the current drivers/filesystem/dm/bcache/...:
+ *
+ * - almost everyone supposes that one bvec only includes one single
+ *   page, so we keep the sp interface not changed, for example,
+ *   bio_for_each_segment() still returns bvec with single page
+ *
+ * - bio_for_each_segment_all() will be changed to return singlepage
+ *   bvec too
+ *
+ * - during iterating, iterator variable(struct bvec_iter) is always
+ *   updated in multipage bvec style and that means bvec_iter_advance()
+ *   is kept not changed
+ *
+ * - returned(copied) singlepage bvec is generated in flight by bvec
+ *   helpers from the stored mp bvec
+ *
+ * - In case that some components(such as iov_iter) need to support mp
+ *   segment, we introduce new helpers(suffixed with _mp) for them.
+ */
+
+/*
  * was unsigned short, but we might as well be ready for > 64kB I/O pages
  */
 struct bio_vec {
@@ -52,16 +88,30 @@ struct bvec_iter {
  */
 #define __bvec_iter_bvec(bvec, iter)	(&(bvec)[(iter).bi_idx])
 
-#define bvec_iter_page(bvec, iter)				\
+#define bvec_iter_page_mp(bvec, iter)				\
 	(__bvec_iter_bvec((bvec), (iter))->bv_page)
 
-#define bvec_iter_len(bvec, iter)				\
+#define bvec_iter_len_mp(bvec, iter)				\
 	min((iter).bi_size,					\
 	    __bvec_iter_bvec((bvec), (iter))->bv_len - (iter).bi_bvec_done)
 
-#define bvec_iter_offset(bvec, iter)				\
+#define bvec_iter_offset_mp(bvec, iter)				\
 	(__bvec_iter_bvec((bvec), (iter))->bv_offset + (iter).bi_bvec_done)
 
+/*
+ * <page, offset,length> of singlepage(sp) segment.
+ *
+ * This helpers will be implemented for building sp bvec in flight.
+ */
+#define bvec_iter_offset_sp(bvec, iter)	bvec_iter_offset_mp((bvec), (iter))
+#define bvec_iter_len_sp(bvec, iter)	bvec_iter_len_mp((bvec), (iter))
+#define bvec_iter_page_sp(bvec, iter)	bvec_iter_page_mp((bvec), (iter))
+
+/* current interfaces support sp style at default */
+#define bvec_iter_page(bvec, iter)	bvec_iter_page_sp((bvec), (iter))
+#define bvec_iter_len(bvec, iter)	bvec_iter_len_sp((bvec), (iter))
+#define bvec_iter_offset(bvec, iter)	bvec_iter_offset_sp((bvec), (iter))
+
 #define bvec_iter_bvec(bvec, iter)				\
 ((struct bio_vec) {						\
 	.bv_page	= bvec_iter_page((bvec), (iter)),	\
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1708491 — Re: [PATCH v3 18/49] block: introduce multipage/single page bvec helpers

FromChristoph Hellwig <hch@infradead.org>
Date2017-08-10 14:10 +0200
SubjectRe: [PATCH v3 18/49] block: introduce multipage/single page bvec helpers
Message-ID<ucUrM-5pA-11@gated-at.bofh.it>
In reply to#1706211
Please skip adding the _sp names for the single page ones - those
are the only used to implement the non postfixed ones anyway.

The _mp ones should have bio_iter_segment_* names instead.

And while you're at it - I think this code would massively benefit
from turning it into inline functions in a prep step before doing these
changes, including passing the iter by reference for all these functions
instead of the odd by value calling convention.

[toc] | [prev] | [next] | [standalone]


#1706212 — [PATCH v3 47/49] fs/direct-io: convert to bio_for_each_segment_all_sp()

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:00 +0200
Subject[PATCH v3 47/49] fs/direct-io: convert to bio_for_each_segment_all_sp()
Message-ID<uc8wP-5yr-67@gated-at.bofh.it>
In reply to#1706169
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 fs/direct-io.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/direct-io.c b/fs/direct-io.c
index 08cf27811e5a..8447f4d55730 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -491,7 +491,9 @@ static blk_status_t dio_bio_complete(struct dio *dio, struct bio *bio)
 	if (dio->is_async && dio->op == REQ_OP_READ && dio->should_dirty) {
 		bio_check_pages_dirty(bio);	/* transfers ownership */
 	} else {
-		bio_for_each_segment_all(bvec, bio, i) {
+		struct bvec_iter_all bia;
+
+		bio_for_each_segment_all_sp(bvec, bio, i, bia) {
 			struct page *page = bvec->bv_page;
 
 			if (dio->op == REQ_OP_READ && !PageCompound(page) &&
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1706213 — [PATCH v3 31/49] block: deal with dirtying pages for multipage bvec

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:00 +0200
Subject[PATCH v3 31/49] block: deal with dirtying pages for multipage bvec
Message-ID<uc8wQ-5yr-73@gated-at.bofh.it>
In reply to#1706169
In bio_check_pages_dirty(), bvec->bv_page is used as flag
for marking if the page has been dirtied & released, and if
no, it will be dirtied in deferred workqueue.

With multipage bvec, we can't do that any more, so change
the logic into checking all pages in one mp bvec, and only
release all these pages if all are dirtied, otherwise dirty
them all in deferred wrokqueue.

Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 block/bio.c | 45 +++++++++++++++++++++++++++++++++++++--------
 1 file changed, 37 insertions(+), 8 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 28697e3c8ce3..716e6917b0fd 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1650,8 +1650,9 @@ void bio_set_pages_dirty(struct bio *bio)
 {
 	struct bio_vec *bvec;
 	int i;
+	struct bvec_iter_all bia;
 
-	bio_for_each_segment_all(bvec, bio, i) {
+	bio_for_each_segment_all_sp(bvec, bio, i, bia) {
 		struct page *page = bvec->bv_page;
 
 		if (page && !PageCompound(page))
@@ -1659,16 +1660,26 @@ void bio_set_pages_dirty(struct bio *bio)
 	}
 }
 
+static inline void release_mp_bvec_pages(struct bio_vec *bvec)
+{
+	struct bio_vec bv;
+	struct bvec_iter iter;
+
+	bvec_for_each_sp_bvec(bv, bvec, iter)
+		put_page(bv.bv_page);
+}
+
 static void bio_release_pages(struct bio *bio)
 {
 	struct bio_vec *bvec;
 	int i;
 
-	bio_for_each_segment_all(bvec, bio, i) {
+	/* iterate each mp bvec */
+	bio_for_each_segment_all_mp(bvec, bio, i) {
 		struct page *page = bvec->bv_page;
 
 		if (page)
-			put_page(page);
+			release_mp_bvec_pages(bvec);
 	}
 }
 
@@ -1712,20 +1723,38 @@ static void bio_dirty_fn(struct work_struct *work)
 	}
 }
 
+static inline void check_mp_bvec_pages(struct bio_vec *bvec,
+		int *nr_dirty, int *nr_pages)
+{
+	struct bio_vec bv;
+	struct bvec_iter iter;
+
+	bvec_for_each_sp_bvec(bv, bvec, iter) {
+		struct page *page = bv.bv_page;
+
+		if (PageDirty(page) || PageCompound(page))
+			(*nr_dirty)++;
+		(*nr_pages)++;
+	}
+}
+
 void bio_check_pages_dirty(struct bio *bio)
 {
 	struct bio_vec *bvec;
 	int nr_clean_pages = 0;
 	int i;
 
-	bio_for_each_segment_all(bvec, bio, i) {
-		struct page *page = bvec->bv_page;
+	bio_for_each_segment_all_mp(bvec, bio, i) {
+		int nr_dirty = 0, nr_pages = 0;
+
+		check_mp_bvec_pages(bvec, &nr_dirty, &nr_pages);
 
-		if (PageDirty(page) || PageCompound(page)) {
-			put_page(page);
+		/* release all pages in the mp bvec if all are dirtied */
+		if (nr_dirty == nr_pages) {
+			release_mp_bvec_pages(bvec);
 			bvec->bv_page = NULL;
 		} else {
-			nr_clean_pages++;
+			nr_clean_pages += nr_pages;
 		}
 	}
 
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1706214 — [PATCH v3 20/49] block: introduce bio_for_each_segment_mp()

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:00 +0200
Subject[PATCH v3 20/49] block: introduce bio_for_each_segment_mp()
Message-ID<uc8wQ-5yr-71@gated-at.bofh.it>
In reply to#1706169
This helper is used to iterate multipage bvec and it is
required in bio_clone().

Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 include/linux/bio.h  | 34 +++++++++++++++++++++++++++++++---
 include/linux/bvec.h | 36 ++++++++++++++++++++++++++++++++----
 2 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/include/linux/bio.h b/include/linux/bio.h
index 80defb3cfca4..ac8248558ab4 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -68,6 +68,9 @@
 #define bio_data_dir(bio) \
 	(op_is_write(bio_op(bio)) ? WRITE : READ)
 
+#define bio_iter_iovec_mp(bio, iter)				\
+	bvec_iter_bvec_mp((bio)->bi_io_vec, (iter))
+
 /*
  * Check whether this bio carries any data or not. A NULL bio is allowed.
  */
@@ -163,8 +166,8 @@ static inline void *bio_data(struct bio *bio)
 #define bio_for_each_segment_all(bvl, bio, i)				\
 	for (i = 0, bvl = (bio)->bi_io_vec; i < (bio)->bi_vcnt; i++, bvl++)
 
-static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
-				    unsigned bytes)
+static inline void __bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
+				      unsigned bytes, bool mp)
 {
 	iter->bi_sector += bytes >> 9;
 
@@ -172,11 +175,26 @@ static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
 		iter->bi_size -= bytes;
 		iter->bi_done += bytes;
 	} else {
-		bvec_iter_advance(bio->bi_io_vec, iter, bytes);
+		if (!mp)
+			bvec_iter_advance(bio->bi_io_vec, iter, bytes);
+		else
+			bvec_iter_advance_mp(bio->bi_io_vec, iter, bytes);
 		/* TODO: It is reasonable to complete bio with error here. */
 	}
 }
 
+static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
+				    unsigned bytes)
+{
+	__bio_advance_iter(bio, iter, bytes, false);
+}
+
+static inline void bio_advance_iter_mp(struct bio *bio, struct bvec_iter *iter,
+				       unsigned bytes)
+{
+	__bio_advance_iter(bio, iter, bytes, true);
+}
+
 static inline bool bio_rewind_iter(struct bio *bio, struct bvec_iter *iter,
 		unsigned int bytes)
 {
@@ -204,6 +222,16 @@ static inline bool bio_rewind_iter(struct bio *bio, struct bvec_iter *iter,
 #define bio_for_each_segment(bvl, bio, iter)				\
 	__bio_for_each_segment(bvl, bio, iter, (bio)->bi_iter)
 
+#define __bio_for_each_segment_mp(bvl, bio, iter, start)		\
+	for (iter = (start);						\
+	     (iter).bi_size &&						\
+		((bvl = bio_iter_iovec_mp((bio), (iter))), 1);		\
+	     bio_advance_iter_mp((bio), &(iter), (bvl).bv_len))
+
+/* returns one real segment(multipage bvec) each time */
+#define bio_for_each_segment_mp(bvl, bio, iter)				\
+	__bio_for_each_segment_mp(bvl, bio, iter, (bio)->bi_iter)
+
 #define bio_iter_last(bvec, iter) ((iter).bi_size == (bvec).bv_len)
 
 static inline unsigned bio_segments(struct bio *bio)
diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index d5f999a493de..c1ec0945451a 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -131,8 +131,16 @@ struct bvec_iter {
 	.bv_offset	= bvec_iter_offset((bvec), (iter)),	\
 })
 
-static inline bool bvec_iter_advance(const struct bio_vec *bv,
-		struct bvec_iter *iter, unsigned bytes)
+#define bvec_iter_bvec_mp(bvec, iter)				\
+((struct bio_vec) {						\
+	.bv_page	= bvec_iter_page_mp((bvec), (iter)),	\
+	.bv_len		= bvec_iter_len_mp((bvec), (iter)),	\
+	.bv_offset	= bvec_iter_offset_mp((bvec), (iter)),	\
+})
+
+static inline bool __bvec_iter_advance(const struct bio_vec *bv,
+				       struct bvec_iter *iter,
+				       unsigned bytes, bool mp)
 {
 	if (WARN_ONCE(bytes > iter->bi_size,
 		     "Attempted to advance past end of bvec iter\n")) {
@@ -141,8 +149,14 @@ static inline bool bvec_iter_advance(const struct bio_vec *bv,
 	}
 
 	while (bytes) {
-		unsigned iter_len = bvec_iter_len(bv, *iter);
-		unsigned len = min(bytes, iter_len);
+		unsigned len;
+
+		if (mp)
+			len = bvec_iter_len_mp(bv, *iter);
+		else
+			len = bvec_iter_len_sp(bv, *iter);
+
+		len = min(bytes, len);
 
 		bytes -= len;
 		iter->bi_size -= len;
@@ -181,6 +195,20 @@ static inline bool bvec_iter_rewind(const struct bio_vec *bv,
 	return true;
 }
 
+static inline bool bvec_iter_advance(const struct bio_vec *bv,
+				     struct bvec_iter *iter,
+				     unsigned bytes)
+{
+	return __bvec_iter_advance(bv, iter, bytes, false);
+}
+
+static inline bool bvec_iter_advance_mp(const struct bio_vec *bv,
+					struct bvec_iter *iter,
+					unsigned bytes)
+{
+	return __bvec_iter_advance(bv, iter, bytes, true);
+}
+
 #define for_each_bvec(bvl, bio_vec, iter, start)			\
 	for (iter = (start);						\
 	     (iter).bi_size &&						\
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1708560 — Re: [PATCH v3 20/49] block: introduce bio_for_each_segment_mp()

FromChristoph Hellwig <hch@infradead.org>
Date2017-08-10 14:30 +0200
SubjectRe: [PATCH v3 20/49] block: introduce bio_for_each_segment_mp()
Message-ID<ucUL8-5wC-19@gated-at.bofh.it>
In reply to#1706214
First: as mentioned in the previous patches I really hate the name
scheme with the _sp and _mp postfixes.

To be clear and understandable we should always name the versions
that iterate over segments *segment* and the ones that iterate over
pages *page*.  To make sure we have a clean compile break for code
using the old _segment name I'd suggest to move to pass the bvec_iter
argument by reference, which is the right thing to do anyway.

As far as the implementation goes I don't think we actually need
to pass the mp argument down.  Instead we always call the full-segment
version of  bvec_iter_len / __bvec_iter_advance and then have an
inner loop that moves the fake bvecs forward inside each full-segment
one - that is implement the per-page version on top of the per-segment
one.

[toc] | [prev] | [next] | [standalone]


#1706215 — [PATCH v3 45/49] fs: crypto: convert to bio_for_each_segment_all_sp()

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:00 +0200
Subject[PATCH v3 45/49] fs: crypto: convert to bio_for_each_segment_all_sp()
Message-ID<uc8wQ-5yr-75@gated-at.bofh.it>
In reply to#1706169
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 fs/crypto/bio.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c
index 6181e9526860..d5516ed19166 100644
--- a/fs/crypto/bio.c
+++ b/fs/crypto/bio.c
@@ -36,8 +36,9 @@ static void completion_pages(struct work_struct *work)
 	struct bio *bio = ctx->r.bio;
 	struct bio_vec *bv;
 	int i;
+	struct bvec_iter_all bia;
 
-	bio_for_each_segment_all(bv, bio, i) {
+	bio_for_each_segment_all_sp(bv, bio, i, bia) {
 		struct page *page = bv->bv_page;
 		int ret = fscrypt_decrypt_page(page->mapping->host, page,
 				PAGE_SIZE, 0, page->index);
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1706217 — [PATCH v3 40/49] ext4: convert to bio_for_each_segment_all_sp()

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:00 +0200
Subject[PATCH v3 40/49] ext4: convert to bio_for_each_segment_all_sp()
Message-ID<uc8wQ-5yr-79@gated-at.bofh.it>
In reply to#1706169
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: linux-ext4@vger.kernel.org
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 fs/ext4/page-io.c  | 3 ++-
 fs/ext4/readpage.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index c2fce4478cca..5a36ad110f14 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -62,8 +62,9 @@ static void ext4_finish_bio(struct bio *bio)
 {
 	int i;
 	struct bio_vec *bvec;
+	struct bvec_iter_all bia;
 
-	bio_for_each_segment_all(bvec, bio, i) {
+	bio_for_each_segment_all_sp(bvec, bio, i, bia) {
 		struct page *page = bvec->bv_page;
 #ifdef CONFIG_EXT4_FS_ENCRYPTION
 		struct page *data_page = NULL;
diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
index 40a5497b0f60..6bd33c4c1f7f 100644
--- a/fs/ext4/readpage.c
+++ b/fs/ext4/readpage.c
@@ -71,6 +71,7 @@ static void mpage_end_io(struct bio *bio)
 {
 	struct bio_vec *bv;
 	int i;
+	struct bvec_iter_all bia;
 
 	if (ext4_bio_encrypted(bio)) {
 		if (bio->bi_status) {
@@ -80,7 +81,7 @@ static void mpage_end_io(struct bio *bio)
 			return;
 		}
 	}
-	bio_for_each_segment_all(bv, bio, i) {
+	bio_for_each_segment_all_sp(bv, bio, i, bia) {
 		struct page *page = bv->bv_page;
 
 		if (!bio->bi_status) {
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1706218 — [PATCH v3 22/49] block: blk-merge: try to make front segments in full size

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:00 +0200
Subject[PATCH v3 22/49] block: blk-merge: try to make front segments in full size
Message-ID<uc8wQ-5yr-81@gated-at.bofh.it>
In reply to#1706169
When merging one bvec into segment, if the bvec is too big
to merge, current policy is to move the whole bvec into another
new segment.

This patchset changes the policy into trying to maximize size of
front segments, that means in above situation, part of bvec
is merged into current segment, and the remainder is put
into next segment.

This patch prepares for support multipage bvec because
it can be quite common to see this case and we should try
to make front segments in full size.

Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 block/blk-merge.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 49 insertions(+), 5 deletions(-)

diff --git a/block/blk-merge.c b/block/blk-merge.c
index d91f07813dee..aeb8933e6cae 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -108,6 +108,7 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
 	bool do_split = true;
 	struct bio *new = NULL;
 	const unsigned max_sectors = get_max_io_size(q, bio);
+	unsigned advance = 0;
 
 	bio_for_each_segment(bv, bio, iter) {
 		/*
@@ -133,12 +134,32 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
 		}
 
 		if (bvprvp && blk_queue_cluster(q)) {
-			if (seg_size + bv.bv_len > queue_max_segment_size(q))
-				goto new_segment;
 			if (!BIOVEC_PHYS_MERGEABLE(bvprvp, &bv))
 				goto new_segment;
 			if (!BIOVEC_SEG_BOUNDARY(q, bvprvp, &bv))
 				goto new_segment;
+			if (seg_size + bv.bv_len > queue_max_segment_size(q)) {
+				/*
+				 * On assumption is that initial value of
+				 * @seg_size(equals to bv.bv_len) won't be
+				 * bigger than max segment size, but will
+				 * becomes false after multipage bvec comes.
+				 */
+				advance = queue_max_segment_size(q) - seg_size;
+
+				if (advance > 0) {
+					seg_size += advance;
+					sectors += advance >> 9;
+					bv.bv_len -= advance;
+					bv.bv_offset += advance;
+				}
+
+				/*
+				 * Still need to put remainder of current
+				 * bvec into a new segment.
+				 */
+				goto new_segment;
+			}
 
 			seg_size += bv.bv_len;
 			bvprv = bv;
@@ -160,6 +181,12 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
 		seg_size = bv.bv_len;
 		sectors += bv.bv_len >> 9;
 
+		/* restore the bvec for iterator */
+		if (advance) {
+			bv.bv_len += advance;
+			bv.bv_offset -= advance;
+			advance = 0;
+		}
 	}
 
 	do_split = false;
@@ -360,16 +387,29 @@ __blk_segment_map_sg(struct request_queue *q, struct bio_vec *bvec,
 {
 
 	int nbytes = bvec->bv_len;
+	unsigned advance = 0;
 
 	if (*sg && *cluster) {
-		if ((*sg)->length + nbytes > queue_max_segment_size(q))
-			goto new_segment;
-
 		if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec))
 			goto new_segment;
 		if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec))
 			goto new_segment;
 
+		/*
+		 * try best to merge part of the bvec into previous
+		 * segment and follow same policy with
+		 * blk_bio_segment_split()
+		 */
+		if ((*sg)->length + nbytes > queue_max_segment_size(q)) {
+			advance = queue_max_segment_size(q) - (*sg)->length;
+			if (advance) {
+				(*sg)->length += advance;
+				bvec->bv_offset += advance;
+				bvec->bv_len -= advance;
+			}
+			goto new_segment;
+		}
+
 		(*sg)->length += nbytes;
 	} else {
 new_segment:
@@ -392,6 +432,10 @@ __blk_segment_map_sg(struct request_queue *q, struct bio_vec *bvec,
 
 		sg_set_page(*sg, bvec->bv_page, nbytes, bvec->bv_offset);
 		(*nsegs)++;
+
+		/* for making iterator happy */
+		bvec->bv_offset -= advance;
+		bvec->bv_len += advance;
 	}
 	*bvprv = *bvec;
 }
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1708584 — Re: [PATCH v3 22/49] block: blk-merge: try to make front segments in full size

FromChristoph Hellwig <hch@infradead.org>
Date2017-08-10 14:30 +0200
SubjectRe: [PATCH v3 22/49] block: blk-merge: try to make front segments in full size
Message-ID<ucULa-5wC-69@gated-at.bofh.it>
In reply to#1706218
This looks like another candidate for a standalone prep series.

[toc] | [prev] | [next] | [standalone]


#1706219 — [PATCH v3 30/49] btrfs: use bvec_get_last_page to get bio's last page

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:00 +0200
Subject[PATCH v3 30/49] btrfs: use bvec_get_last_page to get bio's last page
Message-ID<uc8wQ-5yr-83@gated-at.bofh.it>
In reply to#1706169
Preparing for supporting multipage bvec.

Cc: Chris Mason <clm@fb.com>
Cc: Josef Bacik <jbacik@fb.com>
Cc: David Sterba <dsterba@suse.com>
Cc: linux-btrfs@vger.kernel.org
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 fs/btrfs/compression.c | 5 ++++-
 fs/btrfs/extent_io.c   | 8 ++++++--
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index f795d0a6d176..28746588f228 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -392,8 +392,11 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start,
 static u64 bio_end_offset(struct bio *bio)
 {
 	struct bio_vec *last = &bio->bi_io_vec[bio->bi_vcnt - 1];
+	struct bio_vec bv;
 
-	return page_offset(last->bv_page) + last->bv_len + last->bv_offset;
+	bvec_get_last_page(last, &bv);
+
+	return page_offset(bv.bv_page) + bv.bv_len + bv.bv_offset;
 }
 
 static noinline int add_ra_bio_pages(struct inode *inode,
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 0e7367817b92..c8f6a8657bf2 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2738,11 +2738,15 @@ static int __must_check submit_one_bio(struct bio *bio, int mirror_num,
 {
 	blk_status_t ret = 0;
 	struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
-	struct page *page = bvec->bv_page;
 	struct extent_io_tree *tree = bio->bi_private;
+	struct bio_vec bv;
+	struct page *page;
 	u64 start;
 
-	start = page_offset(page) + bvec->bv_offset;
+	bvec_get_last_page(bvec, &bv);
+	page = bv.bv_page;
+
+	start = page_offset(page) + bv.bv_offset;
 
 	bio->bi_private = NULL;
 	bio_get(bio);
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1706220 — [PATCH v3 36/49] dm-crypt: convert to bio_for_each_segment_all_sp()

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:00 +0200
Subject[PATCH v3 36/49] dm-crypt: convert to bio_for_each_segment_all_sp()
Message-ID<uc8wQ-5yr-85@gated-at.bofh.it>
In reply to#1706169
Cc: Mike Snitzer <snitzer@redhat.com>
Cc:dm-devel@redhat.com
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 drivers/md/dm-crypt.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 664ba3504f48..0f2f44a73a32 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1446,8 +1446,9 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone)
 {
 	unsigned int i;
 	struct bio_vec *bv;
+	struct bvec_iter_all bia;
 
-	bio_for_each_segment_all(bv, clone, i) {
+	bio_for_each_segment_all_sp(bv, clone, i, bia) {
 		BUG_ON(!bv->bv_page);
 		mempool_free(bv->bv_page, cc->page_pool);
 	}
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1706221 — [PATCH v3 19/49] block: implement sp version of bvec iterator helpers

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:00 +0200
Subject[PATCH v3 19/49] block: implement sp version of bvec iterator helpers
Message-ID<uc8wR-5yr-87@gated-at.bofh.it>
In reply to#1706169
This patch implements singlepage version of the following
3 helpers:
	- bvec_iter_offset_sp()
	- bvec_iter_len_sp()
	- bvec_iter_page_sp()

So that one multipage bvec can be splited to singlepage
bvec, and make users of current bvec iterator happy.

Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 include/linux/bvec.h | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index 1eaf7ca5cab3..d5f999a493de 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/bug.h>
 #include <linux/errno.h>
+#include <linux/mm.h>
 
 /*
  * What is multipage bvecs(segment)?
@@ -98,14 +99,25 @@ struct bvec_iter {
 #define bvec_iter_offset_mp(bvec, iter)				\
 	(__bvec_iter_bvec((bvec), (iter))->bv_offset + (iter).bi_bvec_done)
 
+#define bvec_iter_page_idx_mp(bvec, iter)			\
+	(bvec_iter_offset_mp((bvec), (iter)) / PAGE_SIZE)
+
+
 /*
  * <page, offset,length> of singlepage(sp) segment.
  *
  * This helpers will be implemented for building sp bvec in flight.
  */
-#define bvec_iter_offset_sp(bvec, iter)	bvec_iter_offset_mp((bvec), (iter))
-#define bvec_iter_len_sp(bvec, iter)	bvec_iter_len_mp((bvec), (iter))
-#define bvec_iter_page_sp(bvec, iter)	bvec_iter_page_mp((bvec), (iter))
+#define bvec_iter_offset_sp(bvec, iter)					\
+	(bvec_iter_offset_mp((bvec), (iter)) % PAGE_SIZE)
+
+#define bvec_iter_len_sp(bvec, iter)					\
+	min_t(unsigned, bvec_iter_len_mp((bvec), (iter)),		\
+	    (PAGE_SIZE - (bvec_iter_offset_sp((bvec), (iter)))))
+
+#define bvec_iter_page_sp(bvec, iter)					\
+	nth_page(bvec_iter_page_mp((bvec), (iter)),			\
+		 bvec_iter_page_idx_mp((bvec), (iter)))
 
 /* current interfaces support sp style at default */
 #define bvec_iter_page(bvec, iter)	bvec_iter_page_sp((bvec), (iter))
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1708500 — Re: [PATCH v3 19/49] block: implement sp version of bvec iterator helpers

FromChristoph Hellwig <hch@infradead.org>
Date2017-08-10 14:10 +0200
SubjectRe: [PATCH v3 19/49] block: implement sp version of bvec iterator helpers
Message-ID<ucUrN-5pA-29@gated-at.bofh.it>
In reply to#1706221
On Tue, Aug 08, 2017 at 04:45:18PM +0800, Ming Lei wrote:
> This patch implements singlepage version of the following
> 3 helpers:
> 	- bvec_iter_offset_sp()
> 	- bvec_iter_len_sp()
> 	- bvec_iter_page_sp()
> 
> So that one multipage bvec can be splited to singlepage
> bvec, and make users of current bvec iterator happy.

Please merge this into the previous patch, and keep the existing
non postfixed names for the single page version, and use
bvec_iter_segment_* for the multipage versions.

[toc] | [prev] | [next] | [standalone]


#1706231 — [PATCH v3 04/49] mm: page_io.c: comment on direct access to bvec table

FromMing Lei <ming.lei@redhat.com>
Date2017-08-08 11:10 +0200
Subject[PATCH v3 04/49] mm: page_io.c: comment on direct access to bvec table
Message-ID<uc8Gv-5Tu-25@gated-at.bofh.it>
In reply to#1706169
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-mm@kvack.org
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 mm/page_io.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/page_io.c b/mm/page_io.c
index b6c4ac388209..11c6f4a9a25b 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -43,6 +43,7 @@ static struct bio *get_swap_bio(gfp_t gfp_flags,
 
 void end_swap_bio_write(struct bio *bio)
 {
+	/* single page bio, safe for multipage bvec */
 	struct page *page = bio->bi_io_vec[0].bv_page;
 
 	if (bio->bi_status) {
@@ -116,6 +117,7 @@ static void swap_slot_free_notify(struct page *page)
 
 static void end_swap_bio_read(struct bio *bio)
 {
+	/* single page bio, safe for multipage bvec */
 	struct page *page = bio->bi_io_vec[0].bv_page;
 	struct task_struct *waiter = bio->bi_private;
 
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →

Back to top | Article view | linux.kernel


csiph-web