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

« back to all changes in this revision

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