[prev in list] [next in list] [prev in thread] [next in thread] 

List:       git-commits-head
Subject:    btrfs: log csums for all modified extents
From:       "Linux Kernel Mailing List" <linux-kernel () vger ! kernel ! org>
Date:       2017-09-29 20:02:04
Message-ID: 20170929200204.2796121B61 () pdx-korg-gitolite-1 ! ci ! codeaurora ! org
[Download RAW message or body]

Web:        https://git.kernel.org/torvalds/c/8c6c592831a09a28428448e68fb08c6bbb8b9b8b
Commit:     8c6c592831a09a28428448e68fb08c6bbb8b9b8b
Parent:     99c4e3b96c797f047be4e6b7c03cfca01959f146
Refname:    refs/heads/master
Author:     Josef Bacik <jbacik@fb.com>
AuthorDate: Tue Aug 29 10:11:39 2017 -0400
Committer:  David Sterba <dsterba@suse.com>
CommitDate: Tue Sep 26 14:54:16 2017 +0200

    btrfs: log csums for all modified extents
    
    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 <amir73il@gmail.com>
    Signed-off-by: Josef Bacik <jbacik@fb.com>
    Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/tree-log.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index ad7f4bab640b..c800d067fcbf 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4181,6 +4181,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, logged_end;
 	u64 test_gen;
 	int ret = 0;
 	int num = 0;
@@ -4190,10 +4191,11 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
 	down_write(&inode->dio_sem);
 	write_lock(&tree->lock);
 	test_gen = root->fs_info->last_trans_committed;
+	logged_start = start;
+	logged_end = end;
 
 	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
@@ -4208,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);
@@ -4216,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
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic