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
6
/* Internal header file for autofs */
8
#include <linux/auto_fs4.h>
9
+#include <linux/auto_dev-ioctl.h>
10
#include <linux/mutex.h>
11
#include <linux/list.h>
14
#define AUTOFS_IOC_FIRST AUTOFS_IOC_READY
15
#define AUTOFS_IOC_COUNT 32
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)
21
#include <linux/kernel.h>
22
#include <linux/slab.h>
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...) \
30
+ printk(KERN_DEBUG "pid %d: %s: " fmt "\n", \
31
+ current->pid, __func__, ##args); \
34
-#define DPRINTK(fmt,args...) do {} while(0)
35
+#define DPRINTK(fmt, args...) do {} while (0)
38
+#define AUTOFS_WARN(fmt, args...) \
40
+ printk(KERN_WARNING "pid %d: %s: " fmt "\n", \
41
+ current->pid, __func__, ##args); \
44
+#define AUTOFS_ERROR(fmt, args...) \
46
+ printk(KERN_ERR "pid %d: %s: " fmt "\n", \
47
+ current->pid, __func__, ##args); \
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;
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);
78
+/* Device node initialization */
80
+int autofs_dev_ioctl_init(void);
81
+void autofs_dev_ioctl_exit(void);
83
/* Operations structures */
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);
96
ino->last_used = jiffies;
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);
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");
109
seq_printf(m, ",indirect");
110
@@ -282,13 +284,13 @@ static int parse_options(char *options,
114
- *type = AUTOFS_TYPE_INDIRECT;
115
+ set_autofs_type_indirect(type);
118
- *type = AUTOFS_TYPE_DIRECT;
119
+ set_autofs_type_direct(type);
122
- *type = AUTOFS_TYPE_OFFSET;
123
+ set_autofs_type_offset(type);
127
@@ -336,7 +338,7 @@ int autofs4_fill_super(struct super_bloc
130
sbi->sub_version = 0;
131
- sbi->type = AUTOFS_TYPE_INDIRECT;
132
+ set_autofs_type_indirect(&sbi->type);
135
mutex_init(&sbi->wq_mutex);
136
@@ -378,7 +380,7 @@ int autofs4_fill_super(struct super_bloc
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;
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.
153
- if (sbi->type & AUTOFS_TYPE_TRIGGER)
154
+ if (autofs_type_trigger(sbi->type))
156
else if (!IS_ROOT(dentry->d_parent))
158
@@ -348,7 +348,7 @@ int autofs4_wait(struct autofs_sb_info *
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);
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;
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;
176
- type = (sbi->type & AUTOFS_TYPE_TRIGGER) ?
177
+ type = autofs_type_trigger(sbi->type) ?
178
autofs_ptype_expire_direct :
179
autofs_ptype_expire_indirect;
181
@@ -457,6 +457,40 @@ int autofs4_wait(struct autofs_sb_info *
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.
195
+ struct autofs_info *ino;
196
+ struct dentry *de = NULL;
198
+ /* direct mount or browsable map */
199
+ ino = autofs4_dentry_ino(dentry);
201
+ /* If not lookup actual dentry used */
202
+ de = d_lookup(dentry->d_parent, &dentry->d_name);
204
+ ino = autofs4_dentry_ino(de);
207
+ /* Set mount requester */
209
+ spin_lock(&sbi->fs_lock);
210
+ ino->uid = wq->uid;
211
+ ino->gid = wq->gid;
212
+ spin_unlock(&sbi->fs_lock);
219
/* Are we the last process to need status? */
220
mutex_lock(&sbi->wq_mutex);
222
Index: linux-2.6.26/Documentation/filesystems/autofs4-mount-control.txt
223
===================================================================
225
+++ linux-2.6.26/Documentation/filesystems/autofs4-mount-control.txt
228
+Miscellaneous Device control operations for the autofs4 kernel module
229
+====================================================================
234
+There is a problem with active restarts in autofs (that is to say
235
+restarting autofs when there are busy mounts).
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.
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.
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.
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.
265
+Here is a master map with direct and indirect map entries:
268
+/test /etc/auto.indirect
270
+and the corresponding map files:
274
+/automount/dparse/g6 budgie:/autofs/export1
275
+/automount/dparse/g1 shark:/autofs/export1
280
+g1 shark:/autofs/export1
281
+g6 budgie:/autofs/export1
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
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.
295
+But, each entry in direct and indirect maps can have offsets (making
296
+them multi-mount map entries).
298
+For example, an indirect mount map entry could also be:
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
307
+and a similarly a direct mount map entry could also be:
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
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.
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.
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
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
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.
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.
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.
393
+autofs4 Miscellaneous Device mount control interface
394
+====================================================
396
+The control interface is opening a device node, typically /dev/autofs.
398
+All the ioctls use a common structure to pass the needed parameter
399
+information and return operation results:
401
+struct autofs_dev_ioctl {
404
+ __u32 size; /* total size of data passed in
405
+ * including this struct */
406
+ __s32 ioctlfd; /* automount command fd */
408
+ /* Command parameters */
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;
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.
434
+The anonymous union is used to communicate parameters and results of calls
435
+made as described below.
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.
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 *).
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
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.
468
+The device node ioctl operations implemented by this interface are:
471
+AUTOFS_DEV_IOCTL_VERSION
472
+------------------------
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
481
+AUTOFS_DEV_IOCTL_PROTOVER_CMD and AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD
482
+------------------------------------------------------------------
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.
492
+AUTOFS_DEV_IOCTL_OPENMOUNT_CMD and AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD
493
+------------------------------------------------------------------
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.
510
+AUTOFS_DEV_IOCTL_READY_CMD and AUTOFS_DEV_IOCTL_FAIL_CMD
511
+--------------------------------------------------------
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.
522
+AUTOFS_DEV_IOCTL_SETPIPEFD_CMD
523
+------------------------------
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).
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
540
+AUTOFS_DEV_IOCTL_CATATONIC_CMD
541
+------------------------------
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.
547
+The call requires an initialized struct autofs_dev_ioctl with the
548
+ioctlfd field set to the descriptor obtained from the open call.
551
+AUTOFS_DEV_IOCTL_TIMEOUT_CMD
552
+----------------------------
554
+Set the expire timeout for mounts withing an autofs mount point.
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.
563
+AUTOFS_DEV_IOCTL_REQUESTER_CMD
564
+------------------------------
566
+Return the uid and gid of the last process to successfully trigger a the
567
+mount on the given path dentry.
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.
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.
582
+AUTOFS_DEV_IOCTL_EXPIRE_CMD
583
+---------------------------
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.
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.
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.
598
+AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD
599
+------------------------------
601
+Checks if an autofs mount point is in use.
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
609
+AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD
610
+---------------------------------
612
+Check if the given path is a mountpoint.
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.
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.
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
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
647
obj-$(CONFIG_AUTOFS4_FS) += autofs4.o
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
===================================================================
654
+++ linux-2.6.26/fs/autofs4/dev-ioctl.c
657
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
658
+ * Copyright 2008 Ian Kent <raven@themaw.net>
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.
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>
681
+#include "autofs_i.h"
684
+ * This module implements an interface for routing autofs ioctl control
685
+ * commands via a miscellaneous device file.
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.
695
+#define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl)
697
+typedef int (*ioctl_fn)(struct file *,
698
+struct autofs_sb_info *, struct autofs_dev_ioctl *);
700
+static int check_name(const char *name)
702
+ if (!strchr(name, '/'))
708
+ * Check a string doesn't overrun the chunk of
709
+ * memory we copied from user land.
711
+static int invalid_str(char *str, void *end)
713
+ while ((void *) str <= end)
720
+ * Check that the user compiled against correct version of autofs
721
+ * misc device code.
723
+ * As well as checking the version compatibility this always copies
724
+ * the kernel interface version out.
726
+static int check_dev_ioctl_version(int cmd, struct autofs_dev_ioctl *param)
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);
740
+ /* Fill in the kernel version. */
741
+ param->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;
742
+ param->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;
748
+ * Copy parameter control struct, including a possible path allocated
749
+ * at the end of the struct.
751
+static struct autofs_dev_ioctl *copy_dev_ioctl(struct autofs_dev_ioctl __user *in)
753
+ struct autofs_dev_ioctl tmp, *ads;
755
+ if (copy_from_user(&tmp, in, sizeof(tmp)))
756
+ return ERR_PTR(-EFAULT);
758
+ if (tmp.size < sizeof(tmp))
759
+ return ERR_PTR(-EINVAL);
761
+ ads = kmalloc(tmp.size, GFP_KERNEL);
763
+ return ERR_PTR(-ENOMEM);
765
+ if (copy_from_user(ads, in, tmp.size)) {
767
+ return ERR_PTR(-EFAULT);
773
+static inline void free_dev_ioctl(struct autofs_dev_ioctl *param)
780
+ * Check sanity of parameter control fields and if a path is present
781
+ * check that it is terminated and contains at least one "/".
783
+static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
787
+ if ((err = check_dev_ioctl_version(cmd, param))) {
788
+ AUTOFS_WARN("invalid device control module version "
789
+ "supplied for cmd(0x%08x)", cmd);
793
+ if (param->size > sizeof(*param)) {
794
+ err = invalid_str(param->path,
795
+ (void *) ((size_t) param + param->size));
798
+ "path string terminator missing for cmd(0x%08x)",
803
+ err = check_name(param->path);
805
+ AUTOFS_WARN("invalid path supplied for cmd(0x%08x)",
817
+ * Get the autofs super block info struct from the file opened on
818
+ * the autofs mount point.
820
+static struct autofs_sb_info *autofs_dev_ioctl_sbi(struct file *f)
822
+ struct autofs_sb_info *sbi = NULL;
823
+ struct inode *inode;
826
+ inode = f->f_path.dentry->d_inode;
827
+ sbi = autofs4_sbi(inode->i_sb);
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)
837
+ param->protover.version = sbi->version;
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)
846
+ param->protosubver.sub_version = sbi->sub_version;
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).
854
+static int autofs_dev_ioctl_find_super(struct nameidata *nd, dev_t devno)
856
+ struct dentry *dentry;
857
+ struct inode *inode;
858
+ struct super_block *sb;
864
+ /* Lookup the dentry name at the base of our mount point */
865
+ dentry = d_lookup(nd->path.dentry, &nd->last);
869
+ dput(nd->path.dentry);
870
+ nd->path.dentry = dentry;
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;
879
+ s_dev = new_encode_dev(sb->s_dev);
880
+ if (devno == s_dev) {
881
+ if (sb->s_magic == AUTOFS_SUPER_MAGIC) {
892
+ * Walk down the mount stack looking for an autofs mount that
893
+ * has the requested mount type (ie. indirect, direct or offset).
895
+static int autofs_dev_ioctl_find_sbi_type(struct nameidata *nd, unsigned int type)
897
+ struct dentry *dentry;
898
+ struct autofs_info *ino;
903
+ /* Lookup the dentry name at the base of our mount point */
904
+ dentry = d_lookup(nd->path.dentry, &nd->last);
908
+ dput(nd->path.dentry);
909
+ nd->path.dentry = dentry;
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) {
923
+static void autofs_dev_ioctl_fd_install(unsigned int fd, struct file *file)
925
+ struct files_struct *files = current->files;
926
+ struct fdtable *fdt;
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);
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)).
941
+static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid)
944
+ struct nameidata nd;
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);
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.
959
+ err = autofs_dev_ioctl_find_super(&nd, devid);
961
+ path_put(&nd.path);
965
+ filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY);
966
+ if (IS_ERR(filp)) {
967
+ err = PTR_ERR(filp);
971
+ autofs_dev_ioctl_fd_install(fd, filp);
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)
990
+ /* param->path has already been checked */
991
+ if (!param->openmount.devid)
994
+ param->ioctlfd = -1;
996
+ path = param->path;
997
+ devid = param->openmount.devid;
1000
+ fd = autofs_dev_ioctl_open_mountpoint(path, devid);
1001
+ if (unlikely(fd < 0)) {
1006
+ param->ioctlfd = fd;
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)
1016
+ return sys_close(param->ioctlfd);
1020
+ * Send "ready" status for an existing wait (either a mount or an expire
1023
+static int autofs_dev_ioctl_ready(struct file *fp,
1024
+ struct autofs_sb_info *sbi,
1025
+ struct autofs_dev_ioctl *param)
1027
+ autofs_wqt_t token;
1029
+ token = (autofs_wqt_t) param->ready.token;
1030
+ return autofs4_wait_release(sbi, token, 0);
1034
+ * Send "fail" status for an existing wait (either a mount or an expire
1037
+static int autofs_dev_ioctl_fail(struct file *fp,
1038
+ struct autofs_sb_info *sbi,
1039
+ struct autofs_dev_ioctl *param)
1041
+ autofs_wqt_t token;
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);
1050
+ * Set the pipe fd for kernel communication to the daemon.
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.
1058
+ * This also sets the process group id used to identify the
1059
+ * controlling process (eg. the owning automount(8) daemon).
1061
+static int autofs_dev_ioctl_setpipefd(struct file *fp,
1062
+ struct autofs_sb_info *sbi,
1063
+ struct autofs_dev_ioctl *param)
1068
+ if (param->setpipefd.pipefd == -1)
1071
+ pipefd = param->setpipefd.pipefd;
1073
+ mutex_lock(&sbi->wq_mutex);
1074
+ if (!sbi->catatonic) {
1075
+ mutex_unlock(&sbi->wq_mutex);
1078
+ struct file *pipe = fget(pipefd);
1079
+ if (!pipe->f_op || !pipe->f_op->write) {
1084
+ sbi->oz_pgrp = task_pgrp_nr(current);
1085
+ sbi->pipefd = pipefd;
1087
+ sbi->catatonic = 0;
1090
+ mutex_unlock(&sbi->wq_mutex);
1095
+ * Make the autofs mount point catatonic, no longer responsive to
1096
+ * mount requests. Also closes the kernel pipe file descriptor.
1098
+static int autofs_dev_ioctl_catatonic(struct file *fp,
1099
+ struct autofs_sb_info *sbi,
1100
+ struct autofs_dev_ioctl *param)
1102
+ autofs4_catatonic_mode(sbi);
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)
1111
+ unsigned long timeout;
1113
+ timeout = param->timeout.timeout;
1114
+ param->timeout.timeout = sbi->exp_timeout / HZ;
1115
+ sbi->exp_timeout = timeout * HZ;
1120
+ * Return the uid and gid of the last request for the mount
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.
1127
+static int autofs_dev_ioctl_requester(struct file *fp,
1128
+ struct autofs_sb_info *sbi,
1129
+ struct autofs_dev_ioctl *param)
1131
+ struct autofs_info *ino;
1132
+ struct nameidata nd;
1135
+ int err = -ENOENT;
1137
+ if (param->size <= sizeof(*param)) {
1142
+ path = param->path;
1143
+ devid = sbi->sb->s_dev;
1145
+ param->requester.uid = param->requester.gid = -1;
1147
+ /* Get nameidata of the parent directory */
1148
+ err = path_lookup(path, LOOKUP_PARENT, &nd);
1152
+ err = autofs_dev_ioctl_find_super(&nd, devid);
1156
+ ino = autofs4_dentry_ino(nd.path.dentry);
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);
1167
+ path_put(&nd.path);
1173
+ * Call repeatedly until it returns -EAGAIN, meaning there's nothing
1174
+ * more that can be done.
1176
+static int autofs_dev_ioctl_expire(struct file *fp,
1177
+ struct autofs_sb_info *sbi,
1178
+ struct autofs_dev_ioctl *param)
1180
+ struct vfsmount *mnt;
1183
+ how = param->expire.how;
1184
+ mnt = fp->f_path.mnt;
1186
+ return autofs4_do_expire_multi(sbi->sb, mnt, sbi, how);
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)
1194
+ param->askumount.may_umount = 0;
1195
+ if (may_umount(fp->f_path.mnt))
1196
+ param->askumount.may_umount = 1;
1201
+ * Check if the given path is a mountpoint.
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.
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.
1219
+ * In both cases the the device number (as returned by
1220
+ * new_encode_dev()) is also returned.
1222
+static int autofs_dev_ioctl_ismountpoint(struct file *fp,
1223
+ struct autofs_sb_info *sbi,
1224
+ struct autofs_dev_ioctl *param)
1226
+ struct nameidata nd;
1228
+ unsigned int type;
1229
+ unsigned int devid, magic;
1230
+ int err = -ENOENT;
1232
+ if (param->size <= sizeof(*param)) {
1237
+ path = param->path;
1238
+ type = param->ismountpoint.in.type;
1240
+ param->ismountpoint.out.devid = devid = 0;
1241
+ param->ismountpoint.out.magic = magic = 0;
1243
+ if (!fp || param->ioctlfd == -1) {
1244
+ if (autofs_type_any(type)) {
1245
+ struct super_block *sb;
1247
+ err = path_lookup(path, LOOKUP_FOLLOW, &nd);
1251
+ sb = nd.path.dentry->d_sb;
1252
+ devid = new_encode_dev(sb->s_dev);
1254
+ struct autofs_info *ino;
1256
+ err = path_lookup(path, LOOKUP_PARENT, &nd);
1260
+ err = autofs_dev_ioctl_find_sbi_type(&nd, type);
1264
+ ino = autofs4_dentry_ino(nd.path.dentry);
1265
+ devid = autofs4_get_dev(ino->sbi);
1269
+ if (nd.path.dentry->d_inode &&
1270
+ nd.path.mnt->mnt_root == nd.path.dentry) {
1272
+ magic = nd.path.dentry->d_inode->i_sb->s_magic;
1275
+ dev_t dev = autofs4_get_dev(sbi);
1277
+ err = path_lookup(path, LOOKUP_PARENT, &nd);
1281
+ err = autofs_dev_ioctl_find_super(&nd, dev);
1287
+ err = have_submounts(nd.path.dentry);
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;
1297
+ param->ismountpoint.out.devid = devid;
1298
+ param->ismountpoint.out.magic = magic;
1301
+ path_put(&nd.path);
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
1311
+#define cmd_idx(cmd) (cmd - _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST))
1313
+static ioctl_fn lookup_dev_ioctl(unsigned int cmd)
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}
1347
+ unsigned int idx = cmd_idx(cmd);
1349
+ return (idx >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[idx].fn;
1352
+/* ioctl dispatcher */
1353
+static int _autofs_dev_ioctl(unsigned int command, struct autofs_dev_ioctl __user *user)
1355
+ struct autofs_dev_ioctl *param;
1357
+ struct autofs_sb_info *sbi;
1358
+ unsigned int cmd_first, cmd;
1359
+ ioctl_fn fn = NULL;
1362
+ /* only root can play with this */
1363
+ if (!capable(CAP_SYS_ADMIN))
1366
+ cmd_first = _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST);
1367
+ cmd = _IOC_NR(command);
1369
+ if (_IOC_TYPE(command) != _IOC_TYPE(AUTOFS_DEV_IOCTL_IOC_FIRST) ||
1370
+ cmd - cmd_first >= AUTOFS_DEV_IOCTL_IOC_COUNT) {
1374
+ /* Copy the parameters into kernel space. */
1375
+ param = copy_dev_ioctl(user);
1376
+ if (IS_ERR(param))
1377
+ return PTR_ERR(param);
1379
+ err = validate_dev_ioctl(command, param);
1383
+ /* The validate routine above always sets the version */
1384
+ if (cmd == AUTOFS_DEV_IOCTL_VERSION_CMD)
1387
+ fn = lookup_dev_ioctl(cmd);
1389
+ AUTOFS_WARN("unknown command 0x%08x", command);
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.
1401
+ if (cmd != AUTOFS_DEV_IOCTL_OPENMOUNT_CMD &&
1402
+ cmd != AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD) {
1403
+ fp = fget(param->ioctlfd);
1405
+ if (cmd == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD)
1417
+ sbi = autofs_dev_ioctl_sbi(fp);
1418
+ if (!sbi || sbi->magic != AUTOFS_SBI_MAGIC) {
1425
+ * Admin needs to be able to set the mount catatonic in
1426
+ * order to be able to perform the re-open.
1428
+ if (!autofs4_oz_mode(sbi) &&
1429
+ cmd != AUTOFS_DEV_IOCTL_CATATONIC_CMD) {
1436
+ err = fn(fp, sbi, param);
1441
+ if (err >= 0 && copy_to_user(user, param, AUTOFS_DEV_IOCTL_SIZE))
1444
+ free_dev_ioctl(param);
1448
+static long autofs_dev_ioctl(struct file *file, uint command, ulong u)
1451
+ err = _autofs_dev_ioctl(command, (struct autofs_dev_ioctl __user *) u);
1452
+ return (long) err;
1455
+#ifdef CONFIG_COMPAT
1456
+static long autofs_dev_ioctl_compat(struct file *file, uint command, ulong u)
1458
+ return (long) autofs_dev_ioctl(file, command, (ulong) compat_ptr(u));
1461
+#define autofs_dev_ioctl_compat NULL
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,
1470
+static struct miscdevice _autofs_dev_ioctl_misc = {
1471
+ .minor = MISC_DYNAMIC_MINOR,
1472
+ .name = AUTOFS_DEVICE_NAME,
1473
+ .fops = &_dev_ioctl_fops
1476
+/* Register/deregister misc character device */
1477
+int autofs_dev_ioctl_init(void)
1481
+ r = misc_register(&_autofs_dev_ioctl_misc);
1483
+ AUTOFS_ERROR("misc_register failed for control device");
1490
+void autofs_dev_ioctl_exit(void)
1492
+ misc_deregister(&_autofs_dev_ioctl_misc);
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);
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))
1509
@@ -255,10 +255,10 @@ cont:
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,
1517
+struct dentry *autofs4_expire_direct(struct super_block *sb,
1518
+ struct vfsmount *mnt,
1519
+ struct autofs_sb_info *sbi,
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
1528
-static struct dentry *autofs4_expire_indirect(struct super_block *sb,
1529
- struct vfsmount *mnt,
1530
- struct autofs_sb_info *sbi,
1532
+struct dentry *autofs4_expire_indirect(struct super_block *sb,
1533
+ struct vfsmount *mnt,
1534
+ struct autofs_sb_info *sbi,
1537
unsigned long timeout;
1538
struct dentry *root = sb->s_root;
1539
@@ -478,22 +478,16 @@ int autofs4_expire_run(struct super_bloc
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)
1550
struct dentry *dentry;
1554
- if (arg && get_user(do_now, arg))
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);
1562
- dentry = autofs4_expire_indirect(sb, mnt, sbi, do_now);
1563
+ dentry = autofs4_expire_indirect(sb, mnt, sbi, when);
1566
struct autofs_info *ino = autofs4_dentry_ino(dentry);
1567
@@ -516,3 +510,16 @@ int autofs4_expire_multi(struct super_bl
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)
1578
+ if (arg && get_user(do_now, arg))
1581
+ return autofs4_do_expire_multi(sb, mnt, sbi, do_now);
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
1590
static int __init init_autofs4_fs(void)
1592
- return register_filesystem(&autofs_fs_type);
1595
+ err = register_filesystem(&autofs_fs_type);
1599
+ autofs_dev_ioctl_init();
1604
static void __exit exit_autofs4_fs(void)
1606
+ autofs_dev_ioctl_exit();
1607
unregister_filesystem(&autofs_fs_type);
1610
Index: linux-2.6.26/include/linux/auto_dev-ioctl.h
1611
===================================================================
1613
+++ linux-2.6.26/include/linux/auto_dev-ioctl.h
1616
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
1617
+ * Copyright 2008 Ian Kent <raven@themaw.net>
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.
1624
+#ifndef _LINUX_AUTO_DEV_IOCTL_H
1625
+#define _LINUX_AUTO_DEV_IOCTL_H
1627
+#include <linux/string.h>
1628
+#include <linux/types.h>
1630
+#define AUTOFS_DEVICE_NAME "autofs"
1632
+#define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1
1633
+#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0
1635
+#define AUTOFS_DEVID_LEN 16
1637
+#define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl)
1640
+ * An ioctl interface for autofs mount point control.
1643
+struct args_protover {
1647
+struct args_protosubver {
1648
+ __u32 sub_version;
1651
+struct args_openmount {
1655
+struct args_ready {
1664
+struct args_setpipefd {
1668
+struct args_timeout {
1672
+struct args_requester {
1677
+struct args_expire {
1681
+struct args_askumount {
1685
+struct args_ismountpoint {
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
1704
+struct autofs_dev_ioctl {
1707
+ __u32 size; /* total size of data passed in
1708
+ * including this struct */
1709
+ __s32 ioctlfd; /* automount command fd */
1711
+ /* Command parameters */
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;
1730
+static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in)
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);
1741
+ * If you change this make sure you make the corresponding change
1742
+ * to autofs-dev-ioctl.c:lookup_ioctl()
1745
+ /* Get various version info */
1746
+ AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71,
1747
+ AUTOFS_DEV_IOCTL_PROTOVER_CMD,
1748
+ AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD,
1750
+ /* Open mount ioctl fd */
1751
+ AUTOFS_DEV_IOCTL_OPENMOUNT_CMD,
1753
+ /* Close mount ioctl fd */
1754
+ AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD,
1756
+ /* Mount/expire status returns */
1757
+ AUTOFS_DEV_IOCTL_READY_CMD,
1758
+ AUTOFS_DEV_IOCTL_FAIL_CMD,
1760
+ /* Activate/deactivate autofs mount */
1761
+ AUTOFS_DEV_IOCTL_SETPIPEFD_CMD,
1762
+ AUTOFS_DEV_IOCTL_CATATONIC_CMD,
1764
+ /* Expiry timeout */
1765
+ AUTOFS_DEV_IOCTL_TIMEOUT_CMD,
1767
+ /* Get mount last requesting uid and gid */
1768
+ AUTOFS_DEV_IOCTL_REQUESTER_CMD,
1770
+ /* Check for eligible expire candidates */
1771
+ AUTOFS_DEV_IOCTL_EXPIRE_CMD,
1773
+ /* Request busy status */
1774
+ AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD,
1776
+ /* Check if path is a mountpoint */
1777
+ AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD,
1780
+#define AUTOFS_IOCTL 0x93
1782
+#define AUTOFS_DEV_IOCTL_VERSION \
1783
+ _IOWR(AUTOFS_IOCTL, \
1784
+ AUTOFS_DEV_IOCTL_VERSION_CMD, struct autofs_dev_ioctl)
1786
+#define AUTOFS_DEV_IOCTL_PROTOVER \
1787
+ _IOWR(AUTOFS_IOCTL, \
1788
+ AUTOFS_DEV_IOCTL_PROTOVER_CMD, struct autofs_dev_ioctl)
1790
+#define AUTOFS_DEV_IOCTL_PROTOSUBVER \
1791
+ _IOWR(AUTOFS_IOCTL, \
1792
+ AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, struct autofs_dev_ioctl)
1794
+#define AUTOFS_DEV_IOCTL_OPENMOUNT \
1795
+ _IOWR(AUTOFS_IOCTL, \
1796
+ AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, struct autofs_dev_ioctl)
1798
+#define AUTOFS_DEV_IOCTL_CLOSEMOUNT \
1799
+ _IOWR(AUTOFS_IOCTL, \
1800
+ AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, struct autofs_dev_ioctl)
1802
+#define AUTOFS_DEV_IOCTL_READY \
1803
+ _IOWR(AUTOFS_IOCTL, \
1804
+ AUTOFS_DEV_IOCTL_READY_CMD, struct autofs_dev_ioctl)
1806
+#define AUTOFS_DEV_IOCTL_FAIL \
1807
+ _IOWR(AUTOFS_IOCTL, \
1808
+ AUTOFS_DEV_IOCTL_FAIL_CMD, struct autofs_dev_ioctl)
1810
+#define AUTOFS_DEV_IOCTL_SETPIPEFD \
1811
+ _IOWR(AUTOFS_IOCTL, \
1812
+ AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, struct autofs_dev_ioctl)
1814
+#define AUTOFS_DEV_IOCTL_CATATONIC \
1815
+ _IOWR(AUTOFS_IOCTL, \
1816
+ AUTOFS_DEV_IOCTL_CATATONIC_CMD, struct autofs_dev_ioctl)
1818
+#define AUTOFS_DEV_IOCTL_TIMEOUT \
1819
+ _IOWR(AUTOFS_IOCTL, \
1820
+ AUTOFS_DEV_IOCTL_TIMEOUT_CMD, struct autofs_dev_ioctl)
1822
+#define AUTOFS_DEV_IOCTL_REQUESTER \
1823
+ _IOWR(AUTOFS_IOCTL, \
1824
+ AUTOFS_DEV_IOCTL_REQUESTER_CMD, struct autofs_dev_ioctl)
1826
+#define AUTOFS_DEV_IOCTL_EXPIRE \
1827
+ _IOWR(AUTOFS_IOCTL, \
1828
+ AUTOFS_DEV_IOCTL_EXPIRE_CMD, struct autofs_dev_ioctl)
1830
+#define AUTOFS_DEV_IOCTL_ASKUMOUNT \
1831
+ _IOWR(AUTOFS_IOCTL, \
1832
+ AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, struct autofs_dev_ioctl)
1834
+#define AUTOFS_DEV_IOCTL_ISMOUNTPOINT \
1835
+ _IOWR(AUTOFS_IOCTL, \
1836
+ AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl)
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
1844
#define AUTOFS_MIN_PROTO_VERSION 3
1845
#define AUTOFS_MAX_PROTO_VERSION 5
1847
-#define AUTOFS_PROTO_SUBVERSION 0
1848
+#define AUTOFS_PROTO_SUBVERSION 1
1850
/* Mask for expire behaviour */
1851
#define AUTOFS_EXP_IMMEDIATE 1
1852
#define AUTOFS_EXP_LEAVES 2
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
1863
+static inline void set_autofs_type_indirect(unsigned int *type)
1865
+ *type = AUTOFS_TYPE_INDIRECT;
1869
+static inline unsigned int autofs_type_indirect(unsigned int type)
1871
+ return (type == AUTOFS_TYPE_INDIRECT);
1874
+static inline void set_autofs_type_direct(unsigned int *type)
1876
+ *type = AUTOFS_TYPE_DIRECT;
1880
+static inline unsigned int autofs_type_direct(unsigned int type)
1882
+ return (type == AUTOFS_TYPE_DIRECT);
1885
+static inline void set_autofs_type_offset(unsigned int *type)
1887
+ *type = AUTOFS_TYPE_OFFSET;
1891
+static inline unsigned int autofs_type_offset(unsigned int type)
1893
+ return (type == AUTOFS_TYPE_OFFSET);
1896
+static inline unsigned int autofs_type_trigger(unsigned int type)
1898
+ return (type == AUTOFS_TYPE_DIRECT || type == AUTOFS_TYPE_OFFSET);
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.
1906
+static inline void set_autofs_type_any(unsigned int *type)
1908
+ *type = AUTOFS_TYPE_ANY;
1912
+static inline unsigned int autofs_type_any(unsigned int type)
1914
+ return (type == AUTOFS_TYPE_ANY);
1917
/* Daemon notification packet types */
1918
enum autofs_notify {