From patchwork Thu Mar 16 16:12:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 9628855 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8499360244 for ; Thu, 16 Mar 2017 16:15:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 761DA283F9 for ; Thu, 16 Mar 2017 16:15:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6AF582841E; Thu, 16 Mar 2017 16:15:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0A7A1283F9 for ; Thu, 16 Mar 2017 16:15:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755104AbdCPQPU (ORCPT ); Thu, 16 Mar 2017 12:15:20 -0400 Received: from mail-pf0-f195.google.com ([209.85.192.195]:36770 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755098AbdCPQOj (ORCPT ); Thu, 16 Mar 2017 12:14:39 -0400 Received: by mail-pf0-f195.google.com with SMTP id r137so2440668pfr.3; Thu, 16 Mar 2017 09:14:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=0hLJMOQPxZQNjE2Qx6XVp+vKjaTbecQ4+KcPS/SD54U=; b=cAIdoSprrzFv2rTCAKt9XZAdhLUEVGH8wXs17X58FUuihtOES1k0uNX/ZY0cuARzPM I/yIrVZRHUEX4FlnfbQ3FIyNW0002OxbAYIiA9BNRFMHx2mj8njDrnfuJJljB2EX7lRo MorTkEdbgTpinHDwRsu2QT1b0Y6NiYh5APHrPGPtFGEnf+hvzPCat3fJGvYr1qIldmYA GJBL9gEz5vWLRQD3DGKBt4u8odJ2Zy5Iy3AH+ZHBD8bAkM8JtKRl6nmnI7mgCqpN/sq4 wr9wDlJ4WnCA8H4LW6i7P47YCEfv0NvhHPgvkxZpp/67tmE2jTefdxs5PIU+cyGWp5vq JYQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=0hLJMOQPxZQNjE2Qx6XVp+vKjaTbecQ4+KcPS/SD54U=; b=p1GEolpUhhYRRv1tYLAHwHGTzmRgaLKatQXDHkr56iEtUQca76UdrAOrGs8CZ5VodP CAu/8gWHFF8/wyq47wEAlgaNvKVdD62iYNnGhPvyzKehmkKo0mJlqmgL4uNI8Who9hsA zDNPYuYtgDH4RLvglnst8K/bLP9l3/w/HlHXJXUrlHFHsCW08iji9puRcJT+rdwTL0dX 1C2brVQukcaBayQzXc9JwO7vZr5GSyC7AI7qVDFP7ZNsTXWJ5XRoXIYrblXCGNcxHQFu +3aVc0Kffg8Hvdgtmrz1ZzkR3FeC7nVRvT81MAzFV1QaI/5k5hjuUKqHASdXzzKFyeSq 62Fg== X-Gm-Message-State: AFeK/H28UBkrAvHmGRZA6ilOG7Lf1S8gEkoYsCzeOsyIum5S6BqoOZjbvXFBmi4UAdNxSQ== X-Received: by 10.98.82.78 with SMTP id g75mr11237876pfb.245.1489680872982; Thu, 16 Mar 2017 09:14:32 -0700 (PDT) Received: from localhost ([103.192.224.52]) by smtp.gmail.com with ESMTPSA id 19sm11499488pfo.50.2017.03.16.09.14.32 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 16 Mar 2017 09:14:32 -0700 (PDT) From: Ming Lei To: Shaohua Li , Jens Axboe , linux-raid@vger.kernel.org, linux-block@vger.kernel.org, Christoph Hellwig Cc: Ming Lei Subject: [PATCH v3 08/14] block: introduce bio_copy_data_partial Date: Fri, 17 Mar 2017 00:12:29 +0800 Message-Id: <20170316161235.27110-9-tom.leiming@gmail.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170316161235.27110-1-tom.leiming@gmail.com> References: <20170316161235.27110-1-tom.leiming@gmail.com> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Turns out we can use bio_copy_data in raid1's write behind, and we can make alloc_behind_pages() more clean/efficient, but we need to partial version of bio_copy_data(). Signed-off-by: Ming Lei Reviewed-by: Jens Axboe --- block/bio.c | 60 +++++++++++++++++++++++++++++++++++++++++------------ include/linux/bio.h | 2 ++ 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/block/bio.c b/block/bio.c index e75878f8b14a..1ccff0dace89 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1025,19 +1025,8 @@ int bio_alloc_pages(struct bio *bio, gfp_t gfp_mask) } EXPORT_SYMBOL(bio_alloc_pages); -/** - * bio_copy_data - copy contents of data buffers from one chain of bios to - * another - * @src: source bio list - * @dst: destination bio list - * - * If @src and @dst are single bios, bi_next must be NULL - otherwise, treats - * @src and @dst as linked lists of bios. - * - * Stops when it reaches the end of either @src or @dst - that is, copies - * min(src->bi_size, dst->bi_size) bytes (or the equivalent for lists of bios). - */ -void bio_copy_data(struct bio *dst, struct bio *src) +static void __bio_copy_data(struct bio *dst, struct bio *src, + int offset, int size) { struct bvec_iter src_iter, dst_iter; struct bio_vec src_bv, dst_bv; @@ -1047,6 +1036,12 @@ void bio_copy_data(struct bio *dst, struct bio *src) src_iter = src->bi_iter; dst_iter = dst->bi_iter; + /* for supporting partial copy */ + if (offset || size != src->bi_iter.bi_size) { + bio_advance_iter(src, &src_iter, offset); + src_iter.bi_size = size; + } + while (1) { if (!src_iter.bi_size) { src = src->bi_next; @@ -1083,8 +1078,47 @@ void bio_copy_data(struct bio *dst, struct bio *src) bio_advance_iter(dst, &dst_iter, bytes); } } + +/** + * bio_copy_data - copy contents of data buffers from one chain of bios to + * another + * @src: source bio list + * @dst: destination bio list + * + * If @src and @dst are single bios, bi_next must be NULL - otherwise, treats + * @src and @dst as linked lists of bios. + * + * Stops when it reaches the end of either @src or @dst - that is, copies + * min(src->bi_size, dst->bi_size) bytes (or the equivalent for lists of bios). + */ +void bio_copy_data(struct bio *dst, struct bio *src) +{ + __bio_copy_data(dst, src, 0, src->bi_iter.bi_size); +} EXPORT_SYMBOL(bio_copy_data); +/** + * bio_copy_data_partial - copy partial contents of data buffers from one + * chain of bios to another + * @dst: destination bio list + * @src: source bio list + * @offset: starting copy from the offset + * @size: how many bytes to copy + * + * If @src and @dst are single bios, bi_next must be NULL - otherwise, treats + * @src and @dst as linked lists of bios. + * + * Stops when it reaches the end of either @src or @dst - that is, copies + * min(src->bi_size, dst->bi_size) bytes (or the equivalent for lists of bios). + */ +void bio_copy_data_partial(struct bio *dst, struct bio *src, + int offset, int size) +{ + __bio_copy_data(dst, src, offset, size); + +} +EXPORT_SYMBOL(bio_copy_data_partial); + struct bio_map_data { int is_our_pages; struct iov_iter iter; diff --git a/include/linux/bio.h b/include/linux/bio.h index 8e521194f6fc..42b62a0288b0 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -468,6 +468,8 @@ static inline void bio_flush_dcache_pages(struct bio *bi) #endif extern void bio_copy_data(struct bio *dst, struct bio *src); +extern void bio_copy_data_partial(struct bio *dst, struct bio *src, + int offset, int size); extern int bio_alloc_pages(struct bio *bio, gfp_t gfp); extern void bio_free_pages(struct bio *bio);