From 30156b749bd7ceeec3f75f676c07aedafd26799c Mon Sep 17 00:00:00 2001 From: Rakesh Pandit Date: Wed, 26 Mar 2014 21:34:30 +0200 Subject: Btrfs-progs: chunk_recovery: fix mem leak and pthread_cancel call Free memory if open call fails. Prevent pthread_cancel on threads which have already finished successfully. If all calls to pthread_create and pthread_join are successful, we mistakenly call pthread_cancel because cancel_from and cancel_to are both zero. Make POSIX.1-2001 happy by supplying a non-NULL second argument to pthread_setcanceltype. Signed-off-by: Rakesh Pandit Signed-off-by: David Sterba --- chunk-recover.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'chunk-recover.c') diff --git a/chunk-recover.c b/chunk-recover.c index a05e6447..613d7152 100644 --- a/chunk-recover.c +++ b/chunk-recover.c @@ -745,8 +745,9 @@ static int scan_one_device(void *dev_scan_struct) struct recover_control *rc = dev_scan->rc; struct btrfs_device *device = dev_scan->dev; int fd = dev_scan->fd; + int oldtype; - ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); if (ret) return 1; @@ -845,7 +846,8 @@ static int scan_devices(struct recover_control *rc) if (fd < 0) { fprintf(stderr, "Failed to open device %s\n", dev->name); - return -1; + ret = 1; + goto out2; } dev_scans[devidx].rc = rc; dev_scans[devidx].dev = dev; @@ -856,7 +858,7 @@ static int scan_devices(struct recover_control *rc) if (ret) { cancel_from = 0; cancel_to = devidx - 1; - goto out; + goto out1; } devidx++; } @@ -868,15 +870,16 @@ static int scan_devices(struct recover_control *rc) ret = 1; cancel_from = i + 1; cancel_to = devnr - 1; - break; + goto out1; } i++; } -out: - while (cancel_from <= cancel_to) { +out1: + while (ret && (cancel_from <= cancel_to)) { pthread_cancel(t_scans[cancel_from]); cancel_from++; } +out2: free(dev_scans); free(t_scans); free(t_rets); -- cgit v1.2.3