Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp346767ybi; Fri, 7 Jun 2019 09:01:03 -0700 (PDT) X-Google-Smtp-Source: APXvYqyC1bjbMJ5GrCPYq0DLnOn/ahcKGWzKTJfRZ2kzV45YcLv9zUVjtB+0/FFER+vg7srURPh2 X-Received: by 2002:a63:5247:: with SMTP id s7mr3332867pgl.29.1559923263597; Fri, 07 Jun 2019 09:01:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559923263; cv=none; d=google.com; s=arc-20160816; b=a7POPI3ih21QUAT4Hs0gFI5BRo9LphtJWB02hmShPmlOU++cTj0z7rx9Km+CLUASso yWQUTP5P82K3hCKmaOprYHM3X3+WHjg9rxkB22YK99HW22EqSmBWw98puUdMMMC6DM2h w+9st+h3HSxjJwcvDb5xNxbpshxJZ+844Ck87UJLp9YZFW1JhNvtUQXZNwYUoBX92L4r ir3ZnsGYz2a3KmZNYrJALc1k1iiSjRFc/xN4w09+5Injyj3uuCPUBP6Ig8UKNxFVZtSf 3dVyQT4EAQfP3CVUYMmI4QsuziTdtNHN+Nvmg4hjWevw17KLVJBvV30GsoFrMQn5gERY FPxg== 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=dKig9IZ2qmUB/3uK5baleb2x3R/4cpHAab1VW+H3vpA=; b=mStB/3QoNt/2mVvLuOKbC7O6sMGxyGleHzYxqNQT6XS9j3Ntbw3r/T/VM7YgepQg4s aVkVaVSVUQ/MvSjS5U30VwooKRNG8YKV7dbICioG2lgqU4cfoIrnb4jPdjD022/QWf6s mvb+xzAqoqXZW1ruxsgR2qtJ0CvVFeOLvnK1osH+zIYA+ThQsoPJSGotkazWyzzMe5fs rCLHFIzZN138wZqo2Xcr7MYT7gcQfDzwrPExscWATlHl+Z/SGwUZVW+7soOvySccdM2/ OQk2bNUGf7SxPCofz1MmQts210sttpr0VMmQ/7xIF2VjrD+Wim7zKGdHOzGWov/BIk6I 5cnw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=sJ6MwBRt; 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 y15si2015824pfe.133.2019.06.07.09.00.46; Fri, 07 Jun 2019 09:01:03 -0700 (PDT) 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=sJ6MwBRt; 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 S1730539AbfFGPmT (ORCPT + 99 others); Fri, 7 Jun 2019 11:42:19 -0400 Received: from mail.kernel.org ([198.145.29.99]:52766 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730515AbfFGPmQ (ORCPT ); Fri, 7 Jun 2019 11:42:16 -0400 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 D96632146E; Fri, 7 Jun 2019 15:42:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559922136; bh=RjarfynonucbbUomEkYxKJcu/RBYzEt4rAvdZKxpgLc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sJ6MwBRtZg6NTdPt+Nt+HHwWF/cUb78FvGehSK0F+oeRXQ2w/NiympanJJm0yrVbu 3FBzCNztitr9akO9jEEWij/pNwQdb9thK5c+sSk9KxVCi81734mYKhN3Bj5nQjO2Tm YJ/fjrdcCds5wmoOLdcrZUJp1A6JtfeIUk/R+XRw= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Filipe Manana , David Sterba Subject: [PATCH 4.14 42/69] Btrfs: incremental send, fix file corruption when no-holes feature is enabled Date: Fri, 7 Jun 2019 17:39:23 +0200 Message-Id: <20190607153853.568519609@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190607153848.271562617@linuxfoundation.org> References: <20190607153848.271562617@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: Filipe Manana commit 6b1f72e5b82a5c2a4da4d1ebb8cc01913ddbea21 upstream. When using the no-holes feature, if we have a file with prealloc extents with a start offset beyond the file's eof, doing an incremental send can cause corruption of the file due to incorrect hole detection. Such case requires that the prealloc extent(s) exist in both the parent and send snapshots, and that a hole is punched into the file that covers all its extents that do not cross the eof boundary. Example reproducer: $ mkfs.btrfs -f -O no-holes /dev/sdb $ mount /dev/sdb /mnt/sdb $ xfs_io -f -c "pwrite -S 0xab 0 500K" /mnt/sdb/foobar $ xfs_io -c "falloc -k 1200K 800K" /mnt/sdb/foobar $ btrfs subvolume snapshot -r /mnt/sdb /mnt/sdb/base $ btrfs send -f /tmp/base.snap /mnt/sdb/base $ xfs_io -c "fpunch 0 500K" /mnt/sdb/foobar $ btrfs subvolume snapshot -r /mnt/sdb /mnt/sdb/incr $ btrfs send -p /mnt/sdb/base -f /tmp/incr.snap /mnt/sdb/incr $ md5sum /mnt/sdb/incr/foobar 816df6f64deba63b029ca19d880ee10a /mnt/sdb/incr/foobar $ mkfs.btrfs -f /dev/sdc $ mount /dev/sdc /mnt/sdc $ btrfs receive -f /tmp/base.snap /mnt/sdc $ btrfs receive -f /tmp/incr.snap /mnt/sdc $ md5sum /mnt/sdc/incr/foobar cf2ef71f4a9e90c2f6013ba3b2257ed2 /mnt/sdc/incr/foobar --> Different checksum, because the prealloc extent beyond the file's eof confused the hole detection code and it assumed a hole starting at offset 0 and ending at the offset of the prealloc extent (1200Kb) instead of ending at the offset 500Kb (the file's size). Fix this by ensuring we never cross the file's size when issuing the write operations for a hole. Fixes: 16e7549f045d33 ("Btrfs: incompatible format change to remove hole extents") CC: stable@vger.kernel.org # 3.14+ Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/send.c | 6 ++++++ 1 file changed, 6 insertions(+) --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -5013,6 +5013,12 @@ static int send_hole(struct send_ctx *sc u64 len; int ret = 0; + /* + * Don't go beyond the inode's i_size due to prealloc extents that start + * after the i_size. + */ + end = min_t(u64, end, sctx->cur_inode_size); + if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA) return send_update_extent(sctx, offset, end - offset);