]> git.pld-linux.org Git - packages/autofs.git/blob - 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
1 autofs-5.0.4 - improve manual umount recovery
2
3 From: Ian Kent <raven@themaw.net>
4
5 The check for manually umounted mounts in the expire of direct mounts is
6 racy and the check itself is inadequate in that it can incorrectly clear
7 the descriptor of an active mount. Also, we do a similar test following
8 the expire which is a waste since we can catch this on the next expire.
9 So these two tests have been combined and the check done only prior to
10 the expire. In the indirect expire we don't have a check at all so we
11 add 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
20 diff --git a/CHANGELOG b/CHANGELOG
21 index 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  -----------------------
32 diff --git a/daemon/direct.c b/daemon/direct.c
33 index 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);
103 diff --git a/daemon/indirect.c b/daemon/indirect.c
104 index 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.045164 seconds and 3 git commands to generate.