~ubuntu-branches/ubuntu/raring/autofs5/raring

« back to all changes in this revision

Viewing changes to patches/autofs4-2.6.26-dev-ioctl-20081029.patch

  • Committer: Bazaar Package Importer
  • Author(s): Jan Christoph Nordholz
  • Date: 2009-03-09 01:16:48 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090309011648-gjynlid883f0s2c4
Tags: 5.0.4-1
* New upstream version (5.0.4 plus patchset as of 2009/03/09).
  * Closes: #518728.
  * Remove dpatch 14, applied upstream.
* New dpatch 14 to avoid using the relatively young SOCK_CLOEXEC
  feature.
* Only invoke 'make clean' on clean target so ./configure isn't
  purged.
* Fix a typo in the postinst regarding the ucf conffile handling.
* Add 'set -e' to package maintenance scripts.
* Drop unnecessary /var/run/autofs from package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Index: linux-2.6.26/fs/autofs4/autofs_i.h
 
2
===================================================================
 
3
--- linux-2.6.26.orig/fs/autofs4/autofs_i.h
 
4
+++ linux-2.6.26/fs/autofs4/autofs_i.h
 
5
@@ -14,6 +14,7 @@
 
6
 /* Internal header file for autofs */
 
7
 
 
8
 #include <linux/auto_fs4.h>
 
9
+#include <linux/auto_dev-ioctl.h>
 
10
 #include <linux/mutex.h>
 
11
 #include <linux/list.h>
 
12
 
 
13
@@ -21,7 +22,8 @@
 
14
 #define AUTOFS_IOC_FIRST     AUTOFS_IOC_READY
 
15
 #define AUTOFS_IOC_COUNT     32
 
16
 
 
17
-#define AUTOFS_TYPE_TRIGGER    (AUTOFS_TYPE_DIRECT|AUTOFS_TYPE_OFFSET)
 
18
+#define AUTOFS_DEV_IOCTL_IOC_FIRST     (AUTOFS_DEV_IOCTL_VERSION)
 
19
+#define AUTOFS_DEV_IOCTL_IOC_COUNT     (AUTOFS_IOC_COUNT - 11)
 
20
 
 
21
 #include <linux/kernel.h>
 
22
 #include <linux/slab.h>
 
23
@@ -37,11 +39,27 @@
 
24
 /* #define DEBUG */
 
25
 
 
26
 #ifdef DEBUG
 
27
-#define DPRINTK(fmt,args...) do { printk(KERN_DEBUG "pid %d: %s: " fmt "\n" , current->pid , __func__ , ##args); } while(0)
 
28
+#define DPRINTK(fmt, args...)                          \
 
