~ubuntu-branches/debian/wheezy/autofs/wheezy

« back to all changes in this revision

Viewing changes to patches/autofs4-2.4.22-20050404.patch

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2008-03-08 01:36:09 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20080308013609-cvs4f2ecoyoism02
Tags: 4.1.4+debian-2.1
* Non-maintainer upload.
* High-urgency upload for RC bugfix.
* Add -DLDAP_DEPRECATED to CFLAGS, to fix compatibility with OpenLDAP
  2.4 on 64-bit architectures.  Closes: #463419.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
diff -Nur linux-2.4.20.orig/fs/namei.c linux-2.4.20/fs/namei.c
 
2
--- linux-2.4.20.orig/fs/namei.c        2004-04-15 22:13:55.000000000 +0800
 
3
+++ linux-2.4.20/fs/namei.c     2004-04-24 14:43:56.000000000 +0800
 
4
@@ -583,9 +583,9 @@
 
5
                        if (err < 0)
 
6
                                break;
 
7
                }
 
8
-               dentry = cached_lookup(nd->dentry, &this, 0);
 
9
+               dentry = cached_lookup(nd->dentry, &this, nd->flags);
 
10
                if (!dentry) {
 
11
-                       dentry = real_lookup(nd->dentry, &this, 0);
 
12
+                       dentry = real_lookup(nd->dentry, &this, nd->flags);
 
13
                        err = PTR_ERR(dentry);
 
14
                        if (IS_ERR(dentry))
 
15
                                break;
 
16
diff -Nur linux-2.4.22.orig/Documentation/Configure.help linux-2.4.22/Documentation/Configure.help
 
17
--- linux-2.4.22.orig/Documentation/Configure.help      2003-08-25 19:44:39.000000000 +0800
 
18
+++ linux-2.4.22/Documentation/Configure.help   2004-04-24 15:11:14.000000000 +0800
 
19
@@ -16397,7 +16397,7 @@
 
20
   automounter (amd), which is a pure user space daemon.
 
21
 
 
22
   To use the automounter you need the user-space tools from
 
23
-  <ftp://ftp.kernel.org/pub/linux/daemons/autofs/testing-v4/>; you also
 
24
+  <ftp://ftp.kernel.org/pub/linux/daemons/autofs/v4/>; you also
 
25
   want to answer Y to "NFS file system support", below.
 
26
 
 
27
   If you want to compile this as a module ( = code which can be
 
28
--- linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c.compat-ioctl     2004-12-27 10:45:11.000000000 +0800
 
29
+++ linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c  2004-12-27 10:48:04.000000000 +0800
 
30
@@ -4002,6 +4002,10 @@
 
31
 COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
 
32
 COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
 
33
 COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI)
 
34
+COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER)
 
35
+COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST)
 
36
+COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST)
 
37
+COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT)
 
38
 /* DEVFS */
 
39
 COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV)
 
40
 COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
 
41
--- linux-2.4.22/arch/ppc64/kernel/ioctl32.c.compat-ioctl       2004-12-27 10:45:11.000000000 +0800
 
42
+++ linux-2.4.22/arch/ppc64/kernel/ioctl32.c    2004-12-27 10:54:23.000000000 +0800
 
43
@@ -4305,6 +4305,11 @@
 
44
 COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC),
 
45
 COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER),
 
46
 COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE),
 
47
+COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI),
 
48
+COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER),
 
49
+COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST),
 
50
+COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST),
 
51
+COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT),
 
52
 /* DEVFS */
 
53
 COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV),
 
54
 COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK),
 
55
--- linux-2.4.22/arch/sparc64/kernel/ioctl32.c.compat-ioctl     2004-12-27 10:45:11.000000000 +0800
 
56
+++ linux-2.4.22/arch/sparc64/kernel/ioctl32.c  2004-12-27 10:48:04.000000000 +0800
 
57
@@ -4914,6 +4914,10 @@
 
58
 COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
 
59
 COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
 
60
 COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI)
 
61
+COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER)
 
62
+COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST)
 
63
+COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST)
 
64
+COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT)
 
65
 /* DEVFS */
 
66
 COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV)
 
67
 COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
 
68
--- linux-2.4.22/arch/mips64/kernel/ioctl32.c.compat-ioctl      2004-12-27 10:45:11.000000000 +0800
 
69
+++ linux-2.4.22/arch/mips64/kernel/ioctl32.c   2004-12-27 10:48:04.000000000 +0800
 
70
@@ -1247,6 +1247,10 @@
 
71
        IOCTL32_HANDLER(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout),
 
72
        IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE),
 
73
        IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE_MULTI),
 
74
+       IOCTL32_DEFAULT(AUTOFS_IOC_PROTSUBVER),
 
75
+       IOCTL32_DEFAULT(AUTOFS_IOC_ASKREGHOST),
 
76
+       IOCTL32_DEFAULT(AUTOFS_IOC_TOGGLEREGHOST),
 
77
+       IOCTL32_DEFAULT(AUTOFS_IOC_ASKUMOUNT),
 
78
 
 
79
        /* Little p (/dev/rtc, /dev/envctrl, etc.) */
 
80
        IOCTL32_DEFAULT(_IOR('p', 20, int[7])), /* RTCGET */
 
81
--- linux-2.4.22/arch/parisc/kernel/ioctl32.c.compat-ioctl      2004-12-27 10:45:11.000000000 +0800
 
82
+++ linux-2.4.22/arch/parisc/kernel/ioctl32.c   2004-12-27 10:56:17.000000000 +0800
 
83
@@ -3375,6 +3375,11 @@
 
84
 COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
 
85
 COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
 
86
 COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
 
87
+COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI)
 
88
+COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER)
 
89
+COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST)
 
90
+COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST)
 
91
+COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT)
 
92
 /* DEVFS */
 
93
 COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV)
 
94
 COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
 
95
diff -Nur linux-2.4.22/fs/autofs4/autofs_i.h autofs4-2.4/fs/autofs4/autofs_i.h
 
96
--- linux-2.4.22/fs/autofs4/autofs_i.h  2002-08-03 08:39:45.000000000 +0800
 
97
+++ autofs4-2.4/fs/autofs4/autofs_i.h   2005-04-04 22:27:31.000000000 +0800
 
98
@@ -80,7 +80,8 @@
 
99
        char *name;
 
100
        /* This is for status reporting upon return */
 
101
        int status;
 
102
-       int wait_ctr;
 
103
+       atomic_t notified;
 
104
+       atomic_t wait_ctr;
 
105
 };
 
106
 
 
107
 #define AUTOFS_SBI_MAGIC 0x6d4a556d
 
108
@@ -91,7 +92,12 @@
 
109
        pid_t oz_pgrp;
 
110
        int catatonic;
 
111
        int version;
 
112
+       int sub_version;
 
113
        unsigned long exp_timeout;
 
114
+       int reghost_enabled;
 
115
+       int needs_reghost;
 
116
+       struct semaphore wq_sem;
 
117
+       spinlock_t fs_lock;
 
118
        struct super_block *sb;
 
119
        struct autofs_wait_queue *queues; /* Wait queue pointer */
 
120
 };
 
121
@@ -118,13 +124,27 @@
 
122
 static inline int autofs4_ispending(struct dentry *dentry)
 
123
 {
 
124
        struct autofs_info *inf = autofs4_dentry_ino(dentry);
 
125
+       int pending = 0;
 
126
 
 
127
-       return (dentry->d_flags & DCACHE_AUTOFS_PENDING) ||
 
128
-               (inf != NULL && inf->flags & AUTOFS_INF_EXPIRING);
 
129
+       if (dentry->d_flags & DCACHE_AUTOFS_PENDING)
 
130
+               return 1;
 
131
+
 
132
+       if (inf) {
 
133
+               spin_lock(&inf->sbi->fs_lock);
 
134
+               pending = inf->flags & AUTOFS_INF_EXPIRING;
 
135
+               spin_unlock(&inf->sbi->fs_lock);
 
136
+       }
 
137
+
 
138
+       return pending;
 
139
+}
 
140
+
 
141
+static inline void autofs4_copy_atime(struct file *src, struct file *dst)
 
142
+{
 
143
+       dst->f_dentry->d_inode->i_atime = src->f_dentry->d_inode->i_atime;
 
144
+       return;
 
145
 }
 
146
 
 
147
 struct inode *autofs4_get_inode(struct super_block *, struct autofs_info *);
 
148
-struct autofs_info *autofs4_init_inf(struct autofs_sb_info *, mode_t mode);
 
149
 void autofs4_free_ino(struct autofs_info *);
 
150
 
 
151
 /* Expiration */
 
152
@@ -139,6 +159,7 @@
 
153
 extern struct inode_operations autofs4_symlink_inode_operations;
 
154
 extern struct inode_operations autofs4_dir_inode_operations;
 
155
 extern struct inode_operations autofs4_root_inode_operations;
 
156
+extern struct file_operations autofs4_dir_operations;
 
157
 extern struct file_operations autofs4_root_operations;
 
158
 
 
159
 /* Initializing function */
 
160
@@ -155,6 +176,56 @@
 
161
        NFY_EXPIRE
 
162
 };
 
163
 
 
164
-int autofs4_wait(struct autofs_sb_info *,struct qstr *, enum autofs_notify);
 
165
+int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify);
 
166
 int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
 
167
 void autofs4_catatonic_mode(struct autofs_sb_info *);
 
168
+
 
169
+#if !defined(REDHAT_KERNEL) || LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
 
170
+/**
 
171
+ * list_for_each_entry  -       iterate over list of given type
 
172
+ * @pos:        the type * to use as a loop counter.
 
173
+ * @head:       the head for your list.
 
174
+ * @member:     the name of the list_struct within the struct.
 
175
+ */
 
176
+#define list_for_each_entry(pos, head, member)                          \
 
177
+        for (pos = list_entry((head)->next, typeof(*pos), member),      \
 
178
+                     prefetch(pos->member.next);                        \
 
179
+             &pos->member != (head);                                    \
 
180
+             pos = list_entry(pos->member.next, typeof(*pos), member),  \
 
181
+                     prefetch(pos->member.next))
 
182
+
 
183
+#endif
 
184
+
 
185
+static inline int simple_positive(struct dentry *dentry)
 
186
+{
 
187
+       return dentry->d_inode && !d_unhashed(dentry);
 
188
+}
 
189
+
 
190
+static inline int simple_empty_nolock(struct dentry *dentry)
 
191
+{
 
192
+       struct dentry *child;
 
193
+       int ret = 0;
 
194
+
 
195
+       list_for_each_entry(child, &dentry->d_subdirs, d_child)
 
196
+               if (simple_positive(child))
 
197
+                       goto out;
 
198
+       ret = 1;
 
199
+out:
 
200
+       return ret;
 
201
+}
 
202
+
 
