Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp1831986imm; Mon, 3 Sep 2018 10:34:22 -0700 (PDT) X-Google-Smtp-Source: ANB0VdYXl4B3OMHPj2Xtoggm92wRLUo+VSAKRtevYsXBwcyMUnG5nLuh4xGyXvc/0pU/wgHHdieR X-Received: by 2002:a63:352:: with SMTP id 79-v6mr27158000pgd.112.1535996062271; Mon, 03 Sep 2018 10:34:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535996062; cv=none; d=google.com; s=arc-20160816; b=TNRIeIjELo8+HjCgcFEojjKegg4SoPVJXsbzl5IoYlTeWQRGjLKSxiZjx+Kz65YBib itxF0pdMuD80AvnCZJ+z8hfZ6g4t+RfmcNLBvpcIylRivsleXOhEKEHJcuehUh0j/BKv tIrteYXf4Z/2SROHElOfpE3mXYUY2FO06dLyIn8gJoBUh9PnL3JTG21cjuNAlForHTxd y2sCvJXoDQML6Lib0iG///HRkiJ/BDGY9p30B6o6cKeZAnp9MX7l+ZtAmxAfzfhFX+N2 MpiJ9I8czteETgeHvOFc465uF8Ij9Hw1gYCq8FSn/FlJWexQwXi6GFwdA9F9Vudtlq9e JdTg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=AZgZ9hXzS73Ug8h9w913FcI9uX+bjGRX4vNjqK5LYKA=; b=NBn27IhEfCojRATaM2UXwWwUZKXczofjRJRzlPOs/Uj3ScqtcvdrRZUb42L8dkc7NJ XFCQF/8gMFTUCj3RHtgzvOdGEzH4mofgixNaryLUrMgTuWe0M8jw+93W5G+ZCDRBgTGC ZYD0PhLtvP/3b0wzBwroKtUt4p4sMM5FJQPtMtOffme0rTjq05VWmb7TznFmDwnQmZvn vlSIWJbuRFy4NoHXXROJikjFYM2Wiy0pXrX/o4WAWcf4sUYmz87ZaQorW9rbG4tq6it9 exuTbUDrcUbdPNASB61Ea3nO7MyAn1rrO92r/IMxxJN7wCFJ0EglCD0d49LZ2kh/FCIw SzQQ== ARC-Authentication-Results: i=1; mx.google.com; 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 t19-v6si16701960pgu.285.2018.09.03.10.34.07; Mon, 03 Sep 2018 10:34:22 -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; 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 S1731163AbeICVxX (ORCPT + 99 others); Mon, 3 Sep 2018 17:53:23 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:47474 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728303AbeICVxX (ORCPT ); Mon, 3 Sep 2018 17:53:23 -0400 Received: from localhost (ip-213-127-74-90.ip.prioritytelecom.net [213.127.74.90]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 6A3A6D16; Mon, 3 Sep 2018 17:32:13 +0000 (UTC) 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.18 020/123] Btrfs: send, fix incorrect file layout after hole punching beyond eof Date: Mon, 3 Sep 2018 18:56:04 +0200 Message-Id: <20180903165720.352404711@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165719.499675257@linuxfoundation.org> References: <20180903165719.499675257@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Filipe Manana commit 22d3151c2c4cb517a309154d1e828a28106508c7 upstream. When doing an incremental send, if we have a file in the parent snapshot that has prealloc extents beyond EOF and in the send snapshot it got a hole punch that partially covers the prealloc extents, the send stream, when replayed by a receiver, can result in a file that has a size bigger than it should and filled with zeroes past the correct EOF. For example: $ mkfs.btrfs -f /dev/sdb $ mount /dev/sdb /mnt $ xfs_io -f -c "falloc -k 0 4M" /mnt/foobar $ xfs_io -c "pwrite -S 0xea 0 1M" /mnt/foobar $ btrfs subvolume snapshot -r /mnt /mnt/snap1 $ btrfs send -f /tmp/1.send /mnt/snap1 $ xfs_io -c "fpunch 1M 2M" /mnt/foobar $ btrfs subvolume snapshot -r /mnt /mnt/snap2 $ btrfs send -f /tmp/2.send -p /mnt/snap1 /mnt/snap2 $ stat --format %s /mnt/snap2/foobar 1048576 $ md5sum /mnt/snap2/foobar d31659e82e87798acd4669a1e0a19d4f /mnt/snap2/foobar $ umount /mnt $ mkfs.btrfs -f /dev/sdc $ mount /dev/sdc /mnt $ btrfs receive -f /mnt/1.snap /mnt $ btrfs receive -f /mnt/2.snap /mnt $ stat --format %s /mnt/snap2/foobar 3145728 # --> should be 1Mb and not 3Mb (which was the end offset of hole # punch operation) $ md5sum /mnt/snap2/foobar 117baf295297c2a995f92da725b0b651 /mnt/snap2/foobar # --> should be d31659e82e87798acd4669a1e0a19d4f as in the original fs This issue actually happens only since commit ffa7c4296e93 ("Btrfs: send, do not issue unnecessary truncate operations"), but before that commit we were issuing a write operation full of zeroes (to "punch" a hole) which was extending the file size beyond the correct value and then immediately issue a truncate operation to the correct size and undoing the previous write operation. Since the send protocol does not support fallocate, for extent preallocation and hole punching, fix this by not even attempting to send a "hole" (regular write full of zeroes) if it starts at an offset greater then or equals to the file's size. This approach, besides being much more simple then making send issue the truncate operation, adds the benefit of avoiding the useless pair of write of zeroes and truncate operations, saving time and IO at the receiver and reducing the size of the send stream. A test case for fstests follows soon. Fixes: ffa7c4296e93 ("Btrfs: send, do not issue unnecessary truncate operations") CC: stable@vger.kernel.org # 4.17+ Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/send.c | 9 +++++++++ 1 file changed, 9 insertions(+) --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -5007,6 +5007,15 @@ static int send_hole(struct send_ctx *sc u64 len; int ret = 0; + /* + * A hole that starts at EOF or beyond it. Since we do not yet support + * fallocate (for extent preallocation and hole punching), sending a + * write of zeroes starting at EOF or beyond would later require issuing + * a truncate operation which would undo the write and achieve nothing. + */ + if (offset >= sctx->cur_inode_size) + return 0; + if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA) return send_update_extent(sctx, offset, end - offset);