828 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright 2008 Red Hat, Inc. All rights reserved.4 * Copyright 2008 Ian Kent <raven@themaw.net>5 */6 7#include <linux/module.h>8#include <linux/miscdevice.h>9#include <linux/compat.h>10#include <linux/fdtable.h>11#include <linux/magic.h>12#include <linux/nospec.h>13 14#include "autofs_i.h"15 16/*17 * This module implements an interface for routing autofs ioctl control18 * commands via a miscellaneous device file.19 *20 * The alternate interface is needed because we need to be able open21 * an ioctl file descriptor on an autofs mount that may be covered by22 * another mount. This situation arises when starting automount(8)23 * or other user space daemon which uses direct mounts or offset24 * mounts (used for autofs lazy mount/umount of nested mount trees),25 * which have been left busy at service shutdown.26 */27 28typedef int (*ioctl_fn)(struct file *, struct autofs_sb_info *,29 struct autofs_dev_ioctl *);30 31static int check_name(const char *name)32{33 if (!strchr(name, '/'))34 return -EINVAL;35 return 0;36}37 38/*39 * Check a string doesn't overrun the chunk of40 * memory we copied from user land.41 */42static int invalid_str(char *str, size_t size)43{44 if (memchr(str, 0, size))45 return 0;46 return -EINVAL;47}48 49/*50 * Check that the user compiled against correct version of autofs51 * misc device code.52 *53 * As well as checking the version compatibility this always copies54 * the kernel interface version out.55 */56static int check_dev_ioctl_version(int cmd, struct autofs_dev_ioctl *param)57{58 int err = 0;59 60 if ((param->ver_major != AUTOFS_DEV_IOCTL_VERSION_MAJOR) ||61 (param->ver_minor > AUTOFS_DEV_IOCTL_VERSION_MINOR)) {62 pr_warn("ioctl control interface version mismatch: "63 "kernel(%u.%u), user(%u.%u), cmd(0x%08x)\n",64 AUTOFS_DEV_IOCTL_VERSION_MAJOR,65 AUTOFS_DEV_IOCTL_VERSION_MINOR,66 param->ver_major, param->ver_minor, cmd);67 err = -EINVAL;68 }69 70 /* Fill in the kernel version. */71 param->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;72 param->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;73 74 return err;75}76 77/*78 * Copy parameter control struct, including a possible path allocated79 * at the end of the struct.80 */81static struct autofs_dev_ioctl *82copy_dev_ioctl(struct autofs_dev_ioctl __user *in)83{84 struct autofs_dev_ioctl tmp, *res;85 86 if (copy_from_user(&tmp, in, AUTOFS_DEV_IOCTL_SIZE))87 return ERR_PTR(-EFAULT);88 89 if (tmp.size < AUTOFS_DEV_IOCTL_SIZE)90 return ERR_PTR(-EINVAL);91 92 if (tmp.size > AUTOFS_DEV_IOCTL_SIZE + PATH_MAX)93 return ERR_PTR(-ENAMETOOLONG);94 95 res = memdup_user(in, tmp.size);96 if (!IS_ERR(res))97 res->size = tmp.size;98 99 return res;100}101 102static inline void free_dev_ioctl(struct autofs_dev_ioctl *param)103{104 kfree(param);105}106 107/*108 * Check sanity of parameter control fields and if a path is present109 * check that it is terminated and contains at least one "/".110 */111static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)112{113 unsigned int inr = _IOC_NR(cmd);114 int err;115 116 err = check_dev_ioctl_version(cmd, param);117 if (err) {118 pr_warn("invalid device control module version "119 "supplied for cmd(0x%08x)\n", cmd);120 goto out;121 }122 123 if (param->size > AUTOFS_DEV_IOCTL_SIZE) {124 err = invalid_str(param->path, param->size - AUTOFS_DEV_IOCTL_SIZE);125 if (err) {126 pr_warn(127 "path string terminator missing for cmd(0x%08x)\n",128 cmd);129 goto out;130 }131 132 /* Setting the per-dentry expire timeout requires a trailing133 * path component, ie. no '/', so invert the logic of the134 * check_name() return for AUTOFS_DEV_IOCTL_TIMEOUT_CMD.135 */136 err = check_name(param->path);137 if (inr == AUTOFS_DEV_IOCTL_TIMEOUT_CMD)138 err = err ? 0 : -EINVAL;139 if (err) {140 pr_warn("invalid path supplied for cmd(0x%08x)\n",141 cmd);142 goto out;143 }144 } else {145 if (inr == AUTOFS_DEV_IOCTL_OPENMOUNT_CMD ||146 inr == AUTOFS_DEV_IOCTL_REQUESTER_CMD ||147 inr == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD) {148 err = -EINVAL;149 goto out;150 }151 }152 153 err = 0;154out:155 return err;156}157 158/* Return autofs dev ioctl version */159static int autofs_dev_ioctl_version(struct file *fp,160 struct autofs_sb_info *sbi,161 struct autofs_dev_ioctl *param)162{163 /* This should have already been set. */164 param->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;165 param->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;166 return 0;167}168 169/* Return autofs module protocol version */170static int autofs_dev_ioctl_protover(struct file *fp,171 struct autofs_sb_info *sbi,172 struct autofs_dev_ioctl *param)173{174 param->protover.version = sbi->version;175 return 0;176}177 178/* Return autofs module protocol sub version */179static int autofs_dev_ioctl_protosubver(struct file *fp,180 struct autofs_sb_info *sbi,181 struct autofs_dev_ioctl *param)182{183 param->protosubver.sub_version = sbi->sub_version;184 return 0;185}186 187/* Find the topmost mount satisfying test() */188static int find_autofs_mount(const char *pathname,189 struct path *res,190 int test(const struct path *path, void *data),191 void *data)192{193 struct path path;194 int err;195 196 err = kern_path(pathname, LOOKUP_MOUNTPOINT, &path);197 if (err)198 return err;199 err = -ENOENT;200 while (path.dentry == path.mnt->mnt_root) {201 if (path.dentry->d_sb->s_magic == AUTOFS_SUPER_MAGIC) {202 if (test(&path, data)) {203 path_get(&path);204 *res = path;205 err = 0;206 break;207 }208 }209 if (!follow_up(&path))210 break;211 }212 path_put(&path);213 return err;214}215 216static int test_by_dev(const struct path *path, void *p)217{218 return path->dentry->d_sb->s_dev == *(dev_t *)p;219}220 221static int test_by_type(const struct path *path, void *p)222{223 struct autofs_info *ino = autofs_dentry_ino(path->dentry);224 225 return ino && ino->sbi->type & *(unsigned *)p;226}227 228/*229 * Open a file descriptor on the autofs mount point corresponding230 * to the given path and device number (aka. new_encode_dev(sb->s_dev)).231 */232static int autofs_dev_ioctl_open_mountpoint(const char *name, dev_t devid)233{234 int err, fd;235 236 fd = get_unused_fd_flags(O_CLOEXEC);237 if (likely(fd >= 0)) {238 struct file *filp;239 struct path path;240 241 err = find_autofs_mount(name, &path, test_by_dev, &devid);242 if (err)243 goto out;244 245 filp = dentry_open(&path, O_RDONLY, current_cred());246 path_put(&path);247 if (IS_ERR(filp)) {248 err = PTR_ERR(filp);249 goto out;250 }251 252 fd_install(fd, filp);253 }254 255 return fd;256 257out:258 put_unused_fd(fd);259 return err;260}261 262/* Open a file descriptor on an autofs mount point */263static int autofs_dev_ioctl_openmount(struct file *fp,264 struct autofs_sb_info *sbi,265 struct autofs_dev_ioctl *param)266{267 const char *path;268 dev_t devid;269 int err, fd;270 271 /* param->path has been checked in validate_dev_ioctl() */272 273 if (!param->openmount.devid)274 return -EINVAL;275 276 param->ioctlfd = -1;277 278 path = param->path;279 devid = new_decode_dev(param->openmount.devid);280 281 err = 0;282 fd = autofs_dev_ioctl_open_mountpoint(path, devid);283 if (unlikely(fd < 0)) {284 err = fd;285 goto out;286 }287 288 param->ioctlfd = fd;289out:290 return err;291}292 293/* Close file descriptor allocated above (user can also use close(2)). */294static int autofs_dev_ioctl_closemount(struct file *fp,295 struct autofs_sb_info *sbi,296 struct autofs_dev_ioctl *param)297{298 return close_fd(param->ioctlfd);299}300 301/*302 * Send "ready" status for an existing wait (either a mount or an expire303 * request).304 */305static int autofs_dev_ioctl_ready(struct file *fp,306 struct autofs_sb_info *sbi,307 struct autofs_dev_ioctl *param)308{309 autofs_wqt_t token;310 311 token = (autofs_wqt_t) param->ready.token;312 return autofs_wait_release(sbi, token, 0);313}314 315/*316 * Send "fail" status for an existing wait (either a mount or an expire317 * request).318 */319static int autofs_dev_ioctl_fail(struct file *fp,320 struct autofs_sb_info *sbi,321 struct autofs_dev_ioctl *param)322{323 autofs_wqt_t token;324 int status;325 326 token = (autofs_wqt_t) param->fail.token;327 status = param->fail.status < 0 ? param->fail.status : -ENOENT;328 return autofs_wait_release(sbi, token, status);329}330 331/*332 * Set the pipe fd for kernel communication to the daemon.333 *334 * Normally this is set at mount using an option but if we335 * are reconnecting to a busy mount then we need to use this336 * to tell the autofs mount about the new kernel pipe fd. In337 * order to protect mounts against incorrectly setting the338 * pipefd we also require that the autofs mount be catatonic.339 *340 * This also sets the process group id used to identify the341 * controlling process (eg. the owning automount(8) daemon).342 */343static int autofs_dev_ioctl_setpipefd(struct file *fp,344 struct autofs_sb_info *sbi,345 struct autofs_dev_ioctl *param)346{347 int pipefd;348 int err = 0;349 struct pid *new_pid = NULL;350 351 if (param->setpipefd.pipefd == -1)352 return -EINVAL;353 354 pipefd = param->setpipefd.pipefd;355 356 mutex_lock(&sbi->wq_mutex);357 if (!(sbi->flags & AUTOFS_SBI_CATATONIC)) {358 mutex_unlock(&sbi->wq_mutex);359 return -EBUSY;360 } else {361 struct file *pipe;362 363 new_pid = get_task_pid(current, PIDTYPE_PGID);364 365 if (ns_of_pid(new_pid) != ns_of_pid(sbi->oz_pgrp)) {366 pr_warn("not allowed to change PID namespace\n");367 err = -EINVAL;368 goto out;369 }370 371 pipe = fget(pipefd);372 if (!pipe) {373 err = -EBADF;374 goto out;375 }376 if (autofs_prepare_pipe(pipe) < 0) {377 err = -EPIPE;378 fput(pipe);379 goto out;380 }381 swap(sbi->oz_pgrp, new_pid);382 sbi->pipefd = pipefd;383 sbi->pipe = pipe;384 sbi->flags &= ~AUTOFS_SBI_CATATONIC;385 }386out:387 put_pid(new_pid);388 mutex_unlock(&sbi->wq_mutex);389 return err;390}391 392/*393 * Make the autofs mount point catatonic, no longer responsive to394 * mount requests. Also closes the kernel pipe file descriptor.395 */396static int autofs_dev_ioctl_catatonic(struct file *fp,397 struct autofs_sb_info *sbi,398 struct autofs_dev_ioctl *param)399{400 autofs_catatonic_mode(sbi);401 return 0;402}403 404/*405 * Set the autofs mount expire timeout.406 *407 * There are two places an expire timeout can be set, in the autofs408 * super block info. (this is all that's needed for direct and offset409 * mounts because there's a distinct mount corresponding to each of410 * these) and per-dentry within within the dentry info. If a per-dentry411 * timeout is set it will override the expire timeout set in the parent412 * autofs super block info.413 *414 * If setting the autofs super block expire timeout the autofs_dev_ioctl415 * size field will be equal to the autofs_dev_ioctl structure size. If416 * setting the per-dentry expire timeout the mount point name is passed417 * in the autofs_dev_ioctl path field and the size field updated to418 * reflect this.419 *420 * Setting the autofs mount expire timeout sets the timeout in the super421 * block info. struct. Setting the per-dentry timeout does a little more.422 * If the timeout is equal to -1 the per-dentry timeout (and flag) is423 * cleared which reverts to using the super block timeout, otherwise if424 * timeout is 0 the timeout is set to this value and the flag is left425 * set which disables expiration for the mount point, lastly the flag426 * and the timeout are set enabling the dentry to use this timeout.427 */428static int autofs_dev_ioctl_timeout(struct file *fp,429 struct autofs_sb_info *sbi,430 struct autofs_dev_ioctl *param)431{432 unsigned long timeout = param->timeout.timeout;433 434 /* If setting the expire timeout for an individual indirect435 * mount point dentry the mount trailing component path is436 * placed in param->path and param->size adjusted to account437 * for it otherwise param->size it is set to the structure438 * size.439 */440 if (param->size == AUTOFS_DEV_IOCTL_SIZE) {441 param->timeout.timeout = sbi->exp_timeout / HZ;442 sbi->exp_timeout = timeout * HZ;443 } else {444 struct dentry *base = fp->f_path.dentry;445 struct inode *inode = base->d_inode;446 int path_len = param->size - AUTOFS_DEV_IOCTL_SIZE - 1;447 struct dentry *dentry;448 struct autofs_info *ino;449 450 if (!autofs_type_indirect(sbi->type))451 return -EINVAL;452 453 /* An expire timeout greater than the superblock timeout454 * could be a problem at shutdown but the super block455 * timeout itself can change so all we can really do is456 * warn the user.457 */458 if (timeout >= sbi->exp_timeout)459 pr_warn("per-mount expire timeout is greater than "460 "the parent autofs mount timeout which could "461 "prevent shutdown\n");462 463 inode_lock_shared(inode);464 dentry = try_lookup_one_len(param->path, base, path_len);465 inode_unlock_shared(inode);466 if (IS_ERR_OR_NULL(dentry))467 return dentry ? PTR_ERR(dentry) : -ENOENT;468 ino = autofs_dentry_ino(dentry);469 if (!ino) {470 dput(dentry);471 return -ENOENT;472 }473 474 if (ino->exp_timeout && ino->flags & AUTOFS_INF_EXPIRE_SET)475 param->timeout.timeout = ino->exp_timeout / HZ;476 else477 param->timeout.timeout = sbi->exp_timeout / HZ;478 479 if (timeout == -1) {480 /* Revert to using the super block timeout */481 ino->flags &= ~AUTOFS_INF_EXPIRE_SET;482 ino->exp_timeout = 0;483 } else {484 /* Set the dentry expire flag and timeout.485 *486 * If timeout is 0 it will prevent the expire487 * of this particular automount.488 */489 ino->flags |= AUTOFS_INF_EXPIRE_SET;490 ino->exp_timeout = timeout * HZ;491 }492 dput(dentry);493 }494 495 return 0;496}497 498/*499 * Return the uid and gid of the last request for the mount500 *501 * When reconstructing an autofs mount tree with active mounts502 * we need to re-connect to mounts that may have used the original503 * process uid and gid (or string variations of them) for mount504 * lookups within the map entry.505 */506static int autofs_dev_ioctl_requester(struct file *fp,507 struct autofs_sb_info *sbi,508 struct autofs_dev_ioctl *param)509{510 struct autofs_info *ino;511 struct path path;512 dev_t devid;513 int err = -ENOENT;514 515 /* param->path has been checked in validate_dev_ioctl() */516 517 devid = sbi->sb->s_dev;518 519 param->requester.uid = param->requester.gid = -1;520 521 err = find_autofs_mount(param->path, &path, test_by_dev, &devid);522 if (err)523 goto out;524 525 ino = autofs_dentry_ino(path.dentry);526 if (ino) {527 err = 0;528 autofs_expire_wait(&path, 0);529 spin_lock(&sbi->fs_lock);530 param->requester.uid =531 from_kuid_munged(current_user_ns(), ino->uid);532 param->requester.gid =533 from_kgid_munged(current_user_ns(), ino->gid);534 spin_unlock(&sbi->fs_lock);535 }536 path_put(&path);537out:538 return err;539}540 541/*542 * Call repeatedly until it returns -EAGAIN, meaning there's nothing543 * more that can be done.544 */545static int autofs_dev_ioctl_expire(struct file *fp,546 struct autofs_sb_info *sbi,547 struct autofs_dev_ioctl *param)548{549 struct vfsmount *mnt;550 int how;551 552 how = param->expire.how;553 mnt = fp->f_path.mnt;554 555 return autofs_do_expire_multi(sbi->sb, mnt, sbi, how);556}557 558/* Check if autofs mount point is in use */559static int autofs_dev_ioctl_askumount(struct file *fp,560 struct autofs_sb_info *sbi,561 struct autofs_dev_ioctl *param)562{563 param->askumount.may_umount = 0;564 if (may_umount(fp->f_path.mnt))565 param->askumount.may_umount = 1;566 return 0;567}568 569/*570 * Check if the given path is a mountpoint.571 *572 * If we are supplied with the file descriptor of an autofs573 * mount we're looking for a specific mount. In this case574 * the path is considered a mountpoint if it is itself a575 * mountpoint or contains a mount, such as a multi-mount576 * without a root mount. In this case we return 1 if the577 * path is a mount point and the super magic of the covering578 * mount if there is one or 0 if it isn't a mountpoint.579 *580 * If we aren't supplied with a file descriptor then we581 * lookup the path and check if it is the root of a mount.582 * If a type is given we are looking for a particular autofs583 * mount and if we don't find a match we return fail. If the584 * located path is the root of a mount we return 1 along with585 * the super magic of the mount or 0 otherwise.586 *587 * In both cases the device number (as returned by588 * new_encode_dev()) is also returned.589 */590static int autofs_dev_ioctl_ismountpoint(struct file *fp,591 struct autofs_sb_info *sbi,592 struct autofs_dev_ioctl *param)593{594 struct path path;595 const char *name;596 unsigned int type;597 unsigned int devid, magic;598 int err = -ENOENT;599 600 /* param->path has been checked in validate_dev_ioctl() */601 602 name = param->path;603 type = param->ismountpoint.in.type;604 605 param->ismountpoint.out.devid = devid = 0;606 param->ismountpoint.out.magic = magic = 0;607 608 if (!fp || param->ioctlfd == -1) {609 if (autofs_type_any(type))610 err = kern_path(name, LOOKUP_FOLLOW | LOOKUP_MOUNTPOINT,611 &path);612 else613 err = find_autofs_mount(name, &path,614 test_by_type, &type);615 if (err)616 goto out;617 devid = new_encode_dev(path.dentry->d_sb->s_dev);618 err = 0;619 if (path.mnt->mnt_root == path.dentry) {620 err = 1;621 magic = path.dentry->d_sb->s_magic;622 }623 } else {624 dev_t dev = sbi->sb->s_dev;625 626 err = find_autofs_mount(name, &path, test_by_dev, &dev);627 if (err)628 goto out;629 630 devid = new_encode_dev(dev);631 632 err = path_has_submounts(&path);633 634 if (follow_down_one(&path))635 magic = path.dentry->d_sb->s_magic;636 }637 638 param->ismountpoint.out.devid = devid;639 param->ismountpoint.out.magic = magic;640 path_put(&path);641out:642 return err;643}644 645/*646 * Our range of ioctl numbers isn't 0 based so we need to shift647 * the array index by _IOC_NR(AUTOFS_CTL_IOC_FIRST) for the table648 * lookup.649 */650#define cmd_idx(cmd) (cmd - _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST))651 652static ioctl_fn lookup_dev_ioctl(unsigned int cmd)653{654 static const ioctl_fn _ioctls[] = {655 autofs_dev_ioctl_version,656 autofs_dev_ioctl_protover,657 autofs_dev_ioctl_protosubver,658 autofs_dev_ioctl_openmount,659 autofs_dev_ioctl_closemount,660 autofs_dev_ioctl_ready,661 autofs_dev_ioctl_fail,662 autofs_dev_ioctl_setpipefd,663 autofs_dev_ioctl_catatonic,664 autofs_dev_ioctl_timeout,665 autofs_dev_ioctl_requester,666 autofs_dev_ioctl_expire,667 autofs_dev_ioctl_askumount,668 autofs_dev_ioctl_ismountpoint,669 };670 unsigned int idx = cmd_idx(cmd);671 672 if (idx >= ARRAY_SIZE(_ioctls))673 return NULL;674 idx = array_index_nospec(idx, ARRAY_SIZE(_ioctls));675 return _ioctls[idx];676}677 678/* ioctl dispatcher */679static int _autofs_dev_ioctl(unsigned int command,680 struct autofs_dev_ioctl __user *user)681{682 struct autofs_dev_ioctl *param;683 struct file *fp;684 struct autofs_sb_info *sbi;685 unsigned int cmd_first, cmd;686 ioctl_fn fn = NULL;687 int err = 0;688 689 cmd_first = _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST);690 cmd = _IOC_NR(command);691 692 if (_IOC_TYPE(command) != _IOC_TYPE(AUTOFS_DEV_IOCTL_IOC_FIRST) ||693 cmd - cmd_first > AUTOFS_DEV_IOCTL_IOC_COUNT) {694 return -ENOTTY;695 }696 697 /* Only root can use ioctls other than AUTOFS_DEV_IOCTL_VERSION_CMD698 * and AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD699 */700 if (cmd != AUTOFS_DEV_IOCTL_VERSION_CMD &&701 cmd != AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD &&702 !capable(CAP_SYS_ADMIN))703 return -EPERM;704 705 /* Copy the parameters into kernel space. */706 param = copy_dev_ioctl(user);707 if (IS_ERR(param))708 return PTR_ERR(param);709 710 err = validate_dev_ioctl(command, param);711 if (err)712 goto out;713 714 fn = lookup_dev_ioctl(cmd);715 if (!fn) {716 pr_warn("unknown command 0x%08x\n", command);717 err = -ENOTTY;718 goto out;719 }720 721 fp = NULL;722 sbi = NULL;723 724 /*725 * For obvious reasons the openmount can't have a file726 * descriptor yet. We don't take a reference to the727 * file during close to allow for immediate release,728 * and the same for retrieving ioctl version.729 */730 if (cmd != AUTOFS_DEV_IOCTL_VERSION_CMD &&731 cmd != AUTOFS_DEV_IOCTL_OPENMOUNT_CMD &&732 cmd != AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD) {733 struct super_block *sb;734 735 fp = fget(param->ioctlfd);736 if (!fp) {737 if (cmd == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD)738 goto cont;739 err = -EBADF;740 goto out;741 }742 743 sb = file_inode(fp)->i_sb;744 if (sb->s_type != &autofs_fs_type) {745 err = -EINVAL;746 fput(fp);747 goto out;748 }749 sbi = autofs_sbi(sb);750 751 /*752 * Admin needs to be able to set the mount catatonic in753 * order to be able to perform the re-open.754 */755 if (!autofs_oz_mode(sbi) &&756 cmd != AUTOFS_DEV_IOCTL_CATATONIC_CMD) {757 err = -EACCES;758 fput(fp);759 goto out;760 }761 }762cont:763 err = fn(fp, sbi, param);764 765 if (fp)766 fput(fp);767 if (err >= 0 && copy_to_user(user, param, AUTOFS_DEV_IOCTL_SIZE))768 err = -EFAULT;769out:770 free_dev_ioctl(param);771 return err;772}773 774static long autofs_dev_ioctl(struct file *file, unsigned int command,775 unsigned long u)776{777 int err;778 779 err = _autofs_dev_ioctl(command, (struct autofs_dev_ioctl __user *) u);780 return (long) err;781}782 783#ifdef CONFIG_COMPAT784static long autofs_dev_ioctl_compat(struct file *file, unsigned int command,785 unsigned long u)786{787 return autofs_dev_ioctl(file, command, (unsigned long) compat_ptr(u));788}789#else790#define autofs_dev_ioctl_compat NULL791#endif792 793static const struct file_operations _dev_ioctl_fops = {794 .unlocked_ioctl = autofs_dev_ioctl,795 .compat_ioctl = autofs_dev_ioctl_compat,796 .owner = THIS_MODULE,797 .llseek = noop_llseek,798};799 800static struct miscdevice _autofs_dev_ioctl_misc = {801 .minor = AUTOFS_MINOR,802 .name = AUTOFS_DEVICE_NAME,803 .fops = &_dev_ioctl_fops,804 .mode = 0644,805};806 807MODULE_ALIAS_MISCDEV(AUTOFS_MINOR);808MODULE_ALIAS("devname:autofs");809 810/* Register/deregister misc character device */811int __init autofs_dev_ioctl_init(void)812{813 int r;814 815 r = misc_register(&_autofs_dev_ioctl_misc);816 if (r) {817 pr_err("misc_register failed for control device\n");818 return r;819 }820 821 return 0;822}823 824void autofs_dev_ioctl_exit(void)825{826 misc_deregister(&_autofs_dev_ioctl_misc);827}828