203
+static inline int simple_empty(struct dentry *dentry)
 
204
+{
 
205
+       struct dentry *child;
 
206
+       int ret = 0;
 
207
+
 
208
+       spin_lock(&dcache_lock);
 
209
+       list_for_each_entry(child, &dentry->d_subdirs, d_child)
 
210
+               if (simple_positive(child))
 
211
+                       goto out;
 
212
+       ret = 1;
 
213
+out:
 
214
+       spin_unlock(&dcache_lock);
 
215
+       return ret;
 
216
+}
 
217
+
 
218
diff -Nur linux-2.4.22/fs/autofs4/expire.c autofs4-2.4/fs/autofs4/expire.c
 
219
--- linux-2.4.22/fs/autofs4/expire.c    2001-06-12 10:15:27.000000000 +0800
 
220
+++ autofs4-2.4/fs/autofs4/expire.c     2005-04-04 22:27:31.000000000 +0800
 
221
@@ -4,6 +4,7 @@
 
222
  *
 
223
  *  Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
 
224
  *  Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org>
 
225
+ *  Copyright 2001-2003 Ian Kent <raven@themaw.net>
 
226
  *
 
227
  * This file is part of the Linux kernel and is made available under
 
228
  * the terms of the GNU General Public License, version 2, or at your
 
229
@@ -13,134 +14,242 @@
 
230
 
 
231
 #include "autofs_i.h"
 
232
 
 
233
-/*
 
234
- * Determine if a subtree of the namespace is busy.
 
235
- *
 
236
- * mnt is the mount tree under the autofs mountpoint
 
237
- */
 
238
-static inline int is_vfsmnt_tree_busy(struct vfsmount *mnt)
 
239
+static unsigned long now;
 
240
+
 
241
+/* Check if a dentry can be expired return 1 if it can else return 0 */
 
242
+static inline int autofs4_can_expire(struct dentry *dentry,
 
243
+                                       unsigned long timeout, int do_now)
 
244
+{
 
245
+       struct autofs_info *ino = autofs4_dentry_ino(dentry);
 
246
+
 
247
+       /* dentry in the process of being deleted */
 
248
+       if (ino == NULL)
 
249
+               return 0;
 
250
+
 
251
+       /* No point expiring a pending mount */
 
252
+       if (dentry->d_flags & DCACHE_AUTOFS_PENDING)
 
253
+               return 0;
 
254
+
 
255
+       if (!do_now) {
 
256
+               /* Too young to die */
 
257
+               if (time_after(ino->last_used + timeout, now))
 
258
+                       return 0;
 
259
+               
 
260
+               /* update last_used here :- 
 
261
+                  - obviously makes sense if it is in use now
 
262
+                  - less obviously, prevents rapid-fire expire
 
263
+                    attempts if expire fails the first time */
 
264
+               ino->last_used = now;
 
265
+       }
 
266
+
 
267
+       return 1;
 
268
+}
 
269
+
 
270
+/* Sorry I can't solve the problem without using counts either */
 
271
+static int autofs4_may_umount(struct vfsmount *mnt)
 
