diff options
Diffstat (limited to 'fs/btrfs/tree-log.c')
| -rw-r--r-- | fs/btrfs/tree-log.c | 17 | 
1 files changed, 17 insertions, 0 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index e07f3376b7df..a5ce99a6c936 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4396,6 +4396,23 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,  	logged_end = end;  	list_for_each_entry_safe(em, n, &tree->modified_extents, list) { +		/* +		 * Skip extents outside our logging range. It's important to do +		 * it for correctness because if we don't ignore them, we may +		 * log them before their ordered extent completes, and therefore +		 * we could log them without logging their respective checksums +		 * (the checksum items are added to the csum tree at the very +		 * end of btrfs_finish_ordered_io()). Also leave such extents +		 * outside of our range in the list, since we may have another +		 * ranged fsync in the near future that needs them. If an extent +		 * outside our range corresponds to a hole, log it to avoid +		 * leaving gaps between extents (fsck will complain when we are +		 * not using the NO_HOLES feature). +		 */ +		if ((em->start > end || em->start + em->len <= start) && +		    em->block_start != EXTENT_MAP_HOLE) +			continue; +  		list_del_init(&em->list);  		/*  		 * Just an arbitrary number, this can be really CPU intensive  |