diff --git a/CHANGELOG b/CHANGELOG index b469121..fc939ad 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -26,6 +26,7 @@ - spelling corrections to release notes (Jeff Moyer). - expire individual submounts. - add ino_index locking. +- fix nested submount expiring away when pwd is base of submount. 13/7/2006 autofs-5.0.1 rc1 -------------------------- diff --git a/daemon/state.c b/daemon/state.c index 67d8031..d38a64f 100644 --- a/daemon/state.c +++ b/daemon/state.c @@ -12,6 +12,8 @@ * * ----------------------------------------------------------------------- */ +#include + #include "automount.h" extern pthread_attr_t thread_attr; @@ -37,6 +39,34 @@ static pthread_mutex_t task_mutex = PTHR static pthread_cond_t task_cond = PTHREAD_COND_INITIALIZER; static unsigned int task_signaled; +#define st_mutex_lock() \ +do { \ + int status = pthread_mutex_lock(&mutex); \ + if (status) \ + fatal(status); \ +} while (0) + +#define st_mutex_unlock() \ +do { \ + int status = pthread_mutex_unlock(&mutex); \ + if (status) \ + fatal(status); \ +} while (0) + +#define task_mutex_lock() \ +do { \ + int status = pthread_mutex_lock(&task_mutex); \ + if (status) \ + fatal(status); \ +} while (0) + +#define task_mutex_unlock() \ +do { \ + int status = pthread_mutex_unlock(&task_mutex); \ + if (status) \ + fatal(status); \ +} while (0) + int do_mount_autofs_direct(struct autofs_point *, struct mnt_list *, struct mapent *); void dump_state_queue(void) @@ -86,7 +116,7 @@ void expire_cleanup(void *arg) struct autofs_point *ap; int statefd; enum states next = ST_INVAL; - int success; + int success, ret; ea = (struct expire_args *) arg; ap = ea->ap; @@ -112,7 +142,10 @@ void expire_cleanup(void *arg) pruned or expired everything away, try to shut down */ if (ap->submount && !success) { - next = ST_SHUTDOWN_PENDING; + if (!ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret)) { + if (ret) + next = ST_SHUTDOWN_PENDING; + } break; } @@ -415,11 +448,14 @@ static unsigned int st_readmap(struct au debug(ap->logopt, "state %d path %s", ap->state, ap->path); assert(ap->state == ST_READY); + assert(ap->readmap_thread == 0); + ap->state = ST_READMAP; ra = malloc(sizeof(struct readmap_args)); if (!ra) { error(ap->logopt, "failed to malloc reamap cond struct"); + nextstate(ap->state_pipe[1], ST_READY); return 0; } @@ -448,6 +484,8 @@ static unsigned int st_readmap(struct au ap->readmap_thread = thid; st_set_thid(ap, thid); + pthread_cleanup_push(st_readmap_cleanup, ra); + ra->signaled = 0; while (!ra->signaled) { status = pthread_cond_wait(&ra->cond, &ra->mutex); @@ -455,6 +493,8 @@ static unsigned int st_readmap(struct au fatal(status); } + pthread_cleanup_pop(1); + return 1; } @@ -653,16 +693,12 @@ void st_remove_tasks(struct autofs_point struct state_queue *task, *waiting; int status; - status = pthread_mutex_lock(&mutex); - if (status) - fatal(status); + st_mutex_lock(); head = &state_queue; if (list_empty(head)) { - status = pthread_mutex_unlock(&mutex); - if (status) - fatal(status); + st_mutex_unlock(); return; } @@ -692,9 +728,10 @@ void st_remove_tasks(struct autofs_point if (status) fatal(status); - status = pthread_mutex_unlock(&mutex); - if (status) - fatal(status); + st_mutex_unlock(); + + return; + } static void *do_run_task(void *arg) @@ -705,9 +742,7 @@ static void *do_run_task(void *arg) unsigned long ret = 1; int status; - status = pthread_mutex_lock(&task_mutex); - if (status) - fatal(status); + task_mutex_lock(); task = (struct state_queue *) arg; ap = task->ap; @@ -718,9 +753,7 @@ static void *do_run_task(void *arg) if (status) fatal(status); - status = pthread_mutex_unlock(&task_mutex); - if (status) - fatal(status); + task_mutex_unlock(); state_mutex_lock(ap); @@ -764,16 +797,12 @@ static int run_state_task(struct state_q pthread_t thid; int status; - status = pthread_mutex_lock(&task_mutex); - if (status) - fatal(status); + task_mutex_lock(); status = pthread_create(&thid, &thread_attr, do_run_task, task); if (status) { error(task->ap->logopt, "error running task"); - status = pthread_mutex_unlock(&task_mutex); - if (status) - fatal(status); + task_mutex_unlock(); return 0; } @@ -784,9 +813,7 @@ static int run_state_task(struct state_q fatal(status); } - status = pthread_mutex_unlock(&task_mutex); - if (status) - fatal(status); + task_mutex_unlock(); return 1; } @@ -810,11 +837,10 @@ static void *st_queue_handler(void *arg) { struct list_head *head; struct list_head *p; + struct timespec wait; int status; - status = pthread_mutex_lock(&mutex); - if (status) - fatal(status); + st_mutex_lock(); head = &state_queue; @@ -823,10 +849,17 @@ static void *st_queue_handler(void *arg) * If the state queue list is empty, wait until an * entry is added. */ + head = &state_queue; + wait.tv_sec = time(NULL) + 1; + wait.tv_nsec = 0; + while (list_empty(head)) { - status = pthread_cond_wait(&cond, &mutex); - if (status) + status = pthread_cond_timedwait(&cond, &mutex, &wait); + if (status) { + if (status == ETIMEDOUT) + break; fatal(status); + } } list_for_each(p, head) { @@ -850,11 +883,10 @@ static void *st_queue_handler(void *arg) } while (1) { - struct timespec wait; - wait.tv_sec = time(NULL) + 1; wait.tv_nsec = 0; + signaled = 0; while (!signaled) { status = pthread_cond_timedwait(&cond, &mutex, &wait); if (status) { @@ -863,8 +895,8 @@ static void *st_queue_handler(void *arg) fatal(status); } } - signaled = 0; + head = &state_queue; p = head->next; while (p != head) { struct state_queue *task, *next; @@ -901,7 +933,6 @@ static void *st_queue_handler(void *arg) /* No more tasks for this queue */ if (list_empty(&task->pending)) { list_del(&task->list); - /* debug("task complete %p", task); */ free(task); continue; } @@ -911,10 +942,9 @@ static void *st_queue_handler(void *arg) struct state_queue, pending); list_del_init(&next->pending); - list_add_tail(&next->list, head); + list_add_tail(&next->list, p); list_del(&task->list); - /* debug("task complete %p", task); */ free(task); } diff --git a/include/state.h b/include/state.h index ea4c62a..c756338 100644 --- a/include/state.h +++ b/include/state.h @@ -89,18 +89,4 @@ int st_add_task(struct autofs_point *, e void st_remove_tasks(struct autofs_point *); int st_start_handler(void); -#define st_mutex_lock() \ -do { \ - int status = pthread_mutex_lock(&mutex); \ - if (status) \ - fatal(status); \ -} while (0) - -#define st_mutex_unlock() \ -do { \ - int status = pthread_mutex_unlock(&mutex); \ - if (status) \ - fatal(status); \ -} while (0) - #endif