272
 {
 
273
-       struct vfsmount *this_parent = mnt;
 
274
        struct list_head *next;
 
275
-       int count;
 
276
+       struct vfsmount *this_parent = mnt;
 
277
+       int actual_refs;
 
278
+       int minimum_refs;
 
279
 
 
280
-       count = atomic_read(&mnt->mnt_count) - 1;
 
281
+       actual_refs = atomic_read(&mnt->mnt_count);
 
282
+       minimum_refs = 2;
 
283
 
 
284
+       spin_lock(&dcache_lock);
 
285
 repeat:
 
286
        next = this_parent->mnt_mounts.next;
 
287
-       DPRINTK(("is_vfsmnt_tree_busy: mnt=%p, this_parent=%p, next=%p\n",
 
288
-                mnt, this_parent, next));
 
289
 resume:
 
290
-       for( ; next != &this_parent->mnt_mounts; next = next->next) {
 
291
-               struct vfsmount *p = list_entry(next, struct vfsmount,
 
292
-                                               mnt_child);
 
293
-
 
294
-               /* -1 for struct vfs_mount's normal count, 
 
295
-                  -1 to compensate for child's reference to parent */
 
296
-               count += atomic_read(&p->mnt_count) - 1 - 1;
 
297
+       while (next != &this_parent->mnt_mounts) {
 
298
+               struct vfsmount *p = list_entry(next, struct vfsmount, mnt_child);
 
299
+
 
300
+               next = next->next;
 
301
 
 
302
-               DPRINTK(("is_vfsmnt_tree_busy: p=%p, count now %d\n",
 
303
-                        p, count));
 
304
+               actual_refs += atomic_read(&p->mnt_count);
 
305
+               minimum_refs += 2;
 
306
 
 
307
                if (!list_empty(&p->mnt_mounts)) {
 
308
                        this_parent = p;
 
309
                        goto repeat;
 
310
                }
 
311
-               /* root is busy if any leaf is busy */
 
312
-               if (atomic_read(&p->mnt_count) > 1)
 
313
-                       return 1;
 
314
        }
 
315
 
 
316
-       /* All done at this level ... ascend and resume the search. */
 
317
        if (this_parent != mnt) {
 
318
-               next = this_parent->mnt_child.next; 
 
319
+               next = this_parent->mnt_child.next;
 
320
                this_parent = this_parent->mnt_parent;
 
321
                goto resume;
 
322
        }
 
323
+       spin_unlock(&dcache_lock);
 
324
+
 
325
+       DPRINTK(("autofs4_may_umount: done actual = %d, minimum = %d\n",
 
326
+                actual_refs, minimum_refs));
 
327
 
 
328
-       DPRINTK(("is_vfsmnt_tree_busy: count=%d\n", count));
 
329
-       return count != 0; /* remaining users? */
 
330
+       return actual_refs > minimum_refs;
 
331
 }
 
332
 
 
333
-/* Traverse a dentry's list of vfsmounts and return the number of
 
334
-   non-busy mounts */
 
335
-static int check_vfsmnt(struct vfsmount *mnt, struct dentry *dentry)
 
336
+/* Check a mount point for busyness return 1 if not busy, otherwise */
 
337
+static int autofs4_check_mount(struct vfsmount *mnt, struct dentry *dentry)
 
338
 {
 
339
-       int ret = dentry->d_mounted;
 
340
-       struct vfsmount *vfs = lookup_mnt(mnt, dentry);
 
341
+       int status = 0;
 
342
 
 
343
-       if (vfs && is_vfsmnt_tree_busy(vfs))
 
344
-               ret--;
 
345
-       DPRINTK(("check_vfsmnt: ret=%d\n", ret));
 
346
-       return ret;
 
347
+       DPRINTK(("autofs4_check_mount: dentry %p %.*s\n",
 
348
+                dentry, (int)dentry->d_name.len, dentry->d_name.name));
 
349
+
 
350
+       mntget(mnt);
 
351
+       dget(dentry);
 
352
+
 
353
+       if (!follow_down(&mnt, &dentry))
 
354
+               goto done;
 
355
+
 
356
+       while (d_mountpoint(dentry) && follow_down(&mnt, &dentry))
 
357
+               ;
 
358
+
 
359
+       /* This is an autofs submount, we can't expire it */
 
360
+       if (is_autofs4_dentry(dentry))
 
361
+               goto done;
 
362
+       
 
363
+       /* The big question */
 
364
+       if (autofs4_may_umount(mnt) == 0)
 
365
+               status = 1;
 
366
+done:
 
367
+       DPRINTK(("autofs4_check_mount: returning = %d\n", status));
 
368
+       mntput(mnt);
 
369
+       dput(dentry);
 
370
+       return status;
 
371
 }
 
372
 
 
373
-/* Check dentry tree for busyness.  If a dentry appears to be busy
 
374
-   because it is a mountpoint, check to see if the mounted
 
375
-   filesystem is busy. */
 
376
-static int is_tree_busy(struct vfsmount *topmnt, struct dentry *top)
 
377
+/* Check a directory tree of mount points for busyness
 
378
+ * The tree is not busy iff no mountpoints are busy 
 
379
+ * Return 1 if the tree is busy or 0 otherwise
 
380
+ */
 
381
+static int autofs4_check_tree(struct vfsmount *mnt,
 
382
+                             struct dentry *top,
 
383
+                             unsigned long timeout,
 
384
+                             int do_now)
 
385
 {
 
386
-       struct dentry *this_parent;
 
387
+       struct dentry *this_parent = top;
 
388
        struct list_head *next;
 
389
-       int count;
 
390
 
 
391
-       count = atomic_read(&top->d_count);
 
392
-       
 
393
-       DPRINTK(("is_tree_busy: top=%p initial count=%d\n", 
 
394
-                top, count));
 
395
-       this_parent = top;
 
396
-
 
397
-       if (is_autofs4_dentry(top)) {
 
398
-               count--;
 
399
-               DPRINTK(("is_tree_busy: autofs; count=%d\n", count));
 
400
-       }
 
401
+       DPRINTK(("autofs4_check_tree: parent %p %.*s\n",
 
402
+                top, (int)top->d_name.len, top->d_name.name));
 
403
 
 
404
-       if (d_mountpoint(top))
 
405
-               count -= check_vfsmnt(topmnt, top);
 
406
+       /* Negative dentry - give up */
 
407
+       if (!simple_positive(top))
 
408
+               return 0;
 
409
+
 
410
+       /* Timeout of a tree mount is determined by its top dentry */
 
411
+       if (!autofs4_can_expire(top, timeout, do_now))
 
412
+               return 0;
 
413
+
 
414
+       /* Is someone visiting anywhere in the tree ? */
 
415
+       if (autofs4_may_umount(mnt))
 
416
+               return 0;
 
417
 
 
418
- repeat:
 
419
+       spin_lock(&dcache_lock);
 
420
+repeat:
 
421
        next = this_parent->d_subdirs.next;
 
422
- resume:
 
423
+resume:
 
424
        while (next != &this_parent->d_subdirs) {
 
425
-               int adj = 0;
 
426
-               struct dentry *dentry = list_entry(next, struct dentry,
 
427
-                                                  d_child);
 
428
+               struct dentry *dentry = list_entry(next, struct dentry, d_child);
 
429
+
 
430
+               /* Negative dentry - give up */
 
431
+               if (!simple_positive(dentry)) {
 
432
+                       next = next->next;
 
433
+                       continue;
 
434
+               }
 
435
+
 
436
+               DPRINTK(("autofs4_check_tree: dentry %p %.*s\n",
 
437
+                        dentry, (int)dentry->d_name.len, dentry->d_name.name));
 
438
+
 
439
+               if (!list_empty(&dentry->d_subdirs)) {
 
440
+                       this_parent = dentry;
 
441
+                       goto repeat;
 
442
+               }
 
443
+
 
444
+               dentry = dget(dentry);
 
445
+               spin_unlock(&dcache_lock);
 
446
+
 
447
+               if (d_mountpoint(dentry)) {
 
448
+                       /* First busy => tree busy */
 
449
+                       if (!autofs4_check_mount(mnt, dentry)) {
 
450
+                               dput(dentry);
 
451
+                               return 0;
 
452
+                       }
 
453
+               }
 
454
+
 
455
+               dput(dentry);
 
456
+               spin_lock(&dcache_lock);
 
457
                next = next->next;
 
458
+       }
 
459
+
 
460
+       if (this_parent != top) {
 
461
+               next = this_parent->d_child.next;
 
462
+               this_parent = this_parent->d_parent;
 
463
+               goto resume;
 
464
+       }
 
465
+       spin_unlock(&dcache_lock);
 
466
+
 
467
+       return 1;
 
468
+}
 
469
+
 
470
+struct dentry *autofs4_check_leaves(struct vfsmount *mnt,
 
471
+                                   struct dentry *parent,
 
472
+                                   unsigned long timeout,
 
473
+                                   int do_now)
 
474
+{
 
475
+       struct dentry *this_parent = parent;
 
476
+       struct list_head *next;
 
477
 
 
478
-               count += atomic_read(&dentry->d_count) - 1;
 
479
+       DPRINTK(("autofs4_check_leaves: parent %p %.*s\n",
 
480
+                parent, (int)parent->d_name.len, parent->d_name.name));
 
481
 
 
482
-               if (d_mountpoint(dentry))
 
483
-                       adj += check_vfsmnt(topmnt, dentry);
 
484
+       spin_lock(&dcache_lock);
 
485
+repeat:
 
486
+       next = this_parent->d_subdirs.next;
 
487
+resume:
 
488
+       while (next != &this_parent->d_subdirs) {
 
489
+               struct dentry *dentry = list_entry(next, struct dentry, d_child);
 
490
 
 
491
-               if (is_autofs4_dentry(dentry)) {
 
492
-                       adj++;
 
493
-                       DPRINTK(("is_tree_busy: autofs; adj=%d\n",
 
494
-                                adj));
 
495
+               /* Negative dentry - give up */
 
496
+               if (!simple_positive(dentry)) {
 
497
+                       next = next->next;
 
498
+                       continue;
 
499
                }
 
500
 
 
501
-               count -= adj;
 
502
+               DPRINTK(("autofs4_check_leaves: dentry %p %.*s\n",
 
503
+                        dentry, (int)dentry->d_name.len, dentry->d_name.name));
 
504
 
 
505
                if (!list_empty(&dentry->d_subdirs)) {
 
506
                        this_parent = dentry;
 
507
                        goto repeat;
 
508
                }
 
509
 
 
510
-               if (atomic_read(&dentry->d_count) != adj) {
 
511
-                       DPRINTK(("is_tree_busy: busy leaf (d_count=%d adj=%d)\n",
 
512
-                                atomic_read(&dentry->d_count), adj));
 
513
-                       return 1;
 
514
+               dentry = dget(dentry);
 
515
+               spin_unlock(&dcache_lock);
 
516
+
 
517
+               if (d_mountpoint(dentry)) {
 
518
+                       /* Can we expire this guy */
 
519
+                       if (!autofs4_can_expire(dentry, timeout, do_now))
 
520
+                               goto cont;
 
521
+
 
522
+                       /* Can we umount this guy */
 
523
+                       if (autofs4_check_mount(mnt, dentry))
 
524
+                               return dentry;
 
525
                }
 
526
+cont:
 
527
+               dput(dentry);
 
528
+               spin_lock(&dcache_lock);
 
529
+               next = next->next;
 
530
        }
 
531
 
 
532
-       /* All done at this level ... ascend and resume the search. */
 
533
-       if (this_parent != top) {
 
534
-               next = this_parent->d_child.next; 
 
535
+       if (this_parent != parent) {
 
536
+               next = this_parent->d_child.next;
 
537
                this_parent = this_parent->d_parent;
 
538
                goto resume;
 
539
        }
 
540
+       spin_unlock(&dcache_lock);
 
541
 
 
542
-       DPRINTK(("is_tree_busy: count=%d\n", count));
 
543
-       return count != 0; /* remaining users? */
 
544
+       return NULL;
 
545
 }
 
546
 
 
547
 /*
 
548
@@ -152,61 +261,94 @@
 
549
 static struct dentry *autofs4_expire(struct super_block *sb,
 
550
                                     struct vfsmount *mnt,
 
551
                                     struct autofs_sb_info *sbi,
 
552
-                                    int do_now)
 
553
+                                    int how)
 
554
 {
 
555
-       unsigned long now = jiffies;
 
556
        unsigned long timeout;
 
557
        struct dentry *root = sb->s_root;
 
558
-       struct list_head *tmp;
 
559
+       struct dentry *expired = NULL;
 
560
+       struct list_head *next;
 
561
+       int do_now = how & AUTOFS_EXP_IMMEDIATE;
 
562
+       int exp_leaves = how & AUTOFS_EXP_LEAVES;
 
563
 
 
564
        if (!sbi->exp_timeout || !root)
 
565
                return NULL;
 
566
 
 
567
+       now = jiffies;
 
568
        timeout = sbi->exp_timeout;
 
569
 
 
570
        spin_lock(&dcache_lock);
 
571
-       for(tmp = root->d_subdirs.next;
 
572
-           tmp != &root->d_subdirs; 
 
573
-           tmp = tmp->next) {
 
574
-               struct autofs_info *ino;
 
575
-               struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
 
576
+       next = root->d_subdirs.next;
 
577
 
 
578
-               if (dentry->d_inode == NULL)
 
579
+       /* On exit from the loop expire is set to a dgot dentry
 
580
+        * to expire or it's NULL */
 
581
+       while (next != &root->d_subdirs) {
 
582
+               struct dentry *dentry = list_entry(next, struct dentry, d_child);
 
583
+
 
584
+               /* Negative dentry - give up */
 
585
+               if (!simple_positive(dentry)) {
 
586
+                       next = next->next;
 
587
                        continue;
 
588
+               }
 
589
 
 
590
-               ino = autofs4_dentry_ino(dentry);
 
591
+               dentry = dget(dentry);
 
592
+               spin_unlock(&dcache_lock);
 
593
 
 
594
-               if (ino == NULL) {
 
595
-                       /* dentry in the process of being deleted */
 
596
-                       continue;
 
597
+               /* Case 1: indirect mount or top level direct mount */
 
598
+               if (d_mountpoint(dentry)) {
 
599
+                       DPRINTK(("autofs4_expire: checking mountpoint %p %.*s\n",
 
600
+                        dentry, (int)dentry->d_name.len, dentry->d_name.name));
 
601
+
 
602
+                       /* Can we expire this guy */
 
603
+                       if (!autofs4_can_expire(dentry, timeout, do_now))
 
604
+                               goto next;
 
605
+
 
606
+                       /* Can we umount this guy */
 
607
+                       if (autofs4_check_mount(mnt, dentry)) {
 
608
+                               expired = dentry;
 
609
+                               break;
 
610
+                       }
 
611
+                       goto next;
 
612
                }
 
613
 
 
614
-               /* No point expiring a pending mount */
 
615
-               if (dentry->d_flags & DCACHE_AUTOFS_PENDING)
 
616
-                       continue;
 
617
+               if (simple_empty(dentry))
 
618
+                       goto next;
 
619
 
 
620
-               if (!do_now) {
 
621
-                       /* Too young to die */
 
622
-                       if (time_after(ino->last_used + timeout, now))
 
623
-                               continue;
 
624
-               
 
625
-                       /* update last_used here :- 
 
626
-                          - obviously makes sense if it is in use now
 
627
-                          - less obviously, prevents rapid-fire expire
 
628
-                            attempts if expire fails the first time */
 
629
-                       ino->last_used = now;
 
630
+               /* Case 2: tree mount, expire iff entire tree is not busy */
 
631
+               if (!exp_leaves) {
 
632
+                       /* Lock the tree as we must expire as a whole */
 
633
+                       spin_lock(&sbi->fs_lock);
 
634
+                       if (autofs4_check_tree(mnt, dentry, timeout, do_now)) {
 
635
+                               struct autofs_info *inf = autofs4_dentry_ino(dentry);
 
636
+
 
637
+                               /* Set this flag early to catch sys_chdir and the like */
 
638
+                               inf->flags |= AUTOFS_INF_EXPIRING;
 
639
+                               spin_unlock(&sbi->fs_lock);
 
640
+                               expired = dentry;
 
641
+                               break;
 
642
+                       }
 
643
+                       spin_unlock(&sbi->fs_lock);
 
644
+               /* Case 3: direct mount, expire individual leaves */
 
645
+               } else {
 
646
+                       expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
 
647
+                       if (expired) {
 
648
+                               dput(dentry);
 
649
+                               break;
 
650
+                       }
 
651
                }
 
652
-               if (!is_tree_busy(mnt, dentry)) {
 
653
-                       DPRINTK(("autofs_expire: returning %p %.*s\n",
 
654
-                                dentry, (int)dentry->d_name.len, dentry->d_name.name));
 
655
-                       /* Start from here next time */
 
656
-                       list_del(&root->d_subdirs);
 
657
-                       list_add(&root->d_subdirs, &dentry->d_child);
 
658
-                       dget(dentry);
 
659
-                       spin_unlock(&dcache_lock);
 
660
+next:
 
661
+               dput(dentry);
 
662
+               spin_lock(&dcache_lock);
 
663
+               next = next->next;
 
664
+       }
 
665
 
 
666
-                       return dentry;
 
667
-               }
 
668
+       if ( expired ) {
 
669
+               DPRINTK(("autofs4_expire: returning %p %.*s\n",
 
670
+                        expired, (int)expired->d_name.len, expired->d_name.name));
 
671
+               spin_lock(&dcache_lock);
 
672
+               list_del(&expired->d_parent->d_subdirs);
 
673
+               list_add(&expired->d_parent->d_subdirs, &expired->d_child);
 
674
+               spin_unlock(&dcache_lock);
 
675
+               return expired;
 
676
        }
 
677
        spin_unlock(&dcache_lock);
 
678
 
 
679
@@ -259,11 +401,11 @@
 
680
                /* This is synchronous because it makes the daemon a
 
681
                    little easier */
 
682
                de_info->flags |= AUTOFS_INF_EXPIRING;
 
683
-               ret = autofs4_wait(sbi, &dentry->d_name, NFY_EXPIRE);
 
684
+               ret = autofs4_wait(sbi, dentry, NFY_EXPIRE);
 
685
                de_info->flags &= ~AUTOFS_INF_EXPIRING;
 
686
                dput(dentry);
 
687
        }
 
688
-               
 
689
+
 
690
        return ret;
 
691
 }
 
692
 
 
693
diff -Nur linux-2.4.22/fs/autofs4/inode.c autofs4-2.4/fs/autofs4/inode.c
 
694
--- linux-2.4.22/fs/autofs4/inode.c     2002-08-03 08:39:45.000000000 +0800
 
695
+++ autofs4-2.4/fs/autofs4/inode.c      2005-04-04 22:27:31.000000000 +0800
 
696
@@ -87,7 +87,7 @@
 
697
 
 
698
        kfree(sbi);
 
699
 
 
700
-       DPRINTK(("autofs: shutting down\n"));
 
701
+       DPRINTK(("autofs4: shutting down\n"));
 
702
 }
 
703
 
 
704
 static int autofs4_statfs(struct super_block *sb, struct statfs *buf);
 
705
@@ -181,12 +181,13 @@
 
706
        struct file * pipe;
 
707
        int pipefd;
 
708
        struct autofs_sb_info *sbi;
 
709
+       struct autofs_info *ino;
 
710
        int minproto, maxproto;
 
711
 
 
712
        sbi = (struct autofs_sb_info *) kmalloc(sizeof(*sbi), GFP_KERNEL);
 
713
        if ( !sbi )
 
714
                goto fail_unlock;
 
715
-       DPRINTK(("autofs: starting up, sbi = %p\n",sbi));
 
716
+       DPRINTK(("autofs4: starting up, sbi = %p\n",sbi));
 
717
 
 
718
        memset(sbi, 0, sizeof(*sbi));
 
719
 
 
720
@@ -197,7 +198,12 @@
 
721
        sbi->oz_pgrp = current->pgrp;
 
722
        sbi->sb = s;
 
723
        sbi->version = 0;
 
724
+       sbi->sub_version = 0;
 
725
+       init_MUTEX(&sbi->wq_sem);
 
726
+       spin_lock_init(&sbi->fs_lock);
 
727
        sbi->queues = NULL;
 
728
+       sbi->reghost_enabled = 0;
 
729
+       sbi->needs_reghost = 0;
 
730
        s->s_blocksize = 1024;
 
731
        s->s_blocksize_bits = 10;
 
732
        s->s_magic = AUTOFS_SUPER_MAGIC;
 
733
@@ -206,7 +212,12 @@
 
734
        /*
 
735
         * Get the root inode and dentry, but defer checking for errors.
 
736
         */
 
737
-       root_inode = autofs4_get_inode(s, autofs4_mkroot(sbi));
 
738
+       ino = autofs4_mkroot(sbi);
 
739
+       root_inode = autofs4_get_inode(s, ino);
 
740
+       kfree(ino);
 
741
+       if (!root_inode)
 
742
+               goto fail_free;
 
743
+
 
744
        root_inode->i_op = &autofs4_root_inode_operations;
 
745
        root_inode->i_fop = &autofs4_root_operations;
 
746
        root = d_alloc_root(root_inode);
 
747
@@ -220,14 +231,14 @@
 
748
                          &root_inode->i_uid, &root_inode->i_gid,
 
749
                          &sbi->oz_pgrp,
 
750
                          &minproto, &maxproto)) {
 
751
-               printk("autofs: called with bogus options\n");
 
752
+               printk("autofs4: called with bogus options\n");
 
753
                goto fail_dput;
 
754
        }
 
755
 
 
756
        /* Couldn't this be tested earlier? */
 
757
        if (maxproto < AUTOFS_MIN_PROTO_VERSION ||
 
758
            minproto > AUTOFS_MAX_PROTO_VERSION) {
 
759
-               printk("autofs: kernel does not match daemon version "
 
760
+               printk("autofs4: kernel does not match daemon version "
 
761
                       "daemon (%d, %d) kernel (%d, %d)\n",
 
762
                        minproto, maxproto,
 
763
                        AUTOFS_MIN_PROTO_VERSION, AUTOFS_MAX_PROTO_VERSION);
 
764
@@ -235,12 +246,13 @@
 
765
        }
 
766
 
 
767
        sbi->version = maxproto > AUTOFS_MAX_PROTO_VERSION ? AUTOFS_MAX_PROTO_VERSION : maxproto;
 
768
+       sbi->sub_version =  AUTOFS_PROTO_SUBVERSION;
 
769
 
 
770
-       DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, sbi->oz_pgrp));
 
