Skip to content

Commit 76daaec

Browse files
adambuchbinderkdave
authored andcommitted
btrfs-progs: image: Fix data races when reporting progress
Making the code data-race safe requires that reads *and* writes happen under a mutex lock, if any of the access are writes. See Dmitri Vyukov, "Benign data races: what could possibly go wrong?" for more details. The fix here was to put most of the main loop of restore_worker under a mutex lock. This race was detected using fsck-tests/012-leaf-corruption. ================== WARNING: ThreadSanitizer: data race Write of size 4 by main thread: #0 add_cluster btrfs-progs/image/main.c:1931 #1 restore_metadump btrfs-progs/image/main.c:2566 #2 main btrfs-progs/image/main.c:2859 Previous read of size 4 by thread T6: #0 restore_worker btrfs-progs/image/main.c:1720 Location is stack of main thread. Thread T6 (running) created by main thread at: #0 pthread_create <null> #1 mdrestore_init btrfs-progs/image/main.c:1868 #2 restore_metadump btrfs-progs/image/main.c:2534 #3 main btrfs-progs/image/main.c:2859 SUMMARY: ThreadSanitizer: data race btrfs-progs/image/main.c:1931 in add_cluster Signed-off-by: Adam Buchbinder <abuchbinder@google.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 1639cc2 commit 76daaec

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

image/main.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,12 +1720,13 @@ static void *restore_worker(void *data)
17201720
}
17211721
async = list_entry(mdres->list.next, struct async_work, list);
17221722
list_del_init(&async->list);
1723-
pthread_mutex_unlock(&mdres->mutex);
17241723

17251724
if (mdres->compress_method == COMPRESS_ZLIB) {
17261725
size = compress_size;
1726+
pthread_mutex_unlock(&mdres->mutex);
17271727
ret = uncompress(buffer, (unsigned long *)&size,
17281728
async->buffer, async->bufsize);
1729+
pthread_mutex_lock(&mdres->mutex);
17291730
if (ret != Z_OK) {
17301731
error("decompressiion failed with %d", ret);
17311732
err = -EIO;
@@ -1803,7 +1804,6 @@ static void *restore_worker(void *data)
18031804
if (!mdres->multi_devices && async->start == BTRFS_SUPER_INFO_OFFSET)
18041805
write_backup_supers(outfd, outbuf);
18051806

1806-
pthread_mutex_lock(&mdres->mutex);
18071807
if (err && !mdres->error)
18081808
mdres->error = err;
18091809
mdres->num_items--;
@@ -1933,7 +1933,9 @@ static int add_cluster(struct meta_cluster *cluster,
19331933
u32 i, nritems;
19341934
int ret;
19351935

1936+
pthread_mutex_lock(&mdres->mutex);
19361937
mdres->compress_method = header->compress;
1938+
pthread_mutex_unlock(&mdres->mutex);
19371939

19381940
bytenr = le64_to_cpu(header->bytenr) + BLOCK_SIZE;
19391941
nritems = le32_to_cpu(header->nritems);

0 commit comments

Comments
 (0)