|
|
49b67f |
autofs-5.1.6 - use struct mnt_list mounted list for expire
|
|
|
49b67f |
|
|
|
49b67f |
From: Ian Kent <raven@themaw.net>
|
|
|
49b67f |
|
|
|
49b67f |
Now we are keeping track of mounted mounts using the mnt_list struct
|
|
|
49b67f |
use it to drive the expire instead of using the system mount table.
|
|
|
49b67f |
|
|
|
49b67f |
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
|
49b67f |
---
|
|
|
49b67f |
CHANGELOG | 1
|
|
|
49b67f |
daemon/direct.c | 61 +++++++----------
|
|
|
49b67f |
daemon/indirect.c | 66 +++++++++----------
|
|
|
49b67f |
include/mounts.h | 5 -
|
|
|
49b67f |
lib/master.c | 36 +---------
|
|
|
49b67f |
lib/mounts.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++--------
|
|
|
49b67f |
6 files changed, 223 insertions(+), 131 deletions(-)
|
|
|
49b67f |
|
|
|
49b67f |
--- autofs-5.1.4.orig/CHANGELOG
|
|
|
49b67f |
+++ autofs-5.1.4/CHANGELOG
|
|
|
49b67f |
@@ -129,6 +129,7 @@ xx/xx/2018 autofs-5.1.5
|
|
|
49b67f |
- fix remount expire.
|
|
|
49b67f |
- fix stale offset directories disable mount.
|
|
|
49b67f |
- use struct mnt_list to track mounted mounts.
|
|
|
49b67f |
+- use struct mnt_list mounted list for expire.
|
|
|
49b67f |
|
|
|
49b67f |
19/12/2017 autofs-5.1.4
|
|
|
49b67f |
- fix spec file url.
|
|
|
49b67f |
--- autofs-5.1.4.orig/daemon/direct.c
|
|
|
49b67f |
+++ autofs-5.1.4/daemon/direct.c
|
|
|
49b67f |
@@ -77,9 +77,8 @@ static void key_mnt_params_init(void)
|
|
|
49b67f |
|
|
|
49b67f |
static void mnts_cleanup(void *arg)
|
|
|
49b67f |
{
|
|
|
49b67f |
- struct mnt_list *mnts = (struct mnt_list *) arg;
|
|
|
49b67f |
- tree_free_mnt_tree(mnts);
|
|
|
49b67f |
- return;
|
|
|
49b67f |
+ struct list_head *mnts = (struct list_head *) arg;
|
|
|
49b67f |
+ mnts_put_expire_list(mnts);
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me)
|
|
|
49b67f |
@@ -788,8 +787,8 @@ out_err:
|
|
|
49b67f |
void *expire_proc_direct(void *arg)
|
|
|
49b67f |
{
|
|
|
49b67f |
struct ioctl_ops *ops = get_ioctl_ops();
|
|
|
49b67f |
- struct mnt_list *mnts = NULL, *next;
|
|
|
49b67f |
- struct list_head list, *p;
|
|
|
49b67f |
+ struct mnt_list *mnt;
|
|
|
49b67f |
+ LIST_HEAD(mnts);
|
|
|
49b67f |
struct expire_args *ea;
|
|
|
49b67f |
struct expire_args ec;
|
|
|
49b67f |
struct autofs_point *ap;
|
|
|
49b67f |
@@ -821,31 +820,24 @@ void *expire_proc_direct(void *arg)
|
|
|
49b67f |
|
|
|
49b67f |
left = 0;
|
|
|
49b67f |
|
|
|
49b67f |
- mnts = tree_make_mnt_tree("/");
|
|
|
49b67f |
- pthread_cleanup_push(mnts_cleanup, mnts);
|
|
|
49b67f |
-
|
|
|
49b67f |
- /* Get a list of mounts select real ones and expire them if possible */
|
|
|
49b67f |
- INIT_LIST_HEAD(&list);
|
|
|
49b67f |
- if (!tree_get_mnt_list(mnts, &list, "/", 0)) {
|
|
|
49b67f |
- ec.status = 0;
|
|
|
49b67f |
- return NULL;
|
|
|
49b67f |
- }
|
|
|
49b67f |
-
|
|
|
49b67f |
- list_for_each(p, &list) {
|
|
|
49b67f |
- next = list_entry(p, struct mnt_list, list);
|
|
|
49b67f |
-
|
|
|
49b67f |
+ /* Get the list of real mounts and expire them if possible */
|
|
|
49b67f |
+ mnts_get_expire_list(&mnts, ap);
|
|
|
49b67f |
+ if (list_empty(&mnts))
|
|
|
49b67f |
+ goto done;
|
|
|
49b67f |
+ pthread_cleanup_push(mnts_cleanup, &mnts);
|
|
|
49b67f |
+ list_for_each_entry(mnt, &mnts, expire) {
|
|
|
49b67f |
/*
|
|
|
49b67f |
* All direct mounts must be present in the map
|
|
|
49b67f |
* entry cache.
|
|
|
49b67f |
*/
|
|
|
49b67f |
pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
|
|
|
49b67f |
master_source_readlock(ap->entry);
|
|
|
49b67f |
- me = lookup_source_mapent(ap, next->mp, LKP_DISTINCT);
|
|
|
49b67f |
+ me = lookup_source_mapent(ap, mnt->mp, LKP_DISTINCT);
|
|
|
49b67f |
pthread_cleanup_pop(1);
|
|
|
49b67f |
if (!me)
|
|
|
49b67f |
continue;
|
|
|
49b67f |
|
|
|
49b67f |
- if (next->flags & MNTS_AUTOFS) {
|
|
|
49b67f |
+ if (mnt->flags & (MNTS_AUTOFS|MNTS_OFFSET)) {
|
|
|
49b67f |
struct stat st;
|
|
|
49b67f |
int ioctlfd;
|
|
|
49b67f |
|
|
|
49b67f |
@@ -856,22 +848,17 @@ void *expire_proc_direct(void *arg)
|
|
|
49b67f |
* one of them and pass on state change.
|
|
|
49b67f |
*/
|
|
|
49b67f |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
|
49b67f |
- if (next->flags & MNTS_INDIRECT) {
|
|
|
49b67f |
- master_notify_submount(ap, next->mp, ap->state);
|
|
|
49b67f |
- pthread_setcancelstate(cur_state, NULL);
|
|
|
49b67f |
- continue;
|
|
|
49b67f |
- }
|
|
|
49b67f |
+ if (mnt->flags & MNTS_AUTOFS)
|
|
|
49b67f |
+ master_notify_submount(ap, mnt->mp, ap->state);
|
|
|
49b67f |
|
|
|
49b67f |
if (me->ioctlfd == -1) {
|
|
|
49b67f |
pthread_setcancelstate(cur_state, NULL);
|
|
|
49b67f |
continue;
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
- /* It's got a mount, deal with in the outer loop */
|
|
|
49b67f |
- if (is_mounted(me->key, MNTS_REAL)) {
|
|
|
49b67f |
- pthread_setcancelstate(cur_state, NULL);
|
|
|
49b67f |
- continue;
|
|
|
49b67f |
- }
|
|
|
49b67f |
+ /* It's got a mount, just send the expire. */
|
|
|
49b67f |
+ if (is_mounted(me->key, MNTS_REAL))
|
|
|
49b67f |
+ goto cont;
|
|
|
49b67f |
|
|
|
49b67f |
/*
|
|
|
49b67f |
* Maybe a manual umount, repair.
|
|
|
49b67f |
@@ -888,19 +875,19 @@ void *expire_proc_direct(void *arg)
|
|
|
49b67f |
cache_writelock(me->mc);
|
|
|
49b67f |
if (me->ioctlfd != -1 &&
|
|
|
49b67f |
fstat(me->ioctlfd, &st) != -1 &&
|
|
|
49b67f |
- !count_mounts(ap, next->mp, st.st_dev)) {
|
|
|
49b67f |
+ !count_mounts(ap, mnt->mp, st.st_dev)) {
|
|
|
49b67f |
ops->close(ap->logopt, me->ioctlfd);
|
|
|
49b67f |
me->ioctlfd = -1;
|
|
|
49b67f |
cache_unlock(me->mc);
|
|
|
49b67f |
- mnts_remove_mount(next->mp, MNTS_MOUNTED);
|
|
|
49b67f |
+ mnts_remove_mount(mnt->mp, MNTS_MOUNTED);
|
|
|
49b67f |
pthread_setcancelstate(cur_state, NULL);
|
|
|
49b67f |
continue;
|
|
|
49b67f |
}
|
|
|
49b67f |
cache_unlock(me->mc);
|
|
|
49b67f |
-
|
|
|
49b67f |
+cont:
|
|
|
49b67f |
ioctlfd = me->ioctlfd;
|
|
|
49b67f |
|
|
|
49b67f |
- ret = ops->expire(ap->logopt, ioctlfd, next->mp, how);
|
|
|
49b67f |
+ ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how);
|
|
|
49b67f |
if (ret) {
|
|
|
49b67f |
left++;
|
|
|
49b67f |
pthread_setcancelstate(cur_state, NULL);
|
|
|
49b67f |
@@ -923,10 +910,10 @@ void *expire_proc_direct(void *arg)
|
|
|
49b67f |
if (ap->state == ST_EXPIRE || ap->state == ST_PRUNE)
|
|
|
49b67f |
pthread_testcancel();
|
|
|
49b67f |
|
|
|
49b67f |
- debug(ap->logopt, "send expire to trigger %s", next->mp);
|
|
|
49b67f |
+ debug(ap->logopt, "send expire to trigger %s", mnt->mp);
|
|
|
49b67f |
|
|
|
49b67f |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
|
49b67f |
- ret = ops->expire(ap->logopt, ioctlfd, next->mp, how);
|
|
|
49b67f |
+ ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how);
|
|
|
49b67f |
if (ret)
|
|
|
49b67f |
left++;
|
|
|
49b67f |
pthread_setcancelstate(cur_state, NULL);
|
|
|
49b67f |
@@ -935,7 +922,7 @@ void *expire_proc_direct(void *arg)
|
|
|
49b67f |
|
|
|
49b67f |
if (left)
|
|
|
49b67f |
debug(ap->logopt, "%d remaining in %s", left, ap->path);
|
|
|
49b67f |
-
|
|
|
49b67f |
+done:
|
|
|
49b67f |
ec.status = left;
|
|
|
49b67f |
|
|
|
49b67f |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
|
49b67f |
--- autofs-5.1.4.orig/daemon/indirect.c
|
|
|
49b67f |
+++ autofs-5.1.4/daemon/indirect.c
|
|
|
49b67f |
@@ -343,17 +343,17 @@ force_umount:
|
|
|
49b67f |
|
|
|
49b67f |
static void mnts_cleanup(void *arg)
|
|
|
49b67f |
{
|
|
|
49b67f |
- struct mnt_list *mnts = (struct mnt_list *) arg;
|
|
|
49b67f |
- free_mnt_list(mnts);
|
|
|
49b67f |
- return;
|
|
|
49b67f |
+ struct list_head *mnts = (struct list_head *) arg;
|
|
|
49b67f |
+ mnts_put_expire_list(mnts);
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
void *expire_proc_indirect(void *arg)
|
|
|
49b67f |
{
|
|
|
49b67f |
struct ioctl_ops *ops = get_ioctl_ops();
|
|
|
49b67f |
struct autofs_point *ap;
|
|
|
49b67f |
- struct mapent *me = NULL;
|
|
|
49b67f |
- struct mnt_list *mnts = NULL, *next;
|
|
|
49b67f |
+ struct mnt_list *mnt;
|
|
|
49b67f |
+ LIST_HEAD(mnts);
|
|
|
49b67f |
+ struct mapent *me;
|
|
|
49b67f |
struct expire_args *ea;
|
|
|
49b67f |
struct expire_args ec;
|
|
|
49b67f |
unsigned int how;
|
|
|
49b67f |
@@ -385,36 +385,34 @@ void *expire_proc_indirect(void *arg)
|
|
|
49b67f |
|
|
|
49b67f |
left = 0;
|
|
|
49b67f |
|
|
|
49b67f |
- /* Get a list of real mounts and expire them if possible */
|
|
|
49b67f |
- mnts = get_mnt_list(ap->path, 0);
|
|
|
49b67f |
- pthread_cleanup_push(mnts_cleanup, mnts);
|
|
|
49b67f |
- for (next = mnts; next; next = next->next) {
|
|
|
49b67f |
+ /* Get the list of real mounts and expire them if possible */
|
|
|
49b67f |
+ mnts_get_expire_list(&mnts, ap);
|
|
|
49b67f |
+ if (list_empty(&mnts))
|
|
|
49b67f |
+ goto done;
|
|
|
49b67f |
+ pthread_cleanup_push(mnts_cleanup, &mnts);
|
|
|
49b67f |
+ list_for_each_entry(mnt, &mnts, expire) {
|
|
|
49b67f |
char *ind_key;
|
|
|
49b67f |
int ret;
|
|
|
49b67f |
|
|
|
49b67f |
- if (next->flags & MNTS_AUTOFS) {
|
|
|
49b67f |
+ if (mnt->flags & (MNTS_AUTOFS|MNTS_OFFSET)) {
|
|
|
49b67f |
/*
|
|
|
49b67f |
* If we have submounts check if this path lives below
|
|
|
49b67f |
* one of them and pass on the state change.
|
|
|
49b67f |
*/
|
|
|
49b67f |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
|
49b67f |
- if (next->flags & MNTS_INDIRECT)
|
|
|
49b67f |
- master_notify_submount(ap, next->mp, ap->state);
|
|
|
49b67f |
- else if (next->flags & MNTS_OFFSET) {
|
|
|
49b67f |
+ if (mnt->flags & MNTS_AUTOFS)
|
|
|
49b67f |
+ master_notify_submount(ap, mnt->mp, ap->state);
|
|
|
49b67f |
+
|
|
|
49b67f |
+ /* An offset without a real mount, check for manual umount */
|
|
|
49b67f |
+ if (mnt->flags & MNTS_OFFSET &&
|
|
|
49b67f |
+ !is_mounted(mnt->mp, MNTS_REAL)) {
|
|
|
49b67f |
struct mnt_list *sbmnt;
|
|
|
49b67f |
struct map_source *map;
|
|
|
49b67f |
struct mapent_cache *mc = NULL;
|
|
|
49b67f |
- struct mapent *me = NULL;
|
|
|
49b67f |
struct stat st;
|
|
|
49b67f |
|
|
|
49b67f |
- /* It's got a mount, deal with in the outer loop */
|
|
|
49b67f |
- if (is_mounted(next->mp, MNTS_REAL)) {
|
|
|
49b67f |
- pthread_setcancelstate(cur_state, NULL);
|
|
|
49b67f |
- continue;
|
|
|
49b67f |
- }
|
|
|
49b67f |
-
|
|
|
49b67f |
/* Don't touch submounts */
|
|
|
49b67f |
- sbmnt = mnts_find_submount(next->mp);
|
|
|
49b67f |
+ sbmnt = mnts_find_submount(mnt->mp);
|
|
|
49b67f |
if (sbmnt) {
|
|
|
49b67f |
mnts_put_mount(sbmnt);
|
|
|
49b67f |
pthread_setcancelstate(cur_state, NULL);
|
|
|
49b67f |
@@ -427,7 +425,7 @@ void *expire_proc_indirect(void *arg)
|
|
|
49b67f |
while (map) {
|
|
|
49b67f |
mc = map->mc;
|
|
|
49b67f |
cache_writelock(mc);
|
|
|
49b67f |
- me = cache_lookup_distinct(mc, next->mp);
|
|
|
49b67f |
+ me = cache_lookup_distinct(mc, mnt->mp);
|
|
|
49b67f |
if (me)
|
|
|
49b67f |
break;
|
|
|
49b67f |
cache_unlock(mc);
|
|
|
49b67f |
@@ -456,10 +454,10 @@ void *expire_proc_indirect(void *arg)
|
|
|
49b67f |
|
|
|
49b67f |
cache_unlock(mc);
|
|
|
49b67f |
master_source_unlock(ap->entry);
|
|
|
49b67f |
+ pthread_setcancelstate(cur_state, NULL);
|
|
|
49b67f |
+ continue;
|
|
|
49b67f |
}
|
|
|
49b67f |
-
|
|
|
49b67f |
pthread_setcancelstate(cur_state, NULL);
|
|
|
49b67f |
- continue;
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
if (ap->state == ST_EXPIRE || ap->state == ST_PRUNE)
|
|
|
49b67f |
@@ -469,7 +467,7 @@ void *expire_proc_indirect(void *arg)
|
|
|
49b67f |
* If the mount corresponds to an offset trigger then
|
|
|
49b67f |
* the key is the path, otherwise it's the last component.
|
|
|
49b67f |
*/
|
|
|
49b67f |
- ind_key = strrchr(next->mp, '/');
|
|
|
49b67f |
+ ind_key = strrchr(mnt->mp, '/');
|
|
|
49b67f |
if (ind_key)
|
|
|
49b67f |
ind_key++;
|
|
|
49b67f |
|
|
|
49b67f |
@@ -482,7 +480,7 @@ void *expire_proc_indirect(void *arg)
|
|
|
49b67f |
*/
|
|
|
49b67f |
pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
|
|
|
49b67f |
master_source_readlock(ap->entry);
|
|
|
49b67f |
- me = lookup_source_mapent(ap, next->mp, LKP_DISTINCT);
|
|
|
49b67f |
+ me = lookup_source_mapent(ap, mnt->mp, LKP_DISTINCT);
|
|
|
49b67f |
if (!me && ind_key)
|
|
|
49b67f |
me = lookup_source_mapent(ap, ind_key, LKP_NORMAL);
|
|
|
49b67f |
pthread_cleanup_pop(1);
|
|
|
49b67f |
@@ -494,10 +492,10 @@ void *expire_proc_indirect(void *arg)
|
|
|
49b67f |
cache_unlock(me->mc);
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
- debug(ap->logopt, "expire %s", next->mp);
|
|
|
49b67f |
+ debug(ap->logopt, "expire %s", mnt->mp);
|
|
|
49b67f |
|
|
|
49b67f |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
|
49b67f |
- ret = ops->expire(ap->logopt, ioctlfd, next->mp, how);
|
|
|
49b67f |
+ ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how);
|
|
|
49b67f |
if (ret)
|
|
|
49b67f |
left++;
|
|
|
49b67f |
pthread_setcancelstate(cur_state, NULL);
|
|
|
49b67f |
@@ -519,14 +517,14 @@ void *expire_proc_indirect(void *arg)
|
|
|
49b67f |
pthread_cleanup_pop(1);
|
|
|
49b67f |
|
|
|
49b67f |
count = offsets = submnts = 0;
|
|
|
49b67f |
- mnts = get_mnt_list(ap->path, 0);
|
|
|
49b67f |
- pthread_cleanup_push(mnts_cleanup, mnts);
|
|
|
49b67f |
+ mnts_get_expire_list(&mnts, ap);
|
|
|
49b67f |
+ pthread_cleanup_push(mnts_cleanup, &mnts);
|
|
|
49b67f |
/* Are there any real mounts left */
|
|
|
49b67f |
- for (next = mnts; next; next = next->next) {
|
|
|
49b67f |
- if (!(next->flags & MNTS_AUTOFS))
|
|
|
49b67f |
+ list_for_each_entry(mnt, &mnts, expire) {
|
|
|
49b67f |
+ if (!(mnt->flags & MNTS_AUTOFS))
|
|
|
49b67f |
count++;
|
|
|
49b67f |
else {
|
|
|
49b67f |
- if (next->flags & MNTS_INDIRECT)
|
|
|
49b67f |
+ if (mnt->flags & MNTS_INDIRECT)
|
|
|
49b67f |
submnts++;
|
|
|
49b67f |
else
|
|
|
49b67f |
offsets++;
|
|
|
49b67f |
@@ -544,7 +542,7 @@ void *expire_proc_indirect(void *arg)
|
|
|
49b67f |
*/
|
|
|
49b67f |
if (count)
|
|
|
49b67f |
debug(ap->logopt, "%d remaining in %s", count, ap->path);
|
|
|
49b67f |
-
|
|
|
49b67f |
+done:
|
|
|
49b67f |
ec.status = left;
|
|
|
49b67f |
|
|
|
49b67f |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
|
49b67f |
--- autofs-5.1.4.orig/include/mounts.h
|
|
|
49b67f |
+++ autofs-5.1.4/include/mounts.h
|
|
|
49b67f |
@@ -63,6 +63,8 @@ struct mnt_list {
|
|
|
49b67f |
|
|
|
49b67f |
/* List of mounts of an autofs_point */
|
|
|
49b67f |
struct list_head mount;
|
|
|
49b67f |
+ /* Mounted mounts list for expire */
|
|
|
49b67f |
+ struct list_head expire;
|
|
|
49b67f |
|
|
|
49b67f |
/* List of sub-mounts of an autofs_point */
|
|
|
49b67f |
struct autofs_point *ap;
|
|
|
49b67f |
@@ -129,15 +131,12 @@ void mnts_put_mount(struct mnt_list *mnt
|
|
|
49b67f |
struct mnt_list *mnts_find_submount(const char *path);
|
|
|
49b67f |
struct mnt_list *mnts_add_submount(struct autofs_point *ap);
|
|
|
49b67f |
void mnts_remove_submount(const char *mp);
|
|
|
49b67f |
-void mnts_get_submount_list(struct list_head *mnts, struct autofs_point *ap);
|
|
|
49b67f |
-void mnts_put_submount_list(struct list_head *mnts);
|
|
|
49b67f |
struct mnt_list *mnts_find_amdmount(const char *path);
|
|
|
49b67f |
struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *entry);
|
|
|
49b67f |
void mnts_remove_amdmount(const char *mp);
|
|
|
49b67f |
struct mnt_list *mnts_add_mount(struct autofs_point *ap, const char *name, unsigned int flags);
|
|
|
49b67f |
void mnts_remove_mount(const char *mp, unsigned int flags);
|
|
|
49b67f |
struct mnt_list *get_mnt_list(const char *path, int include);
|
|
|
49b67f |
-unsigned int mnts_has_mounted_mounts(struct autofs_point *ap);
|
|
|
49b67f |
void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap);
|
|
|
49b67f |
void mnts_put_expire_list(struct list_head *mnts);
|
|
|
49b67f |
void mnts_set_mounted_mount(struct autofs_point *ap, const char *name);
|
|
|
49b67f |
--- autofs-5.1.4.orig/lib/master.c
|
|
|
49b67f |
+++ autofs-5.1.4/lib/master.c
|
|
|
49b67f |
@@ -1133,40 +1133,17 @@ int master_submount_list_empty(struct au
|
|
|
49b67f |
int master_notify_submount(struct autofs_point *ap, const char *path, enum states state)
|
|
|
49b67f |
{
|
|
|
49b67f |
struct mnt_list *this, *sbmnt;
|
|
|
49b67f |
- LIST_HEAD(sbmnts);
|
|
|
49b67f |
int ret = 1;
|
|
|
49b67f |
|
|
|
49b67f |
- mnts_get_submount_list(&sbmnts, ap);
|
|
|
49b67f |
- if (list_empty(&sbmnts))
|
|
|
49b67f |
- return 1;
|
|
|
49b67f |
-
|
|
|
49b67f |
- list_for_each_entry(this, &sbmnts, submount_work) {
|
|
|
49b67f |
- /* Not a submount */
|
|
|
49b67f |
- if (!(this->flags & MNTS_AUTOFS))
|
|
|
49b67f |
- continue;
|
|
|
49b67f |
-
|
|
|
49b67f |
- /* path not the same */
|
|
|
49b67f |
- if (strcmp(this->mp, path))
|
|
|
49b67f |
- continue;
|
|
|
49b67f |
-
|
|
|
49b67f |
- if (!master_submount_list_empty(this->ap)) {
|
|
|
49b67f |
- struct mnt_list *sm;
|
|
|
49b67f |
-
|
|
|
49b67f |
- master_notify_submount(this->ap, path, state);
|
|
|
49b67f |
- sm = mnts_find_submount(path);
|
|
|
49b67f |
- if (!sm)
|
|
|
49b67f |
- continue;
|
|
|
49b67f |
- mnts_put_mount(sm);
|
|
|
49b67f |
- }
|
|
|
49b67f |
-
|
|
|
49b67f |
- /* Now we have found the submount we want to expire */
|
|
|
49b67f |
-
|
|
|
49b67f |
+ this = mnts_find_submount(path);
|
|
|
49b67f |
+ if (this) {
|
|
|
49b67f |
+ /* We have found a submount to expire */
|
|
|
49b67f |
st_mutex_lock();
|
|
|
49b67f |
|
|
|
49b67f |
if (this->ap->state == ST_SHUTDOWN) {
|
|
|
49b67f |
this = NULL;
|
|
|
49b67f |
st_mutex_unlock();
|
|
|
49b67f |
- break;
|
|
|
49b67f |
+ goto done;
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
this->ap->shutdown = ap->shutdown;
|
|
|
49b67f |
@@ -1202,11 +1179,10 @@ int master_notify_submount(struct autofs
|
|
|
49b67f |
st_mutex_lock();
|
|
|
49b67f |
}
|
|
|
49b67f |
st_mutex_unlock();
|
|
|
49b67f |
- break;
|
|
|
49b67f |
+done:
|
|
|
49b67f |
+ mnts_put_mount(this);
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
- mnts_put_submount_list(&sbmnts);
|
|
|
49b67f |
-
|
|
|
49b67f |
return ret;
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
--- autofs-5.1.4.orig/lib/mounts.c
|
|
|
49b67f |
+++ autofs-5.1.4/lib/mounts.c
|
|
|
49b67f |
@@ -888,6 +888,7 @@ static struct mnt_list *mnts_alloc_mount
|
|
|
49b67f |
INIT_LIST_HEAD(&this->submount);
|
|
|
49b67f |
INIT_LIST_HEAD(&this->submount_work);
|
|
|
49b67f |
INIT_LIST_HEAD(&this->amdmount);
|
|
|
49b67f |
+ INIT_LIST_HEAD(&this->expire);
|
|
|
49b67f |
done:
|
|
|
49b67f |
return this;
|
|
|
49b67f |
}
|
|
|
49b67f |
@@ -1022,33 +1023,6 @@ void mnts_remove_submount(const char *mp
|
|
|
49b67f |
mnts_hash_mutex_unlock();
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
-void mnts_get_submount_list(struct list_head *mnts, struct autofs_point *ap)
|
|
|
49b67f |
-{
|
|
|
49b67f |
- struct mnt_list *mnt;
|
|
|
49b67f |
-
|
|
|
49b67f |
- mnts_hash_mutex_lock();
|
|
|
49b67f |
- if (list_empty(&ap->submounts))
|
|
|
49b67f |
- goto done;
|
|
|
49b67f |
- list_for_each_entry(mnt, &ap->submounts, submount) {
|
|
|
49b67f |
- __mnts_get_mount(mnt);
|
|
|
49b67f |
- list_add(&mnt->submount_work, mnts);
|
|
|
49b67f |
- }
|
|
|
49b67f |
-done:
|
|
|
49b67f |
- mnts_hash_mutex_unlock();
|
|
|
49b67f |
-}
|
|
|
49b67f |
-
|
|
|
49b67f |
-void mnts_put_submount_list(struct list_head *mnts)
|
|
|
49b67f |
-{
|
|
|
49b67f |
- struct mnt_list *mnt, *tmp;
|
|
|
49b67f |
-
|
|
|
49b67f |
- mnts_hash_mutex_lock();
|
|
|
49b67f |
- list_for_each_entry_safe(mnt, tmp, mnts, submount_work) {
|
|
|
49b67f |
- list_del_init(&mnt->submount_work);
|
|
|
49b67f |
- __mnts_put_mount(mnt);
|
|
|
49b67f |
- }
|
|
|
49b67f |
- mnts_hash_mutex_unlock();
|
|
|
49b67f |
-}
|
|
|
49b67f |
-
|
|
|
49b67f |
struct mnt_list *mnts_find_amdmount(const char *path)
|
|
|
49b67f |
{
|
|
|
49b67f |
struct mnt_list *mnt;
|
|
|
49b67f |
@@ -1234,6 +1208,163 @@ void mnts_set_mounted_mount(struct autof
|
|
|
49b67f |
}
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
+struct node {
|
|
|
49b67f |
+ struct mnt_list *mnt;
|
|
|
49b67f |
+ struct node *left;
|
|
|
49b67f |
+ struct node *right;
|
|
|
49b67f |
+};
|
|
|
49b67f |
+
|
|
|
49b67f |
+static struct node *new(struct mnt_list *mnt)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ struct node *n;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ n = malloc(sizeof(struct node));
|
|
|
49b67f |
+ if (!n)
|
|
|
49b67f |
+ return NULL;
|
|
|
49b67f |
+ memset(n, 0, sizeof(struct node));
|
|
|
49b67f |
+ n->mnt = mnt;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ return n;
|
|
|
49b67f |
+}
|
|
|
49b67f |
+
|
|
|
49b67f |
+static struct node *tree_root(struct mnt_list *mnt)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ struct node *n;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ n = new(mnt);
|
|
|
49b67f |
+ if (!n) {
|
|
|
49b67f |
+ error(LOGOPT_ANY, "failed to allcate tree root");
|
|
|
49b67f |
+ return NULL;
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+
|
|
|
49b67f |
+ return n;
|
|
|
49b67f |
+}
|
|
|
49b67f |
+
|
|
|
49b67f |
+static struct node *add_left(struct node *this, struct mnt_list *mnt)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ struct node *n;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ n = new(mnt);
|
|
|
49b67f |
+ if (!n) {
|
|
|
49b67f |
+ error(LOGOPT_ANY, "failed to allcate tree node");
|
|
|
49b67f |
+ return NULL;
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+ this->left = n;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ return n;
|
|
|
49b67f |
+}
|
|
|
49b67f |
+
|
|
|
49b67f |
+static struct node *add_right(struct node *this, struct mnt_list *mnt)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ struct node *n;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ n = new(mnt);
|
|
|
49b67f |
+ if (!n) {
|
|
|
49b67f |
+ error(LOGOPT_ANY, "failed to allcate tree node");
|
|
|
49b67f |
+ return NULL;
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+ this->right = n;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ return n;
|
|
|
49b67f |
+}
|
|
|
49b67f |
+
|
|
|
49b67f |
+static struct node *add_node(struct node *root, struct mnt_list *mnt)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ struct node *p, *q;
|
|
|
49b67f |
+ unsigned int mp_len;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ mp_len = strlen(mnt->mp);
|
|
|
49b67f |
+
|
|
|
49b67f |
+ q = root;
|
|
|
49b67f |
+ p = root;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ while (q && strcmp(mnt->mp, p->mnt->mp)) {
|
|
|
49b67f |
+ p = q;
|
|
|
49b67f |
+ if (mp_len < strlen(p->mnt->mp))
|
|
|
49b67f |
+ q = p->left;
|
|
|
49b67f |
+ else
|
|
|
49b67f |
+ q = p->right;
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+
|
|
|
49b67f |
+ if (strcmp(mnt->mp, p->mnt->mp) == 0)
|
|
|
49b67f |
+ error(LOGOPT_ANY, "duplicate entry in mounts list");
|
|
|
49b67f |
+ else {
|
|
|
49b67f |
+ if (mp_len < strlen(p->mnt->mp))
|
|
|
49b67f |
+ return add_left(p, mnt);
|
|
|
49b67f |
+ else
|
|
|
49b67f |
+ return add_right(p, mnt);
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+
|
|
|
49b67f |
+ return NULL;
|
|
|
49b67f |
+}
|
|
|
49b67f |
+
|
|
|
49b67f |
+static void tree_free(struct node *tree)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ if (tree->right)
|
|
|
49b67f |
+ tree_free(tree->right);
|
|
|
49b67f |
+ if (tree->left)
|
|
|
49b67f |
+ tree_free(tree->left);
|
|
|
49b67f |
+ free(tree);
|
|
|
49b67f |
+}
|
|
|
49b67f |
+
|
|
|
49b67f |
+static void traverse(struct node *node, struct list_head *mnts)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ if (node->right)
|
|
|
49b67f |
+ traverse(node->right, mnts);
|
|
|
49b67f |
+ list_add_tail(&node->mnt->expire, mnts);
|
|
|
49b67f |
+ if (node->left)
|
|
|
49b67f |
+ traverse(node->left, mnts);
|
|
|
49b67f |
+}
|
|
|
49b67f |
+
|
|
|
49b67f |
+void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ struct mnt_list *mnt;
|
|
|
49b67f |
+ struct node *tree = NULL;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ mnts_hash_mutex_lock();
|
|
|
49b67f |
+ if (list_empty(&ap->mounts))
|
|
|
49b67f |
+ goto done;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ list_for_each_entry(mnt, &ap->mounts, mount) {
|
|
|
49b67f |
+ struct node *n;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ __mnts_get_mount(mnt);
|
|
|
49b67f |
+
|
|
|
49b67f |
+ if (!tree) {
|
|
|
49b67f |
+ tree = tree_root(mnt);
|
|
|
49b67f |
+ if (!tree) {
|
|
|
49b67f |
+ error(LOGOPT_ANY, "failed to create expire tree root");
|
|
|
49b67f |
+ goto done;
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+ continue;
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+
|
|
|
49b67f |
+ n = add_node(tree, mnt);
|
|
|
49b67f |
+ if (!n) {
|
|
|
49b67f |
+ error(LOGOPT_ANY, "failed to add expire tree node");
|
|
|
49b67f |
+ tree_free(tree);
|
|
|
49b67f |
+ goto done;
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+
|
|
|
49b67f |
+ traverse(tree, mnts);
|
|
|
49b67f |
+ tree_free(tree);
|
|
|
49b67f |
+done:
|
|
|
49b67f |
+ mnts_hash_mutex_unlock();
|
|
|
49b67f |
+}
|
|
|
49b67f |
+
|
|
|
49b67f |
+void mnts_put_expire_list(struct list_head *mnts)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ struct mnt_list *mnt, *tmp;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ mnts_hash_mutex_lock();
|
|
|
49b67f |
+ list_for_each_entry_safe(mnt, tmp, mnts, expire) {
|
|
|
49b67f |
+ list_del_init(&mnt->expire);
|
|
|
49b67f |
+ __mnts_put_mount(mnt);
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+ mnts_hash_mutex_unlock();
|
|
|
49b67f |
+}
|
|
|
49b67f |
+
|
|
|
49b67f |
/* From glibc decode_name() */
|
|
|
49b67f |
/* Since the values in a line are separated by spaces, a name cannot
|
|
|
49b67f |
* contain a space. Therefore some programs encode spaces in names
|