Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp519992yba; Mon, 1 Apr 2019 10:57:45 -0700 (PDT) X-Google-Smtp-Source: APXvYqy+P1r9kxrHyyCkNdCj8J2IGDOf53PnvlvbKKr3Sc/azG0XPP5HDEMqtdCktObnjWWL9bkR X-Received: by 2002:a62:1318:: with SMTP id b24mr61326393pfj.201.1554141465137; Mon, 01 Apr 2019 10:57:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1554141465; cv=none; d=google.com; s=arc-20160816; b=COXTzo8HcNzYdLL8xjG9ToqT7SPu+3jrx4zlV6HWM0bIG+c8qsjdmSSomad0DDmhG/ w+NfSXsq/hdxUjxzNDghCfEYCt8PNAo/0Ex2zRuj1c5RfvDuAow3kZY4xaoKiB8PrUzl jNvG7Zli0SjlgjUWKV01iMZS0Mubj594FqWqt9cx0bbcifoyBdDF49RvMAZJ/bUc7CBa L5AkMQkSXMz5MYtxk1uJng48NTf+dtErGwicHQ7dsfkyULDyEoB6Vb/ympwm5Cck/qOz F/AZmgurm/Fjc9cOxdtDjgpwOeYkQhPT1y/0Gcq/5PbU4e1e/4dvgGRG1t7nhh62uw/R CgbA== 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=zdlLSybMAfrTfO9ICIKA3DhVPNvNevlkfyqtBeMjiY4=; b=Dqn2Y7X5jjwYCv/S9WzaTs5cDdNv/EOGLub6M77cCDCquIjZYvh1Mk296G92xmVpyn MGIp7De/F7j+X46+nFo3eYZcKhIN3N39fiUBYfE1ocVkpxAos31xVdnxeJAxtcEaFdoL A0feKmewJIzwn+gXnWBhWOP/6LolYguFxca4F9O7zzcDs5aj2QIRdbMaQu1KATlRGU88 b8l7oHrbpy+j8wbKcdCDwAqr3vf7n5bp8MRBdPnk3mbLtj9sVe0VTNbRnKuocZp0FRRt AYfDpUHTcgC2LvhbAGVcS3r9gPbpI2T5ZJX1WRbM5AYzX1UNZAhuhDCtqhxqsPEea3dU 3N3A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=rGRf1LZY; 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 q1si4947066pgh.396.2019.04.01.10.57.29; Mon, 01 Apr 2019 10:57:45 -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=rGRf1LZY; 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 S1732135AbfDARzi (ORCPT + 99 others); Mon, 1 Apr 2019 13:55:38 -0400 Received: from mail.kernel.org ([198.145.29.99]:52282 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731381AbfDARWs (ORCPT ); Mon, 1 Apr 2019 13:22:48 -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 5342220883; Mon, 1 Apr 2019 17:22:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1554139367; bh=i5jEq9cExRRNWCNzTqoeygOE3SJcrAFODK7ey2Q3lto=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rGRf1LZYTod5yRghtd5S7OimwqmeZqyQ2d8GTbnAHc9gi6Nmc7jZbrsbp6qAUZrNu tjgtLBhD5SJbSQTl/dYyoymkdTnJ9VKx6khzPDEQKQ8yK6hSB5FsbmOqLzyTxqaaTl Zaf1n1xVmU7a6jvnGjN8SymgODIgUWsV8skO4YmE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Seulbae Kim , Filipe Manana , David Sterba Subject: [PATCH 4.14 056/107] Btrfs: fix incorrect file size after shrinking truncate and fsync Date: Mon, 1 Apr 2019 19:02:11 +0200 Message-Id: <20190401170050.862866177@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190401170045.246405031@linuxfoundation.org> References: <20190401170045.246405031@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore 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 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Filipe Manana commit bf504110bc8aa05df48b0e5f0aa84bfb81e0574b upstream. If we do a shrinking truncate against an inode which is already present in the respective log tree and then rename it, as part of logging the new name we end up logging an inode item that reflects the old size of the file (the one which we previously logged) and not the new smaller size. The decision to preserve the size previously logged was added by commit 1a4bcf470c886b ("Btrfs: fix fsync data loss after adding hard link to inode") in order to avoid data loss after replaying the log. However that decision is only needed for the case the logged inode size is smaller then the current size of the inode, as explained in that commit's change log. If the current size of the inode is smaller then the previously logged size, we know a shrinking truncate happened and therefore need to use that smaller size. Example to trigger the problem: $ mkfs.btrfs -f /dev/sdb $ mount /dev/sdb /mnt $ xfs_io -f -c "pwrite -S 0xab 0 8000" /mnt/foo $ xfs_io -c "fsync" /mnt/foo $ xfs_io -c "truncate 3000" /mnt/foo $ mv /mnt/foo /mnt/bar $ xfs_io -c "fsync" /mnt/bar $ mount /dev/sdb /mnt $ od -t x1 -A d /mnt/bar 0000000 ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab * 0008000 Once we rename the file, we log its name (and inode item), and because the inode was already logged before in the current transaction, we log it with a size of 8000 bytes because that is the size we previously logged (with the first fsync). As part of the rename, besides logging the inode, we do also sync the log, which is done since commit d4682ba03ef618 ("Btrfs: sync log after logging new name"), so the next fsync against our inode is effectively a no-op, since no new changes happened since the rename operation. Even if did not sync the log during the rename operation, the same problem (fize size of 8000 bytes instead of 3000 bytes) would be visible after replaying the log if the log ended up getting synced to disk through some other means, such as for example by fsyncing some other modified file. In the example above the fsync after the rename operation is there just because not every filesystem may guarantee logging/journalling the inode (and syncing the log/journal) during the rename operation, for example it is needed for f2fs, but not for ext4 and xfs. Fix this scenario by, when logging a new name (which is triggered by rename and link operations), using the current size of the inode instead of the previously logged inode size. A test case for fstests follows soon. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202695 CC: stable@vger.kernel.org # 4.4+ Reported-by: Seulbae Kim Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/tree-log.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4501,6 +4501,19 @@ static int logged_inode_size(struct btrf item = btrfs_item_ptr(path->nodes[0], path->slots[0], struct btrfs_inode_item); *size_ret = btrfs_inode_size(path->nodes[0], item); + /* + * If the in-memory inode's i_size is smaller then the inode + * size stored in the btree, return the inode's i_size, so + * that we get a correct inode size after replaying the log + * when before a power failure we had a shrinking truncate + * followed by addition of a new name (rename / new hard link). + * Otherwise return the inode size from the btree, to avoid + * data loss when replaying a log due to previously doing a + * write that expands the inode's size and logging a new name + * immediately after. + */ + if (*size_ret > inode->vfs_inode.i_size) + *size_ret = inode->vfs_inode.i_size; } btrfs_release_path(path);