From patchwork Tue Aug 29 14:11:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 9927469 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 E948D6022E for ; Tue, 29 Aug 2017 14:11:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E105722638 for ; Tue, 29 Aug 2017 14:11:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D615028949; Tue, 29 Aug 2017 14:11:47 +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.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID 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 B46702894B for ; Tue, 29 Aug 2017 14:11:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751942AbdH2OLn (ORCPT ); Tue, 29 Aug 2017 10:11:43 -0400 Received: from mail-qt0-f195.google.com ([209.85.216.195]:37002 "EHLO mail-qt0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751417AbdH2OLm (ORCPT ); Tue, 29 Aug 2017 10:11:42 -0400 Received: by mail-qt0-f195.google.com with SMTP id g13so2870495qta.4 for ; Tue, 29 Aug 2017 07:11:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=gVCTsxTuPnmcoAiOkxTFo5TGkg9Vqpik2iCIj3kqv5o=; b=agTZRGA0ZWYLdEnALIBi/Z5KN3ARzLtpXeXBQPW+pcPN3aPXzxii9KtciCqH7vX4lm GddzGZp1U45XlGNKB1RNhUIPgrpAa0Wm8dCXrY6yMQLtpqFbxSjTDFbd3bhAucjHPXIy NYf5lNAGoLyuDUrZGGOQkWqROREvivgfo/RS+BM8m3UYMGAeKC1HrITnzx+x97JU+QNH UIYIRTg1l3hkVWB7KVuMyo1F+IKFFgl0BHv54a1cciXpcbdQYmmufMHwV5tNKKafRVVp gMjoZlOO9sc4f2/TZIEefeTE48rYeU+7Ge9kPrHdZ0aNVYLq/ImPrxX8zdlmx+B7NR87 7p2g== 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; bh=gVCTsxTuPnmcoAiOkxTFo5TGkg9Vqpik2iCIj3kqv5o=; b=ROdA9mVTWOGpXmumlDzZGxod9KRYmmDYt+NC6yqqxiWovSgR0QAEDmX2PRlnEHR00V 47WwskMk/4wLMSklLw/5OVbArgu15Qb0YpwmJTowqVO9b99GhDioCM0RvB2Oegz5nipm 1HbN52qLpPOZuZSFCJiwWTywGUHuPmm+tS+pn9DvApjt5N+GQ6ltrhMjcB3EyUfddhoH GUBIiqTtV/O4mHMIybL1IZKnpafxAMqONo7vFGncyMTvrOeX8ScLkOJVA3lyCt3BnEfR aDH/QRjvzY8EAo6l/CSsBrc158aJvmGpReHMdzY+UFUgNUpBmQwVfEXN33VV0zR2IQ/S qifA== X-Gm-Message-State: AHYfb5g1xGopxcghYd7eCp3MjC3MhBWFatTIneJoikLqeKHJykF+osxJ QU58STnZmkLQrTONRV0= X-Received: by 10.200.43.103 with SMTP id 36mr5912746qtv.283.1504015901704; Tue, 29 Aug 2017 07:11:41 -0700 (PDT) Received: from localhost ([2606:a000:4381:1201:225:22ff:feb3:e51a]) by smtp.gmail.com with ESMTPSA id q203sm1991368qke.27.2017.08.29.07.11.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Aug 2017 07:11:40 -0700 (PDT) From: josef@toxicpanda.com X-Google-Original-From: jbacik@fb.com To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Cc: Josef Bacik Subject: [PATCH] btrfs: log csums for all modified extents Date: Tue, 29 Aug 2017 10:11:39 -0400 Message-Id: <1504015899-13655-1-git-send-email-jbacik@fb.com> X-Mailer: git-send-email 2.7.4 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Josef Bacik Amir reported a bug discovered by his cleaned up version of my dm-log-writes xfstests where we were missing csums at certain replay points. This is because fsx was doing an msync(), which essentially fsync()'s a specific range of a file. We will log all modified extents, but only search for the checksums in the range we are being asked to sync. We cannot simply log the extents in the range we're being asked because we are logging the inode item as it is currently, which if it has had a i_size update before the msync means we will miss extents when replaying. We could possibly get around this by marking the inode with the transaction that extended the i_size to see if we have this case, but this would be racy and we'd have to lock the whole range of the inode to make sure we didn't have an ordered extent outside of our range that was in the middle of completing. Fix this simply by keeping track of the modified extents range and logging the csums for the entire range of extents that we are logging. This makes the xfstest pass. Reported-by: Amir Goldstein Signed-off-by: Josef Bacik --- fs/btrfs/tree-log.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 3a11ae6..1d7b527 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4183,6 +4183,7 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, struct extent_map *em, *n; struct list_head extents; struct extent_map_tree *tree = &inode->extent_tree; + u64 logged_start = start, logged_end = end; u64 test_gen; int ret = 0; int num = 0; @@ -4195,7 +4196,6 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, list_for_each_entry_safe(em, n, &tree->modified_extents, list) { list_del_init(&em->list); - /* * Just an arbitrary number, this can be really CPU intensive * once we start getting a lot of extents, and really once we @@ -4210,6 +4210,12 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, if (em->generation <= test_gen) continue; + + if (em->start < logged_start) + logged_start = em->start; + if ((em->start + em->len - 1) > logged_end) + logged_end = em->start +em->len - 1; + /* Need a ref to keep it from getting evicted from cache */ refcount_inc(&em->refs); set_bit(EXTENT_FLAG_LOGGING, &em->flags); @@ -4218,7 +4224,7 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, } list_sort(NULL, &extents, extent_cmp); - btrfs_get_logged_extents(inode, logged_list, start, end); + btrfs_get_logged_extents(inode, logged_list, logged_start, logged_end); /* * Some ordered extents started by fsync might have completed * before we could collect them into the list logged_list, which