771
+       DPRINTK(("autofs4: pipe fd = %d, pgrp = %u\n", pipefd, sbi->oz_pgrp));
 
772
        pipe = fget(pipefd);
 
773
        
 
774
        if ( !pipe ) {
 
775
-               printk("autofs: could not open pipe file descriptor\n");
 
776
+               printk("autofs4: could not open pipe file descriptor\n");
 
777
                goto fail_dput;
 
778
        }
 
779
        if ( !pipe->f_op || !pipe->f_op->write )
 
780
@@ -257,7 +269,7 @@
 
781
         * Failure ... clean up.
 
782
         */
 
783
 fail_fput:
 
784
-       printk("autofs: pipe file descriptor does not contain proper ops\n");
 
785
+       printk("autofs4: pipe file descriptor does not contain proper ops\n");
 
786
        /*
 
787
         * fput() can block, so we clear the super block first.
 
788
         */
 
789
@@ -270,7 +282,7 @@
 
790
        dput(root);
 
791
        goto fail_free;
 
792
 fail_iput:
 
793
-       printk("autofs: get root dentry failed\n");
 
794
+       printk("autofs4: get root dentry failed\n");
 
795
        /*
 
796
         * iput() can block, so we clear the super block first.
 
797
         */
 
798
@@ -314,7 +326,7 @@
 
799
        if (S_ISDIR(inf->mode)) {
 
800
                inode->i_nlink = 2;
 
801
                inode->i_op = &autofs4_dir_inode_operations;
 
802
-               inode->i_fop = &dcache_dir_ops;
 
803
+               inode->i_fop = &autofs4_dir_operations;
 
804
        } else if (S_ISLNK(inf->mode)) {
 
805
                inode->i_size = inf->size;
 
806
                inode->i_op = &autofs4_symlink_inode_operations;
 
807
diff -Nur linux-2.4.22/fs/autofs4/root.c autofs4-2.4/fs/autofs4/root.c
 
808
--- linux-2.4.22/fs/autofs4/root.c      2003-08-25 19:44:43.000000000 +0800
 
809
+++ autofs4-2.4/fs/autofs4/root.c       2005-04-04 22:27:31.000000000 +0800
 
810
@@ -4,6 +4,7 @@
 
811
  *
 
812
  *  Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
 
813
  *  Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org>
 
814
+ *  Copyright 2001-2003 Ian Kent <raven@themaw.net>
 
815
  *
 
816
  * This file is part of the Linux kernel and is made available under
 
817
  * the terms of the GNU General Public License, version 2, or at your
 
818
@@ -16,28 +17,39 @@
 
819
 #include <linux/param.h>
 
820
 #include <linux/sched.h>
 
821
 #include <linux/smp_lock.h>
 
822
+#include <linux/file.h>
 
823
+#include <linux/limits.h>
 
824
+#include <linux/iobuf.h>
 
825
+#include <linux/module.h>
 
826
 #include "autofs_i.h"
 
827
 
 
828
-static struct dentry *autofs4_dir_lookup(struct inode *,struct dentry *);
 
829
 static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *);
 
830
 static int autofs4_dir_unlink(struct inode *,struct dentry *);
 
831
 static int autofs4_dir_rmdir(struct inode *,struct dentry *);
 
832
 static int autofs4_dir_mkdir(struct inode *,struct dentry *,int);
 
833
 static int autofs4_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long);
 
834
-static struct dentry *autofs4_root_lookup(struct inode *,struct dentry *);
 
835
+static int autofs4_dir_open(struct inode *inode, struct file *file);
 
836
+static int autofs4_dir_close(struct inode *inode, struct file *file);
 
837
+static int autofs4_dir_readdir(struct file * filp, void * dirent, filldir_t filldir);
 
838
+static int autofs4_root_readdir(struct file * filp, void * dirent, filldir_t filldir);
 
839
+static struct dentry *autofs4_lookup(struct inode *,struct dentry *);
 
840
+static int autofs4_dcache_readdir(struct file *, void *, filldir_t);
 
841
 
 
842
 struct file_operations autofs4_root_operations = {
 
843
-       open:           dcache_dir_open,
 
844
-       release:        dcache_dir_close,
 
845
-       llseek:         dcache_dir_lseek,
 
846
        read:           generic_read_dir,
 
847
-       readdir:        dcache_readdir,
 
848
-       fsync:          dcache_dir_fsync,
 
849
+       readdir:        autofs4_root_readdir,
 
850
        ioctl:          autofs4_root_ioctl,
 
851
 };
 
852
 
 
853
+struct file_operations autofs4_dir_operations = {
 
854
+       open:           autofs4_dir_open,
 
855
+       release:        autofs4_dir_close,
 
856
+       read:           generic_read_dir,
 
857
+       readdir:        autofs4_dir_readdir,
 
858
+};
 
859
+
 
860
 struct inode_operations autofs4_root_inode_operations = {
 
861
-       lookup:         autofs4_root_lookup,
 
862
+       lookup:         autofs4_lookup,
 
863
        unlink:         autofs4_dir_unlink,
 
864
        symlink:        autofs4_dir_symlink,
 
865
        mkdir:          autofs4_dir_mkdir,
 
866
@@ -45,7 +57,7 @@
 
867
 };
 
868
 
 
869
 struct inode_operations autofs4_dir_inode_operations = {
 
870
-       lookup:         autofs4_dir_lookup,
 
871
+       lookup:         autofs4_lookup,
 
872
        unlink:         autofs4_dir_unlink,
 
873
        symlink:        autofs4_dir_symlink,
 
874
        mkdir:          autofs4_dir_mkdir,
 
875
@@ -54,10 +66,11 @@
 
876
 
 
877
 /* Update usage from here to top of tree, so that scan of
 
878
    top-level directories will give a useful result */
 
879
-static void autofs4_update_usage(struct dentry *dentry)
 
880
+static inline void autofs4_update_usage(struct dentry *dentry)
 
881
 {
 
882
        struct dentry *top = dentry->d_sb->s_root;
 
883
 
 
884
+       spin_lock(&dcache_lock);
 
885
        for(; dentry != top; dentry = dentry->d_parent) {
 
886
                struct autofs_info *ino = autofs4_dentry_ino(dentry);
 
887
 
 
888
@@ -66,11 +79,213 @@
 
889
                        ino->last_used = jiffies;
 
890
                }
 
891
        }
 
892
+       spin_unlock(&dcache_lock);
 
893
+}
 
894
+
 
895
+static int autofs4_root_readdir(struct file *file, void *dirent, filldir_t filldir)
 
