Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 4dfd459b738cf1f65b3eac4e0a9b19bc93cc91c6 765 lines 19 kB view raw
1/* 2 * Copyright 2008 Red Hat, Inc. All rights reserved. 3 * Copyright 2008 Ian Kent <raven@themaw.net> 4 * 5 * This file is part of the Linux kernel and is made available under 6 * the terms of the GNU General Public License, version 2, or at your 7 * option, any later version, incorporated herein by reference. 8 */ 9 10#include <linux/module.h> 11#include <linux/vmalloc.h> 12#include <linux/miscdevice.h> 13#include <linux/init.h> 14#include <linux/wait.h> 15#include <linux/namei.h> 16#include <linux/fcntl.h> 17#include <linux/file.h> 18#include <linux/fdtable.h> 19#include <linux/sched.h> 20#include <linux/compat.h> 21#include <linux/syscalls.h> 22#include <linux/magic.h> 23#include <linux/dcache.h> 24#include <linux/uaccess.h> 25 26#include "autofs_i.h" 27 28/* 29 * This module implements an interface for routing autofs ioctl control 30 * commands via a miscellaneous device file. 31 * 32 * The alternate interface is needed because we need to be able open 33 * an ioctl file descriptor on an autofs mount that may be covered by 34 * another mount. This situation arises when starting automount(8) 35 * or other user space daemon which uses direct mounts or offset 36 * mounts (used for autofs lazy mount/umount of nested mount trees), 37 * which have been left busy at at service shutdown. 38 */ 39 40#define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl) 41 42typedef int (*ioctl_fn)(struct file *, struct autofs_sb_info *, 43 struct autofs_dev_ioctl *); 44 45static int check_name(const char *name) 46{ 47 if (!strchr(name, '/')) 48 return -EINVAL; 49 return 0; 50} 51 52/* 53 * Check a string doesn't overrun the chunk of 54 * memory we copied from user land. 55 */ 56static int invalid_str(char *str, size_t size) 57{ 58 if (memchr(str, 0, size)) 59 return 0; 60 return -EINVAL; 61} 62 63/* 64 * Check that the user compiled against correct version of autofs 65 * misc device code. 66 * 67 * As well as checking the version compatibility this always copies 68 * the kernel interface version out. 69 */ 70static int check_dev_ioctl_version(int cmd, struct autofs_dev_ioctl *param) 71{ 72 int err = 0; 73 74 if ((AUTOFS_DEV_IOCTL_VERSION_MAJOR != param->ver_major) || 75 (AUTOFS_DEV_IOCTL_VERSION_MINOR < param->ver_minor)) { 76 AUTOFS_WARN("ioctl control interface version mismatch: " 77 "kernel(%u.%u), user(%u.%u), cmd(%d)", 78 AUTOFS_DEV_IOCTL_VERSION_MAJOR, 79 AUTOFS_DEV_IOCTL_VERSION_MINOR, 80 param->ver_major, param->ver_minor, cmd); 81 err = -EINVAL; 82 } 83 84 /* Fill in the kernel version. */ 85 param->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR; 86 param->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR; 87 88 return err; 89} 90 91/* 92 * Copy parameter control struct, including a possible path allocated 93 * at the end of the struct. 94 */ 95static struct autofs_dev_ioctl *copy_dev_ioctl(struct autofs_dev_ioctl __user *in) 96{ 97 struct autofs_dev_ioctl tmp, *ads; 98 99 if (copy_from_user(&tmp, in, sizeof(tmp))) 100 return ERR_PTR(-EFAULT); 101 102 if (tmp.size < sizeof(tmp)) 103 return ERR_PTR(-EINVAL); 104 105 ads = kmalloc(tmp.size, GFP_KERNEL); 106 if (!ads) 107 return ERR_PTR(-ENOMEM); 108 109 if (copy_from_user(ads, in, tmp.size)) { 110 kfree(ads); 111 return ERR_PTR(-EFAULT); 112 } 113 114 return ads; 115} 116 117static inline void free_dev_ioctl(struct autofs_dev_ioctl *param) 118{ 119 kfree(param); 120 return; 121} 122 123/* 124 * Check sanity of parameter control fields and if a path is present 125 * check that it is terminated and contains at least one "/". 126 */ 127static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param) 128{ 129 int err; 130 131 err = check_dev_ioctl_version(cmd, param); 132 if (err) { 133 AUTOFS_WARN("invalid device control module version " 134 "supplied for cmd(0x%08x)", cmd); 135 goto out; 136 } 137 138 if (param->size > sizeof(*param)) { 139 err = invalid_str(param->path, param->size - sizeof(*param)); 140 if (err) { 141 AUTOFS_WARN( 142 "path string terminator missing for cmd(0x%08x)", 143 cmd); 144 goto out; 145 } 146 147 err = check_name(param->path); 148 if (err) { 149 AUTOFS_WARN("invalid path supplied for cmd(0x%08x)", 150 cmd); 151 goto out; 152 } 153 } 154 155 err = 0; 156out: 157 return err; 158} 159 160/* 161 * Get the autofs super block info struct from the file opened on 162 * the autofs mount point. 163 */ 164static struct autofs_sb_info *autofs_dev_ioctl_sbi(struct file *f) 165{ 166 struct autofs_sb_info *sbi = NULL; 167 struct inode *inode; 168 169 if (f) { 170 inode = f->f_path.dentry->d_inode; 171 sbi = autofs4_sbi(inode->i_sb); 172 } 173 return sbi; 174} 175 176/* Return autofs module protocol version */ 177static int autofs_dev_ioctl_protover(struct file *fp, 178 struct autofs_sb_info *sbi, 179 struct autofs_dev_ioctl *param) 180{ 181 param->protover.version = sbi->version; 182 return 0; 183} 184 185/* Return autofs module protocol sub version */ 186static int autofs_dev_ioctl_protosubver(struct file *fp, 187 struct autofs_sb_info *sbi, 188 struct autofs_dev_ioctl *param) 189{ 190 param->protosubver.sub_version = sbi->sub_version; 191 return 0; 192} 193 194static int find_autofs_mount(const char *pathname, 195 struct path *res, 196 int test(struct path *path, void *data), 197 void *data) 198{ 199 struct path path; 200 int err = kern_path(pathname, 0, &path); 201 if (err) 202 return err; 203 err = -ENOENT; 204 while (path.dentry == path.mnt->mnt_root) { 205 if (path.mnt->mnt_sb->s_magic == AUTOFS_SUPER_MAGIC) { 206 if (test(&path, data)) { 207 path_get(&path); 208 if (!err) /* already found some */ 209 path_put(res); 210 *res = path; 211 err = 0; 212 } 213 } 214 if (!follow_up(&path)) 215 break; 216 } 217 path_put(&path); 218 return err; 219} 220 221static int test_by_dev(struct path *path, void *p) 222{ 223 return path->mnt->mnt_sb->s_dev == *(dev_t *)p; 224} 225 226static int test_by_type(struct path *path, void *p) 227{ 228 struct autofs_info *ino = autofs4_dentry_ino(path->dentry); 229 return ino && ino->sbi->type & *(unsigned *)p; 230} 231 232static void autofs_dev_ioctl_fd_install(unsigned int fd, struct file *file) 233{ 234 struct files_struct *files = current->files; 235 struct fdtable *fdt; 236 237 spin_lock(&files->file_lock); 238 fdt = files_fdtable(files); 239 BUG_ON(fdt->fd[fd] != NULL); 240 rcu_assign_pointer(fdt->fd[fd], file); 241 FD_SET(fd, fdt->close_on_exec); 242 spin_unlock(&files->file_lock); 243} 244 245 246/* 247 * Open a file descriptor on the autofs mount point corresponding 248 * to the given path and device number (aka. new_encode_dev(sb->s_dev)). 249 */ 250static int autofs_dev_ioctl_open_mountpoint(const char *name, dev_t devid) 251{ 252 int err, fd; 253 254 fd = get_unused_fd(); 255 if (likely(fd >= 0)) { 256 struct file *filp; 257 struct path path; 258 259 err = find_autofs_mount(name, &path, test_by_dev, &devid); 260 if (err) 261 goto out; 262 263 /* 264 * Find autofs super block that has the device number 265 * corresponding to the autofs fs we want to open. 266 */ 267 268 filp = dentry_open(path.dentry, path.mnt, O_RDONLY, 269 current_cred()); 270 if (IS_ERR(filp)) { 271 err = PTR_ERR(filp); 272 goto out; 273 } 274 275 autofs_dev_ioctl_fd_install(fd, filp); 276 } 277 278 return fd; 279 280out: 281 put_unused_fd(fd); 282 return err; 283} 284 285/* Open a file descriptor on an autofs mount point */ 286static int autofs_dev_ioctl_openmount(struct file *fp, 287 struct autofs_sb_info *sbi, 288 struct autofs_dev_ioctl *param) 289{ 290 const char *path; 291 dev_t devid; 292 int err, fd; 293 294 /* param->path has already been checked */ 295 if (!param->openmount.devid) 296 return -EINVAL; 297 298 param->ioctlfd = -1; 299 300 path = param->path; 301 devid = new_decode_dev(param->openmount.devid); 302 303 err = 0; 304 fd = autofs_dev_ioctl_open_mountpoint(path, devid); 305 if (unlikely(fd < 0)) { 306 err = fd; 307 goto out; 308 } 309 310 param->ioctlfd = fd; 311out: 312 return err; 313} 314 315/* Close file descriptor allocated above (user can also use close(2)). */ 316static int autofs_dev_ioctl_closemount(struct file *fp, 317 struct autofs_sb_info *sbi, 318 struct autofs_dev_ioctl *param) 319{ 320 return sys_close(param->ioctlfd); 321} 322 323/* 324 * Send "ready" status for an existing wait (either a mount or an expire 325 * request). 326 */ 327static int autofs_dev_ioctl_ready(struct file *fp, 328 struct autofs_sb_info *sbi, 329 struct autofs_dev_ioctl *param) 330{ 331 autofs_wqt_t token; 332 333 token = (autofs_wqt_t) param->ready.token; 334 return autofs4_wait_release(sbi, token, 0); 335} 336 337/* 338 * Send "fail" status for an existing wait (either a mount or an expire 339 * request). 340 */ 341static int autofs_dev_ioctl_fail(struct file *fp, 342 struct autofs_sb_info *sbi, 343 struct autofs_dev_ioctl *param) 344{ 345 autofs_wqt_t token; 346 int status; 347 348 token = (autofs_wqt_t) param->fail.token; 349 status = param->fail.status ? param->fail.status : -ENOENT; 350 return autofs4_wait_release(sbi, token, status); 351} 352 353/* 354 * Set the pipe fd for kernel communication to the daemon. 355 * 356 * Normally this is set at mount using an option but if we 357 * are reconnecting to a busy mount then we need to use this 358 * to tell the autofs mount about the new kernel pipe fd. In 359 * order to protect mounts against incorrectly setting the 360 * pipefd we also require that the autofs mount be catatonic. 361 * 362 * This also sets the process group id used to identify the 363 * controlling process (eg. the owning automount(8) daemon). 364 */ 365static int autofs_dev_ioctl_setpipefd(struct file *fp, 366 struct autofs_sb_info *sbi, 367 struct autofs_dev_ioctl *param) 368{ 369 int pipefd; 370 int err = 0; 371 372 if (param->setpipefd.pipefd == -1) 373 return -EINVAL; 374 375 pipefd = param->setpipefd.pipefd; 376 377 mutex_lock(&sbi->wq_mutex); 378 if (!sbi->catatonic) { 379 mutex_unlock(&sbi->wq_mutex); 380 return -EBUSY; 381 } else { 382 struct file *pipe = fget(pipefd); 383 if (!pipe->f_op || !pipe->f_op->write) { 384 err = -EPIPE; 385 fput(pipe); 386 goto out; 387 } 388 sbi->oz_pgrp = task_pgrp_nr(current); 389 sbi->pipefd = pipefd; 390 sbi->pipe = pipe; 391 sbi->catatonic = 0; 392 } 393out: 394 mutex_unlock(&sbi->wq_mutex); 395 return err; 396} 397 398/* 399 * Make the autofs mount point catatonic, no longer responsive to 400 * mount requests. Also closes the kernel pipe file descriptor. 401 */ 402static int autofs_dev_ioctl_catatonic(struct file *fp, 403 struct autofs_sb_info *sbi, 404 struct autofs_dev_ioctl *param) 405{ 406 autofs4_catatonic_mode(sbi); 407 return 0; 408} 409 410/* Set the autofs mount timeout */ 411static int autofs_dev_ioctl_timeout(struct file *fp, 412 struct autofs_sb_info *sbi, 413 struct autofs_dev_ioctl *param) 414{ 415 unsigned long timeout; 416 417 timeout = param->timeout.timeout; 418 param->timeout.timeout = sbi->exp_timeout / HZ; 419 sbi->exp_timeout = timeout * HZ; 420 return 0; 421} 422 423/* 424 * Return the uid and gid of the last request for the mount 425 * 426 * When reconstructing an autofs mount tree with active mounts 427 * we need to re-connect to mounts that may have used the original 428 * process uid and gid (or string variations of them) for mount 429 * lookups within the map entry. 430 */ 431static int autofs_dev_ioctl_requester(struct file *fp, 432 struct autofs_sb_info *sbi, 433 struct autofs_dev_ioctl *param) 434{ 435 struct autofs_info *ino; 436 struct path path; 437 dev_t devid; 438 int err = -ENOENT; 439 440 if (param->size <= sizeof(*param)) { 441 err = -EINVAL; 442 goto out; 443 } 444 445 devid = sbi->sb->s_dev; 446 447 param->requester.uid = param->requester.gid = -1; 448 449 err = find_autofs_mount(param->path, &path, test_by_dev, &devid); 450 if (err) 451 goto out; 452 453 ino = autofs4_dentry_ino(path.dentry); 454 if (ino) { 455 err = 0; 456 autofs4_expire_wait(path.dentry); 457 spin_lock(&sbi->fs_lock); 458 param->requester.uid = ino->uid; 459 param->requester.gid = ino->gid; 460 spin_unlock(&sbi->fs_lock); 461 } 462 path_put(&path); 463out: 464 return err; 465} 466 467/* 468 * Call repeatedly until it returns -EAGAIN, meaning there's nothing 469 * more that can be done. 470 */ 471static int autofs_dev_ioctl_expire(struct file *fp, 472 struct autofs_sb_info *sbi, 473 struct autofs_dev_ioctl *param) 474{ 475 struct vfsmount *mnt; 476 int how; 477 478 how = param->expire.how; 479 mnt = fp->f_path.mnt; 480 481 return autofs4_do_expire_multi(sbi->sb, mnt, sbi, how); 482} 483 484/* Check if autofs mount point is in use */ 485static int autofs_dev_ioctl_askumount(struct file *fp, 486 struct autofs_sb_info *sbi, 487 struct autofs_dev_ioctl *param) 488{ 489 param->askumount.may_umount = 0; 490 if (may_umount(fp->f_path.mnt)) 491 param->askumount.may_umount = 1; 492 return 0; 493} 494 495/* 496 * Check if the given path is a mountpoint. 497 * 498 * If we are supplied with the file descriptor of an autofs 499 * mount we're looking for a specific mount. In this case 500 * the path is considered a mountpoint if it is itself a 501 * mountpoint or contains a mount, such as a multi-mount 502 * without a root mount. In this case we return 1 if the 503 * path is a mount point and the super magic of the covering 504 * mount if there is one or 0 if it isn't a mountpoint. 505 * 506 * If we aren't supplied with a file descriptor then we 507 * lookup the nameidata of the path and check if it is the 508 * root of a mount. If a type is given we are looking for 509 * a particular autofs mount and if we don't find a match 510 * we return fail. If the located nameidata path is the 511 * root of a mount we return 1 along with the super magic 512 * of the mount or 0 otherwise. 513 * 514 * In both cases the the device number (as returned by 515 * new_encode_dev()) is also returned. 516 */ 517static int autofs_dev_ioctl_ismountpoint(struct file *fp, 518 struct autofs_sb_info *sbi, 519 struct autofs_dev_ioctl *param) 520{ 521 struct path path; 522 const char *name; 523 unsigned int type; 524 unsigned int devid, magic; 525 int err = -ENOENT; 526 527 if (param->size <= sizeof(*param)) { 528 err = -EINVAL; 529 goto out; 530 } 531 532 name = param->path; 533 type = param->ismountpoint.in.type; 534 535 param->ismountpoint.out.devid = devid = 0; 536 param->ismountpoint.out.magic = magic = 0; 537 538 if (!fp || param->ioctlfd == -1) { 539 if (autofs_type_any(type)) 540 err = kern_path(name, LOOKUP_FOLLOW, &path); 541 else 542 err = find_autofs_mount(name, &path, test_by_type, &type); 543 if (err) 544 goto out; 545 devid = new_encode_dev(path.mnt->mnt_sb->s_dev); 546 err = 0; 547 if (path.dentry->d_inode && 548 path.mnt->mnt_root == path.dentry) { 549 err = 1; 550 magic = path.dentry->d_inode->i_sb->s_magic; 551 } 552 } else { 553 dev_t dev = sbi->sb->s_dev; 554 555 err = find_autofs_mount(name, &path, test_by_dev, &dev); 556 if (err) 557 goto out; 558 559 devid = new_encode_dev(dev); 560 561 err = have_submounts(path.dentry); 562 563 if (path.mnt->mnt_mountpoint != path.mnt->mnt_root) { 564 if (follow_down(&path)) 565 magic = path.mnt->mnt_sb->s_magic; 566 } 567 } 568 569 param->ismountpoint.out.devid = devid; 570 param->ismountpoint.out.magic = magic; 571 path_put(&path); 572out: 573 return err; 574} 575 576/* 577 * Our range of ioctl numbers isn't 0 based so we need to shift 578 * the array index by _IOC_NR(AUTOFS_CTL_IOC_FIRST) for the table 579 * lookup. 580 */ 581#define cmd_idx(cmd) (cmd - _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST)) 582 583static ioctl_fn lookup_dev_ioctl(unsigned int cmd) 584{ 585 static struct { 586 int cmd; 587 ioctl_fn fn; 588 } _ioctls[] = { 589 {cmd_idx(AUTOFS_DEV_IOCTL_VERSION_CMD), NULL}, 590 {cmd_idx(AUTOFS_DEV_IOCTL_PROTOVER_CMD), 591 autofs_dev_ioctl_protover}, 592 {cmd_idx(AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD), 593 autofs_dev_ioctl_protosubver}, 594 {cmd_idx(AUTOFS_DEV_IOCTL_OPENMOUNT_CMD), 595 autofs_dev_ioctl_openmount}, 596 {cmd_idx(AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD), 597 autofs_dev_ioctl_closemount}, 598 {cmd_idx(AUTOFS_DEV_IOCTL_READY_CMD), 599 autofs_dev_ioctl_ready}, 600 {cmd_idx(AUTOFS_DEV_IOCTL_FAIL_CMD), 601 autofs_dev_ioctl_fail}, 602 {cmd_idx(AUTOFS_DEV_IOCTL_SETPIPEFD_CMD), 603 autofs_dev_ioctl_setpipefd}, 604 {cmd_idx(AUTOFS_DEV_IOCTL_CATATONIC_CMD), 605 autofs_dev_ioctl_catatonic}, 606 {cmd_idx(AUTOFS_DEV_IOCTL_TIMEOUT_CMD), 607 autofs_dev_ioctl_timeout}, 608 {cmd_idx(AUTOFS_DEV_IOCTL_REQUESTER_CMD), 609 autofs_dev_ioctl_requester}, 610 {cmd_idx(AUTOFS_DEV_IOCTL_EXPIRE_CMD), 611 autofs_dev_ioctl_expire}, 612 {cmd_idx(AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD), 613 autofs_dev_ioctl_askumount}, 614 {cmd_idx(AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD), 615 autofs_dev_ioctl_ismountpoint} 616 }; 617 unsigned int idx = cmd_idx(cmd); 618 619 return (idx >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[idx].fn; 620} 621 622/* ioctl dispatcher */ 623static int _autofs_dev_ioctl(unsigned int command, struct autofs_dev_ioctl __user *user) 624{ 625 struct autofs_dev_ioctl *param; 626 struct file *fp; 627 struct autofs_sb_info *sbi; 628 unsigned int cmd_first, cmd; 629 ioctl_fn fn = NULL; 630 int err = 0; 631 632 /* only root can play with this */ 633 if (!capable(CAP_SYS_ADMIN)) 634 return -EPERM; 635 636 cmd_first = _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST); 637 cmd = _IOC_NR(command); 638 639 if (_IOC_TYPE(command) != _IOC_TYPE(AUTOFS_DEV_IOCTL_IOC_FIRST) || 640 cmd - cmd_first >= AUTOFS_DEV_IOCTL_IOC_COUNT) { 641 return -ENOTTY; 642 } 643 644 /* Copy the parameters into kernel space. */ 645 param = copy_dev_ioctl(user); 646 if (IS_ERR(param)) 647 return PTR_ERR(param); 648 649 err = validate_dev_ioctl(command, param); 650 if (err) 651 goto out; 652 653 /* The validate routine above always sets the version */ 654 if (cmd == AUTOFS_DEV_IOCTL_VERSION_CMD) 655 goto done; 656 657 fn = lookup_dev_ioctl(cmd); 658 if (!fn) { 659 AUTOFS_WARN("unknown command 0x%08x", command); 660 return -ENOTTY; 661 } 662 663 fp = NULL; 664 sbi = NULL; 665 666 /* 667 * For obvious reasons the openmount can't have a file 668 * descriptor yet. We don't take a reference to the 669 * file during close to allow for immediate release. 670 */ 671 if (cmd != AUTOFS_DEV_IOCTL_OPENMOUNT_CMD && 672 cmd != AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD) { 673 fp = fget(param->ioctlfd); 674 if (!fp) { 675 if (cmd == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD) 676 goto cont; 677 err = -EBADF; 678 goto out; 679 } 680 681 if (!fp->f_op) { 682 err = -ENOTTY; 683 fput(fp); 684 goto out; 685 } 686 687 sbi = autofs_dev_ioctl_sbi(fp); 688 if (!sbi || sbi->magic != AUTOFS_SBI_MAGIC) { 689 err = -EINVAL; 690 fput(fp); 691 goto out; 692 } 693 694 /* 695 * Admin needs to be able to set the mount catatonic in 696 * order to be able to perform the re-open. 697 */ 698 if (!autofs4_oz_mode(sbi) && 699 cmd != AUTOFS_DEV_IOCTL_CATATONIC_CMD) { 700 err = -EACCES; 701 fput(fp); 702 goto out; 703 } 704 } 705cont: 706 err = fn(fp, sbi, param); 707 708 if (fp) 709 fput(fp); 710done: 711 if (err >= 0 && copy_to_user(user, param, AUTOFS_DEV_IOCTL_SIZE)) 712 err = -EFAULT; 713out: 714 free_dev_ioctl(param); 715 return err; 716} 717 718static long autofs_dev_ioctl(struct file *file, uint command, ulong u) 719{ 720 int err; 721 err = _autofs_dev_ioctl(command, (struct autofs_dev_ioctl __user *) u); 722 return (long) err; 723} 724 725#ifdef CONFIG_COMPAT 726static long autofs_dev_ioctl_compat(struct file *file, uint command, ulong u) 727{ 728 return (long) autofs_dev_ioctl(file, command, (ulong) compat_ptr(u)); 729} 730#else 731#define autofs_dev_ioctl_compat NULL 732#endif 733 734static const struct file_operations _dev_ioctl_fops = { 735 .unlocked_ioctl = autofs_dev_ioctl, 736 .compat_ioctl = autofs_dev_ioctl_compat, 737 .owner = THIS_MODULE, 738}; 739 740static struct miscdevice _autofs_dev_ioctl_misc = { 741 .minor = MISC_DYNAMIC_MINOR, 742 .name = AUTOFS_DEVICE_NAME, 743 .fops = &_dev_ioctl_fops 744}; 745 746/* Register/deregister misc character device */ 747int autofs_dev_ioctl_init(void) 748{ 749 int r; 750 751 r = misc_register(&_autofs_dev_ioctl_misc); 752 if (r) { 753 AUTOFS_ERROR("misc_register failed for control device"); 754 return r; 755 } 756 757 return 0; 758} 759 760void autofs_dev_ioctl_exit(void) 761{ 762 misc_deregister(&_autofs_dev_ioctl_misc); 763 return; 764} 765