]>
Commit | Line | Data |
---|---|---|
e5fd101c PS |
1 | autofs-5.0.4 - expire specific submount only |
2 | ||
3 | From: Ian Kent <raven@themaw.net> | |
4 | ||
5 | The submount shutdown at expire assumes that certain locks are not | |
6 | held but when notifying submounts containing nested submounts not | |
7 | all locks were being released. This leads to occassional deadlock | |
8 | when child submounts attempt to shutdown. | |
9 | --- | |
10 | ||
11 | CHANGELOG | 1 + | |
12 | lib/master.c | 33 ++++++++------------------------- | |
13 | 2 files changed, 9 insertions(+), 25 deletions(-) | |
14 | ||
15 | ||
16 | diff --git a/CHANGELOG b/CHANGELOG | |
17 | index 4e8209e..88ca579 100644 | |
18 | --- a/CHANGELOG | |
19 | +++ b/CHANGELOG | |
20 | @@ -1,6 +1,7 @@ | |
21 | ??/??/2009 autofs-5.0.5 | |
22 | ----------------------- | |
23 | - fix dumb libxml2 check | |
24 | +- fix nested submount expire deadlock. | |
25 | ||
26 | 4/11/2008 autofs-5.0.4 | |
27 | ----------------------- | |
28 | diff --git a/lib/master.c b/lib/master.c | |
29 | index a243e6a..e1cc062 100644 | |
30 | --- a/lib/master.c | |
31 | +++ b/lib/master.c | |
32 | @@ -834,7 +834,6 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state | |
33 | { | |
34 | struct list_head *head, *p; | |
35 | struct autofs_point *this = NULL; | |
36 | - size_t plen = strlen(path); | |
37 | int ret = 1; | |
38 | ||
39 | mounts_mutex_lock(ap); | |
40 | @@ -842,37 +841,19 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state | |
41 | head = &ap->submounts; | |
42 | p = head->prev; | |
43 | while (p != head) { | |
44 | - size_t len; | |
45 | - | |
46 | this = list_entry(p, struct autofs_point, mounts); | |
47 | p = p->prev; | |
48 | ||
49 | if (!master_submount_list_empty(this)) { | |
50 | - if (!master_notify_submount(this, path, state)) { | |
51 | - ret = 0; | |
52 | - break; | |
53 | - } | |
54 | + mounts_mutex_unlock(ap); | |
55 | + return master_notify_submount(this, path, state); | |
56 | } | |
57 | ||
58 | - len = strlen(this->path); | |
59 | - | |
60 | - /* Initial path not the same */ | |
61 | - if (strncmp(this->path, path, len)) | |
62 | + /* path not the same */ | |
63 | + if (strcmp(this->path, path)) | |
64 | continue; | |
65 | ||
66 | - /* | |
67 | - * Part of submount tree? | |
68 | - * We must wait till we get to submount itself. | |
69 | - * If it is tell caller by returning true. | |
70 | - */ | |
71 | - if (plen > len) { | |
72 | - /* Not part of this directory tree */ | |
73 | - if (path[len] != '/') | |
74 | - continue; | |
75 | - break; | |
76 | - } | |
77 | - | |
78 | - /* Now we have a submount to expire */ | |
79 | + /* Now we have found the submount we want to expire */ | |
80 | ||
81 | st_mutex_lock(); | |
82 | ||
83 | @@ -901,8 +882,10 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state | |
84 | struct timespec t = { 0, 300000000 }; | |
85 | struct timespec r; | |
86 | ||
87 | - if (this->state != ST_SHUTDOWN) | |
88 | + if (this->state != ST_SHUTDOWN) { | |
89 | + ret = 0; | |
90 | break; | |
91 | + } | |
92 | ||
93 | st_mutex_unlock(); | |
94 | mounts_mutex_unlock(ap); |