896
+{
 
897
+       struct autofs_sb_info *sbi = autofs4_sbi(file->f_dentry->d_sb);
 
898
+       int oz_mode = autofs4_oz_mode(sbi);
 
899
+
 
900
+       DPRINTK(("autofs4_root_readdir called, filp->f_pos = %lld\n", file->f_pos));
 
901
+
 
902
+       /*
 
903
+        * Don't set reghost flag if:
 
904
+        * 1) f_pos is larger than zero -- we've already been here.
 
905
+        * 2) we haven't even enabled reghosting in the 1st place.
 
906
+        * 3) this is the daemon doing a readdir
 
907
+        */
 
908
+       if ( oz_mode && file->f_pos == 0 && sbi->reghost_enabled )
 
909
+               sbi->needs_reghost = 1;
 
910
+
 
911
+       DPRINTK(("autofs4_root_readdir: needs_reghost = %d\n", sbi->needs_reghost));
 
912
+
 
913
+       return autofs4_dcache_readdir(file, dirent, filldir);
 
914
+}
 
915
+
 
916
+/*
 
917
+ * From 2.4 kernel readdir.c
 
918
+ */
 
919
+static int autofs4_dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
 
920
+{
 
921
+       int i;
 
922
+       struct dentry *dentry = filp->f_dentry;
 
923
+
 
924
+       i = filp->f_pos;
 
925
+       switch (i) {
 
926
+               case 0:
 
927
+                       if (filldir(dirent, ".", 1, i, dentry->d_inode->i_ino, DT_DIR) < 0)
 
928
+                               break;
 
929
+                       i++;
 
930
+                       filp->f_pos++;
 
931
+                       /* fallthrough */
 
932
+               case 1:
 
933
+                       if (filldir(dirent, "..", 2, i, dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
 
934
+                               break;
 
935
+                       i++;
 
936
+                       filp->f_pos++;
 
937
+                       /* fallthrough */
 
938
+               default: {
 
939
+                       struct list_head *list;
 
940
+                       int j = i-2;
 
941
+
 
942
+                       spin_lock(&dcache_lock);
 
943
+                       list = dentry->d_subdirs.next;
 
944
+
 
945
+                       for (;;) {
 
946
+                               if (list == &dentry->d_subdirs) {
 
947
+                                       spin_unlock(&dcache_lock);
 
948
+                                       return 0;
 
949
+                               }
 
950
+                               if (!j)
 
951
+                                       break;
 
952
+                               j--;
 
953
+                               list = list->next;
 
954
+                       }
 
955
+
 
956
+                       while(1) {
 
957
+                               struct dentry *de = list_entry(list, struct dentry, d_child);
 
958
+
 
959
+                               if (!list_empty(&de->d_hash) && de->d_inode) {
 
960
+                                       spin_unlock(&dcache_lock);
 
961
+                                       if (filldir(dirent, de->d_name.name, de->d_name.len, filp->f_pos, de->d_inode->i_ino, DT_UNKNOWN) < 0)
 
962
+                                               break;
 
963
+                                       spin_lock(&dcache_lock);
 
964
+                               }
 
965
+                               filp->f_pos++;
 
966
+                               list = list->next;
 
967
+                               if (list != &dentry->d_subdirs)
 
968
+                                       continue;
 
969
+                               spin_unlock(&dcache_lock);
 
970
+                               break;
 
971
+                       }
 
972
+               }
 
973
+       }
 
974
+       return 0;
 
975
+}
 
976
+
 
977
+static int autofs4_dir_open(struct inode *inode, struct file *file)
 
978
+{
 
979
+       struct dentry *dentry = file->f_dentry;
 
980
+       struct vfsmount *mnt = file->f_vfsmnt;
 
981
+       struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
 
982
+       int status;
 
983
+
 
984
+       DPRINTK(("autofs4_dir_open: file=%p dentry=%p %.*s\n",
 
985
+                file, dentry, dentry->d_name.len, dentry->d_name.name));
 
986
+
 
987
+       if (autofs4_oz_mode(sbi))
 
988
+               goto out;
 
989
+
 
990
+       if (autofs4_ispending(dentry)) {
 
991
+               DPRINTK(("autofs4_dir_open: dentry busy\n"));
 
992
+               return -EBUSY;
 
993
+       }
 
994
+
 
995
+       if (!d_mountpoint(dentry) && dentry->d_op && dentry->d_op->d_revalidate) {
 
996
+               int empty;
 
997
+
 
998
+               /* In case there are stale directory dentrys from a failed mount */
 
999
+               spin_lock(&dcache_lock);
 
1000
+               empty = list_empty(&dentry->d_subdirs);
 
1001
+               spin_unlock(&dcache_lock);
 
1002
+
 
1003
+               if (!empty)
 
1004
+                       d_invalidate(dentry);
 
1005
+
 
1006
+               status = (dentry->d_op->d_revalidate)(dentry, LOOKUP_CONTINUE);
 
1007
+
 
1008
+               if ( !status )
 
1009
+                       return -ENOENT;
 
1010
+       }
 
1011
+
 
1012
+       if ( d_mountpoint(dentry) ) {
 
1013
+               struct file *fp = NULL;
 
1014
+               struct vfsmount *fp_mnt = mntget(mnt);
 
1015
+               struct dentry *fp_dentry = dget(dentry);
 
1016
+
 
1017
+               while (follow_down(&fp_mnt, &fp_dentry) && d_mountpoint(fp_dentry));
 
1018
+
 
1019
+               fp = dentry_open(fp_dentry, fp_mnt, file->f_flags);
 
1020
+               status = PTR_ERR(fp);
 
1021
+               if ( IS_ERR(fp) ) {
 
1022
+                       file->private_data = NULL;
 
1023
+                       return status;
 
1024
+               }
 
1025
+               file->private_data = fp;
 
1026
+       }
 
1027
+out:
 
1028
+       return 0;
 
1029
+}
 
1030
+
 
1031
+static int autofs4_dir_close(struct inode *inode, struct file *file)
 
1032
+{
 
1033
+       struct dentry *dentry = file->f_dentry;
 
1034
+       struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
 
1035
+
 
1036
+       DPRINTK(("autofs4_dir_close: file=%p dentry=%p %.*s\n",
 
1037
+                file, dentry, dentry->d_name.len, dentry->d_name.name));
 
1038
+
 
1039
+       if ( autofs4_oz_mode(sbi) )
 
1040
+               goto out;
 
1041
+
 
1042
+       if ( autofs4_ispending(dentry) ) {
 
1043
+               DPRINTK(("autofs4_dir_close: dentry busy\n"));
 
1044
+               return -EBUSY;
 
1045
+       }
 
1046
+
 
1047
+       if ( d_mountpoint(dentry) ) {
 
1048
+               struct file *fp = file->private_data;
 
1049
+
 
1050
+               if (!fp)
 
1051
+                       return -ENOENT;
 
1052
+
 
1053
+               filp_close(fp, current->files);
 
1054
+               file->private_data = NULL;
 
1055
+       }
 
1056
+out:
 
1057
+       return 0;
 
1058
+}
 
1059
+
 
1060
+static int autofs4_dir_readdir(struct file *file, void *dirent, filldir_t filldir)
 
1061
+{
 
1062
+       struct dentry *dentry = file->f_dentry;
 
1063
+       struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
 
1064
+       int status;
 
1065
+
 
1066
+       DPRINTK(("autofs4_readdir: file=%p dentry=%p %.*s\n",
 
1067
+                file, dentry, dentry->d_name.len, dentry->d_name.name));
 
1068
+
 
1069
+       if ( autofs4_oz_mode(sbi) )
 
1070
+               goto out;
 
1071
+
 
1072
+       if ( autofs4_ispending(dentry) ) {
 
1073
+               DPRINTK(("autofs4_readdir: dentry busy\n"));
 
1074
+               return -EBUSY;
 
1075
+       }
 
1076
+
 
1077
+       if ( d_mountpoint(dentry) ) {
 
1078
+               struct file *fp = file->private_data;
 
1079
+
 
1080
+               if (!fp)
 
1081
+                       return -ENOENT;
 
1082
+
 
1083
+               if (!fp->f_op || !fp->f_op->readdir)
 
1084
+                       goto out;
 
1085
+
 
1086
+               status = vfs_readdir(fp, filldir, dirent);
 
1087
+               file->f_pos = fp->f_pos;
 
1088
+               if ( status )
 
1089
+                       autofs4_copy_atime(file, fp);
 
1090
+               return status;
 
1091
+       }
 
1092
+out:
 
1093
+       return autofs4_dcache_readdir(file, dirent, filldir);
 
1094
 }
 
1095
 
 
1096
 static int try_to_fill_dentry(struct dentry *dentry, 
 
1097
                              struct super_block *sb,
 
1098
-                             struct autofs_sb_info *sbi)
 
1099
+                             struct autofs_sb_info *sbi, int flags)
 
1100
 {
 
1101
        struct autofs_info *de_info = autofs4_dentry_ino(dentry);
 
1102
        int status = 0;
 
1103
@@ -79,12 +294,11 @@
 
1104
            when expiration is done to trigger mount request with a new
 
1105
            dentry */
 
1106
        if (de_info && (de_info->flags & AUTOFS_INF_EXPIRING)) {
 
1107
-               DPRINTK(("try_to_fill_entry: waiting for expire %p name=%.*s, flags&PENDING=%s de_info=%p de_info->flags=%x\n",
 
1108
-                        dentry, dentry->d_name.len, dentry->d_name.name, 
 
1109
-                        dentry->d_flags & DCACHE_AUTOFS_PENDING?"t":"f",
 
1110
-                        de_info, de_info?de_info->flags:0));
 
1111
-               status = autofs4_wait(sbi, &dentry->d_name, NFY_NONE);
 
1112
-               
 
1113
+               DPRINTK(("try_to_fill_entry: waiting for expire %p name=%.*s\n",
 
1114
+                        dentry, dentry->d_name.len, dentry->d_name.name));
 
1115
+
 
1116
+               status = autofs4_wait(sbi, dentry, NFY_NONE);
 
1117
+
 
1118
                DPRINTK(("try_to_fill_entry: expire done status=%d\n", status));
 
1119
                
 
1120
                return 0;
 
1121
@@ -94,12 +308,12 @@
 
1122
                 dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode));
 
1123
 
 
1124
        /* Wait for a pending mount, triggering one if there isn't one already */
 
1125
-       while(dentry->d_inode == NULL) {
 
1126
-               DPRINTK(("try_to_fill_entry: waiting for mount name=%.*s, de_info=%p de_info->flags=%x\n",
 
1127
-                        dentry->d_name.len, dentry->d_name.name, 
 
1128
-                        de_info, de_info?de_info->flags:0));
 
1129
-               status = autofs4_wait(sbi, &dentry->d_name, NFY_MOUNT);
 
1130
-                
 
1131
+       if (dentry->d_inode == NULL) {
 
1132
+               DPRINTK(("try_to_fill_entry: waiting for mount name=%.*s\n",
 
1133
+                        dentry->d_name.len, dentry->d_name.name));
 
1134
+
 
1135
+               status = autofs4_wait(sbi, dentry, NFY_MOUNT);
 
1136
+
 
1137
                DPRINTK(("try_to_fill_entry: mount done status=%d\n", status));
 
1138
 
 
1139
                if (status && dentry->d_inode)
 
1140
@@ -108,72 +322,86 @@
 
1141
                /* Turn this into a real negative dentry? */
 
1142
                if (status == -ENOENT) {
 
1143
                        dentry->d_time = jiffies + AUTOFS_NEGATIVE_TIMEOUT;
 
1144
+                       spin_lock(&dcache_lock);
 
1145
                        dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
 
1146
+                       spin_unlock(&dcache_lock);
 
1147
                        return 1;
 
1148
                } else if (status) {
 
1149
                        /* Return a negative dentry, but leave it "pending" */
 
1150
                        return 1;
 
1151
                }
 
1152
-       }
 
1153
+       /* Trigger mount for path component or follow link */
 
1154
+       } else if ( flags & (LOOKUP_CONTINUE | LOOKUP_DIRECTORY) ||
 
1155
+                       current->link_count ) {
 
1156
+               DPRINTK(("try_to_fill_entry: waiting for mount name=%.*s\n",
 
1157
+                        dentry->d_name.len, dentry->d_name.name));
 
1158
 
 
1159
-       /* If this is an unused directory that isn't a mount point,
 
1160
-          bitch at the daemon and fix it in user space */
 
1161
-       spin_lock(&dcache_lock);
 
1162
-       if (S_ISDIR(dentry->d_inode->i_mode) &&
 
1163
-           !d_mountpoint(dentry) && 
 
1164
-           list_empty(&dentry->d_subdirs)) {
 
1165
-               DPRINTK(("try_to_fill_entry: mounting existing dir\n"));
 
1166
+               spin_lock(&dcache_lock);
 
1167
+               dentry->d_flags |= DCACHE_AUTOFS_PENDING;
 
1168
                spin_unlock(&dcache_lock);
 
1169
-               return autofs4_wait(sbi, &dentry->d_name, NFY_MOUNT) == 0;
 
1170
+               status = autofs4_wait(sbi, dentry, NFY_MOUNT);
 
1171
+
 
1172
+               DPRINTK(("try_to_fill_entry: mount done status=%d\n", status));
 
1173
+
 
1174
+               if ( status ) {
 
1175
+                       spin_lock(&dcache_lock);
 
1176
+                       dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
 
1177
+                       spin_unlock(&dcache_lock);
 
1178
+                       return 0;
 
1179
+               }
 
1180
        }
 
1181
-       spin_unlock(&dcache_lock);
 
1182
 
 
1183
        /* We don't update the usages for the autofs daemon itself, this
 
1184
           is necessary for recursive autofs mounts */
 
1185
        if (!autofs4_oz_mode(sbi))
 
1186
                autofs4_update_usage(dentry);
 
1187
 
 
1188
+       spin_unlock(&dcache_lock);
 
1189
        dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
 
1190
+       spin_unlock(&dcache_lock);
 
1191
        return 1;
 
1192
 }
 
1193
 
 
1194
-
 
1195
 /*
 
1196
  * Revalidate is called on every cache lookup.  Some of those
 
1197
  * cache lookups may actually happen while the dentry is not
 
1198
  * yet completely filled in, and revalidate has to delay such
 
1199
  * lookups..
 
1200
  */
 
1201
-static int autofs4_root_revalidate(struct dentry * dentry, int flags)
 
1202
+static int autofs4_revalidate(struct dentry * dentry, int flags)
 
1203
 {
 
1204
        struct inode * dir = dentry->d_parent->d_inode;
 
1205
        struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
 
1206
        int oz_mode = autofs4_oz_mode(sbi);
 
1207
+       int status = 1;
 
1208
+
 
1209
+       DPRINTK(("autofs4_revalidate: dentry=%p %.*s flags=%d\n",
 
1210
+                dentry, dentry->d_name.len, dentry->d_name.name, flags));
 
1211
 
 
1212
        /* Pending dentry */
 
1213
        if (autofs4_ispending(dentry)) {
 
1214
-               if (autofs4_oz_mode(sbi))
 
1215
-                       return 1;
 
1216
-               else
 
1217
-                       return try_to_fill_dentry(dentry, dir->i_sb, sbi);
 
1218
+               if ( !oz_mode )
 
1219
+                       status = try_to_fill_dentry(dentry, dir->i_sb, sbi, flags);
 
1220
+               return status;
 
1221
        }
 
1222
 
 
1223
        /* Negative dentry.. invalidate if "old" */
 
1224
-       if (dentry->d_inode == NULL)
 
1225
-               return (dentry->d_time - jiffies <= AUTOFS_NEGATIVE_TIMEOUT);
 
1226
+       if (dentry->d_inode == NULL) {
 
1227
+               status = (dentry->d_time - jiffies <= AUTOFS_NEGATIVE_TIMEOUT);
 
1228
+               return status;
 
1229
+       }
 
1230
 
 
1231
        /* Check for a non-mountpoint directory with no contents */
 
1232
        spin_lock(&dcache_lock);
 
1233
        if (S_ISDIR(dentry->d_inode->i_mode) &&
 
1234
            !d_mountpoint(dentry) && 
 
1235
            list_empty(&dentry->d_subdirs)) {
 
1236
-               DPRINTK(("autofs_root_revalidate: dentry=%p %.*s, emptydir\n",
 
1237
+               DPRINTK(("autofs4_revalidate: dentry=%p %.*s, emptydir\n",
 
1238
                         dentry, dentry->d_name.len, dentry->d_name.name));
 
1239
                spin_unlock(&dcache_lock);
 
1240
-               if (oz_mode)
 
1241
-                       return 1;
 
1242
-               else
 
1243
-                       return try_to_fill_dentry(dentry, dir->i_sb, sbi);
 
1244
+               if (!oz_mode)
 
1245
+                       status = try_to_fill_dentry(dentry, dir->i_sb, sbi, flags);
 
1246
+               return status;
 
1247
        }
 
1248
        spin_unlock(&dcache_lock);
 
1249
 
 
1250
@@ -181,25 +409,13 @@
 
1251
        if (!oz_mode)
 
1252
                autofs4_update_usage(dentry);
 
1253
 
 
1254
-       return 1;
 
1255
-}
 
1256
-
 
1257
-static int autofs4_revalidate(struct dentry *dentry, int flags)
 
1258
-{
 
1259
-       struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
 
1260
-
 
1261
-       if (!autofs4_oz_mode(sbi))
 
1262
-               autofs4_update_usage(dentry);
 
1263
-
 
1264
-       return 1;
 
1265
+       return status;
 
1266
 }
 
1267
 
 
1268
 static void autofs4_dentry_release(struct dentry *de)
 
1269
 {
 
1270
        struct autofs_info *inf;
 
1271
 
 
1272
-       lock_kernel();
 
1273
-
 
1274
        DPRINTK(("autofs4_dentry_release: releasing %p\n", de));
 
1275
 
 
1276
        inf = autofs4_dentry_ino(de);
 
1277
@@ -211,13 +427,11 @@
 
1278
 
 
1279
                autofs4_free_ino(inf);
 
1280
        }
 
1281
-
 
1282
-       unlock_kernel();
 
1283
 }
 
1284
 
 
1285
 /* For dentries of directories in the root dir */
 
1286
 static struct dentry_operations autofs4_root_dentry_operations = {
 
1287
-       d_revalidate:   autofs4_root_revalidate,
 
1288
+       d_revalidate:   autofs4_revalidate,
 
1289
        d_release:      autofs4_dentry_release,
 
1290
 };
 
1291
 
 
1292
@@ -227,28 +441,13 @@
 
1293
        d_release:      autofs4_dentry_release,
 
1294
 };
 
1295
 
 
1296
-/* Lookups in non-root dirs never find anything - if it's there, it's
 
1297
-   already in the dcache */
 
1298
-static struct dentry *autofs4_dir_lookup(struct inode *dir, struct dentry *dentry)
 
1299
-{
 
1300
-#if 0
 
1301
-       DPRINTK(("autofs_dir_lookup: ignoring lookup of %.*s/%.*s\n",
 
1302
-                dentry->d_parent->d_name.len, dentry->d_parent->d_name.name,
 
1303
-                dentry->d_name.len, dentry->d_name.name));
 
1304
-#endif
 
1305
-
 
1306
-       dentry->d_fsdata = NULL;
 
1307
-       d_add(dentry, NULL);
 
1308
-       return NULL;
 
1309
-}
 
1310
-
 
1311
 /* Lookups in the root directory */
 
1312
-static struct dentry *autofs4_root_lookup(struct inode *dir, struct dentry *dentry)
 
1313
+static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry)
 
