Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp5962ybl; Tue, 7 Jan 2020 13:01:44 -0800 (PST) X-Google-Smtp-Source: APXvYqxeUQxccIqTsDF7uMnQtGX/XRDIi8BYTGcRwnob9PjnSsOXkrXP9R940+iTuMP7eeJGWTfh X-Received: by 2002:aca:d6c4:: with SMTP id n187mr310407oig.29.1578430903579; Tue, 07 Jan 2020 13:01:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1578430903; cv=none; d=google.com; s=arc-20160816; b=cMW1t0xQH5+53uGzE4i74TETtFd9MUliLKZ6cMSU4S1QimAv1ubgwVXmj2dubVlFIT r/wHdkUtUomMUSfUHcd+qsJLL7OfZKE2YyMA3HIF0hsexekh1hsjPxpzKlsuP4jMdfLI H9H0gfEqS57Lp3e6PmJywlPj8DHsOnyiQlPMOYNy+4ylm2SYVL+F7eKz6nGZu/zkpMPc tahzncwTWkhqlfadfDMho7Y+5kpupJ1M6hX92PxGv/UeeDuoLpSR6jXOcWhNZmkDhrfr RInXcdkWxsusowLyLYVTh4NYSfcUnAy6HkpYozdImy+W4rCFIw/z4ZTDP3xe4FxIzZwp re3g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=/YR2tfUkCtq52yKdgso3Y/vHgQAi1WuvbwjJSaeYmMI=; b=oGFRVy7gI9LdS34yB1eCyllvg75JFML/G0dTTXF6I18IvxlOiyyoG+Pftni+/oUBdG 179eHtm4xICaeXYO0mSjXw7Ul/Fc0ifIsmEEhgolHztNp7hbe7CUwxebS+FRiNY+SITH FfPcVkAKjzjxGZeDw6FcCNq2X+0PDLglNE+uLEfacSNjWyuu+DObeglhDJYZKfgEqBBA GO9F0sRaqSJiz6z+rpi80Irztiv7yqv2v2Nu7TTvrRhQBDOwqXiprk/ppu7rlRXnf/6V irI53sTF0ItF3WhzCxI9Inok20jwPeGFHJGve0fCvQBEXnqqwA+YQMxTSzDPiTWrRya7 hDxA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="v1nEGe/Z"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v13si654688otr.140.2020.01.07.13.01.08; Tue, 07 Jan 2020 13:01:43 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="v1nEGe/Z"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728228AbgAGU77 (ORCPT + 99 others); Tue, 7 Jan 2020 15:59:59 -0500 Received: from mail.kernel.org ([198.145.29.99]:33708 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728219AbgAGU74 (ORCPT ); Tue, 7 Jan 2020 15:59:56 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C53812081E; Tue, 7 Jan 2020 20:59:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1578430795; bh=PW1R0kCwObUs5ugOMMm2hMtOWrAcVFJshBPjuKNsFGk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=v1nEGe/ZN8DX1/LThJnGa/Hz57RYbnCx9rdYkFpU60Hte5+mzT/YvrOFOJTB5dNlr rALppzSaqXvT4qfd+yLU7hftljC+6+xfbUrA4wt9G6XX0i8q5Hfhp4DaxqzscuvypR ToH9qf3Nv/FVcHAOJTDkMwvU+rCIwuCYh49j2iA4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Chris Mason , Ming Lei , Jens Axboe Subject: [PATCH 5.4 100/191] block: fix splitting segments on boundary masks Date: Tue, 7 Jan 2020 21:53:40 +0100 Message-Id: <20200107205338.341621494@linuxfoundation.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200107205332.984228665@linuxfoundation.org> References: <20200107205332.984228665@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ming Lei commit 429120f3df2dba2bf3a4a19f4212a53ecefc7102 upstream. We ran into a problem with a mpt3sas based controller, where we would see random (and hard to reproduce) file corruption). The issue seemed specific to this controller, but wasn't specific to the file system. After a lot of debugging, we find out that it's caused by segments spanning a 4G memory boundary. This shouldn't happen, as the default setting for segment boundary masks is 4G. Turns out there are two issues in get_max_segment_size(): 1) The default segment boundary mask is bypassed 2) The segment start address isn't taken into account when checking segment boundary limit Fix these two issues by removing the bypass of the segment boundary check even if the mask is set to the default value, and taking into account the actual start address of the request when checking if a segment needs splitting. Cc: stable@vger.kernel.org # v5.1+ Reviewed-by: Chris Mason Tested-by: Chris Mason Fixes: dcebd755926b ("block: use bio_for_each_bvec() to compute multi-page bvec count") Signed-off-by: Ming Lei Dropped const on the page pointer, ppc page_to_phys() doesn't mark the page as const... Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- block/blk-merge.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -157,16 +157,14 @@ static inline unsigned get_max_io_size(s return sectors & (lbs - 1); } -static unsigned get_max_segment_size(const struct request_queue *q, - unsigned offset) +static inline unsigned get_max_segment_size(const struct request_queue *q, + struct page *start_page, + unsigned long offset) { unsigned long mask = queue_segment_boundary(q); - /* default segment boundary mask means no boundary limit */ - if (mask == BLK_SEG_BOUNDARY_MASK) - return queue_max_segment_size(q); - - return min_t(unsigned long, mask - (mask & offset) + 1, + offset = mask & (page_to_phys(start_page) + offset); + return min_t(unsigned long, mask - offset + 1, queue_max_segment_size(q)); } @@ -201,7 +199,8 @@ static bool bvec_split_segs(const struct unsigned seg_size = 0; while (len && *nsegs < max_segs) { - seg_size = get_max_segment_size(q, bv->bv_offset + total_len); + seg_size = get_max_segment_size(q, bv->bv_page, + bv->bv_offset + total_len); seg_size = min(seg_size, len); (*nsegs)++; @@ -404,7 +403,8 @@ static unsigned blk_bvec_map_sg(struct r while (nbytes > 0) { unsigned offset = bvec->bv_offset + total; - unsigned len = min(get_max_segment_size(q, offset), nbytes); + unsigned len = min(get_max_segment_size(q, bvec->bv_page, + offset), nbytes); struct page *page = bvec->bv_page; /*