]> git.pld-linux.org Git - packages/autofs.git/blame - autofs-5.0.4-improve-manual-umount-recovery.patch
- updated to 5.0.5, nfy.
[packages/autofs.git] / autofs-5.0.4-improve-manual-umount-recovery.patch
CommitLineData
e5fd101c
PS
1autofs-5.0.4 - improve manual umount recovery
2
3From: Ian Kent <raven@themaw.net>
4
5The check for manually umounted mounts in the expire of direct mounts is
6racy and the check itself is inadequate in that it can incorrectly clear
7the descriptor of an active mount. Also, we do a similar test following
8the expire which is a waste since we can catch this on the next expire.
9So these two tests have been combined and the check done only prior to
10the expire. In the indirect expire we don't have a check at all so we
11add one.
12---
13
14 CHANGELOG | 1 +
15 daemon/direct.c | 28 ++++++++++------------------
16 daemon/indirect.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
17 3 files changed, 57 insertions(+), 19 deletions(-)
18
19
20diff --git a/CHANGELOG b/CHANGELOG
21index 5e01812..89aaa99 100644
22--- a/CHANGELOG
23+++ b/CHANGELOG
24@@ -45,6 +45,7 @@
25 - fix kernel includes.
26 - dont umount existing direct mount on master re-read.
27 - fix incorrect shutdown introduced by library relaod fixes.
28+- improve manual umount recovery.
29
30 4/11/2008 autofs-5.0.4
31 -----------------------
32diff --git a/daemon/direct.c b/daemon/direct.c
33index 4f4ff20..1ed2b15 100644
34--- a/daemon/direct.c
35+++ b/daemon/direct.c
36@@ -881,13 +881,14 @@ void *expire_proc_direct(void *arg)
37 * avoid maintaining a file handle for control
38 * functions as once it's mounted all opens are
39 * directed to the mount not the trigger.
40- * But first expire possible rootless offsets first.
41 */
42
43- /* Offsets always have a real mount at their base */
44+ /* Check for manual umount */
45 cache_writelock(me->mc);
46- if (strstr(next->opts, "offset")) {
47- ops->close(ap->logopt, me->ioctlfd);
48+ if (me->ioctlfd != -1 &&
49+ fstat(ioctlfd, &st) != -1 &&
50+ !count_mounts(ap->logopt, next->path, st.st_dev)) {
51+ ops->close(ap->logopt, ioctlfd);
52 me->ioctlfd = -1;
53 cache_unlock(me->mc);
54 pthread_setcancelstate(cur_state, NULL);
55@@ -904,15 +905,6 @@ void *expire_proc_direct(void *arg)
56 continue;
57 }
58
59- cache_writelock(me->mc);
60- if (me->ioctlfd != -1 &&
61- fstat(ioctlfd, &st) != -1 &&
62- !count_mounts(ap->logopt, next->path, st.st_dev)) {
63- ops->close(ap->logopt, ioctlfd);
64- me->ioctlfd = -1;
65- }
66- cache_unlock(me->mc);
67-
68 pthread_setcancelstate(cur_state, NULL);
69 continue;
70 }
71@@ -1068,7 +1060,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
72 map = ap->entry->maps;
73 while (map) {
74 mc = map->mc;
75- cache_readlock(mc);
76+ cache_writelock(mc);
77 me = cache_lookup_ino(mc, pkt->dev, pkt->ino);
78 if (me)
79 break;
80@@ -1345,7 +1337,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
81 }
82
83 mc = map->mc;
84- cache_readlock(mc);
85+ cache_writelock(mc);
86 me = cache_lookup_ino(mc, pkt->dev, pkt->ino);
87 if (me)
88 break;
89@@ -1367,10 +1359,10 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
90
91 if (me->ioctlfd != -1) {
92 /* Maybe someone did a manual umount, clean up ! */
93- ioctlfd = me->ioctlfd;
94+ close(me->ioctlfd);
95 me->ioctlfd = -1;
96- } else
97- ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
98+ }
99+ ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
100
101 if (ioctlfd == -1) {
102 cache_unlock(mc);
103diff --git a/daemon/indirect.c b/daemon/indirect.c
104index 2539282..bc39e63 100644
105--- a/daemon/indirect.c
106+++ b/daemon/indirect.c
107@@ -428,8 +428,53 @@ void *expire_proc_indirect(void *arg)
108 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
109 if (strstr(next->opts, "indirect"))
110 master_notify_submount(ap, next->path, ap->state);
111- pthread_setcancelstate(cur_state, NULL);
112+ else if (strstr(next->opts, "offset")) {
113+ struct map_source *map;
114+ struct mapent_cache *mc = NULL;
115+ struct mapent *me = NULL;
116+ struct stat st;
117+
118+ master_source_readlock(ap->entry);
119+
120+ map = ap->entry->maps;
121+ while (map) {
122+ mc = map->mc;
123+ cache_writelock(mc);
124+ me = cache_lookup_distinct(mc, next->path);
125+ if (me)
126+ break;
127+ cache_unlock(mc);
128+ map = map->next;
129+ }
130
131+ if (!mc || !me) {
132+ master_source_unlock(ap->entry);
133+ pthread_setcancelstate(cur_state, NULL);
134+ continue;
135+ }
136+
137+ /* Check for manual umount */
138+ if (me->ioctlfd != -1 &&
139+ (fstat(me->ioctlfd, &st) == -1 ||
140+ !count_mounts(ap->logopt, me->key, st.st_dev))) {
141+ if (is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL)) {
142+ error(ap->logopt,
143+ "error: possible mtab mismatch %s",
144+ me->key);
145+ cache_unlock(mc);
146+ master_source_unlock(ap->entry);
147+ pthread_setcancelstate(cur_state, NULL);
148+ continue;
149+ }
150+ close(me->ioctlfd);
151+ me->ioctlfd = -1;
152+ }
153+
154+ cache_unlock(mc);
155+ master_source_unlock(ap->entry);
156+ }
157+
158+ pthread_setcancelstate(cur_state, NULL);
159 continue;
160 }
161
This page took 0.095448 seconds and 4 git commands to generate.