95 lines
2.4 KiB
Diff
95 lines
2.4 KiB
Diff
autofs-5.0.4 - expire specific submount only
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
The submount shutdown at expire assumes that certain locks are not
|
|
held but when notifying submounts containing nested submounts not
|
|
all locks were being released. This leads to occassional deadlock
|
|
when child submounts attempt to shutdown.
|
|
---
|
|
|
|
CHANGELOG | 1 +
|
|
lib/master.c | 33 ++++++++-------------------------
|
|
2 files changed, 9 insertions(+), 25 deletions(-)
|
|
|
|
|
|
diff --git a/CHANGELOG b/CHANGELOG
|
|
index 4e8209e..88ca579 100644
|
|
--- a/CHANGELOG
|
|
+++ b/CHANGELOG
|
|
@@ -1,6 +1,7 @@
|
|
??/??/2009 autofs-5.0.5
|
|
-----------------------
|
|
- fix dumb libxml2 check
|
|
+- fix nested submount expire deadlock.
|
|
|
|
4/11/2008 autofs-5.0.4
|
|
-----------------------
|
|
diff --git a/lib/master.c b/lib/master.c
|
|
index a243e6a..e1cc062 100644
|
|
--- a/lib/master.c
|
|
+++ b/lib/master.c
|
|
@@ -834,7 +834,6 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state
|
|
{
|
|
struct list_head *head, *p;
|
|
struct autofs_point *this = NULL;
|
|
- size_t plen = strlen(path);
|
|
int ret = 1;
|
|
|
|
mounts_mutex_lock(ap);
|
|
@@ -842,37 +841,19 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state
|
|
head = &ap->submounts;
|
|
p = head->prev;
|
|
while (p != head) {
|
|
- size_t len;
|
|
-
|
|
this = list_entry(p, struct autofs_point, mounts);
|
|
p = p->prev;
|
|
|
|
if (!master_submount_list_empty(this)) {
|
|
- if (!master_notify_submount(this, path, state)) {
|
|
- ret = 0;
|
|
- break;
|
|
- }
|
|
+ mounts_mutex_unlock(ap);
|
|
+ return master_notify_submount(this, path, state);
|
|
}
|
|
|
|
- len = strlen(this->path);
|
|
-
|
|
- /* Initial path not the same */
|
|
- if (strncmp(this->path, path, len))
|
|
+ /* path not the same */
|
|
+ if (strcmp(this->path, path))
|
|
continue;
|
|
|
|
- /*
|
|
- * Part of submount tree?
|
|
- * We must wait till we get to submount itself.
|
|
- * If it is tell caller by returning true.
|
|
- */
|
|
- if (plen > len) {
|
|
- /* Not part of this directory tree */
|
|
- if (path[len] != '/')
|
|
- continue;
|
|
- break;
|
|
- }
|
|
-
|
|
- /* Now we have a submount to expire */
|
|
+ /* Now we have found the submount we want to expire */
|
|
|
|
st_mutex_lock();
|
|
|
|
@@ -901,8 +882,10 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state
|
|
struct timespec t = { 0, 300000000 };
|
|
struct timespec r;
|
|
|
|
- if (this->state != ST_SHUTDOWN)
|
|
+ if (this->state != ST_SHUTDOWN) {
|
|
+ ret = 0;
|
|
break;
|
|
+ }
|
|
|
|
st_mutex_unlock();
|
|
mounts_mutex_unlock(ap);
|