|
|
49b67f |
autofs-5.1.6 - use mnt_list for submounts
|
|
|
49b67f |
|
|
|
49b67f |
From: Ian Kent <raven@themaw.net>
|
|
|
49b67f |
|
|
|
49b67f |
Use struct mnt_list objects for submount list entries instead of
|
|
|
49b67f |
struct autofs_point itself.
|
|
|
49b67f |
|
|
|
49b67f |
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
|
49b67f |
---
|
|
|
49b67f |
CHANGELOG | 1
|
|
|
49b67f |
daemon/automount.c | 11 ++++-
|
|
|
49b67f |
daemon/direct.c | 7 ++-
|
|
|
49b67f |
daemon/indirect.c | 5 ++
|
|
|
49b67f |
include/automount.h | 2 -
|
|
|
49b67f |
include/master.h | 2 -
|
|
|
49b67f |
include/mounts.h | 10 +++++
|
|
|
49b67f |
lib/master.c | 93 +++++++++++++++----------------------------------
|
|
|
49b67f |
lib/mounts.c | 81 ++++++++++++++++++++++++++++++++++++++++++
|
|
|
49b67f |
modules/mount_autofs.c | 17 ++++++++
|
|
|
49b67f |
10 files changed, 157 insertions(+), 72 deletions(-)
|
|
|
49b67f |
|
|
|
49b67f |
--- autofs-5.1.4.orig/CHANGELOG
|
|
|
49b67f |
+++ autofs-5.1.4/CHANGELOG
|
|
|
49b67f |
@@ -122,6 +122,7 @@ xx/xx/2018 autofs-5.1.5
|
|
|
49b67f |
- make external mounts independent of amd_entry.
|
|
|
49b67f |
- make external mounts use simpler hashtable.
|
|
|
49b67f |
- add a hash index to mnt_list.
|
|
|
49b67f |
+- use mnt_list for submounts.
|
|
|
49b67f |
|
|
|
49b67f |
19/12/2017 autofs-5.1.4
|
|
|
49b67f |
- fix spec file url.
|
|
|
49b67f |
--- autofs-5.1.4.orig/daemon/automount.c
|
|
|
49b67f |
+++ autofs-5.1.4/daemon/automount.c
|
|
|
49b67f |
@@ -624,6 +624,7 @@ done:
|
|
|
49b67f |
it also tries to umount path itself */
|
|
|
49b67f |
int umount_multi(struct autofs_point *ap, const char *path, int incl)
|
|
|
49b67f |
{
|
|
|
49b67f |
+ struct mnt_list *sbmnt;
|
|
|
49b67f |
int is_autofs_fs;
|
|
|
49b67f |
struct stat st;
|
|
|
49b67f |
int left;
|
|
|
49b67f |
@@ -685,8 +686,11 @@ int umount_multi(struct autofs_point *ap
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
is_autofs_fs = 0;
|
|
|
49b67f |
- if (master_find_submount(ap, path))
|
|
|
49b67f |
+ sbmnt = mnts_find_submount(path);
|
|
|
49b67f |
+ if (sbmnt) {
|
|
|
49b67f |
is_autofs_fs = 1;
|
|
|
49b67f |
+ mnts_put_mount(sbmnt);
|
|
|
49b67f |
+ }
|
|
|
49b67f |
|
|
|
49b67f |
left = 0;
|
|
|
49b67f |
|
|
|
49b67f |
@@ -1717,9 +1721,12 @@ static void handle_mounts_cleanup(void *
|
|
|
49b67f |
|
|
|
49b67f |
if (submount) {
|
|
|
49b67f |
struct amd_entry *am;
|
|
|
49b67f |
+
|
|
|
49b67f |
/* We are finishing up */
|
|
|
49b67f |
ap->parent->submnt_count--;
|
|
|
49b67f |
- list_del_init(&ap->mounts);
|
|
|
49b67f |
+
|
|
|
49b67f |
+ /* Submount at ap->path belongs to parent submount list. */
|
|
|
49b67f |
+ mnts_remove_submount(ap->path);
|
|
|
49b67f |
am = __master_find_amdmount(ap->parent, ap->path);
|
|
|
49b67f |
if (am) {
|
|
|
49b67f |
list_del_init(&am->entries);
|
|
|
49b67f |
--- autofs-5.1.4.orig/daemon/direct.c
|
|
|
49b67f |
+++ autofs-5.1.4/daemon/direct.c
|
|
|
49b67f |
@@ -1211,14 +1211,17 @@ static void *do_mount_direct(void *arg)
|
|
|
49b67f |
*/
|
|
|
49b67f |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
|
|
49b67f |
if (status) {
|
|
|
49b67f |
+ struct mnt_list *sbmnt;
|
|
|
49b67f |
struct mapent *me;
|
|
|
49b67f |
struct statfs fs;
|
|
|
49b67f |
unsigned int close_fd = 0;
|
|
|
49b67f |
|
|
|
49b67f |
+ sbmnt = mnts_find_submount(mt.name);
|
|
|
49b67f |
if (statfs(mt.name, &fs) == -1 ||
|
|
|
49b67f |
- (fs.f_type == AUTOFS_SUPER_MAGIC &&
|
|
|
49b67f |
- !master_find_submount(ap, mt.name)))
|
|
|
49b67f |
+ (fs.f_type == AUTOFS_SUPER_MAGIC && !sbmnt))
|
|
|
49b67f |
close_fd = 1;
|
|
|
49b67f |
+ if (sbmnt)
|
|
|
49b67f |
+ mnts_put_mount(sbmnt);
|
|
|
49b67f |
cache_writelock(mt.mc);
|
|
|
49b67f |
if ((me = cache_lookup_distinct(mt.mc, mt.name))) {
|
|
|
49b67f |
/*
|
|
|
49b67f |
--- autofs-5.1.4.orig/daemon/indirect.c
|
|
|
49b67f |
+++ autofs-5.1.4/daemon/indirect.c
|
|
|
49b67f |
@@ -401,6 +401,7 @@ void *expire_proc_indirect(void *arg)
|
|
|
49b67f |
if (next->flags & MNTS_INDIRECT)
|
|
|
49b67f |
master_notify_submount(ap, next->mp, ap->state);
|
|
|
49b67f |
else if (next->flags & MNTS_OFFSET) {
|
|
|
49b67f |
+ struct mnt_list *sbmnt;
|
|
|
49b67f |
struct map_source *map;
|
|
|
49b67f |
struct mapent_cache *mc = NULL;
|
|
|
49b67f |
struct mapent *me = NULL;
|
|
|
49b67f |
@@ -413,7 +414,9 @@ void *expire_proc_indirect(void *arg)
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
/* Don't touch submounts */
|
|
|
49b67f |
- if (master_find_submount(ap, next->mp)) {
|
|
|
49b67f |
+ sbmnt = mnts_find_submount(next->mp);
|
|
|
49b67f |
+ if (sbmnt) {
|
|
|
49b67f |
+ mnts_put_mount(sbmnt);
|
|
|
49b67f |
pthread_setcancelstate(cur_state, NULL);
|
|
|
49b67f |
continue;
|
|
|
49b67f |
}
|
|
|
49b67f |
--- autofs-5.1.4.orig/include/automount.h
|
|
|
49b67f |
+++ autofs-5.1.4/include/automount.h
|
|
|
49b67f |
@@ -570,9 +570,9 @@ struct autofs_point {
|
|
|
49b67f |
struct list_head mounts; /* List of autofs mounts at current level */
|
|
|
49b67f |
struct list_head amdmounts; /* List of non submount amd mounts */
|
|
|
49b67f |
unsigned int submount; /* Is this a submount */
|
|
|
49b67f |
- unsigned int shutdown; /* Shutdown notification */
|
|
|
49b67f |
unsigned int submnt_count; /* Number of submounts */
|
|
|
49b67f |
struct list_head submounts; /* List of child submounts */
|
|
|
49b67f |
+ unsigned int shutdown; /* Shutdown notification */
|
|
|
49b67f |
};
|
|
|
49b67f |
|
|
|
49b67f |
#define UNLINK_AND_CONT 0x01
|
|
|
49b67f |
--- autofs-5.1.4.orig/include/master.h
|
|
|
49b67f |
+++ autofs-5.1.4/include/master.h
|
|
|
49b67f |
@@ -109,8 +109,6 @@ void master_source_current_wait(struct m
|
|
|
49b67f |
void master_source_current_signal(struct master_mapent *);
|
|
|
49b67f |
struct master_mapent *master_find_mapent(struct master *, const char *);
|
|
|
49b67f |
unsigned int master_partial_match_mapent(struct master *, const char *);
|
|
|
49b67f |
-struct autofs_point *__master_find_submount(struct autofs_point *, const char *);
|
|
|
49b67f |
-struct autofs_point *master_find_submount(struct autofs_point *, const char *);
|
|
|
49b67f |
struct amd_entry *__master_find_amdmount(struct autofs_point *, const char *);
|
|
|
49b67f |
struct amd_entry *master_find_amdmount(struct autofs_point *, const char *);
|
|
|
49b67f |
struct master_mapent *master_new_mapent(struct master *, const char *, time_t);
|
|
|
49b67f |
--- autofs-5.1.4.orig/include/mounts.h
|
|
|
49b67f |
+++ autofs-5.1.4/include/mounts.h
|
|
|
49b67f |
@@ -59,6 +59,11 @@ struct mnt_list {
|
|
|
49b67f |
struct hlist_node hash;
|
|
|
49b67f |
unsigned int ref;
|
|
|
49b67f |
|
|
|
49b67f |
+ /* List of sub-mounts of an autofs_point */
|
|
|
49b67f |
+ struct autofs_point *ap;
|
|
|
49b67f |
+ struct list_head submount;
|
|
|
49b67f |
+ struct list_head submount_work;
|
|
|
49b67f |
+
|
|
|
49b67f |
/*
|
|
|
49b67f |
* List operations ie. get_mnt_list.
|
|
|
49b67f |
*/
|
|
|
49b67f |
@@ -108,6 +113,11 @@ int ext_mount_remove(const char *);
|
|
|
49b67f |
int ext_mount_inuse(const char *);
|
|
|
49b67f |
struct mnt_list *mnts_lookup_mount(const char *mp);
|
|
|
49b67f |
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 *get_mnt_list(const char *path, int include);
|
|
|
49b67f |
int unlink_mount_tree(struct autofs_point *ap, const char *mp);
|
|
|
49b67f |
void free_mnt_list(struct mnt_list *list);
|
|
|
49b67f |
--- autofs-5.1.4.orig/lib/master.c
|
|
|
49b67f |
+++ autofs-5.1.4/lib/master.c
|
|
|
49b67f |
@@ -761,34 +761,6 @@ unsigned int master_partial_match_mapent
|
|
|
49b67f |
return ret;
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
-struct autofs_point *__master_find_submount(struct autofs_point *ap, const char *path)
|
|
|
49b67f |
-{
|
|
|
49b67f |
- struct list_head *head, *p;
|
|
|
49b67f |
-
|
|
|
49b67f |
- head = &ap->submounts;
|
|
|
49b67f |
- list_for_each(p, head) {
|
|
|
49b67f |
- struct autofs_point *submount;
|
|
|
49b67f |
-
|
|
|
49b67f |
- submount = list_entry(p, struct autofs_point, mounts);
|
|
|
49b67f |
-
|
|
|
49b67f |
- if (!strcmp(submount->path, path))
|
|
|
49b67f |
- return submount;
|
|
|
49b67f |
- }
|
|
|
49b67f |
-
|
|
|
49b67f |
- return NULL;
|
|
|
49b67f |
-}
|
|
|
49b67f |
-
|
|
|
49b67f |
-struct autofs_point *master_find_submount(struct autofs_point *ap, const char *path)
|
|
|
49b67f |
-{
|
|
|
49b67f |
- struct autofs_point *submount;
|
|
|
49b67f |
-
|
|
|
49b67f |
- mounts_mutex_lock(ap);
|
|
|
49b67f |
- submount = __master_find_submount(ap, path);
|
|
|
49b67f |
- mounts_mutex_unlock(ap);
|
|
|
49b67f |
-
|
|
|
49b67f |
- return submount;
|
|
|
49b67f |
-}
|
|
|
49b67f |
-
|
|
|
49b67f |
struct amd_entry *__master_find_amdmount(struct autofs_point *ap, const char *path)
|
|
|
49b67f |
{
|
|
|
49b67f |
struct list_head *head, *p;
|
|
|
49b67f |
@@ -1190,85 +1162,80 @@ int master_submount_list_empty(struct au
|
|
|
49b67f |
|
|
|
49b67f |
int master_notify_submount(struct autofs_point *ap, const char *path, enum states state)
|
|
|
49b67f |
{
|
|
|
49b67f |
- struct list_head *head, *p;
|
|
|
49b67f |
- struct autofs_point *this = NULL;
|
|
|
49b67f |
+ struct mnt_list *this, *sbmnt;
|
|
|
49b67f |
+ LIST_HEAD(sbmnts);
|
|
|
49b67f |
int ret = 1;
|
|
|
49b67f |
|
|
|
49b67f |
- mounts_mutex_lock(ap);
|
|
|
49b67f |
-
|
|
|
49b67f |
- head = &ap->submounts;
|
|
|
49b67f |
- p = head->prev;
|
|
|
49b67f |
- while (p != head) {
|
|
|
49b67f |
- this = list_entry(p, struct autofs_point, mounts);
|
|
|
49b67f |
- p = p->prev;
|
|
|
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->path, path))
|
|
|
49b67f |
+ if (strcmp(this->mp, path))
|
|
|
49b67f |
continue;
|
|
|
49b67f |
|
|
|
49b67f |
- if (!master_submount_list_empty(this)) {
|
|
|
49b67f |
- char *this_path = strdup(this->path);
|
|
|
49b67f |
- if (this_path) {
|
|
|
49b67f |
- mounts_mutex_unlock(ap);
|
|
|
49b67f |
- master_notify_submount(this, path, state);
|
|
|
49b67f |
- mounts_mutex_lock(ap);
|
|
|
49b67f |
- if (!__master_find_submount(ap, this_path)) {
|
|
|
49b67f |
- free(this_path);
|
|
|
49b67f |
- continue;
|
|
|
49b67f |
- }
|
|
|
49b67f |
- free(this_path);
|
|
|
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 |
st_mutex_lock();
|
|
|
49b67f |
|
|
|
49b67f |
- if (this->state == ST_SHUTDOWN) {
|
|
|
49b67f |
+ if (this->ap->state == ST_SHUTDOWN) {
|
|
|
49b67f |
this = NULL;
|
|
|
49b67f |
st_mutex_unlock();
|
|
|
49b67f |
break;
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
- this->shutdown = ap->shutdown;
|
|
|
49b67f |
+ this->ap->shutdown = ap->shutdown;
|
|
|
49b67f |
|
|
|
49b67f |
- __st_add_task(this, state);
|
|
|
49b67f |
+ __st_add_task(this->ap, state);
|
|
|
49b67f |
|
|
|
49b67f |
st_mutex_unlock();
|
|
|
49b67f |
- mounts_mutex_unlock(ap);
|
|
|
49b67f |
|
|
|
49b67f |
- st_wait_task(this, state, 0);
|
|
|
49b67f |
+ st_wait_task(this->ap, state, 0);
|
|
|
49b67f |
|
|
|
49b67f |
/*
|
|
|
49b67f |
* If our submount gets to state ST_SHUTDOWN, ST_SHUTDOWN_PENDING or
|
|
|
49b67f |
* ST_SHUTDOWN_FORCE we need to wait until it goes away or changes
|
|
|
49b67f |
* to ST_READY.
|
|
|
49b67f |
*/
|
|
|
49b67f |
- mounts_mutex_lock(ap);
|
|
|
49b67f |
st_mutex_lock();
|
|
|
49b67f |
- while ((this = __master_find_submount(ap, path))) {
|
|
|
49b67f |
+ while ((sbmnt = mnts_find_submount(path))) {
|
|
|
49b67f |
struct timespec t = { 0, 300000000 };
|
|
|
49b67f |
struct timespec r;
|
|
|
49b67f |
|
|
|
49b67f |
- if (this->state != ST_SHUTDOWN &&
|
|
|
49b67f |
- this->state != ST_SHUTDOWN_PENDING &&
|
|
|
49b67f |
- this->state != ST_SHUTDOWN_FORCE) {
|
|
|
49b67f |
+ if (sbmnt->ap->state != ST_SHUTDOWN &&
|
|
|
49b67f |
+ sbmnt->ap->state != ST_SHUTDOWN_PENDING &&
|
|
|
49b67f |
+ sbmnt->ap->state != ST_SHUTDOWN_FORCE) {
|
|
|
49b67f |
ret = 0;
|
|
|
49b67f |
+ mnts_put_mount(sbmnt);
|
|
|
49b67f |
break;
|
|
|
49b67f |
}
|
|
|
49b67f |
+ mnts_put_mount(sbmnt);
|
|
|
49b67f |
|
|
|
49b67f |
st_mutex_unlock();
|
|
|
49b67f |
- mounts_mutex_unlock(ap);
|
|
|
49b67f |
while (nanosleep(&t, &r) == -1 && errno == EINTR)
|
|
|
49b67f |
memcpy(&t, &r, sizeof(struct timespec));
|
|
|
49b67f |
- mounts_mutex_lock(ap);
|
|
|
49b67f |
st_mutex_lock();
|
|
|
49b67f |
}
|
|
|
49b67f |
st_mutex_unlock();
|
|
|
49b67f |
break;
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
- mounts_mutex_unlock(ap);
|
|
|
49b67f |
+ mnts_put_submount_list(&sbmnts);
|
|
|
49b67f |
|
|
|
49b67f |
return ret;
|
|
|
49b67f |
}
|
|
|
49b67f |
--- autofs-5.1.4.orig/lib/mounts.c
|
|
|
49b67f |
+++ autofs-5.1.4/lib/mounts.c
|
|
|
49b67f |
@@ -885,6 +885,8 @@ static struct mnt_list *mnts_alloc_mount
|
|
|
49b67f |
|
|
|
49b67f |
this->ref = 1;
|
|
|
49b67f |
INIT_HLIST_NODE(&this->hash);
|
|
|
49b67f |
+ INIT_LIST_HEAD(&this->submount);
|
|
|
49b67f |
+ INIT_LIST_HEAD(&this->submount_work);
|
|
|
49b67f |
done:
|
|
|
49b67f |
return this;
|
|
|
49b67f |
}
|
|
|
49b67f |
@@ -967,6 +969,85 @@ void mnts_put_mount(struct mnt_list *mnt
|
|
|
49b67f |
mnts_hash_mutex_unlock();
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
+struct mnt_list *mnts_find_submount(const char *path)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ struct mnt_list *mnt;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ mnt = mnts_lookup_mount(path);
|
|
|
49b67f |
+ if (mnt && mnt->flags & MNTS_AUTOFS)
|
|
|
49b67f |
+ return mnt;
|
|
|
49b67f |
+ mnts_put_mount(mnt);
|
|
|
49b67f |
+ return NULL;
|
|
|
49b67f |
+}
|
|
|
49b67f |
+
|
|
|
49b67f |
+struct mnt_list *mnts_add_submount(struct autofs_point *ap)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ struct mnt_list *this;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ mnts_hash_mutex_lock();
|
|
|
49b67f |
+ this = mnts_get_mount(ap->path);
|
|
|
49b67f |
+ if (this) {
|
|
|
49b67f |
+ if (!this->ap)
|
|
|
49b67f |
+ this->ap = ap;
|
|
|
49b67f |
+ else if (this->ap != ap ||
|
|
|
49b67f |
+ this->ap->parent != ap->parent) {
|
|
|
49b67f |
+ __mnts_put_mount(this);
|
|
|
49b67f |
+ mnts_hash_mutex_unlock();
|
|
|
49b67f |
+ error(ap->logopt,
|
|
|
49b67f |
+ "conflict with submount owner: %s", ap->path);
|
|
|
49b67f |
+ goto fail;
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+ this->flags |= MNTS_AUTOFS;
|
|
|
49b67f |
+ if (list_empty(&this->submount))
|
|
|
49b67f |
+ list_add_tail(&this->submount, &ap->parent->submounts);
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+ mnts_hash_mutex_unlock();
|
|
|
49b67f |
+fail:
|
|
|
49b67f |
+ return this;
|
|
|
49b67f |
+}
|
|
|
49b67f |
+
|
|
|
49b67f |
+void mnts_remove_submount(const char *mp)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ struct mnt_list *this;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ mnts_hash_mutex_lock();
|
|
|
49b67f |
+ this = mnts_lookup(mp);
|
|
|
49b67f |
+ if (this && this->flags & MNTS_AUTOFS) {
|
|
|
49b67f |
+ this->flags &= ~MNTS_AUTOFS;
|
|
|
49b67f |
+ this->ap = NULL;
|
|
|
49b67f |
+ list_del_init(&this->submount);
|
|
|
49b67f |
+ __mnts_put_mount(this);
|
|
|
49b67f |
+ }
|
|
|
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 |
/* 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
|
|
|
49b67f |
--- autofs-5.1.4.orig/modules/mount_autofs.c
|
|
|
49b67f |
+++ autofs-5.1.4/modules/mount_autofs.c
|
|
|
49b67f |
@@ -65,6 +65,7 @@ int mount_mount(struct autofs_point *ap,
|
|
|
49b67f |
struct master_mapent *entry;
|
|
|
49b67f |
struct map_source *source;
|
|
|
49b67f |
struct autofs_point *nap;
|
|
|
49b67f |
+ struct mnt_list *mnt;
|
|
|
49b67f |
char buf[MAX_ERR_BUF];
|
|
|
49b67f |
char *options, *p;
|
|
|
49b67f |
int len, ret;
|
|
|
49b67f |
@@ -307,6 +308,18 @@ int mount_mount(struct autofs_point *ap,
|
|
|
49b67f |
return 1;
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
+ mnt = mnts_add_submount(nap);
|
|
|
49b67f |
+ if (!mnt) {
|
|
|
49b67f |
+ crit(ap->logopt,
|
|
|
49b67f |
+ MODPREFIX "failed to allocate mount %s", realpath);
|
|
|
49b67f |
+ handle_mounts_startup_cond_destroy(&suc);
|
|
|
49b67f |
+ mounts_mutex_unlock(ap);
|
|
|
49b67f |
+ master_free_map_source(source, 1);
|
|
|
49b67f |
+ master_free_mapent(entry);
|
|
|
49b67f |
+ return 1;
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+
|
|
|
49b67f |
+
|
|
|
49b67f |
suc.ap = nap;
|
|
|
49b67f |
suc.root = mountpoint;
|
|
|
49b67f |
suc.done = 0;
|
|
|
49b67f |
@@ -318,6 +331,7 @@ int mount_mount(struct autofs_point *ap,
|
|
|
49b67f |
"failed to create mount handler thread for %s",
|
|
|
49b67f |
realpath);
|
|
|
49b67f |
handle_mounts_startup_cond_destroy(&suc);
|
|
|
49b67f |
+ mnts_remove_submount(nap->path);
|
|
|
49b67f |
mounts_mutex_unlock(ap);
|
|
|
49b67f |
master_free_map_source(source, 1);
|
|
|
49b67f |
master_free_mapent(entry);
|
|
|
49b67f |
@@ -328,6 +342,7 @@ int mount_mount(struct autofs_point *ap,
|
|
|
49b67f |
status = pthread_cond_wait(&suc.cond, &suc.mutex);
|
|
|
49b67f |
if (status) {
|
|
|
49b67f |
handle_mounts_startup_cond_destroy(&suc);
|
|
|
49b67f |
+ mnts_remove_submount(nap->path);
|
|
|
49b67f |
mounts_mutex_unlock(ap);
|
|
|
49b67f |
master_free_map_source(source, 1);
|
|
|
49b67f |
master_free_mapent(entry);
|
|
|
49b67f |
@@ -339,6 +354,7 @@ int mount_mount(struct autofs_point *ap,
|
|
|
49b67f |
crit(ap->logopt,
|
|
|
49b67f |
MODPREFIX "failed to create submount for %s", realpath);
|
|
|
49b67f |
handle_mounts_startup_cond_destroy(&suc);
|
|
|
49b67f |
+ mnts_remove_submount(nap->path);
|
|
|
49b67f |
mounts_mutex_unlock(ap);
|
|
|
49b67f |
master_free_map_source(source, 1);
|
|
|
49b67f |
master_free_mapent(entry);
|
|
|
49b67f |
@@ -347,7 +363,6 @@ int mount_mount(struct autofs_point *ap,
|
|
|
49b67f |
nap->thid = thid;
|
|
|
49b67f |
|
|
|
49b67f |
ap->submnt_count++;
|
|
|
49b67f |
- list_add(&nap->mounts, &ap->submounts);
|
|
|
49b67f |
|
|
|
49b67f |
handle_mounts_startup_cond_destroy(&suc);
|
|
|
49b67f |
mounts_mutex_unlock(ap);
|