autofs-5.0.3 - mount thread create condition handling fix From: Ian Kent Make the mount thread creation condition mutex specific to the thread being created. --- daemon/direct.c | 31 +++++++++++++++++++++++-------- daemon/indirect.c | 31 +++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 16 deletions(-) --- autofs-5.0.2.orig/daemon/direct.c +++ autofs-5.0.2/daemon/direct.c @@ -50,7 +50,6 @@ pthread_key_t key_mnt_direct_params; pthread_key_t key_mnt_offset_params; pthread_once_t key_mnt_params_once = PTHREAD_ONCE_INIT; -static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER; static void key_mnt_params_destroy(void *arg) @@ -1218,9 +1217,18 @@ static void mount_send_fail(void *arg) close(mt->ioctlfd); } +static void pending_mutex_destroy(void *arg) +{ + struct pending_args *mt = (struct pending_args *) arg; + int status = pthread_mutex_destroy(&mt->mutex); + if (status) + fatal(status); +} + static void mount_mutex_unlock(void *arg) { - int status = pthread_mutex_unlock(&ma_mutex); + struct pending_args *mt = (struct pending_args *) arg; + int status = pthread_mutex_unlock(&mt->mutex); if (status) fatal(status); } @@ -1243,7 +1251,7 @@ static void *do_mount_direct(void *arg) args = (struct pending_args *) arg; - status = pthread_mutex_lock(&ma_mutex); + status = pthread_mutex_lock(&args->mutex); if (status) fatal(status); @@ -1256,7 +1264,7 @@ static void *do_mount_direct(void *arg) if (status) fatal(status); - mount_mutex_unlock(NULL); + mount_mutex_unlock(args); pthread_cleanup_push(mount_send_fail, &mt); @@ -1533,7 +1541,11 @@ int handle_packet_missing_direct(struct if (status) fatal(status); - status = pthread_mutex_lock(&ma_mutex); + status = pthread_mutex_init(&mt->mutex, NULL); + if (status) + fatal(status); + + status = pthread_mutex_lock(&mt->mutex); if (status) fatal(status); @@ -1553,8 +1565,9 @@ int handle_packet_missing_direct(struct send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token); close(ioctlfd); cache_unlock(mc); - mount_mutex_unlock(NULL); + mount_mutex_unlock(mt); pending_cond_destroy(mt); + pending_mutex_destroy(mt); free_pending_args(mt); pthread_setcancelstate(state, NULL); return 1; @@ -1562,13 +1575,14 @@ int handle_packet_missing_direct(struct cache_unlock(mc); pthread_cleanup_push(free_pending_args, mt); + pthread_cleanup_push(pending_mutex_destroy, mt); pthread_cleanup_push(pending_cond_destroy, mt); - pthread_cleanup_push(mount_mutex_unlock, NULL); + pthread_cleanup_push(mount_mutex_unlock, mt); pthread_setcancelstate(state, NULL); mt->signaled = 0; while (!mt->signaled) { - status = pthread_cond_wait(&mt->cond, &ma_mutex); + status = pthread_cond_wait(&mt->cond, &mt->mutex); if (status) fatal(status); } @@ -1576,6 +1590,7 @@ int handle_packet_missing_direct(struct pthread_cleanup_pop(1); pthread_cleanup_pop(1); pthread_cleanup_pop(1); + pthread_cleanup_pop(1); return 0; } --- autofs-5.0.2.orig/daemon/indirect.c +++ autofs-5.0.2/daemon/indirect.c @@ -40,7 +40,6 @@ extern pthread_attr_t thread_attr; -static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER; static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts) @@ -651,9 +650,18 @@ static void mount_send_fail(void *arg) send_fail(mt->ap->logopt, mt->ap->ioctlfd, mt->wait_queue_token); } +static void pending_mutex_destroy(void *arg) +{ + struct pending_args *mt = (struct pending_args *) arg; + int status = pthread_mutex_destroy(&mt->mutex); + if (status) + fatal(status); +} + static void mount_mutex_unlock(void *arg) { - int status = pthread_mutex_unlock(&ma_mutex); + struct pending_args *mt = (struct pending_args *) arg; + int status = pthread_mutex_unlock(&mt->mutex); if (status) fatal(status); } @@ -676,7 +684,7 @@ static void *do_mount_indirect(void *arg args = (struct pending_args *) arg; - status = pthread_mutex_lock(&ma_mutex); + status = pthread_mutex_lock(&args->mutex); if (status) fatal(status); @@ -689,7 +697,7 @@ static void *do_mount_indirect(void *arg if (status) fatal(status); - mount_mutex_unlock(NULL); + mount_mutex_unlock(args); pthread_cleanup_push(mount_send_fail, &mt); @@ -884,7 +892,11 @@ int handle_packet_missing_indirect(struc if (status) fatal(status); - status = pthread_mutex_lock(&ma_mutex); + status = pthread_mutex_init(&mt->mutex, NULL); + if (status) + fatal(status); + + status = pthread_mutex_lock(&mt->mutex); if (status) fatal(status); @@ -901,21 +913,23 @@ int handle_packet_missing_indirect(struc if (status) { error(ap->logopt, "expire thread create failed"); send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token); - mount_mutex_unlock(NULL); + mount_mutex_unlock(mt); pending_cond_destroy(mt); + pending_mutex_destroy(mt); free_pending_args(mt); pthread_setcancelstate(state, NULL); return 1; } pthread_cleanup_push(free_pending_args, mt); + pthread_cleanup_push(pending_mutex_destroy, mt); pthread_cleanup_push(pending_cond_destroy, mt); - pthread_cleanup_push(mount_mutex_unlock, NULL); + pthread_cleanup_push(mount_mutex_unlock, mt); pthread_setcancelstate(state, NULL); mt->signaled = 0; while (!mt->signaled) { - status = pthread_cond_wait(&mt->cond, &ma_mutex); + status = pthread_cond_wait(&mt->cond, &mt->mutex); if (status) fatal(status); } @@ -923,6 +937,7 @@ int handle_packet_missing_indirect(struc pthread_cleanup_pop(1); pthread_cleanup_pop(1); pthread_cleanup_pop(1); + pthread_cleanup_pop(1); return 0; }