aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/autofs4/dev-ioctl.c54
-rw-r--r--include/linux/auto_dev-ioctl.h75
2 files changed, 100 insertions, 29 deletions
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index 63b7c7afe8df..054d6d9ad9ba 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -180,7 +180,7 @@ static int autofs_dev_ioctl_protover(struct file *fp,
180 struct autofs_sb_info *sbi, 180 struct autofs_sb_info *sbi,
181 struct autofs_dev_ioctl *param) 181 struct autofs_dev_ioctl *param)
182{ 182{
183 param->arg1 = sbi->version; 183 param->protover.version = sbi->version;
184 return 0; 184 return 0;
185} 185}
186 186
@@ -189,7 +189,7 @@ static int autofs_dev_ioctl_protosubver(struct file *fp,
189 struct autofs_sb_info *sbi, 189 struct autofs_sb_info *sbi,
190 struct autofs_dev_ioctl *param) 190 struct autofs_dev_ioctl *param)
191{ 191{
192 param->arg1 = sbi->sub_version; 192 param->protosubver.sub_version = sbi->sub_version;
193 return 0; 193 return 0;
194} 194}
195 195
@@ -335,13 +335,13 @@ static int autofs_dev_ioctl_openmount(struct file *fp,
335 int err, fd; 335 int err, fd;
336 336
337 /* param->path has already been checked */ 337 /* param->path has already been checked */
338 if (!param->arg1) 338 if (!param->openmount.devid)
339 return -EINVAL; 339 return -EINVAL;
340 340
341 param->ioctlfd = -1; 341 param->ioctlfd = -1;
342 342
343 path = param->path; 343 path = param->path;
344 devid = param->arg1; 344 devid = param->openmount.devid;
345 345
346 err = 0; 346 err = 0;
347 fd = autofs_dev_ioctl_open_mountpoint(path, devid); 347 fd = autofs_dev_ioctl_open_mountpoint(path, devid);
@@ -373,7 +373,7 @@ static int autofs_dev_ioctl_ready(struct file *fp,
373{ 373{
374 autofs_wqt_t token; 374 autofs_wqt_t token;
375 375
376 token = (autofs_wqt_t) param->arg1; 376 token = (autofs_wqt_t) param->ready.token;
377 return autofs4_wait_release(sbi, token, 0); 377 return autofs4_wait_release(sbi, token, 0);
378} 378}
379 379
@@ -388,8 +388,8 @@ static int autofs_dev_ioctl_fail(struct file *fp,
388 autofs_wqt_t token; 388 autofs_wqt_t token;
389 int status; 389 int status;
390 390
391 token = (autofs_wqt_t) param->arg1; 391 token = (autofs_wqt_t) param->fail.token;
392 status = param->arg2 ? param->arg2 : -ENOENT; 392 status = param->fail.status ? param->fail.status : -ENOENT;
393 return autofs4_wait_release(sbi, token, status); 393 return autofs4_wait_release(sbi, token, status);
394} 394}
395 395
@@ -412,10 +412,10 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,
412 int pipefd; 412 int pipefd;
413 int err = 0; 413 int err = 0;
414 414
415 if (param->arg1 == -1) 415 if (param->setpipefd.pipefd == -1)
416 return -EINVAL; 416 return -EINVAL;
417 417
418 pipefd = param->arg1; 418 pipefd = param->setpipefd.pipefd;
419 419
420 mutex_lock(&sbi->wq_mutex); 420 mutex_lock(&sbi->wq_mutex);
421 if (!sbi->catatonic) { 421 if (!sbi->catatonic) {
@@ -457,8 +457,8 @@ static int autofs_dev_ioctl_timeout(struct file *fp,
457{ 457{
458 unsigned long timeout; 458 unsigned long timeout;
459 459
460 timeout = param->arg1; 460 timeout = param->timeout.timeout;
461 param->arg1 = sbi->exp_timeout / HZ; 461 param->timeout.timeout = sbi->exp_timeout / HZ;
462 sbi->exp_timeout = timeout * HZ; 462 sbi->exp_timeout = timeout * HZ;
463 return 0; 463 return 0;
464} 464}
@@ -489,7 +489,7 @@ static int autofs_dev_ioctl_requester(struct file *fp,
489 path = param->path; 489 path = param->path;
490 devid = sbi->sb->s_dev; 490 devid = sbi->sb->s_dev;
491 491
492 param->arg1 = param->arg2 = -1; 492 param->requester.uid = param->requester.gid = -1;
493 493
494 /* Get nameidata of the parent directory */ 494 /* Get nameidata of the parent directory */
495 err = path_lookup(path, LOOKUP_PARENT, &nd); 495 err = path_lookup(path, LOOKUP_PARENT, &nd);
@@ -505,8 +505,8 @@ static int autofs_dev_ioctl_requester(struct file *fp,
505 err = 0; 505 err = 0;
506 autofs4_expire_wait(nd.path.dentry); 506 autofs4_expire_wait(nd.path.dentry);
507 spin_lock(&sbi->fs_lock); 507 spin_lock(&sbi->fs_lock);
508 param->arg1 = ino->uid; 508 param->requester.uid = ino->uid;
509 param->arg2 = ino->gid; 509 param->requester.gid = ino->gid;
510 spin_unlock(&sbi->fs_lock); 510 spin_unlock(&sbi->fs_lock);
511 } 511 }
512 512
@@ -529,7 +529,7 @@ static int autofs_dev_ioctl_expire(struct file *fp,
529 int err = -EAGAIN; 529 int err = -EAGAIN;
530 int how; 530 int how;
531 531
532 how = param->arg1; 532 how = param->expire.how;
533 mnt = fp->f_path.mnt; 533 mnt = fp->f_path.mnt;
534 534
535 if (sbi->type & AUTOFS_TYPE_TRIGGER) 535 if (sbi->type & AUTOFS_TYPE_TRIGGER)
@@ -565,9 +565,9 @@ static int autofs_dev_ioctl_askumount(struct file *fp,
565 struct autofs_sb_info *sbi, 565 struct autofs_sb_info *sbi,
566 struct autofs_dev_ioctl *param) 566 struct autofs_dev_ioctl *param)
567{ 567{
568 param->arg1 = 0; 568 param->askumount.may_umount = 0;
569 if (may_umount(fp->f_path.mnt)) 569 if (may_umount(fp->f_path.mnt))
570 param->arg1 = 1; 570 param->askumount.may_umount = 1;
571 return 0; 571 return 0;
572} 572}
573 573
@@ -600,6 +600,7 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
600 struct nameidata nd; 600 struct nameidata nd;
601 const char *path; 601 const char *path;
602 unsigned int type; 602 unsigned int type;
603 unsigned int devid, magic;
603 int err = -ENOENT; 604 int err = -ENOENT;
604 605
605 if (param->size <= sizeof(*param)) { 606 if (param->size <= sizeof(*param)) {
@@ -608,10 +609,10 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
608 } 609 }
609 610
610 path = param->path; 611 path = param->path;
611 type = param->arg1; 612 type = param->ismountpoint.in.type;
612 613
613 param->arg1 = 0; 614 param->ismountpoint.out.devid = devid = 0;
614 param->arg2 = 0; 615 param->ismountpoint.out.magic = magic = 0;
615 616
616 if (!fp || param->ioctlfd == -1) { 617 if (!fp || param->ioctlfd == -1) {
617 if (type == AUTOFS_TYPE_ANY) { 618 if (type == AUTOFS_TYPE_ANY) {
@@ -622,7 +623,7 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
622 goto out; 623 goto out;
623 624
624 sb = nd.path.dentry->d_sb; 625 sb = nd.path.dentry->d_sb;
625 param->arg1 = new_encode_dev(sb->s_dev); 626 devid = new_encode_dev(sb->s_dev);
626 } else { 627 } else {
627 struct autofs_info *ino; 628 struct autofs_info *ino;
628 629
@@ -635,14 +636,14 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
635 goto out_release; 636 goto out_release;
636 637
637 ino = autofs4_dentry_ino(nd.path.dentry); 638 ino = autofs4_dentry_ino(nd.path.dentry);
638 param->arg1 = autofs4_get_dev(ino->sbi); 639 devid = autofs4_get_dev(ino->sbi);
639 } 640 }
640 641
641 err = 0; 642 err = 0;
642 if (nd.path.dentry->d_inode && 643 if (nd.path.dentry->d_inode &&
643 nd.path.mnt->mnt_root == nd.path.dentry) { 644 nd.path.mnt->mnt_root == nd.path.dentry) {
644 err = 1; 645 err = 1;
645 param->arg2 = nd.path.dentry->d_inode->i_sb->s_magic; 646 magic = nd.path.dentry->d_inode->i_sb->s_magic;
646 } 647 }
647 } else { 648 } else {
648 dev_t devid = new_encode_dev(sbi->sb->s_dev); 649 dev_t devid = new_encode_dev(sbi->sb->s_dev);
@@ -655,18 +656,21 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
655 if (err) 656 if (err)
656 goto out_release; 657 goto out_release;
657 658
658 param->arg1 = autofs4_get_dev(sbi); 659 devid = autofs4_get_dev(sbi);
659 660
660 err = have_submounts(nd.path.dentry); 661 err = have_submounts(nd.path.dentry);
661 662
662 if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) { 663 if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) {
663 if (follow_down(&nd.path.mnt, &nd.path.dentry)) { 664 if (follow_down(&nd.path.mnt, &nd.path.dentry)) {
664 struct inode *inode = nd.path.dentry->d_inode; 665 struct inode *inode = nd.path.dentry->d_inode;
665 param->arg2 = inode->i_sb->s_magic; 666 magic = inode->i_sb->s_magic;
666 } 667 }
667 } 668 }
668 } 669 }
669 670
671 param->ismountpoint.out.devid = devid;
672 param->ismountpoint.out.magic = magic;
673
670out_release: 674out_release:
671 path_put(&nd.path); 675 path_put(&nd.path);
672out: 676out:
diff --git a/include/linux/auto_dev-ioctl.h b/include/linux/auto_dev-ioctl.h
index f4d05ccd731f..91a773993a5c 100644
--- a/include/linux/auto_dev-ioctl.h
+++ b/include/linux/auto_dev-ioctl.h
@@ -10,6 +10,7 @@
10#ifndef _LINUX_AUTO_DEV_IOCTL_H 10#ifndef _LINUX_AUTO_DEV_IOCTL_H
11#define _LINUX_AUTO_DEV_IOCTL_H 11#define _LINUX_AUTO_DEV_IOCTL_H
12 12
13#include <linux/string.h>
13#include <linux/types.h> 14#include <linux/types.h>
14 15
15#define AUTOFS_DEVICE_NAME "autofs" 16#define AUTOFS_DEVICE_NAME "autofs"
@@ -25,6 +26,60 @@
25 * An ioctl interface for autofs mount point control. 26 * An ioctl interface for autofs mount point control.
26 */ 27 */
27 28
29struct args_protover {
30 __u32 version;
31};
32
33struct args_protosubver {
34 __u32 sub_version;
35};
36
37struct args_openmount {
38 __u32 devid;
39};
40
41struct args_ready {
42 __u32 token;
43};
44
45struct args_fail {
46 __u32 token;
47 __s32 status;
48};
49
50struct args_setpipefd {
51 __s32 pipefd;
52};
53
54struct args_timeout {
55 __u64 timeout;
56};
57
58struct args_requester {
59 __u32 uid;
60 __u32 gid;
61};
62
63struct args_expire {
64 __u32 how;
65};
66
67struct args_askumount {
68 __u32 may_umount;
69};
70
71struct args_ismountpoint {
72 union {
73 struct args_in {
74 __u32 type;
75 } in;
76 struct args_out {
77 __u32 devid;
78 __u32 magic;
79 } out;
80 };
81};
82
28/* 83/*
29 * All the ioctls use this structure. 84 * All the ioctls use this structure.
30 * When sending a path size must account for the total length 85 * When sending a path size must account for the total length
@@ -39,20 +94,32 @@ struct autofs_dev_ioctl {
39 * including this struct */ 94 * including this struct */
40 __s32 ioctlfd; /* automount command fd */ 95 __s32 ioctlfd; /* automount command fd */
41 96
42 __u32 arg1; /* Command parameters */ 97 /* Command parameters */
43 __u32 arg2; 98
99 union {
100 struct args_protover protover;
101 struct args_protosubver protosubver;
102 struct args_openmount openmount;
103 struct args_ready ready;
104 struct args_fail fail;
105 struct args_setpipefd setpipefd;
106 struct args_timeout timeout;
107 struct args_requester requester;
108 struct args_expire expire;
109 struct args_askumount askumount;
110 struct args_ismountpoint ismountpoint;
111 };
44 112
45 char path[0]; 113 char path[0];
46}; 114};
47 115
48static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in) 116static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in)
49{ 117{
118 memset(in, 0, sizeof(struct autofs_dev_ioctl));
50 in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR; 119 in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;
51 in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR; 120 in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;
52 in->size = sizeof(struct autofs_dev_ioctl); 121 in->size = sizeof(struct autofs_dev_ioctl);
53 in->ioctlfd = -1; 122 in->ioctlfd = -1;
54 in->arg1 = 0;
55 in->arg2 = 0;
56 return; 123 return;
57} 124}
58 125