1314
 {
 
1315
        struct autofs_sb_info *sbi;
 
1316
        int oz_mode;
 
1317
 
 
1318
-       DPRINTK(("autofs_root_lookup: name = %.*s\n", 
 
1319
+       DPRINTK(("autofs4_root_lookup: name = %.*s\n", 
 
1320
                 dentry->d_name.len, dentry->d_name.name));
 
1321
 
 
1322
        if (dentry->d_name.len > NAME_MAX)
 
1323
@@ -257,7 +456,8 @@
 
1324
        sbi = autofs4_sbi(dir->i_sb);
 
1325
 
 
1326
        oz_mode = autofs4_oz_mode(sbi);
 
1327
-       DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n",
 
1328
+
 
1329
+       DPRINTK(("autofs4_root_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n",
 
1330
                 current->pid, current->pgrp, sbi->catatonic, oz_mode));
 
1331
 
 
1332
        /*
 
1333
@@ -288,8 +488,15 @@
 
1334
         * a signal. If so we can force a restart..
 
1335
         */
 
1336
        if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
 
1337
-               if (signal_pending(current))
 
1338
-                       return ERR_PTR(-ERESTARTNOINTR);
 
1339
+               /* See if we were interrupted */
 
1340
+               if (signal_pending(current)) {
 
1341
+                       sigset_t *sigset = &current->pending.signal;
 
1342
+                       if (sigismember (sigset, SIGKILL) ||
 
1343
+                           sigismember (sigset, SIGQUIT) ||
 
1344
+                           sigismember (sigset, SIGINT)) {
 
1345
+                           return ERR_PTR(-ERESTARTNOINTR);
 
1346
+                       }
 
1347
+               }
 
1348
        }
 
1349
 
 
1350
        /*
 
1351
@@ -313,7 +520,7 @@
 
1352
        struct inode *inode;
 
1353
        char *cp;
 
1354
 
 
1355
-       DPRINTK(("autofs_dir_symlink: %s <- %.*s\n", symname, 
 
1356
+       DPRINTK(("autofs4_dir_symlink: %s <- %.*s\n", symname, 
 
1357
                 dentry->d_name.len, dentry->d_name.name));
 
1358
 
 
1359
        if (!autofs4_oz_mode(sbi))
 
1360
@@ -363,7 +570,7 @@
 
1361
  * If a process is blocked on the dentry waiting for the expire to finish,
 
1362
  * it will invalidate the dentry and try to mount with a new one.
 
1363
  *
 
1364
- * Also see autofs_dir_rmdir().. 
 
1365
+ * Also see autofs4_dir_rmdir().. 
 
1366
  */
 
1367
 static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
 
1368
 {
 
1369
@@ -413,8 +620,6 @@
 
1370
        return 0;
 
1371
 }
 
1372
 
 
1373
-
 
1374
-
 
1375
 static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
1376
 {
 
1377
        struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
 
1378
@@ -424,7 +629,7 @@
 
1379
        if ( !autofs4_oz_mode(sbi) )
 
1380
                return -EACCES;
 
1381
 
 
1382
-       DPRINTK(("autofs_dir_mkdir: dentry %p, creating %.*s\n",
 
1383
+       DPRINTK(("autofs4_dir_mkdir: dentry %p, creating %.*s\n",
 
1384
                 dentry, dentry->d_name.len, dentry->d_name.name));
 
1385
 
 
1386
        ino = autofs4_init_ino(ino, sbi, S_IFDIR | 0555);
 
1387
@@ -448,6 +653,19 @@
 
1388
        return 0;
 
1389
 }
 
1390
 
 
1391
+/* 
 
1392
+ * Identify autofs_dentries - this is so we can tell if there's
 
1393
+ * an extra dentry refcount or not.  We only hold a refcount on the
 
1394
+ * dentry if its non-negative (ie, d_inode != NULL)
 
1395
+ */
 
1396
+int is_autofs4_dentry(struct dentry *dentry)
 
1397
+{
 
1398
+       return dentry && dentry->d_inode &&
 
1399
+               (dentry->d_op == &autofs4_root_dentry_operations ||
 
1400
+                dentry->d_op == &autofs4_dentry_operations) &&
 
1401
+               dentry->d_fsdata != NULL;
 
1402
+}
 
1403
+
 
1404
 /* Get/set timeout ioctl() operation */
 
1405
 static inline int autofs4_get_set_timeout(struct autofs_sb_info *sbi,
 
1406
                                         unsigned long *p)
 
1407
@@ -473,16 +691,65 @@
 
1408
        return put_user(sbi->version, p);
 
1409
 }
 
1410
 
 
1411
-/* Identify autofs_dentries - this is so we can tell if there's
 
1412
-   an extra dentry refcount or not.  We only hold a refcount on the
 
1413
-   dentry if its non-negative (ie, d_inode != NULL)
 
1414
-*/
 
1415
-int is_autofs4_dentry(struct dentry *dentry)
 
1416
+/* Return protocol sub version */
 
1417
+static inline int autofs4_get_protosubver(struct autofs_sb_info *sbi, int *p)
 
1418
 {
 
1419
-       return dentry && dentry->d_inode &&
 
1420
-               (dentry->d_op == &autofs4_root_dentry_operations ||
 
1421
-                dentry->d_op == &autofs4_dentry_operations) &&
 
1422
-               dentry->d_fsdata != NULL;
 
1423
+       return put_user(sbi->sub_version, p);
 
1424
+}
 
1425
+
 
1426
+/*
 
1427
+ * Tells the daemon whether we need to reghost or not. Also, clears
 
1428
+ * the reghost_needed flag.
 
1429
+ */
 
1430
+static inline int autofs4_ask_reghost(struct autofs_sb_info *sbi, int *p)
 
1431
+{
 
1432
+       int status;
 
1433
+
 
1434
+       DPRINTK(("autofs_ask_reghost: returning %d\n", sbi->needs_reghost));
 
1435
+
 
1436
+       status = put_user(sbi->needs_reghost, p);
 
1437
+       if ( status )
 
1438
+               return status;
 
1439
+
 
1440
+        sbi->needs_reghost = 0;
 
1441
+        return 0;
 
1442
+}
 
1443
+
 
1444
+/*
 
1445
+ * Enable / Disable reghosting ioctl() operation
 
1446
+ */
 
1447
+static inline int autofs4_toggle_reghost(struct autofs_sb_info *sbi, int *p)
 
1448
+{
 
1449
+       int status;
 
1450
+       int val;
 
1451
+
 
1452
+       status = get_user(val, p);
 
1453
+
 
1454
+       DPRINTK(("autofs4_toggle_reghost: reghost = %d\n", val));
 
1455
+
 
1456
+       if (status)
 
1457
+               return status;
 
1458
+
 
1459
+       /* turn on/off reghosting, with the val */
 
1460
+       sbi->reghost_enabled = val;
 
1461
+       return 0;
 
1462
+}
 
1463
+
 
1464
+/*
 
1465
+ * Tells the daemon whether we can umaont the autofs mount.
 
1466
+ */
 
1467
+static inline int autofs4_ask_umount(struct vfsmount *mnt, int *p)
 
1468
+{
 
1469
+       int status = 0;
 
1470
+
 
1471
+       if (may_umount(mnt) == 0)
 
1472
+               status = 1;
 
1473
+
 
1474
+       DPRINTK(("autofs_ask_umount: returning %d\n", status));
 
1475
+
 
1476
+       status = put_user(status, p);
 
1477
+
 
1478
+       return status;
 
1479
 }
 
1480
 
 
1481
 /*
 
1482
@@ -494,7 +761,7 @@
 
1483
 {
 
1484
        struct autofs_sb_info *sbi = autofs4_sbi(inode->i_sb);
 
1485
 
 
1486
-       DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",
 
1487
+       DPRINTK(("autofs4_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",
 
1488
                 cmd,arg,sbi,current->pgrp));
 
1489
 
 
1490
        if ( _IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
 
1491
@@ -514,9 +781,19 @@
 
1492
                return 0;
 
1493
        case AUTOFS_IOC_PROTOVER: /* Get protocol version */
 
1494
                return autofs4_get_protover(sbi, (int *)arg);
 
1495
+       case AUTOFS_IOC_PROTOSUBVER: /* Get protocol sub version */
 
1496
+               return autofs4_get_protosubver(sbi, (int *) arg);
 
1497
        case AUTOFS_IOC_SETTIMEOUT:
 
1498
                return autofs4_get_set_timeout(sbi,(unsigned long *)arg);
 
1499
 
 
1500
+       case AUTOFS_IOC_TOGGLEREGHOST:
 
1501
+               return autofs4_toggle_reghost(sbi, (int *) arg);
 
1502
+       case AUTOFS_IOC_ASKREGHOST:
 
1503
+               return autofs4_ask_reghost(sbi, (int *) arg);
 
1504
+
 
1505
+       case AUTOFS_IOC_ASKUMOUNT:
 
1506
+               return autofs4_ask_umount(filp->f_vfsmnt, (int *) arg);
 
1507
+
 
1508
        /* return a single thing to expire */
 
1509
        case AUTOFS_IOC_EXPIRE:
 
1510
                return autofs4_expire_run(inode->i_sb,filp->f_vfsmnt,sbi,
 
1511
diff -Nur linux-2.4.22/fs/autofs4/waitq.c autofs4-2.4/fs/autofs4/waitq.c
 
1512
--- linux-2.4.22/fs/autofs4/waitq.c     2001-02-10 03:29:44.000000000 +0800
 
1513
+++ autofs4-2.4/fs/autofs4/waitq.c      2005-04-04 22:27:32.000000000 +0800
 
1514
@@ -3,6 +3,7 @@
 
1515
  * linux/fs/autofs/waitq.c
 
1516
  *
 
1517
  *  Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
 
1518
+ *  Copyright 2001-2003 Ian Kent <raven@themaw.net>
 
1519
  *
 
1520
  * This file is part of the Linux kernel and is made available under
 
1521
  * the terms of the GNU General Public License, version 2, or at your
 
1522
@@ -27,7 +28,7 @@
 
1523
 {
 
1524
        struct autofs_wait_queue *wq, *nwq;
 
1525
 
 
1526
-       DPRINTK(("autofs: entering catatonic mode\n"));
 
1527
+       DPRINTK(("autofs4: entering catatonic mode\n"));
 
1528
 
 
1529
        sbi->catatonic = 1;
 
1530
        wq = sbi->queues;
 
1531
@@ -35,9 +36,11 @@
 
1532
        while ( wq ) {
 
1533
                nwq = wq->next;
 
1534
                wq->status = -ENOENT; /* Magic is gone - report failure */
 
1535
-               kfree(wq->name);
 
1536
-               wq->name = NULL;
 
1537
-               wake_up(&wq->queue);
 
1538
+               if ( wq->name ) {
 
1539
+                       kfree(wq->name);
 
1540
+                       wq->name = NULL;
 
1541
+               }
 
1542
+               wake_up_interruptible(&wq->queue);
 
1543
                wq = nwq;
 
1544
        }
 
1545
        if (sbi->pipe) {
 
1546
@@ -90,8 +93,8 @@
 
1547
        union autofs_packet_union pkt;
 
1548
        size_t pktsz;
 
1549
 
 
1550
-       DPRINTK(("autofs_notify: wait id = 0x%08lx, name = %.*s, type=%d\n",
 
1551
-                wq->wait_queue_token, wq->len, wq->name, type));
 
1552
+       DPRINTK(("autofs4_notify: wait id = 0x%08lx, name = %.*s, type=%d\n",
 
1553
+               (unsigned long) wq->wait_queue_token, wq->len, wq->name, type));
 
1554
 
 
1555
        memset(&pkt,0,sizeof pkt); /* For security reasons */
 
1556
 
 
1557
@@ -116,7 +119,7 @@
 
1558
                memcpy(ep->name, wq->name, wq->len);
 
1559
                ep->name[wq->len] = '\0';
 
1560
        } else {
 
1561
-               printk("autofs_notify_daemon: bad type %d!\n", type);
 
1562
+               printk("autofs4_notify_daemon: bad type %d!\n", type);
 
1563
                return;
 
1564
        }
 
1565
 
 
1566
@@ -124,62 +127,110 @@
 
1567
                autofs4_catatonic_mode(sbi);
 
1568
 }
 
1569
 
 
1570
-int autofs4_wait(struct autofs_sb_info *sbi, struct qstr *name,
 
1571
+static int autofs4_getpath(struct autofs_sb_info *sbi,
 
1572
+                          struct dentry *dentry, char **name)
 
1573
+{
 
1574
+       struct dentry *root = sbi->sb->s_root;
 
1575
+       struct dentry *tmp;
 
1576
+       char *buf = *name;
 
1577
+       char *p;
 
1578
+       int len = 0;
 
1579
+
 
1580
+       spin_lock(&dcache_lock);
 
1581
+       for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent)
 
1582
+               len += tmp->d_name.len + 1;
 
1583
+
 
1584
+       if (--len > NAME_MAX) {
 
1585
+               spin_unlock(&dcache_lock);
 
1586
+               return 0;
 
1587
+       }
 
1588
+
 
1589
+       *(buf + len) = '\0';
 
1590
+       p = buf + len - dentry->d_name.len;
 
1591
+       strncpy(p, dentry->d_name.name, dentry->d_name.len);
 
1592
+
 
1593
+       for (tmp = dentry->d_parent; tmp != root ; tmp = tmp->d_parent) {
 
1594
+               *(--p) = '/';
 
1595
+               p -= tmp->d_name.len;
 
1596
+               strncpy(p, tmp->d_name.name, tmp->d_name.len);
 
1597
+       }
 
1598
+       spin_unlock(&dcache_lock);
 
1599
+
 
1600
+       return len;
 
1601
+}
 
1602
+
 
1603
+int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
 
1604
                enum autofs_notify notify)
 
1605
 {
 
1606
        struct autofs_wait_queue *wq;
 
1607
-       int status;
 
1608
+       char *name;
 
1609
+       int len, status;
 
1610
 
 
1611
        /* In catatonic mode, we don't wait for nobody */
 
1612
-       if ( sbi->catatonic )
 
1613
+       if (sbi->catatonic)
 
1614
                return -ENOENT;
 
1615
-       
 
1616
-       /* We shouldn't be able to get here, but just in case */
 
1617
-       if ( name->len > NAME_MAX )
 
1618
+
 
1619
+       name = kmalloc(NAME_MAX + 1, GFP_KERNEL);
 
1620
+       if (!name)
 
1621
+               return -ENOMEM;
 
1622
+
 
1623
+       len = autofs4_getpath(sbi, dentry, &name);
 
1624
+       if (!len) {
 
1625
+               kfree(name);
 
1626
                return -ENOENT;
 
1627
+       }
 
1628
+
 
1629
+       if (down_interruptible(&sbi->wq_sem)) {
 
1630
+               kfree(name);
 
1631
+               return -EINTR;
 
1632
+       }
 
1633
 
 
1634
        for ( wq = sbi->queues ; wq ; wq = wq->next ) {
 
1635
-               if ( wq->hash == name->hash &&
 
1636
-                    wq->len == name->len &&
 
1637
-                    wq->name && !memcmp(wq->name,name->name,name->len) )
 
1638
+               if ( wq->hash == dentry->d_name.hash &&
 
1639
+                    wq->len == len &&
 
1640
+                    wq->name && !memcmp(wq->name, name, len) )
 
1641
                        break;
 
1642
        }
 
1643
        
 
1644
        if ( !wq ) {
 
1645
                /* Create a new wait queue */
 
1646
-               wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);
 
1647
-               if ( !wq )
 
1648
-                       return -ENOMEM;
 
1649
-
 
1650
-               wq->name = kmalloc(name->len,GFP_KERNEL);
 
1651
-               if ( !wq->name ) {
 
1652
-                       kfree(wq);
 
1653
+               wq = kmalloc(sizeof(struct autofs_wait_queue), GFP_KERNEL);
 
1654
+               if ( !wq ) {
 
1655
+                       kfree(name);
 
1656
+                       up(&sbi->wq_sem);
 
1657
                        return -ENOMEM;
 
1658
                }
 
1659
+
 
1660
                wq->wait_queue_token = autofs4_next_wait_queue;
 
1661
                if (++autofs4_next_wait_queue == 0)
 
1662
                        autofs4_next_wait_queue = 1;
 
1663
-               init_waitqueue_head(&wq->queue);
 
1664
-               wq->hash = name->hash;
 
1665
-               wq->len = name->len;
 
1666
-               wq->status = -EINTR; /* Status return if interrupted */
 
1667
-               memcpy(wq->name, name->name, name->len);
 
1668
                wq->next = sbi->queues;
 
1669
                sbi->queues = wq;
 
1670
+               init_waitqueue_head(&wq->queue);
 
1671
+               wq->hash = dentry->d_name.hash;
 
1672
+               wq->name = name;
 
1673
+               wq->len = len;
 
1674
+               wq->status = -EINTR; /* Status return if interrupted */
 
1675
+               atomic_set(&wq->wait_ctr, 2);
 
1676
+               atomic_set(&wq->notified, 1);
 
1677
+               up(&sbi->wq_sem);
 
1678
+       } else {
 
1679
+               atomic_inc(&wq->wait_ctr);
 
1680
+               up(&sbi->wq_sem);
 
1681
+               kfree(name);
 
1682
+               DPRINTK(("autofs4_wait: existing wait id = 0x%08lx, name = %.*s, nfy=%d\n",
 
1683
+                       (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify));
 
1684
+       }
 
1685
+
 
1686
+       if (notify != NFY_NONE && atomic_dec_and_test(&wq->notified)) {
 
1687
+               int type = (notify == NFY_MOUNT ? 
 
1688
+                       autofs_ptype_missing : autofs_ptype_expire_multi);
 
1689
+
 
1690
+               DPRINTK(("autofs4_wait: new wait id = 0x%08lx, name = %.*s, nfy=%d\n",
 
1691
+                       (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify));
 
1692
 
 
1693
-               DPRINTK(("autofs_wait: new wait id = 0x%08lx, name = %.*s, nfy=%d\n",
 
1694
-                        wq->wait_queue_token, wq->len, wq->name, notify));
 
1695
                /* autofs4_notify_daemon() may block */
 
1696
-               wq->wait_ctr = 2;
 
1697
-               if (notify != NFY_NONE) {
 
1698
-                       autofs4_notify_daemon(sbi,wq, 
 
1699
-                                             notify == NFY_MOUNT ? autofs_ptype_missing :
 
1700
-                                                                   autofs_ptype_expire_multi);
 
1701
-               }
 
1702
-       } else {
 
1703
-               wq->wait_ctr++;
 
1704
-               DPRINTK(("autofs_wait: existing wait id = 0x%08lx, name = %.*s, nfy=%d\n",
 
1705
-                        wq->wait_queue_token, wq->len, wq->name, notify));
 
1706
+               autofs4_notify_daemon(sbi, wq, type);
 
1707
        }
 
1708
 
 
1709
        /* wq->name is NULL if and only if the lock is already released */
 
1710
@@ -204,7 +255,7 @@
 
1711
                recalc_sigpending(current);
 
1712
                spin_unlock_irqrestore(&current->sigmask_lock, irqflags);
 
1713
 
 
1714
-               interruptible_sleep_on(&wq->queue);
 
1715
+               wait_event_interruptible(wq->queue, wq->name == NULL);
 
1716
 
 
1717
                spin_lock_irqsave(&current->sigmask_lock, irqflags);
 
1718
                current->blocked = oldset;
 
1719
@@ -216,7 +267,8 @@
 
1720
 
 
1721
        status = wq->status;
 
1722
 
 
1723
-       if (--wq->wait_ctr == 0)        /* Are we the last process to need status? */
 
1724
+       /* Are we the last process to need status? */
 
1725
+       if (atomic_dec_and_test(&wq->wait_ctr))
 
1726
                kfree(wq);
 
1727
 
 
1728
        return status;
 
1729
@@ -227,23 +279,29 @@
 
1730
 {
 
1731
        struct autofs_wait_queue *wq, **wql;
 
1732
 
 
1733
+       down(&sbi->wq_sem);
 
1734
        for ( wql = &sbi->queues ; (wq = *wql) ; wql = &wq->next ) {
 
1735
                if ( wq->wait_queue_token == wait_queue_token )
 
1736
                        break;
 
1737
        }
 
1738
-       if ( !wq )
 
1739
+
 
1740
+       if ( !wq ) {
 
1741
+               up(&sbi->wq_sem);
 
1742
                return -EINVAL;
 
1743
+       }
 
1744
 
 
1745
        *wql = wq->next;        /* Unlink from chain */
 
1746
+       up(&sbi->wq_sem);
 
1747
        kfree(wq->name);
 
1748
        wq->name = NULL;        /* Do not wait on this queue */
 
1749
 
 
1750
        wq->status = status;
 
1751
 
 
1752
-       if (--wq->wait_ctr == 0)        /* Is anyone still waiting for this guy? */
 
1753
+       /* Is anyone still waiting for this guy? */
 
1754
+       if (atomic_dec_and_test(&wq->wait_ctr))
 
1755
                kfree(wq);
 
1756
        else
 
1757
-               wake_up(&wq->queue);
 
1758
+               wake_up_interruptible(&wq->queue);
 
1759
 
 
1760
        return 0;
 
1761
 }
 
1762
diff -Nur linux-2.4.22/include/linux/auto_fs.h autofs4-2.4/include/linux/auto_fs.h
 
1763
--- linux-2.4.22/include/linux/auto_fs.h        2003-06-13 22:51:38.000000000 +0800
 
1764
+++ autofs4-2.4/include/linux/auto_fs.h 2005-04-04 22:27:31.000000000 +0800
 
1765
@@ -45,7 +45,7 @@
 
1766
  * If so, 32-bit user-space code should be backwards compatible.
 
1767
  */
 
1768
 
 
1769
-#if !defined(__alpha__) && !defined(__ia64__)   
 
1770
+#if defined(__sparc__) || defined(__mips__) || defined(__s390__) || defined(__powerpc__) || defined(__x86_64__)
 
1771
 typedef unsigned int autofs_wqt_t;
 
1772
 #else
 
1773
 typedef unsigned long autofs_wqt_t;
 
1774
diff -Nur linux-2.4.22/include/linux/auto_fs4.h autofs4-2.4/include/linux/auto_fs4.h
 
1775
--- linux-2.4.22/include/linux/auto_fs4.h       2001-11-23 03:46:40.000000000 +0800
 
1776
+++ autofs4-2.4/include/linux/auto_fs4.h        2005-04-04 22:27:31.000000000 +0800
 
1777
@@ -23,6 +23,12 @@
 
1778
 #define AUTOFS_MIN_PROTO_VERSION       3
 
1779
 #define AUTOFS_MAX_PROTO_VERSION       4
 
1780
 
 
1781
+#define AUTOFS_PROTO_SUBVERSION                6
 
1782
+
 
1783
+/* Mask for expire behaviour */
 
1784
+#define AUTOFS_EXP_IMMEDIATE            1
 
1785
+#define AUTOFS_EXP_LEAVES               2
 
1786
+
 
1787
 /* New message type */
 
1788
 #define autofs_ptype_expire_multi      2       /* Expire entry (umount request) */
 
1789
 
 
1790
@@ -41,7 +47,10 @@
 
1791
        struct autofs_packet_expire_multi expire_multi;
 
1792
 };
 
1793
 
 
1794
-#define AUTOFS_IOC_EXPIRE_MULTI _IOW(0x93,0x66,int)
 
1795
-
 
1796
+#define AUTOFS_IOC_EXPIRE_MULTI                _IOW(0x93,0x66,int)
 
1797
+#define AUTOFS_IOC_PROTOSUBVER         _IOR(0x93,0x67,int)
 
1798
+#define AUTOFS_IOC_ASKREGHOST          _IOR(0x93,0x68,int)
 
1799
+#define AUTOFS_IOC_TOGGLEREGHOST       _IOR(0x93,0x69,int)
 
1800
+#define AUTOFS_IOC_ASKUMOUNT           _IOR(0x93,0x70,int)
 
1801
 
 
1802
 #endif /* _LINUX_AUTO_FS4_H */