diff options
-rw-r--r-- | fs/autofs4/dev-ioctl.c | 54 | ||||
-rw-r--r-- | include/linux/auto_dev-ioctl.h | 75 |
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 | |||
670 | out_release: | 674 | out_release: |
671 | path_put(&nd.path); | 675 | path_put(&nd.path); |
672 | out: | 676 | out: |
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 | ||
29 | struct args_protover { | ||
30 | __u32 version; | ||
31 | }; | ||
32 | |||
33 | struct args_protosubver { | ||
34 | __u32 sub_version; | ||
35 | }; | ||
36 | |||
37 | struct args_openmount { | ||
38 | __u32 devid; | ||
39 | }; | ||
40 | |||
41 | struct args_ready { | ||
42 | __u32 token; | ||
43 | }; | ||
44 | |||
45 | struct args_fail { | ||
46 | __u32 token; | ||
47 | __s32 status; | ||
48 | }; | ||
49 | |||
50 | struct args_setpipefd { | ||
51 | __s32 pipefd; | ||
52 | }; | ||
53 | |||
54 | struct args_timeout { | ||
55 | __u64 timeout; | ||
56 | }; | ||
57 | |||
58 | struct args_requester { | ||
59 | __u32 uid; | ||
60 | __u32 gid; | ||
61 | }; | ||
62 | |||
63 | struct args_expire { | ||
64 | __u32 how; | ||
65 | }; | ||
66 | |||
67 | struct args_askumount { | ||
68 | __u32 may_umount; | ||
69 | }; | ||
70 | |||
71 | struct 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 | ||
48 | static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in) | 116 | static 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 | ||