29
+do {                                                   \
 
30
+       printk(KERN_DEBUG "pid %d: %s: " fmt "\n",      \
 
31
+               current->pid, __func__, ##args);        \
 
32
+} while (0)
 
33
 #else
 
34
-#define DPRINTK(fmt,args...) do {} while(0)
 
35
+#define DPRINTK(fmt, args...) do {} while (0)
 
36
 #endif
 
37
 
 
38
+#define AUTOFS_WARN(fmt, args...)                      \
 
39
+do {                                                   \
 
40
+       printk(KERN_WARNING "pid %d: %s: " fmt "\n",    \
 
41
+               current->pid, __func__, ##args);        \
 
42
+} while (0)
 
43
+
 
44
+#define AUTOFS_ERROR(fmt, args...)                     \
 
45
+do {                                                   \
 
46
+       printk(KERN_ERR "pid %d: %s: " fmt "\n",        \
 
47
+               current->pid, __func__, ##args);        \
 
48
+} while (0)
 
49
+
 
50
 /* Unified info structure.  This is pointed to by both the dentry and
 
51
    inode structures.  Each file in the filesystem has an instance of this
 
52
    structure.  It holds a reference to the dentry, so dentries are never
 
53
@@ -63,6 +81,9 @@ struct autofs_info {
 
54
        unsigned long last_used;
 
55
        atomic_t count;
 
56
 
 
57
+       uid_t uid;
 
58
+       gid_t gid;
 
59
+
 
60
        mode_t  mode;
 
61
        size_t  size;
 
62
 
 
63
@@ -165,8 +186,21 @@ int autofs4_expire_wait(struct dentry *d
 
64
 int autofs4_expire_run(struct super_block *, struct vfsmount *,
 
65
                        struct autofs_sb_info *,
 
66
                        struct autofs_packet_expire __user *);
 
67
+int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
 
68
+                           struct autofs_sb_info *sbi, int when);
 
69
 int autofs4_expire_multi(struct super_block *, struct vfsmount *,
 
70
                        struct autofs_sb_info *, int __user *);
 
71
+struct dentry *autofs4_expire_direct(struct super_block *sb,
 
72
+                                    struct vfsmount *mnt,
 
73
+                                    struct autofs_sb_info *sbi, int how);
 
74
+struct dentry *autofs4_expire_indirect(struct super_block *sb,
 
75
+                                      struct vfsmount *mnt,
 
76
+                                      struct autofs_sb_info *sbi, int how);
 
77
+
 
78
+/* Device node initialization */
 
79
+
 
80
+int autofs_dev_ioctl_init(void);
 
81
+void autofs_dev_ioctl_exit(void);
 
82
 
 
83
 /* Operations structures */
 
84
 
 
85
Index: linux-2.6.26/fs/autofs4/inode.c
 
86
===================================================================
 
87
--- linux-2.6.26.orig/fs/autofs4/inode.c
 
88
+++ linux-2.6.26/fs/autofs4/inode.c
 
89
@@ -53,6 +53,8 @@ struct autofs_info *autofs4_init_ino(str
 
90
                atomic_set(&ino->count, 0);
 
91
        }
 
92
 
 
93
+       ino->uid = 0;
 
94
+       ino->gid = 0;
 
95
        ino->mode = mode;
 
96
        ino->last_used = jiffies;
 
97
 
 
98
@@ -195,9 +197,9 @@ static int autofs4_show_options(struct s
 
99
        seq_printf(m, ",minproto=%d", sbi->min_proto);
 
100
        seq_printf(m, ",maxproto=%d", sbi->max_proto);
 
101
 
 
102
-       if (sbi->type & AUTOFS_TYPE_OFFSET)
 
103
+       if (autofs_type_offset(sbi->type))
 
104
                seq_printf(m, ",offset");
 
105
-       else if (sbi->type & AUTOFS_TYPE_DIRECT)
 
106
+       else if (autofs_type_direct(sbi->type))
 
107
                seq_printf(m, ",direct");
 
108
        else
 
109
                seq_printf(m, ",indirect");
 
110
@@ -282,13 +284,13 @@ static int parse_options(char *options, 
 
111
                        *maxproto = option;
 
112
                        break;
 
113
                case Opt_indirect:
 
114
-                       *type = AUTOFS_TYPE_INDIRECT;
 
115
+                       set_autofs_type_indirect(type);
 
116
                        break;
 
117
                case Opt_direct:
 
118
-                       *type = AUTOFS_TYPE_DIRECT;
 
119
+                       set_autofs_type_direct(type);
 
120
                        break;
 
121
                case Opt_offset:
 
122
-                       *type = AUTOFS_TYPE_OFFSET;
 
123
+                       set_autofs_type_offset(type);
 
124
                        break;
 
125
                default:
 
126
                        return 1;
 
127
@@ -336,7 +338,7 @@ int autofs4_fill_super(struct super_bloc
 
128
        sbi->sb = s;
 
129
        sbi->version = 0;
 
130
        sbi->sub_version = 0;
 
131
-       sbi->type = AUTOFS_TYPE_INDIRECT;
 
132
+       set_autofs_type_indirect(&sbi->type);
 
133
        sbi->min_proto = 0;
 
134
        sbi->max_proto = 0;
 
135
        mutex_init(&sbi->wq_mutex);
 
136
@@ -378,7 +380,7 @@ int autofs4_fill_super(struct super_bloc
 
137
        }
 
138
 
 
139
        root_inode->i_fop = &autofs4_root_operations;
 
140
-       root_inode->i_op = sbi->type & AUTOFS_TYPE_TRIGGER ?
 
141
+       root_inode->i_op = autofs_type_trigger(sbi->type) ?
 
142
                        &autofs4_direct_root_inode_operations :
 
143
                        &autofs4_indirect_root_inode_operations;
 
144
 
 
145
Index: linux-2.6.26/fs/autofs4/waitq.c
 
146
===================================================================
 
147
--- linux-2.6.26.orig/fs/autofs4/waitq.c
 
148
+++ linux-2.6.26/fs/autofs4/waitq.c
 
149
@@ -337,7 +337,7 @@ int autofs4_wait(struct autofs_sb_info *
 
150
                 * is very similar for indirect mounts except only dentrys
 
151
                 * in the root of the autofs file system may be negative.
 
152
                 */
 
153
-               if (sbi->type & AUTOFS_TYPE_TRIGGER)
 
154
+               if (autofs_type_trigger(sbi->type))
 
155
                        return -ENOENT;
 
156
                else if (!IS_ROOT(dentry->d_parent))
 
157
                        return -ENOENT;
 
158
@@ -348,7 +348,7 @@ int autofs4_wait(struct autofs_sb_info *
 
159
                return -ENOMEM;
 
160
 
 
161
        /* If this is a direct mount request create a dummy name */
 
162
-       if (IS_ROOT(dentry) && sbi->type & AUTOFS_TYPE_TRIGGER)
 
163
+       if (IS_ROOT(dentry) && autofs_type_trigger(sbi->type))
 
164
                qstr.len = sprintf(name, "%p", dentry);
 
165
        else {
 
166
                qstr.len = autofs4_getpath(sbi, dentry, &name);
 
167
@@ -406,11 +406,11 @@ int autofs4_wait(struct autofs_sb_info *
 
168
                                type = autofs_ptype_expire_multi;
 
169
                } else {
 
170
                        if (notify == NFY_MOUNT)
 
171
-                               type = (sbi->type & AUTOFS_TYPE_TRIGGER) ?
 
172
+                               type = autofs_type_trigger(sbi->type) ?
 
173
                                        autofs_ptype_missing_direct :
 
174
                                         autofs_ptype_missing_indirect;
 
175
                        else
 
176
-                               type = (sbi->type & AUTOFS_TYPE_TRIGGER) ?
 
177
+                               type = autofs_type_trigger(sbi->type) ?
 
178
                                        autofs_ptype_expire_direct :
 
179
                                        autofs_ptype_expire_indirect;
 
180
                }
 
181
@@ -457,6 +457,40 @@ int autofs4_wait(struct autofs_sb_info *
 
182
 
 
183
        status = wq->status;
 
184
 
 
185
+       /*
 
186
+        * For direct and offset mounts we need to track the requester's
 
187
+        * uid and gid in the dentry info struct. This is so it can be
 
188
+        * supplied, on request, by the misc device ioctl interface.
 
189
+        * This is needed during daemon resatart when reconnecting
 
190
+        * to existing, active, autofs mounts. The uid and gid (and
 
191
+        * related string values) may be used for macro substitution
 
192
+        * in autofs mount maps.
 
193
+        */
 
194
+       if (!status) {
 
195
+               struct autofs_info *ino;
 
196
+               struct dentry *de = NULL;
 
197
+
 
198
+               /* direct mount or browsable map */
 
199
+               ino = autofs4_dentry_ino(dentry);
 
200
+               if (!ino) {
 
201
+                       /* If not lookup actual dentry used */
 
202
+                       de = d_lookup(dentry->d_parent, &dentry->d_name);
 
203
+                       if (de)
 
204
+                               ino = autofs4_dentry_ino(de);
 
205
+               }
 
206
+
 
207
+               /* Set mount requester */
 
208
+               if (ino) {
 
209
+                       spin_lock(&sbi->fs_lock);
 
210
+                       ino->uid = wq->uid;
 
211
+                       ino->gid = wq->gid;
 
212
+                       spin_unlock(&sbi->fs_lock);
 
213
+               }
 
214
+
 
215
+               if (de)
 
216
+                       dput(de);
 
217
+       }
 
218
+
 
219
        /* Are we the last process to need status? */
 
220
        mutex_lock(&sbi->wq_mutex);
 
221
        if (!--wq->wait_ctr)
 
222
Index: linux-2.6.26/Documentation/filesystems/autofs4-mount-control.txt
 
223
===================================================================
 
224
--- /dev/null
 
225
+++ linux-2.6.26/Documentation/filesystems/autofs4-mount-control.txt
 
226
@@ -0,0 +1,414 @@
 
227
+
 
228
+Miscellaneous Device control operations for the autofs4 kernel module
 
229
+====================================================================
 
230
+
 
231
+The problem
 
232
+===========
 
233
+
 
234
+There is a problem with active restarts in autofs (that is to say
 
235
+restarting autofs when there are busy mounts).
 
236
+
 
237
+During normal operation autofs uses a file descriptor opened on the
 
238
+directory that is being managed in order to be able to issue control
 
239
+operations. Using a file descriptor gives ioctl operations access to
 
240
+autofs specific information stored in the super block. The operations
 
241
+are things such as setting an autofs mount catatonic, setting the
 
242
+expire timeout and requesting expire checks. As is explained below,
 
243
+certain types of autofs triggered mounts can end up covering an autofs
 
244
+mount itself which prevents us being able to use open(2) to obtain a
 
245
+file descriptor for these operations if we don't already have one open.
 
246
+
 
247
+Currently autofs uses "umount -l" (lazy umount) to clear active mounts
 
248
+at restart. While using lazy umount works for most cases, anything that
 
249
+needs to walk back up the mount tree to construct a path, such as
 
250
+getcwd(2) and the proc file system /proc/<pid>/cwd, no longer works
 
251
+because the point from which the path is constructed has been detached
 
252
+from the mount tree.
 
253
+
 
254
+The actual problem with autofs is that it can't reconnect to existing
 
255
+mounts. Immediately one thinks of just adding the ability to remount
 
256
+autofs file systems would solve it, but alas, that can't work. This is
 
257
+because autofs direct mounts and the implementation of "on demand mount
 
258
+and expire" of nested mount trees have the file system mounted directly
 
259
+on top of the mount trigger directory dentry.
 
260
+
 
261
+For example, there are two types of automount maps, direct (in the kernel
 
262
+module source you will see a third type called an offset, which is just
 
263
+a direct mount in disguise) and indirect.
 
264
+
 
265
+Here is a master map with direct and indirect map entries:
 
266
+
 
267
+/-      /etc/auto.direct
 
268
+/test   /etc/auto.indirect
 
269
+
 
270
+and the corresponding map files:
 
271
+
 
272
+/etc/auto.direct:
 
273
+
 
274
+/automount/dparse/g6  budgie:/autofs/export1
 
275
+/automount/dparse/g1  shark:/autofs/export1
 
276
+and so on.
 
277
+
 
278
+/etc/auto.indirect:
 
279
+
 
280
+g1    shark:/autofs/export1
 
281
+g6    budgie:/autofs/export1
 
282
+and so on.
 
283
+
 
284
+For the above indirect map an autofs file system is mounted on /test and
 
285
+mounts are triggered for each sub-directory key by the inode lookup
 
286
+operation. So we see a mount of shark:/autofs/export1 on /test/g1, for
 
287
+example.
 
288
+
 
289
+The way that direct mounts are handled is by making an autofs mount on
 
290
+each full path, such as /automount/dparse/g1, and using it as a mount
 
291
+trigger. So when we walk on the path we mount shark:/autofs/export1 "on
 
292
+top of this mount point". Since these are always directories we can
 
293
+use the follow_link inode operation to trigger the mount.
 
294
+
 
295
+But, each entry in direct and indirect maps can have offsets (making
 
296
+them multi-mount map entries).
 
297
+
 
298
+For example, an indirect mount map entry could also be:
 
299
+
 
300
+g1  \
 
301
+   /        shark:/autofs/export5/testing/test \
 
302
+   /s1      shark:/autofs/export/testing/test/s1 \
 
303
+   /s2      shark:/autofs/export5/testing/test/s2 \
 
304
+   /s1/ss1  shark:/autofs/export1 \
 
305
+   /s2/ss2  shark:/autofs/export2
 
306
+
 
307
+and a similarly a direct mount map entry could also be:
 
308
+
 
309
+/automount/dparse/g1 \
 
310
+    /       shark:/autofs/export5/testing/test \
 
311
+    /s1     shark:/autofs/export/testing/test/s1 \
 
312
+    /s2     shark:/autofs/export5/testing/test/s2 \
 
313
+    /s1/ss1 shark:/autofs/export2 \
 
314
+    /s2/ss2 shark:/autofs/export2
 
315
+
 
316
+One of the issues with version 4 of autofs was that, when mounting an
 
317
+entry with a large number of offsets, possibly with nesting, we needed
 
318
+to mount and umount all of the offsets as a single unit. Not really a
 
319
+problem, except for people with a large number of offsets in map entries.
 
320
+This mechanism is used for the well known "hosts" map and we have seen
 
321
+cases (in 2.4) where the available number of mounts are exhausted or
 
322
+where the number of privileged ports available is exhausted.
 
323
+
 
324
+In version 5 we mount only as we go down the tree of offsets and
 
325
+similarly for expiring them which resolves the above problem. There is
 
326
+somewhat more detail to the implementation but it isn't needed for the
 
327
+sake of the problem explanation. The one important detail is that these
 
328
+offsets are implemented using the same mechanism as the direct mounts
 
329
+above and so the mount points can be covered by a mount.
 
330
+
 
331
+The current autofs implementation uses an ioctl file descriptor opened
 
332
+on the mount point for control operations. The references held by the
 
333
+descriptor are accounted for in checks made to determine if a mount is
 
334
+in use and is also used to access autofs file system information held
 
335
+in the mount super block. So the use of a file handle needs to be
 
336
+retained.
 
337
+
 
338
+
 
339
+The Solution
 
340
+============
 
341
+
 
342
+To be able to restart autofs leaving existing direct, indirect and
 
343
+offset mounts in place we need to be able to obtain a file handle
 
344
+for these potentially covered autofs mount points. Rather than just
 
345
+implement an isolated operation it was decided to re-implement the
 
346
+existing ioctl interface and add new operations to provide this
 
347
+functionality.
 
348
+
 
349
+In addition, to be able to reconstruct a mount tree that has busy mounts,
 
350
+the uid and gid of the last user that triggered the mount needs to be
 
351
+available because these can be used as macro substitution variables in
 
352
+autofs maps. They are recorded at mount request time and an operation
 
353
+has been added to retrieve them.
 
354
+
 
355
+Since we're re-implementing the control interface, a couple of other
 
356
+problems with the existing interface have been addressed. First, when
 
357
+a mount or expire operation completes a status is returned to the
 
358
+kernel by either a "send ready" or a "send fail" operation. The
 
359
+"send fail" operation of the ioctl interface could only ever send
 
360
+ENOENT so the re-implementation allows user space to send an actual
 
361
+status. Another expensive operation in user space, for those using
 
362
+very large maps, is discovering if a mount is present. Usually this
 
363
+involves scanning /proc/mounts and since it needs to be done quite
 
364
+often it can introduce significant overhead when there are many entries
 
365
+in the mount table. An operation to lookup the mount status of a mount
 
366
+point dentry (covered or not) has also been added.
 
367
+
 
368
+Current kernel development policy recommends avoiding the use of the
 
369
+ioctl mechanism in favor of systems such as Netlink. An implementation
 
370
+using this system was attempted to evaluate its suitability and it was
 
371
+found to be inadequate, in this case. The Generic Netlink system was
 
372
+used for this as raw Netlink would lead to a significant increase in
 
373
+complexity. There's no question that the Generic Netlink system is an
 
374
+elegant solution for common case ioctl functions but it's not a complete
 
375
+replacement probably because it's primary purpose in life is to be a
 
376
+message bus implementation rather than specifically an ioctl replacement.
 
377
+While it would be possible to work around this there is one concern
 
378
+that lead to the decision to not use it. This is that the autofs
 
379
+expire in the daemon has become far to complex because umount
 
380
+candidates are enumerated, almost for no other reason than to "count"
 
381
+the number of times to call the expire ioctl. This involves scanning
 
382
+the mount table which has proved to be a big overhead for users with
 
383
+large maps. The best way to improve this is try and get back to the
 
384
+way the expire was done long ago. That is, when an expire request is
 
385
+issued for a mount (file handle) we should continually call back to
 
386
+the daemon until we can't umount any more mounts, then return the
 
387
+appropriate status to the daemon. At the moment we just expire one
 
388
+mount at a time. A Generic Netlink implementation would exclude this
 
389
+possibility for future development due to the requirements of the
 
390
+message bus architecture.
 
391
+
 
392
+
 
393
+autofs4 Miscellaneous Device mount control interface
 
394
+====================================================
 
395
+
 
396
+The control interface is opening a device node, typically /dev/autofs.
 
397
+
 
398
+All the ioctls use a common structure to pass the needed parameter
 
399
+information and return operation results:
 
400
+
 
401
+struct autofs_dev_ioctl {
 
402
+       __u32 ver_major;
 
403
+       __u32 ver_minor;
 
404
+       __u32 size;             /* total size of data passed in
 
405
+                                * including this struct */
 
406
+       __s32 ioctlfd;          /* automount command fd */
 
407
+
 
408
+       /* Command parameters */
 
409
+
 
410
+       union {
 
411
+               struct args_protover            protover;
 
412
+               struct args_protosubver         protosubver;
 
413
+               struct args_openmount           openmount;
 
414
+               struct args_ready               ready;
 
415
+               struct args_fail                fail;
 
416
+               struct args_setpipefd           setpipefd;
 
417
+               struct args_timeout             timeout;
 
418
+               struct args_requester           requester;
 
419
+               struct args_expire              expire;
 
420
+               struct args_askumount           askumount;
 
421
+               struct args_ismountpoint        ismountpoint;
 
422
+       };
 
423
+
 
424
+       char path[0];
 
425
+};
 
426
+
 
427
+The ioctlfd field is a mount point file descriptor of an autofs mount
 
428
+point. It is returned by the open call and is used by all calls except
 
429
+the check for whether a given path is a mount point, where it may
 
430
+optionally be used to check a specific mount corresponding to a given
 
431
+mount point file descriptor, and when requesting the uid and gid of the
 
432
+last successful mount on a directory within the autofs file system.
 
433
+
 
434
+The anonymous union is used to communicate parameters and results of calls
 
435
+made as described below.
 
436
+
 
437
+The path field is used to pass a path where it is needed and the size field
 
438
+is used account for the increased structure length when translating the
 
439
+structure sent from user space.
 
440
+
 
441
+This structure can be initialized before setting specific fields by using
 
442
+the void function call init_autofs_dev_ioctl(struct autofs_dev_ioctl *).
 
443
+
 
444
+All of the ioctls perform a copy of this structure from user space to
 
445
+kernel space and return -EINVAL if the size parameter is smaller than
 
446
+the structure size itself, -ENOMEM if the kernel memory allocation fails
 
447
+or -EFAULT if the copy itself fails. Other checks include a version check
 
448
+of the compiled in user space version against the module version and a
 
449
+mismatch results in a -EINVAL return. If the size field is greater than
 
450
+the structure size then a path is assumed to be present and is checked to
 
451
+ensure it begins with a "/" and is NULL terminated, otherwise -EINVAL is
 
452
+returned. Following these checks, for all ioctl commands except
 
453
+AUTOFS_DEV_IOCTL_VERSION_CMD, AUTOFS_DEV_IOCTL_OPENMOUNT_CMD and
 
454
+AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD the ioctlfd is validated and if it is
 
455
+not a valid descriptor or doesn't correspond to an autofs mount point
 
456
+an error of -EBADF, -ENOTTY or -EINVAL (not an autofs descriptor) is
 
457
+returned.
 
458
+
 
459
+
 
460
+The ioctls
 
461
+==========
 
462
+
 
463
+An example of an implementation which uses this interface can be seen
 
464
+in autofs version 5.0.4 and later in file lib/dev-ioctl-lib.c of the
 
465
+distribution tar available for download from kernel.org in directory
 
466
+/pub/linux/daemons/autofs/v5.
 
467
+
 
468
+The device node ioctl operations implemented by this interface are:
 
469
+
 
470
+
 
471
+AUTOFS_DEV_IOCTL_VERSION
 
472
+------------------------
 
473
+
 
474
+Get the major and minor version of the autofs4 device ioctl kernel module
 
475
+implementation. It requires an initialized struct autofs_dev_ioctl as an
 
476
+input parameter and sets the version information in the passed in structure.
 
477
+It returns 0 on success or the error -EINVAL if a version mismatch is
 
478
+detected.
 
479
+
 
480
+
 
481
+AUTOFS_DEV_IOCTL_PROTOVER_CMD and AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD
 
482
+------------------------------------------------------------------
 
483
+
 
484
+Get the major and minor version of the autofs4 protocol version understood
 
485
+by loaded module. This call requires an initialized struct autofs_dev_ioctl
 
486
+with the ioctlfd field set to a valid autofs mount point descriptor
 
487
+and sets the requested version number in structure field protover.version
 
488
+and ptotosubver.sub_version respectively. These commands return 0 on
 
489
+success or one of the negative error codes if validation fails.
 
490
+
 
491
+
 
492
+AUTOFS_DEV_IOCTL_OPENMOUNT_CMD and AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD
 
493
+------------------------------------------------------------------
 
494
+
 
495
+Obtain and release a file descriptor for an autofs managed mount point
 
496
+path. The open call requires an initialized struct autofs_dev_ioctl with
 
497
+the the path field set and the size field adjusted appropriately as well
 
498
+as the openmount.devid field set to the device number of the autofs mount.
 
499
+The device number of an autofs mounted filesystem can be obtained by using
 
500
+the AUTOFS_DEV_IOCTL_ISMOUNTPOINT ioctl function by providing the path
 
501
+and autofs mount type, as described below. The close call requires an
 
502
+initialized struct autofs_dev_ioct with the ioctlfd field set to the
 
503
+descriptor obtained from the open call. The release of the file descriptor
 
504
+can also be done with close(2) so any open descriptors will also be
 
505
+closed at process exit. The close call is included in the implemented
 
506
+operations largely for completeness and to provide for a consistent
 
507
+user space implementation.
 
508
+
 
509
+
 
510
+AUTOFS_DEV_IOCTL_READY_CMD and AUTOFS_DEV_IOCTL_FAIL_CMD
 
511
+--------------------------------------------------------
 
512
+
 
513
+Return mount and expire result status from user space to the kernel.
 
514
+Both of these calls require an initialized struct autofs_dev_ioctl
 
515
+with the ioctlfd field set to the descriptor obtained from the open
 
516
+call and the ready.token or fail.token field set to the wait queue
 
517
+token number, received by user space in the foregoing mount or expire
 
518
+request. The fail.status field is set to the status to be returned when
 
519
+sending a failure notification with AUTOFS_DEV_IOCTL_FAIL_CMD.
 
520
+
 
521
+
 
522
+AUTOFS_DEV_IOCTL_SETPIPEFD_CMD
 
523
+------------------------------
 
524
+
 
525
+Set the pipe file descriptor used for kernel communication to the daemon.
 
526
+Normally this is set at mount time using an option but when reconnecting
 
527
+to a existing mount we need to use this to tell the autofs mount about
 
528
+the new kernel pipe descriptor. In order to protect mounts against
 
529
+incorrectly setting the pipe descriptor we also require that the autofs
 
530
+mount be catatonic (see next call).
 
531
+
 
532
+The call requires an initialized struct autofs_dev_ioctl with the
 
533
+ioctlfd field set to the descriptor obtained from the open call and
 
534
+the setpipefd.pipefd field set to descriptor of the pipe. On success
 
535
+the call also sets the process group id used to identify the controlling
 
536
+process (eg. the owning automount(8) daemon) to the process group of
 
537
+the caller.
 
538
+
 
539
+
 
540
+AUTOFS_DEV_IOCTL_CATATONIC_CMD
 
541
+------------------------------
 
542
+
 
543
+Make the autofs mount point catatonic. The autofs mount will no longer
 
544
+issue mount requests, the kernel communication pipe descriptor is released
 
545
+and any remaining waits in the queue released.
 
546
+
 
547
+The call requires an initialized struct autofs_dev_ioctl with the
 
548
+ioctlfd field set to the descriptor obtained from the open call.
 
549
+
 
550
+
 
551
+AUTOFS_DEV_IOCTL_TIMEOUT_CMD
 
552
+----------------------------
 
553
+
 
554
+Set the expire timeout for mounts withing an autofs mount point.
 
555
+
 
556
+The call requires an initialized struct autofs_dev_ioctl with the
 
557
+ioctlfd field set to the descriptor obtained from the open call.
 
558
+The timeout.timeout field is set to the desired timeout and this
 
559
+field is set to the value of the value of the current timeout of
 
560
+the mount upon successful completion.
 
561
+
 
562
+
 
563
+AUTOFS_DEV_IOCTL_REQUESTER_CMD
 
564
+------------------------------
 
565
+
 
566
+Return the uid and gid of the last process to successfully trigger a the
 
567
+mount on the given path dentry.
 
568
+
 
569
+The call requires an initialized struct autofs_dev_ioctl with the path
 
570
+field set to the mount point in question and the size field adjusted
 
571
+appropriately as well as the ioctlfd field set to the descriptor obtained
 
572
+from the open call. Upon return the struct fields requester.uid and
 
573
+requester.gid contain the uid and gid respectively.
 
574
+
 
575
+When reconstructing an autofs mount tree with active mounts we need to
 
576
+re-connect to mounts that may have used the original process uid and
 
577
+gid (or string variations of them) for mount lookups within the map entry.
 
578
+This call provides the ability to obtain this uid and gid so they may be
 
579
+used by user space for the mount map lookups.
 
580
+
 
581
+
 
582
+AUTOFS_DEV_IOCTL_EXPIRE_CMD
 
583
+---------------------------
 
584
+
 
585
+Issue an expire request to the kernel for an autofs mount. Typically
 
586
+this ioctl is called until no further expire candidates are found.
 
587
+
 
588
+The call requires an initialized struct autofs_dev_ioctl with the
 
589
+ioctlfd field set to the descriptor obtained from the open call. In
 
590
+addition an immediate expire, independent of the mount timeout, can be
 
591
+requested by setting the expire.how field to 1. If no expire candidates
 
592
+can be found the ioctl returns -1 with errno set to EAGAIN.
 
593
+
 
594
+This call causes the kernel module to check the mount corresponding
 
595
+to the given ioctlfd for mounts that can be expired, issues an expire
 
596
+request back to the daemon and waits for completion.
 
597
+
 
598
+AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD
 
599
+------------------------------
 
600
+
 
601
+Checks if an autofs mount point is in use.
 
602
+
 
603
+The call requires an initialized struct autofs_dev_ioctl with the
 
604
+ioctlfd field set to the descriptor obtained from the open call and
 
605
+it returns the result in the askumount.may_umount field, 1 for busy
 
606
+and 0 otherwise.
 
607
+
 
608
+
 
609
+AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD
 
610
+---------------------------------
 
611
+
 
612
+Check if the given path is a mountpoint.
 
613
+
 
614
+The call requires an initialized struct autofs_dev_ioctl. There are two
 
615
+possible variations. Both use the path field set to the path of the mount
 
616
+point to check and the size field must be adjusted appropriately. One uses
 
617
+the ioctlfd field to identify a specific mount point to check while the
 
618
+other variation uses the path and optionaly the ismountpoint.in.type 
 
619
+field set to an autofs mount type. The call returns 1 if this is a mount
 
620
+point and sets the ismountpoint.out.devid field to the device number of
 
621
+the mount and the ismountpoint.out.magic field to the relevant super
 
622
+block magic number (described below) or 0 if it isn't a mountpoint. In
 
623
+both cases the the device number (as returned by new_encode_dev()) is
 
624
+returned in the ismountpoint.out.devid field.
 
625
+
 
626
+If supplied with a file descriptor we're looking for a specific mount,
 
627
+not necessarily at the top of the mounted stack. In this case the path
 
628
+the descriptor corresponds to is considered a mountpoint if it is itself
 
629
+a mountpoint or contains a mount, such as a multi-mount without a root
 
630
+mount. In this case we return 1 if the descriptor corresponds to a mount
 
631
+point and and also returns the super magic of the covering mount if there
 
632
+is one or 0 if it isn't a mountpoint.
 
633
+
 
634
+If a path is supplied (and the ioctlfd field is set to -1) then the path
 
635
+is looked up and is checked to see if it is the root of a mount. If a
 
636
+type is also given we are looking for a particular autofs mount and if
 
637
+a match isn't found a fail is returned. If the the located path is the
 
638
+root of a mount 1 is returned along with the super magic of the mount
 
639
+or 0 otherwise.
 
640
 
641
Index: linux-2.6.26/fs/autofs4/Makefile
 
642
===================================================================
 
643
--- linux-2.6.26.orig/fs/autofs4/Makefile
 
644
+++ linux-2.6.26/fs/autofs4/Makefile
 
645
@@ -4,4 +4,4 @@
 
646
 
 
647
 obj-$(CONFIG_AUTOFS4_FS) += autofs4.o
 
648
 
 
649
-autofs4-objs := init.o inode.o root.o symlink.o waitq.o expire.o
 
650
+autofs4-objs := init.o inode.o root.o symlink.o waitq.o expire.o dev-ioctl.o
 
651
Index: linux-2.6.26/fs/autofs4/dev-ioctl.c
 
652
===================================================================
 
653
--- /dev/null
 
654
+++ linux-2.6.26/fs/autofs4/dev-ioctl.c
 
655
@@ -0,0 +1,840 @@
 
656
+/*
 
657
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
 
658
+ * Copyright 2008 Ian Kent <raven@themaw.net>
 
659
+ *
 
660
+ * This file is part of the Linux kernel and is made available under
 
661
+ * the terms of the GNU General Public License, version 2, or at your
 
662
+ * option, any later version, incorporated herein by reference.
 
663
+ */
 
664
+
 
665
+#include <linux/module.h>
 
666
+#include <linux/vmalloc.h>
 
667
+#include <linux/miscdevice.h>
 
668
+#include <linux/init.h>
 
669
+#include <linux/wait.h>
 
670
+#include <linux/namei.h>
 
671
+#include <linux/fcntl.h>
 
672
+#include <linux/file.h>
 
673
+#include <linux/sched.h>
 
674
+#include <linux/compat.h>
 
675
+#include <linux/syscalls.h>
 
676
+#include <linux/smp_lock.h>
 
677
+#include <linux/magic.h>
 
678
+#include <linux/dcache.h>
 
679
+#include <linux/uaccess.h>
 
680
+
 
681
+#include "autofs_i.h"
 
682
+
 
683
+/*
 
684
+ * This module implements an interface for routing autofs ioctl control
 
685
+ * commands via a miscellaneous device file.
 
686
+ *
 
687
+ * The alternate interface is needed because we need to be able open
 
688
+ * an ioctl file descriptor on an autofs mount that may be covered by
 
689
+ * another mount. This situation arises when starting automount(8)
 
690
+ * or other user space daemon which uses direct mounts or offset
 
691
+ * mounts (used for autofs lazy mount/umount of nested mount trees),
 
692
+ * which have been left busy at at service shutdown.
 
693
+ */
 
694
+
 
695
+#define AUTOFS_DEV_IOCTL_SIZE  sizeof(struct autofs_dev_ioctl)
 
696
+
 
697
+typedef int (*ioctl_fn)(struct file *,
 
698
+struct autofs_sb_info *, struct autofs_dev_ioctl *);
 
699
+
 
700
+static int check_name(const char *name)
 
701
+{
 
702
+       if (!strchr(name, '/'))
 
703
+               return -EINVAL;
 
704
+       return 0;
 
705
+}
 
706
+
 
707
+/*
 
708
+ * Check a string doesn't overrun the chunk of
 
709
+ * memory we copied from user land.
 
710
+ */
 
711
+static int invalid_str(char *str, void *end)
 
712
+{
 
713
+       while ((void *) str <= end)
 
714
+               if (!*str++)
 
715
+                       return 0;
 
716
+       return -EINVAL;
 
717
+}
 
718
+
 
719
+/*
 
720
+ * Check that the user compiled against correct version of autofs
 
721
+ * misc device code.
 
722
+ *
 
723
+ * As well as checking the version compatibility this always copies
 
724
+ * the kernel interface version out.
 
725
+ */
 
726
+static int check_dev_ioctl_version(int cmd, struct autofs_dev_ioctl *param)
 
727
+{
 
728
+       int err = 0;
 
729
+
 
730
+       if ((AUTOFS_DEV_IOCTL_VERSION_MAJOR != param->ver_major) ||
 
731
+           (AUTOFS_DEV_IOCTL_VERSION_MINOR < param->ver_minor)) {
 
732
+               AUTOFS_WARN("ioctl control interface version mismatch: "
 
733
+                    "kernel(%u.%u), user(%u.%u), cmd(%d)",
 
734
+                    AUTOFS_DEV_IOCTL_VERSION_MAJOR,
 
735
+                    AUTOFS_DEV_IOCTL_VERSION_MINOR,
 
736
+                    param->ver_major, param->ver_minor, cmd);
 
737
+               err = -EINVAL;
 
738
+       }
 
739
+
 
740
+       /* Fill in the kernel version. */
 
741
+       param->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;
 
742
+       param->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;
 
743
+
 
744
+       return err;
 
745
+}
 
746
+
 
747
+/*
 
748
+ * Copy parameter control struct, including a possible path allocated
 
749
+ * at the end of the struct.
 
750
+ */
 
751
+static struct autofs_dev_ioctl *copy_dev_ioctl(struct autofs_dev_ioctl __user *in)
 
752
+{
 
753
+       struct autofs_dev_ioctl tmp, *ads;
 
754
+
 
755
+       if (copy_from_user(&tmp, in, sizeof(tmp)))
 
756
+               return ERR_PTR(-EFAULT);
 
757
+
 
758
+       if (tmp.size < sizeof(tmp))
 
759
+               return ERR_PTR(-EINVAL);
 
760
+
 
761
+       ads = kmalloc(tmp.size, GFP_KERNEL);
 
762
+       if (!ads)
 
763
+               return ERR_PTR(-ENOMEM);
 
764
+
 
765
+       if (copy_from_user(ads, in, tmp.size)) {
 
766
+               kfree(ads);
 
767
+               return ERR_PTR(-EFAULT);
 
768
+       }
 
769
+
 
770
+       return ads;
 
771
+}
 
772
+
 
773
+static inline void free_dev_ioctl(struct autofs_dev_ioctl *param)
 
774
+{
 
775
+       kfree(param);
 
776
+       return;
 
777
+}
 
778
+
 
779
+/*
 
780
+ * Check sanity of parameter control fields and if a path is present
 
781
+ * check that it is terminated and contains at least one "/".
 
782
+ */
 
783
+static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
 
784
+{
 
785
+       int err;
 
786
+
 
787
+       if ((err = check_dev_ioctl_version(cmd, param))) {
 
788
+               AUTOFS_WARN("invalid device control module version "
 
789
+                    "supplied for cmd(0x%08x)", cmd);
 
790
+               goto out;
 
791
+       }
 
792
+
 
793
+       if (param->size > sizeof(*param)) {
 
794
+               err = invalid_str(param->path,
 
795
+                                (void *) ((size_t) param + param->size));
 
796
+               if (err) {
 
797
+                       AUTOFS_WARN(
 
798
+                         "path string terminator missing for cmd(0x%08x)",
 
799
+                         cmd);
 
800
+                       goto out;
 
801
+               }
 
802
+
 
803
+               err = check_name(param->path);
 
804
+               if (err) {
 
805
+                       AUTOFS_WARN("invalid path supplied for cmd(0x%08x)",
 
806
+                                   cmd);
 
807
+                       goto out;
 
808
+               }
 
809
+       }
 
810
+
 
811
+       err = 0;
 
812
+out:
 
813
+       return err;
 
814
+}
 
815
+
 
816
+/*
 
817
+ * Get the autofs super block info struct from the file opened on
 
818
+ * the autofs mount point.
 
819
+ */
 
820
+static struct autofs_sb_info *autofs_dev_ioctl_sbi(struct file *f)
 
821
+{
 
822
+       struct autofs_sb_info *sbi = NULL;
 
823
+       struct inode *inode;
 
824
+
 
825
+       if (f) {
 
826
+               inode = f->f_path.dentry->d_inode;
 
827
+               sbi = autofs4_sbi(inode->i_sb);
 
828
+       }
 
829
+       return sbi;
 
830
+}
 
831
+
 
832
+/* Return autofs module protocol version */
 
833
+static int autofs_dev_ioctl_protover(struct file *fp,
 
834
+                                    struct autofs_sb_info *sbi,
 
835
+                                    struct autofs_dev_ioctl *param)
 
836
+{
 
837
+       param->protover.version = sbi->version;
 
838
+       return 0;
 
839
+}
 
840
+
 
841
+/* Return autofs module protocol sub version */
 
842
+static int autofs_dev_ioctl_protosubver(struct file *fp,
 
843
+                                       struct autofs_sb_info *sbi,
 
844
+                                       struct autofs_dev_ioctl *param)
 
845
+{
 
846
+       param->protosubver.sub_version = sbi->sub_version;
 
847
+       return 0;
 
848
+}
 
849
+
 
850
+/*
 
851
+ * Walk down the mount stack looking for an autofs mount that
 
852
+ * has the requested device number (aka. new_encode_dev(sb->s_dev).
 
853
+ */
 
854
+static int autofs_dev_ioctl_find_super(struct nameidata *nd, dev_t devno)
 
855
+{
 
856
+       struct dentry *dentry;
 
857
+       struct inode *inode;
 
858
+       struct super_block *sb;
 
859
+       dev_t s_dev;
 
860
+       unsigned int err;
 
861
+
 
862
+       err = -ENOENT;
 
863
+
 
864
+       /* Lookup the dentry name at the base of our mount point */
 
865
+       dentry = d_lookup(nd->path.dentry, &nd->last);
 
866
+       if (!dentry)
 
867
+               goto out;
 
868
+
 
869
+       dput(nd->path.dentry);
 
870
+       nd->path.dentry = dentry;
 
871
+
 
872
+       /* And follow the mount stack looking for our autofs mount */
 
873
+       while (follow_down(&nd->path.mnt, &nd->path.dentry)) {
 
874
+               inode = nd->path.dentry->d_inode;
 
875
+               if (!inode)
 
876
+                       break;
 
877
+
 
878
+               sb = inode->i_sb;
 
879
+               s_dev = new_encode_dev(sb->s_dev);
 
880
+               if (devno == s_dev) {
 
881
+                       if (sb->s_magic == AUTOFS_SUPER_MAGIC) {
 
882
+                               err = 0;
 
883
+                               break;
 
884
+                       }
 
885
+               }
 
886
+       }
 
887
+out:
 
888
+       return err;
 
889
+}
 
890
+
 
891
+/*
 
892
+ * Walk down the mount stack looking for an autofs mount that
 
893
+ * has the requested mount type (ie. indirect, direct or offset).
 
894
+ */
 
895
+static int autofs_dev_ioctl_find_sbi_type(struct nameidata *nd, unsigned int type)
 
896
+{
 
897
+       struct dentry *dentry;
 
898
+       struct autofs_info *ino;
 
899
+       unsigned int err;
 
900
+
 
901
+       err = -ENOENT;
 
902
+
 
903
+       /* Lookup the dentry name at the base of our mount point */
 
904
+       dentry = d_lookup(nd->path.dentry, &nd->last);
 
905
+       if (!dentry)
 
906
+               goto out;
 
907
+
 
908
+       dput(nd->path.dentry);
 
909
+       nd->path.dentry = dentry;
 
910
+
 
911
+       /* And follow the mount stack looking for our autofs mount */
 
912
+       while (follow_down(&nd->path.mnt, &nd->path.dentry)) {
 
913
+               ino = autofs4_dentry_ino(nd->path.dentry);
 
914
+               if (ino && ino->sbi->type & type) {
 
915
+                       err = 0;
 
916
+                       break;
 
917
+               }
 
918
+       }
 
919
+out:
 
920
+       return err;
 
921
+}
 
922
+
 
923
+static void autofs_dev_ioctl_fd_install(unsigned int fd, struct file *file)
 
924
+{
 
925
+       struct files_struct *files = current->files;
 
926
+       struct fdtable *fdt;
 
927
+
 
928
+       spin_lock(&files->file_lock);
 
929
+       fdt = files_fdtable(files);
 
930
+       BUG_ON(fdt->fd[fd] != NULL);
 
931
+       rcu_assign_pointer(fdt->fd[fd], file);
 
932
+       FD_SET(fd, fdt->close_on_exec);
 
933
+       spin_unlock(&files->file_lock);
 
934
+}
 
935
+
 
936
+
 
937
+/*
 
938
+ * Open a file descriptor on the autofs mount point corresponding
 
939
+ * to the given path and device number (aka. new_encode_dev(sb->s_dev)).
 
940
+ */
 
941
+static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid)
 
942
+{
 
943
+       struct file *filp;
 
944
+       struct nameidata nd;
 
945
+       int err, fd;
 
946
+
 
947
+       fd = get_unused_fd();
 
948
+       if (likely(fd >= 0)) {
 
949
+               /* Get nameidata of the parent directory */
 
950
+               err = path_lookup(path, LOOKUP_PARENT, &nd);
 
951
+               if (err)
 
952
+                       goto out;
 
953
+
 
954
+               /*
 
955
+                * Search down, within the parent, looking for an
 
956
+                * autofs super block that has the device number
 
957
+                * corresponding to the autofs fs we want to open.
 
958
+                */
 
959
+               err = autofs_dev_ioctl_find_super(&nd, devid);
 
960
+               if (err) {
 
961
+                       path_put(&nd.path);
 
962
+                       goto out;
 
963
+               }
 
964
+
 
965
+               filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY);
 
966
+               if (IS_ERR(filp)) {
 
967
+                       err = PTR_ERR(filp);
 
968
+                       goto out;
 
969
+               }
 
970
+
 
971
+               autofs_dev_ioctl_fd_install(fd, filp);
 
972
+       }
 
973
+
 
974
+       return fd;
 
975
+
 
976
+out:
 
977
+       put_unused_fd(fd);
 
978
+       return err;
 
979
+}
 
980
+
 
981
+/* Open a file descriptor on an autofs mount point */
 
982
+static int autofs_dev_ioctl_openmount(struct file *fp,
 
983
+                                     struct autofs_sb_info *sbi,
 
984
+                                     struct autofs_dev_ioctl *param)
 
985
+{
 
986
+       const char *path;
 
987
+       dev_t devid;
 
988
+       int err, fd;
 
989
+
 
990
+       /* param->path has already been checked */
 
991
+       if (!param->openmount.devid)
 
992
+               return -EINVAL;
 
993
+
 
994
+       param->ioctlfd = -1;
 
995
+
 
996
+       path = param->path;
 
997
+       devid = param->openmount.devid;
 
998
+
 
999
+       err = 0;
 
1000
+       fd = autofs_dev_ioctl_open_mountpoint(path, devid);
 
1001
+       if (unlikely(fd < 0)) {
 
1002
+               err = fd;
 
1003
+               goto out;
 
1004
+       }
 
1005
+
 
1006
+       param->ioctlfd = fd;
 
1007
+out:
 
1008
+       return err;
 
1009
+}
 
1010
+
 
1011
+/* Close file descriptor allocated above (user can also use close(2)). */
 
1012
+static int autofs_dev_ioctl_closemount(struct file *fp,
 
1013
+                                      struct autofs_sb_info *sbi,
 
1014
+                                      struct autofs_dev_ioctl *param)
 
1015
+{
 
1016
+       return sys_close(param->ioctlfd);
 
1017
+}
 
1018
+
 
1019
+/*
 
1020
+ * Send "ready" status for an existing wait (either a mount or an expire
 
1021
+ * request).
 
1022
+ */
 
1023
+static int autofs_dev_ioctl_ready(struct file *fp,
 
1024
+                                 struct autofs_sb_info *sbi,
 
1025
+                                 struct autofs_dev_ioctl *param)
 
1026
+{
 
1027
+       autofs_wqt_t token;
 
1028
+
 
1029
+       token = (autofs_wqt_t) param->ready.token;
 
1030
+       return autofs4_wait_release(sbi, token, 0);
 
1031
+}
 
1032
+
 
1033
+/*
 
1034
+ * Send "fail" status for an existing wait (either a mount or an expire
 
1035
+ * request).
 
1036
+ */
 
1037
+static int autofs_dev_ioctl_fail(struct file *fp,
 
1038
+                                struct autofs_sb_info *sbi,
 
1039
+                                struct autofs_dev_ioctl *param)
 
1040
+{
 
1041
+       autofs_wqt_t token;
 
1042
+       int status;
 
1043
+
 
1044
+       token = (autofs_wqt_t) param->fail.token;
 
1045
+       status = param->fail.status ? param->fail.status : -ENOENT;
 
1046
+       return autofs4_wait_release(sbi, token, status);
 
1047
+}
 
1048
+
 
1049
+/*
 
1050
+ * Set the pipe fd for kernel communication to the daemon.
 
1051
+ *
 
1052
+ * Normally this is set at mount using an option but if we
 
1053
+ * are reconnecting to a busy mount then we need to use this
 
1054
+ * to tell the autofs mount about the new kernel pipe fd. In
 
1055
+ * order to protect mounts against incorrectly setting the
 
1056
+ * pipefd we also require that the autofs mount be catatonic.
 
1057
+ *
 
1058
+ * This also sets the process group id used to identify the
 
1059
+ * controlling process (eg. the owning automount(8) daemon).
 
1060
+ */
 
1061
+static int autofs_dev_ioctl_setpipefd(struct file *fp,
 
1062
+                                     struct autofs_sb_info *sbi,
 
1063
+                                     struct autofs_dev_ioctl *param)
 
1064
+{
 
1065
+       int pipefd;
 
1066
+       int err = 0;
 
1067
+
 
1068
+       if (param->setpipefd.pipefd == -1)
 
1069
+               return -EINVAL;
 
1070
+
 
1071
+       pipefd = param->setpipefd.pipefd;
 
1072
+
 
1073
+       mutex_lock(&sbi->wq_mutex);
 
1074
+       if (!sbi->catatonic) {
 
1075
+               mutex_unlock(&sbi->wq_mutex);
 
1076
+               return -EBUSY;
 
1077
+       } else {
 
1078
+               struct file *pipe = fget(pipefd);
 
1079
+               if (!pipe->f_op || !pipe->f_op->write) {
 
1080
+                       err = -EPIPE;
 
1081
+                       fput(pipe);
 
1082
+                       goto out;
 
1083
+               }
 
1084
+               sbi->oz_pgrp = task_pgrp_nr(current);
 
1085
+               sbi->pipefd = pipefd;
 
1086
+               sbi->pipe = pipe;
 
1087
+               sbi->catatonic = 0;
 
1088
+       }
 
1089
+out:
 
1090
+       mutex_unlock(&sbi->wq_mutex);
 
1091
+       return err;
 
1092
+}
 
1093
+
 
1094
+/*
 
1095
+ * Make the autofs mount point catatonic, no longer responsive to
 
1096
+ * mount requests. Also closes the kernel pipe file descriptor.
 
1097
+ */
 
1098
+static int autofs_dev_ioctl_catatonic(struct file *fp,
 
1099
+                                     struct autofs_sb_info *sbi,
 
1100
+                                     struct autofs_dev_ioctl *param)
 
1101
+{
 
1102
+       autofs4_catatonic_mode(sbi);
 
1103
+       return 0;
 
1104
+}
 
1105
+
 
1106
+/* Set the autofs mount timeout */
 
1107
+static int autofs_dev_ioctl_timeout(struct file *fp,
 
1108
+                                   struct autofs_sb_info *sbi,
 
1109
+                                   struct autofs_dev_ioctl *param)
 
1110
+{
 
1111
+       unsigned long timeout;
 
1112
+
 
1113
+       timeout = param->timeout.timeout;
 
1114
+       param->timeout.timeout = sbi->exp_timeout / HZ;
 
1115
+       sbi->exp_timeout = timeout * HZ;
 
1116
+       return 0;
 
1117
+}
 
1118
+
 
1119
+/*
 
1120
+ * Return the uid and gid of the last request for the mount
 
1121
+ *
 
1122
+ * When reconstructing an autofs mount tree with active mounts
 
1123
+ * we need to re-connect to mounts that may have used the original
 
1124
+ * process uid and gid (or string variations of them) for mount
 
1125
+ * lookups within the map entry.
 
1126
+ */
 
1127
+static int autofs_dev_ioctl_requester(struct file *fp,
 
1128
+                                     struct autofs_sb_info *sbi,
 
1129
+                                     struct autofs_dev_ioctl *param)
 
1130
+{
 
1131
+       struct autofs_info *ino;
 
1132
+       struct nameidata nd;
 
1133
+       const char *path;
 
1134
+       dev_t devid;
 
1135
+       int err = -ENOENT;
 
1136
+
 
1137
+       if (param->size <= sizeof(*param)) {
 
1138
+               err = -EINVAL;
 
1139
+               goto out;
 
1140
+       }
 
1141
+
 
1142
+       path = param->path;
 
1143
+       devid = sbi->sb->s_dev;
 
1144
+
 
1145
+       param->requester.uid = param->requester.gid = -1;
 
1146
+
 
1147
+       /* Get nameidata of the parent directory */
 
1148
+       err = path_lookup(path, LOOKUP_PARENT, &nd);
 
1149
+       if (err)
 
1150
+               goto out;
 
1151
+
 
1152
+       err = autofs_dev_ioctl_find_super(&nd, devid);
 
1153
+       if (err)
 
1154
+               goto out_release;
 
1155
+
 
1156
+       ino = autofs4_dentry_ino(nd.path.dentry);
 
1157
+       if (ino) {
 
1158
+               err = 0;
 
1159
+               autofs4_expire_wait(nd.path.dentry);
 
1160
+               spin_lock(&sbi->fs_lock);
 
1161
+               param->requester.uid = ino->uid;
 
1162
+               param->requester.gid = ino->gid;
 
1163
+               spin_unlock(&sbi->fs_lock);
 
1164
+       }
 
1165
+
 
1166
+out_release:
 
1167
+       path_put(&nd.path);
 
1168
+out:
 
1169
+       return err;
 
1170
+}
 
1171
+
 
1172
+/*
 
1173
+ * Call repeatedly until it returns -EAGAIN, meaning there's nothing
 
1174
+ * more that can be done.
 
1175
+ */
 
1176
+static int autofs_dev_ioctl_expire(struct file *fp,
 
1177
+                                  struct autofs_sb_info *sbi,
 
1178
+                                  struct autofs_dev_ioctl *param)
 
1179
+{
 
1180
+       struct vfsmount *mnt;
 
1181
+       int how;
 
1182
+
 
1183
+       how = param->expire.how;
 
1184
+       mnt = fp->f_path.mnt;
 
1185
+
 
1186
+       return autofs4_do_expire_multi(sbi->sb, mnt, sbi, how);
 
1187
+}
 
1188
+
 
1189
+/* Check if autofs mount point is in use */
 
1190
+static int autofs_dev_ioctl_askumount(struct file *fp,
 
1191
+                                     struct autofs_sb_info *sbi,
 
1192
+                                     struct autofs_dev_ioctl *param)
 
1193
+{
 
1194
+       param->askumount.may_umount = 0;
 
1195
+       if (may_umount(fp->f_path.mnt))
 
1196
+               param->askumount.may_umount = 1;
 
1197
+       return 0;
 
1198
+}
 
1199
+
 
1200
+/*
 
1201
+ * Check if the given path is a mountpoint.
 
1202
+ *
 
1203
+ * If we are supplied with the file descriptor of an autofs
 
1204
+ * mount we're looking for a specific mount. In this case
 
1205
+ * the path is considered a mountpoint if it is itself a
 
1206
+ * mountpoint or contains a mount, such as a multi-mount
 
1207
+ * without a root mount. In this case we return 1 if the
 
1208
+ * path is a mount point and the super magic of the covering
 
1209
+ * mount if there is one or 0 if it isn't a mountpoint.
 
1210
+ *
 
1211
+ * If we aren't supplied with a file descriptor then we
 
1212
+ * lookup the nameidata of the path and check if it is the
 
1213
+ * root of a mount. If a type is given we are looking for
 
1214
+ * a particular autofs mount and if we don't find a match
 
1215
+ * we return fail. If the located nameidata path is the
 
1216
+ * root of a mount we return 1 along with the super magic
 
1217
+ * of the mount or 0 otherwise.
 
1218
+ *
 
1219
+ * In both cases the the device number (as returned by
 
1220
+ * new_encode_dev()) is also returned.
 
1221
+ */
 
1222
+static int autofs_dev_ioctl_ismountpoint(struct file *fp,
 
1223
+                                        struct autofs_sb_info *sbi,
 
1224
+                                        struct autofs_dev_ioctl *param)
 
1225
+{
 
1226
+       struct nameidata nd;
 
1227
+       const char *path;
 
1228
+       unsigned int type;
 
1229
+       unsigned int devid, magic;
 
1230
+       int err = -ENOENT;
 
1231
+
 
1232
+       if (param->size <= sizeof(*param)) {
 
1233
+               err = -EINVAL;
 
1234
+               goto out;
 
1235
+       }
 
1236
+
 
1237
+       path = param->path;
 
1238
+       type = param->ismountpoint.in.type;
 
1239
+
 
1240
+       param->ismountpoint.out.devid = devid = 0;
 
1241
+       param->ismountpoint.out.magic = magic = 0;
 
1242
+
 
1243
+       if (!fp || param->ioctlfd == -1) {
 
1244
+               if (autofs_type_any(type)) {
 
1245
+                       struct super_block *sb;
 
1246
+
 
1247
+                       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
 
1248
+                       if (err)
 
1249
+                               goto out;
 
1250
+
 
1251
+                       sb = nd.path.dentry->d_sb;
 
1252
+                       devid = new_encode_dev(sb->s_dev);
 
1253
+               } else {
 
1254
+                       struct autofs_info *ino;
 
1255
+
 
1256
+                       err = path_lookup(path, LOOKUP_PARENT, &nd);
 
1257
+                       if (err)
 
1258
+                               goto out;
 
1259
+
 
1260
+                       err = autofs_dev_ioctl_find_sbi_type(&nd, type);
 
1261
+                       if (err)
 
1262
+                               goto out_release;
 
1263
+
 
1264
+                       ino = autofs4_dentry_ino(nd.path.dentry);
 
1265
+                       devid = autofs4_get_dev(ino->sbi);
 
1266
+               }
 
1267
+
 
1268
+               err = 0;
 
1269
+               if (nd.path.dentry->d_inode &&
 
1270
+                   nd.path.mnt->mnt_root == nd.path.dentry) {
 
1271
+                       err = 1;
 
1272
+                       magic = nd.path.dentry->d_inode->i_sb->s_magic;
 
1273
+               }
 
1274
+       } else {
 
1275
+               dev_t dev = autofs4_get_dev(sbi);
 
1276
+
 
1277
+               err = path_lookup(path, LOOKUP_PARENT, &nd);
 
1278
+               if (err)
 
1279
+                       goto out;
 
1280
+
 
1281
+               err = autofs_dev_ioctl_find_super(&nd, dev);
 
1282
+               if (err)
 
1283
+                       goto out_release;
 
1284
+
 
1285
+               devid = dev;
 
1286
+
 
1287
+               err = have_submounts(nd.path.dentry);
 
1288
+
 
1289
+               if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) {
 
1290
+                       if (follow_down(&nd.path.mnt, &nd.path.dentry)) {
 
1291
+                               struct inode *inode = nd.path.dentry->d_inode;
 
1292
+                               magic = inode->i_sb->s_magic;
 
1293
+                       }
 
1294
+               }
 
1295
+       }
 
1296
+
 
1297
+       param->ismountpoint.out.devid = devid;
 
1298
+       param->ismountpoint.out.magic = magic;
 
1299
+
 
1300
+out_release:
 
1301
+       path_put(&nd.path);
 
1302
+out:
 
1303
+       return err;
 
1304
+}
 
1305
+
 
1306
+/*
 
1307
+ * Our range of ioctl numbers isn't 0 based so we need to shift
 
1308
+ * the array index by _IOC_NR(AUTOFS_CTL_IOC_FIRST) for the table
 
1309
+ * lookup.
 
1310
+ */
 
1311
+#define cmd_idx(cmd)   (cmd - _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST))
 
1312
+
 
1313
+static ioctl_fn lookup_dev_ioctl(unsigned int cmd)
 
1314
+{
 
1315
+       static struct {
 
1316
+               int cmd;
 
1317
+               ioctl_fn fn;
 
1318
+       } _ioctls[] = {
 
1319
+               {cmd_idx(AUTOFS_DEV_IOCTL_VERSION_CMD), NULL},
 
1320
+               {cmd_idx(AUTOFS_DEV_IOCTL_PROTOVER_CMD),
 
1321
+                        autofs_dev_ioctl_protover},
 
1322
+               {cmd_idx(AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD),
 
1323
+                        autofs_dev_ioctl_protosubver},
 
1324
+               {cmd_idx(AUTOFS_DEV_IOCTL_OPENMOUNT_CMD),
 
1325
+                        autofs_dev_ioctl_openmount},
 
1326
+               {cmd_idx(AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD),
 
1327
+                        autofs_dev_ioctl_closemount},
 
1328
+               {cmd_idx(AUTOFS_DEV_IOCTL_READY_CMD),
 
1329
+                        autofs_dev_ioctl_ready},
 
1330
+               {cmd_idx(AUTOFS_DEV_IOCTL_FAIL_CMD),
 
1331
+                        autofs_dev_ioctl_fail},
 
1332
+               {cmd_idx(AUTOFS_DEV_IOCTL_SETPIPEFD_CMD),
 
1333
+                        autofs_dev_ioctl_setpipefd},
 
1334
+               {cmd_idx(AUTOFS_DEV_IOCTL_CATATONIC_CMD),
 
1335
+                        autofs_dev_ioctl_catatonic},
 
1336
+               {cmd_idx(AUTOFS_DEV_IOCTL_TIMEOUT_CMD),
 
1337
+                        autofs_dev_ioctl_timeout},
 
1338
+               {cmd_idx(AUTOFS_DEV_IOCTL_REQUESTER_CMD),
 
1339
+                        autofs_dev_ioctl_requester},
 
1340
+               {cmd_idx(AUTOFS_DEV_IOCTL_EXPIRE_CMD),
 
1341
+                        autofs_dev_ioctl_expire},
 
1342
+               {cmd_idx(AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD),
 
1343
+                        autofs_dev_ioctl_askumount},
 
1344
+               {cmd_idx(AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD),
 
1345
+                        autofs_dev_ioctl_ismountpoint}
 
1346
+       };
 
1347
+       unsigned int idx = cmd_idx(cmd);
 
1348
+
 
1349
+       return (idx >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[idx].fn;
 
1350
+}
 
1351
+
 
1352
+/* ioctl dispatcher */
 
1353
+static int _autofs_dev_ioctl(unsigned int command, struct autofs_dev_ioctl __user *user)
 
1354
+{
 
1355
+       struct autofs_dev_ioctl *param;
 
1356
+       struct file *fp;
 
1357
+       struct autofs_sb_info *sbi;
 
1358
+       unsigned int cmd_first, cmd;
 
1359
+       ioctl_fn fn = NULL;
 
1360
+       int err = 0;
 
1361
+
 
1362
+       /* only root can play with this */
 
1363
+       if (!capable(CAP_SYS_ADMIN))
 
1364
+               return -EPERM;
 
1365
+
 
1366
+       cmd_first = _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST);
 
1367
+       cmd = _IOC_NR(command);
 
1368
+
 
1369
+       if (_IOC_TYPE(command) != _IOC_TYPE(AUTOFS_DEV_IOCTL_IOC_FIRST) ||
 
1370
+           cmd - cmd_first >= AUTOFS_DEV_IOCTL_IOC_COUNT) {
 
1371
+               return -ENOTTY;
 
1372
+       }
 
1373
+
 
1374
+       /* Copy the parameters into kernel space. */
 
1375
+       param = copy_dev_ioctl(user);
 
1376
+       if (IS_ERR(param))
 
1377
+               return PTR_ERR(param);
 
1378
+
 
1379
+       err = validate_dev_ioctl(command, param);
 
1380
+       if (err)
 
1381
+               goto out;
 
1382
+
 
1383
+       /* The validate routine above always sets the version */
 
1384
+       if (cmd == AUTOFS_DEV_IOCTL_VERSION_CMD)
 
1385
+               goto done;
 
1386
+
 
1387
+       fn = lookup_dev_ioctl(cmd);
 
1388
+       if (!fn) {
 
1389
+               AUTOFS_WARN("unknown command 0x%08x", command);
 
1390
+               return -ENOTTY;
 
1391
+       }
 
1392
+
 
1393
+       fp = NULL;
 
1394
+       sbi = NULL;
 
1395
+
 
1396
+       /*
 
1397
+        * For obvious reasons the openmount can't have a file
 
1398
+        * descriptor yet. We don't take a reference to the
 
1399
+        * file during close to allow for immediate release.
 
1400
+        */
 
1401
+       if (cmd != AUTOFS_DEV_IOCTL_OPENMOUNT_CMD &&
 
1402
+           cmd != AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD) {
 
1403
+               fp = fget(param->ioctlfd);
 
1404
+               if (!fp) {
 
1405
+                       if (cmd == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD)
 
1406
+                               goto cont;
 
1407
+                       err = -EBADF;
 
1408
+                       goto out;
 
1409
+               }
 
1410
+
 
1411
+               if (!fp->f_op) {
 
1412
+                       err = -ENOTTY;
 
1413
+                       fput(fp);
 
1414
+                       goto out;
 
1415
+               }
 
1416
+
 
1417
+               sbi = autofs_dev_ioctl_sbi(fp);
 
1418
+               if (!sbi || sbi->magic != AUTOFS_SBI_MAGIC) {
 
1419
+                       err = -EINVAL;
 
1420
+                       fput(fp);
 
1421
+                       goto out;
 
1422
+               }
 
1423
+
 
1424
+               /*
 
1425
+                * Admin needs to be able to set the mount catatonic in
 
1426
+                * order to be able to perform the re-open.
 
1427
+                */
 
1428
+               if (!autofs4_oz_mode(sbi) &&
 
1429
+                   cmd != AUTOFS_DEV_IOCTL_CATATONIC_CMD) {
 
1430
+                       err = -EACCES;
 
1431
+                       fput(fp);
 
1432
+                       goto out;
 
1433
+               }
 
1434
+       }
 
1435
+cont:
 
1436
+       err = fn(fp, sbi, param);
 
1437
+
 
1438
+       if (fp)
 
1439
+               fput(fp);
 
1440
+done:
 
1441
+       if (err >= 0 && copy_to_user(user, param, AUTOFS_DEV_IOCTL_SIZE))
 
1442
+               err = -EFAULT;
 
1443
+out:
 
1444
+       free_dev_ioctl(param);
 
1445
+       return err;
 
1446
+}
 
1447
+
 
1448
+static long autofs_dev_ioctl(struct file *file, uint command, ulong u)
 
1449
+{
 
1450
+       int err;
 
1451
+       err = _autofs_dev_ioctl(command, (struct autofs_dev_ioctl __user *) u);
 
1452
+       return (long) err;
 
1453
+}
 
1454
+
 
1455
+#ifdef CONFIG_COMPAT
 
1456
+static long autofs_dev_ioctl_compat(struct file *file, uint command, ulong u)
 
1457
+{
 
1458
+       return (long) autofs_dev_ioctl(file, command, (ulong) compat_ptr(u));
 
1459
+}
 
1460
+#else
 
1461
+#define autofs_dev_ioctl_compat NULL
 
1462
+#endif
 
1463
+
 
1464
+static const struct file_operations _dev_ioctl_fops = {
 
1465
+       .unlocked_ioctl  = autofs_dev_ioctl,
 
1466
+       .compat_ioctl = autofs_dev_ioctl_compat,
 
1467
+       .owner   = THIS_MODULE,
 
1468
+};
 
1469
+
 
1470
+static struct miscdevice _autofs_dev_ioctl_misc = {
 
1471
+       .minor          = MISC_DYNAMIC_MINOR,
 
1472
+       .name           = AUTOFS_DEVICE_NAME,
 
1473
+       .fops           = &_dev_ioctl_fops
 
1474
+};
 
1475
+
 
1476
+/* Register/deregister misc character device */
 
1477
+int autofs_dev_ioctl_init(void)
 
1478
+{
 
1479
+       int r;
 
1480
+
 
1481
+       r = misc_register(&_autofs_dev_ioctl_misc);
 
1482
+       if (r) {
 
1483
+               AUTOFS_ERROR("misc_register failed for control device");
 
1484
+               return r;
 
1485
+       }
 
1486
+
 
1487
+       return 0;
 
1488
+}
 
1489
+
 
1490
+void autofs_dev_ioctl_exit(void)
 
1491
+{
 
1492
+       misc_deregister(&_autofs_dev_ioctl_misc);
 
1493
+       return;
 
1494
+}
 
1495
+
 
1496
Index: linux-2.6.26/fs/autofs4/expire.c
 
1497
===================================================================
 
1498
--- linux-2.6.26.orig/fs/autofs4/expire.c
 
1499
+++ linux-2.6.26/fs/autofs4/expire.c
 
1500
@@ -63,7 +63,7 @@ static int autofs4_mount_busy(struct vfs
 
1501
                struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
 
1502
 
 
1503
                /* This is an autofs submount, we can't expire it */
 
1504
-               if (sbi->type == AUTOFS_TYPE_INDIRECT)
 
1505
+               if (autofs_type_indirect(sbi->type))
 
1506
                        goto done;
 
1507
 
 
1508
                /*
 
1509
@@ -255,10 +255,10 @@ cont:
 
1510
 }
 
1511
 
 
1512
 /* Check if we can expire a direct mount (possibly a tree) */
 
1513
-static struct dentry *autofs4_expire_direct(struct super_block *sb,
 
1514
-                                           struct vfsmount *mnt,
 
1515
-                                           struct autofs_sb_info *sbi,
 
1516
-                                           int how)
 
1517
+struct dentry *autofs4_expire_direct(struct super_block *sb,
 
1518
+                                    struct vfsmount *mnt,
 
1519
+                                    struct autofs_sb_info *sbi,
 
1520
+                                    int how)
 
1521
 {
 
1522
        unsigned long timeout;
 
1523
        struct dentry *root = dget(sb->s_root);
 
1524
@@ -294,10 +294,10 @@ static struct dentry *autofs4_expire_dir
 
1525
  *  - it is unused by any user process
 
1526
  *  - it has been unused for exp_timeout time
 
1527
  */
 
1528
-static struct dentry *autofs4_expire_indirect(struct super_block *sb,
 
1529
-                                             struct vfsmount *mnt,
 
1530
-                                             struct autofs_sb_info *sbi,
 
1531
-                                             int how)
 
1532
+struct dentry *autofs4_expire_indirect(struct super_block *sb,
 
1533
+                                      struct vfsmount *mnt,
 
1534
+                                      struct autofs_sb_info *sbi,
 
1535
+                                      int how)
 
1536
 {
 
1537
        unsigned long timeout;
 
1538
        struct dentry *root = sb->s_root;
 
1539
@@ -478,22 +478,16 @@ int autofs4_expire_run(struct super_bloc
 
1540
        return ret;
 
1541
 }
 
1542
 
 
1543
-/* Call repeatedly until it returns -EAGAIN, meaning there's nothing
 
1544
-   more to be done */
 
1545
-int autofs4_expire_multi(struct super_block *sb, struct vfsmount *mnt,
 
1546
-                       struct autofs_sb_info *sbi, int __user *arg)
 
1547
+int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
 
1548
+                           struct autofs_sb_info *sbi, int when)
 
1549
 {
 
1550
        struct dentry *dentry;
 
1551
        int ret = -EAGAIN;
 
1552
-       int do_now = 0;
 
1553
 
 
1554
-       if (arg && get_user(do_now, arg))
 
1555
-               return -EFAULT;
 
1556
-
 
1557
-       if (sbi->type & AUTOFS_TYPE_TRIGGER)
 
1558
-               dentry = autofs4_expire_direct(sb, mnt, sbi, do_now);
 
1559
+       if (autofs_type_trigger(sbi->type))
 
1560
+               dentry = autofs4_expire_direct(sb, mnt, sbi, when);
 
1561
        else
 
1562
-               dentry = autofs4_expire_indirect(sb, mnt, sbi, do_now);
 
1563
+               dentry = autofs4_expire_indirect(sb, mnt, sbi, when);
 
1564
 
 
1565
        if (dentry) {
 
1566
                struct autofs_info *ino = autofs4_dentry_ino(dentry);
 
1567
@@ -516,3 +510,16 @@ int autofs4_expire_multi(struct super_bl
 
1568
        return ret;
 
1569
 }
 
1570
 
 
1571
+/* Call repeatedly until it returns -EAGAIN, meaning there's nothing
 
1572
+   more to be done */
 
1573
+int autofs4_expire_multi(struct super_block *sb, struct vfsmount *mnt,
 
1574
+                       struct autofs_sb_info *sbi, int __user *arg)
 
1575
+{
 
1576
+       int do_now = 0;
 
1577
+
 
1578
+       if (arg && get_user(do_now, arg))
 
1579
+               return -EFAULT;
 
1580
+
 
1581
+       return autofs4_do_expire_multi(sb, mnt, sbi, do_now);
 
1582
+}
 
1583
+
 
1584
Index: linux-2.6.26/fs/autofs4/init.c
 
1585
===================================================================
 
1586
--- linux-2.6.26.orig/fs/autofs4/init.c
 
1587
+++ linux-2.6.26/fs/autofs4/init.c
 
1588
@@ -29,11 +29,20 @@ static struct file_system_type autofs_fs
 
1589
 
 
1590
 static int __init init_autofs4_fs(void)
 
1591
 {
 
1592
-       return register_filesystem(&autofs_fs_type);
 
1593
+       int err;
 
1594
+
 
1595
+       err = register_filesystem(&autofs_fs_type);
 
1596
+       if (err)
 
1597
+               return err;
 
1598
+
 
1599
+       autofs_dev_ioctl_init();
 
1600
+
 
1601
+       return err;
 
1602
 }
 
1603
 
 
1604
 static void __exit exit_autofs4_fs(void)
 
1605
 {
 
1606
+       autofs_dev_ioctl_exit();
 
1607
        unregister_filesystem(&autofs_fs_type);
 
1608
 }
 
1609
 
 
1610
Index: linux-2.6.26/include/linux/auto_dev-ioctl.h
 
1611
===================================================================
 
1612
--- /dev/null
 
1613
+++ linux-2.6.26/include/linux/auto_dev-ioctl.h
 
1614
@@ -0,0 +1,224 @@
 
1615
+/*
 
1616
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
 
1617
+ * Copyright 2008 Ian Kent <raven@themaw.net>
 
1618
+ *
 
1619
+ * This file is part of the Linux kernel and is made available under
 
1620
+ * the terms of the GNU General Public License, version 2, or at your
 
1621
+ * option, any later version, incorporated herein by reference.
 
1622
+ */
 
1623
+
 
1624
+#ifndef _LINUX_AUTO_DEV_IOCTL_H
 
1625
+#define _LINUX_AUTO_DEV_IOCTL_H
 
1626
+
 
1627
+#include <linux/string.h>
 
1628
+#include <linux/types.h>
 
1629
+
 
1630
+#define AUTOFS_DEVICE_NAME             "autofs"
 
1631
+
 
1632
+#define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1
 
1633
+#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0
 
1634
+
 
1635
+#define AUTOFS_DEVID_LEN               16
 
1636
+
 
1637
+#define AUTOFS_DEV_IOCTL_SIZE          sizeof(struct autofs_dev_ioctl)
 
1638
+
 
1639
+/*
 
1640
+ * An ioctl interface for autofs mount point control.
 
1641
+ */
 
1642
+
 
1643
+struct args_protover {
 
1644
+       __u32   version;
 
1645
+};
 
1646
+
 
1647
+struct args_protosubver {
 
1648
+       __u32   sub_version;
 
1649
+};
 
1650
+
 
1651
+struct args_openmount {
 
1652
+       __u32   devid;
 
1653
+};
 
1654
+
 
1655
+struct args_ready {
 
1656
+       __u32   token;
 
1657
+};
 
1658
+
 
1659
+struct args_fail {
 
1660
+       __u32   token;
 
1661
+       __s32   status;
 
1662
+};
 
1663
+
 
1664
+struct args_setpipefd {
 
1665
+       __s32   pipefd;
 
1666
+};
 
1667
+
 
1668
+struct args_timeout {
 
1669
+       __u64   timeout;
 
1670
+};
 
1671
+
 
1672
+struct args_requester {
 
1673
+       __u32   uid;
 
1674
+       __u32   gid;
 
1675
+};
 
1676
+
 
1677
+struct args_expire {
 
1678
+       __u32   how;
 
1679
+};
 
1680
+
 
1681
+struct args_askumount {
 
1682
+       __u32   may_umount;
 
1683
+};
 
1684
+
 
1685
+struct args_ismountpoint {
 
1686
+       union {
 
1687
+               struct args_in {
 
1688
+                       __u32   type;
 
1689
+               } in;
 
1690
+               struct args_out {
 
1691
+                       __u32   devid;
 
1692
+                       __u32   magic;
 
1693
+               } out;
 
1694
+       };
 
1695
+};
 
1696
+
 
1697
+/*
 
1698
+ * All the ioctls use this structure.
 
1699
+ * When sending a path size must account for the total length
 
1700
+ * of the chunk of memory otherwise is is the size of the
 
1701
+ * structure.
 
1702
+ */
 
1703
+
 
1704
+struct autofs_dev_ioctl {
 
1705
+       __u32 ver_major;
 
1706
+       __u32 ver_minor;
 
1707
+       __u32 size;             /* total size of data passed in
 
1708
+                                * including this struct */
 
1709
+       __s32 ioctlfd;          /* automount command fd */
 
1710
+
 
1711
+       /* Command parameters */
 
1712
+
 
1713
+       union {
 
1714
+               struct args_protover            protover;
 
1715
+               struct args_protosubver         protosubver;
 
1716
+               struct args_openmount           openmount;
 
1717
+               struct args_ready               ready;
 
1718
+               struct args_fail                fail;
 
1719
+               struct args_setpipefd           setpipefd;
 
1720
+               struct args_timeout             timeout;
 
1721
+               struct args_requester           requester;
 
1722
+               struct args_expire              expire;
 
1723
+               struct args_askumount           askumount;
 
1724
+               struct args_ismountpoint        ismountpoint;
 
1725
+       };
 
1726
+
 
1727
+       char path[0];
 
1728
+};
 
1729
+
 
1730
+static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in)
 
1731
+{
 
1732
+       memset(in, 0, sizeof(struct autofs_dev_ioctl));
 
1733
+       in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;
 
1734
+       in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;
 
1735
+       in->size = sizeof(struct autofs_dev_ioctl);
 
1736
+       in->ioctlfd = -1;
 
1737
+       return;
 
1738
+}
 
1739
+
 
1740
+/*
 
1741
+ * If you change this make sure you make the corresponding change
 
1742
+ * to autofs-dev-ioctl.c:lookup_ioctl()
 
1743
+ */
 
1744
+enum {
 
1745
+       /* Get various version info */
 
1746
+       AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71,
 
1747
+       AUTOFS_DEV_IOCTL_PROTOVER_CMD,
 
1748
+       AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD,
 
1749
+
 
1750
+       /* Open mount ioctl fd */
 
1751
+       AUTOFS_DEV_IOCTL_OPENMOUNT_CMD,
 
1752
+
 
1753
+       /* Close mount ioctl fd */
 
1754
+       AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD,
 
1755
+
 
1756
+       /* Mount/expire status returns */
 
1757
+       AUTOFS_DEV_IOCTL_READY_CMD,
 
1758
+       AUTOFS_DEV_IOCTL_FAIL_CMD,
 
1759
+
 
1760
+       /* Activate/deactivate autofs mount */
 
1761
+       AUTOFS_DEV_IOCTL_SETPIPEFD_CMD,
 
1762
+       AUTOFS_DEV_IOCTL_CATATONIC_CMD,
 
1763
+
 
1764
+       /* Expiry timeout */
 
1765
+       AUTOFS_DEV_IOCTL_TIMEOUT_CMD,
 
1766
+
 
1767
+       /* Get mount last requesting uid and gid */
 
1768
+       AUTOFS_DEV_IOCTL_REQUESTER_CMD,
 
1769
+
 
1770
+       /* Check for eligible expire candidates */
 
1771
+       AUTOFS_DEV_IOCTL_EXPIRE_CMD,
 
1772
+
 
1773
+       /* Request busy status */
 
1774
+       AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD,
 
1775
+
 
1776
+       /* Check if path is a mountpoint */
 
1777
+       AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD,
 
1778
+};
 
1779
+
 
1780
+#define AUTOFS_IOCTL 0x93
 
1781
+
 
1782
+#define AUTOFS_DEV_IOCTL_VERSION \
 
1783
+       _IOWR(AUTOFS_IOCTL, \
 
1784
+             AUTOFS_DEV_IOCTL_VERSION_CMD, struct autofs_dev_ioctl)
 
1785
+
 
1786
+#define AUTOFS_DEV_IOCTL_PROTOVER \
 
1787
+       _IOWR(AUTOFS_IOCTL, \
 
1788
+             AUTOFS_DEV_IOCTL_PROTOVER_CMD, struct autofs_dev_ioctl)
 
1789
+
 
1790
+#define AUTOFS_DEV_IOCTL_PROTOSUBVER \
 
1791
+       _IOWR(AUTOFS_IOCTL, \
 
1792
+             AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, struct autofs_dev_ioctl)
 
1793
+
 
1794
+#define AUTOFS_DEV_IOCTL_OPENMOUNT \
 
1795
+       _IOWR(AUTOFS_IOCTL, \
 
1796
+             AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, struct autofs_dev_ioctl)
 
1797
+
 
1798
+#define AUTOFS_DEV_IOCTL_CLOSEMOUNT \
 
1799
+       _IOWR(AUTOFS_IOCTL, \
 
1800
+             AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, struct autofs_dev_ioctl)
 
1801
+
 
1802
+#define AUTOFS_DEV_IOCTL_READY \
 
1803
+       _IOWR(AUTOFS_IOCTL, \
 
1804
+             AUTOFS_DEV_IOCTL_READY_CMD, struct autofs_dev_ioctl)
 
1805
+
 
1806
+#define AUTOFS_DEV_IOCTL_FAIL \
 
1807
+       _IOWR(AUTOFS_IOCTL, \
 
1808
+             AUTOFS_DEV_IOCTL_FAIL_CMD, struct autofs_dev_ioctl)
 
1809
+
 
1810
+#define AUTOFS_DEV_IOCTL_SETPIPEFD \
 
1811
+       _IOWR(AUTOFS_IOCTL, \
 
1812
+             AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, struct autofs_dev_ioctl)
 
1813
+
 
1814
+#define AUTOFS_DEV_IOCTL_CATATONIC \
 
1815
+       _IOWR(AUTOFS_IOCTL, \
 
1816
+             AUTOFS_DEV_IOCTL_CATATONIC_CMD, struct autofs_dev_ioctl)
 
1817
+
 
1818
+#define AUTOFS_DEV_IOCTL_TIMEOUT \
 
1819
+       _IOWR(AUTOFS_IOCTL, \
 
1820
+             AUTOFS_DEV_IOCTL_TIMEOUT_CMD, struct autofs_dev_ioctl)
 
1821
+
 
1822
+#define AUTOFS_DEV_IOCTL_REQUESTER \
 
1823
+       _IOWR(AUTOFS_IOCTL, \
 
1824
+             AUTOFS_DEV_IOCTL_REQUESTER_CMD, struct autofs_dev_ioctl)
 
1825
+
 
1826
+#define AUTOFS_DEV_IOCTL_EXPIRE \
 
1827
+       _IOWR(AUTOFS_IOCTL, \
 
1828
+             AUTOFS_DEV_IOCTL_EXPIRE_CMD, struct autofs_dev_ioctl)
 
1829
+
 
1830
+#define AUTOFS_DEV_IOCTL_ASKUMOUNT \
 
1831
+       _IOWR(AUTOFS_IOCTL, \
 
1832
+             AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, struct autofs_dev_ioctl)
 
1833
+
 
1834
+#define AUTOFS_DEV_IOCTL_ISMOUNTPOINT \
 
1835
+       _IOWR(AUTOFS_IOCTL, \
 
1836
+             AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl)
 
1837
+
 
1838
+#endif /* _LINUX_AUTO_DEV_IOCTL_H */
 
1839
Index: linux-2.6.26/include/linux/auto_fs4.h
 
1840
===================================================================
 
1841
--- linux-2.6.26.orig/include/linux/auto_fs4.h
 
1842
+++ linux-2.6.26/include/linux/auto_fs4.h
 
1843
@@ -23,16 +23,70 @@
 
1844
 #define AUTOFS_MIN_PROTO_VERSION       3
 
1845
 #define AUTOFS_MAX_PROTO_VERSION       5
 
1846
 
 
1847
-#define AUTOFS_PROTO_SUBVERSION                0
 
1848
+#define AUTOFS_PROTO_SUBVERSION                1
 
1849
 
 
1850
 /* Mask for expire behaviour */
 
1851
 #define AUTOFS_EXP_IMMEDIATE           1
 
1852
 #define AUTOFS_EXP_LEAVES              2
 
1853
 
 
1854
-#define AUTOFS_TYPE_ANY                        0x0000
 
1855
-#define AUTOFS_TYPE_INDIRECT           0x0001
 
1856
-#define AUTOFS_TYPE_DIRECT             0x0002
 
1857
-#define AUTOFS_TYPE_OFFSET             0x0004
 
1858
+#define AUTOFS_TYPE_ANY                        0U
 
1859
+#define AUTOFS_TYPE_INDIRECT           1U
 
1860
+#define AUTOFS_TYPE_DIRECT             2U
 
1861
+#define AUTOFS_TYPE_OFFSET             4U
 
1862
+
 
1863
+static inline void set_autofs_type_indirect(unsigned int *type)
 
1864
+{
 
1865
+       *type = AUTOFS_TYPE_INDIRECT;
 
1866
+       return;
 
1867
+}
 
1868
+
 
1869
+static inline unsigned int autofs_type_indirect(unsigned int type)
 
1870
+{
 
1871
+       return (type == AUTOFS_TYPE_INDIRECT);
 
1872
+}
 
1873
+
 
1874
+static inline void set_autofs_type_direct(unsigned int *type)
 
1875
+{
 
1876
+       *type = AUTOFS_TYPE_DIRECT;
 
1877
+       return;
 
1878
+}
 
1879
+
 
1880
+static inline unsigned int autofs_type_direct(unsigned int type)
 
1881
+{
 
1882
+       return (type == AUTOFS_TYPE_DIRECT);
 
1883
+}
 
1884
+
 
1885
+static inline void set_autofs_type_offset(unsigned int *type)
 
1886
+{
 
1887
+       *type = AUTOFS_TYPE_OFFSET;
 
1888
+       return;
 
1889
+}
 
1890
+
 
1891
+static inline unsigned int autofs_type_offset(unsigned int type)
 
1892
+{
 
1893
+       return (type == AUTOFS_TYPE_OFFSET);
 
1894
+}
 
1895
+
 
1896
+static inline unsigned int autofs_type_trigger(unsigned int type)
 
1897
+{
 
1898
+       return (type == AUTOFS_TYPE_DIRECT || type == AUTOFS_TYPE_OFFSET);
 
1899
+}
 
1900
+
 
1901
+/*
 
1902
+ * This isn't really a type as we use it to say "no type set" to
 
1903
+ * indicate we want to search for "any" mount in the
 
1904
+ * autofs_dev_ioctl_ismountpoint() device ioctl function.
 
1905
+ */
 
1906
+static inline void set_autofs_type_any(unsigned int *type)
 
1907
+{
 
1908
+       *type = AUTOFS_TYPE_ANY;
 
1909
+       return;
 
1910
+}
 
1911
+
 
1912
+static inline unsigned int autofs_type_any(unsigned int type)
 
1913
+{
 
1914
+       return (type == AUTOFS_TYPE_ANY);
 
1915
+}
 
1916
 
 
1917
 /* Daemon notification packet types */
 
1918
 enum autofs_notify {