summaryrefslogtreecommitdiff
path: root/btrfs-image.c
diff options
context:
space:
mode:
authorAdam Buchbinder <abuchbinder@google.com>2014-05-18 22:40:42 -0700
committerDavid Sterba <dsterba@suse.cz>2014-08-22 14:39:32 +0200
commitc2429c8a0d34ab47e69c8e66803ad4112ff31985 (patch)
tree56fd93eb10b4de01d0294d21297ab0f321fdef63 /btrfs-image.c
parent85691ebeac9432b4ebb1a268514279a0b2c7c61d (diff)
btrfs-image: Fix a data race in build_chunk_tree.
A mdrestore_struct was being written to without its mutex being held. This race was found with ThreadSanitizer; the relevant part of the report looks like this: WARNING: ThreadSanitizer: data race (pid=18828) Write of size 8 at 0x7fffffc3d088 by main thread: #0 build_chunk_tree .../btrfs-progs/btrfs-image.c:2233 #1 __restore_metadump .../btrfs-progs/btrfs-image.c:2294 #2 restore_metadump .../btrfs-progs/btrfs-image.c:2345 #3 main .../btrfs-progs/btrfs-image.c:2545 Previous read of size 8 at 0x7fffffc3d088 by thread T1 (mutexes: write M0): #0 restore_worker .../btrfs-progs/btrfs-image.c:1636 Location is stack of main thread. Mutex M0 created at: #0 pthread_mutex_init ??:0 #1 mdrestore_init .../btrfs-progs/btrfs-image.c:1766 #2 __restore_metadump .../btrfs-progs/btrfs-image.c:2286 #3 restore_metadump .../btrfs-progs/btrfs-image.c:2345 #4 main .../btrfs-progs/btrfs-image.c:2545 Thread T1 (tid=18830, running) created by main thread at: #0 pthread_create ??:0 #1 mdrestore_init .../btrfs-progs/btrfs-image.c:1784 #2 __restore_metadump .../btrfs-progs/btrfs-image.c:2286 #3 restore_metadump .../btrfs-progs/btrfs-image.c:2345 #4 main .../btrfs-progs/btrfs-image.c:2545 Signed-off-by: Adam Buchbinder <abuchbinder@google.com> Signed-off-by: David Sterba <dsterba@suse.cz>
Diffstat (limited to 'btrfs-image.c')
-rw-r--r--btrfs-image.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/btrfs-image.c b/btrfs-image.c
index 4c31e28c..cf1fe2d9 100644
--- a/btrfs-image.c
+++ b/btrfs-image.c
@@ -2216,6 +2216,7 @@ static int build_chunk_tree(struct mdrestore_struct *mdres,
buffer = tmp;
}
+ pthread_mutex_lock(&mdres->mutex);
super = (struct btrfs_super_block *)buffer;
chunk_root_bytenr = btrfs_super_chunk_root(super);
mdres->leafsize = btrfs_super_leafsize(super);
@@ -2224,6 +2225,7 @@ static int build_chunk_tree(struct mdrestore_struct *mdres,
BTRFS_UUID_SIZE);
mdres->devid = le64_to_cpu(super->dev_item.devid);
free(buffer);
+ pthread_mutex_unlock(&mdres->mutex);
return search_for_chunk_blocks(mdres, chunk_root_bytenr, 0);
}