diff options
Diffstat (limited to 'fs/autofs/root.c')
| -rw-r--r-- | fs/autofs/root.c | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 9a0520b50663..11b1ea786d00 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
| 17 | #include <linux/param.h> | 17 | #include <linux/param.h> |
| 18 | #include <linux/time.h> | 18 | #include <linux/time.h> |
| 19 | #include <linux/compat.h> | ||
| 19 | #include <linux/smp_lock.h> | 20 | #include <linux/smp_lock.h> |
| 20 | #include "autofs_i.h" | 21 | #include "autofs_i.h" |
| 21 | 22 | ||
| @@ -25,13 +26,17 @@ static int autofs_root_symlink(struct inode *,struct dentry *,const char *); | |||
| 25 | static int autofs_root_unlink(struct inode *,struct dentry *); | 26 | static int autofs_root_unlink(struct inode *,struct dentry *); |
| 26 | static int autofs_root_rmdir(struct inode *,struct dentry *); | 27 | static int autofs_root_rmdir(struct inode *,struct dentry *); |
| 27 | static int autofs_root_mkdir(struct inode *,struct dentry *,int); | 28 | static int autofs_root_mkdir(struct inode *,struct dentry *,int); |
| 28 | static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long); | 29 | static long autofs_root_ioctl(struct file *,unsigned int,unsigned long); |
| 30 | static long autofs_root_compat_ioctl(struct file *,unsigned int,unsigned long); | ||
| 29 | 31 | ||
| 30 | const struct file_operations autofs_root_operations = { | 32 | const struct file_operations autofs_root_operations = { |
| 31 | .llseek = generic_file_llseek, | 33 | .llseek = generic_file_llseek, |
| 32 | .read = generic_read_dir, | 34 | .read = generic_read_dir, |
| 33 | .readdir = autofs_root_readdir, | 35 | .readdir = autofs_root_readdir, |
| 34 | .ioctl = autofs_root_ioctl, | 36 | .unlocked_ioctl = autofs_root_ioctl, |
| 37 | #ifdef CONFIG_COMPAT | ||
| 38 | .compat_ioctl = autofs_root_compat_ioctl, | ||
| 39 | #endif | ||
| 35 | }; | 40 | }; |
| 36 | 41 | ||
| 37 | const struct inode_operations autofs_root_inode_operations = { | 42 | const struct inode_operations autofs_root_inode_operations = { |
| @@ -492,6 +497,25 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 492 | } | 497 | } |
| 493 | 498 | ||
| 494 | /* Get/set timeout ioctl() operation */ | 499 | /* Get/set timeout ioctl() operation */ |
| 500 | #ifdef CONFIG_COMPAT | ||
| 501 | static inline int autofs_compat_get_set_timeout(struct autofs_sb_info *sbi, | ||
| 502 | unsigned int __user *p) | ||
| 503 | { | ||
| 504 | unsigned long ntimeout; | ||
| 505 | |||
| 506 | if (get_user(ntimeout, p) || | ||
| 507 | put_user(sbi->exp_timeout / HZ, p)) | ||
| 508 | return -EFAULT; | ||
| 509 | |||
| 510 | if (ntimeout > UINT_MAX/HZ) | ||
| 511 | sbi->exp_timeout = 0; | ||
| 512 | else | ||
| 513 | sbi->exp_timeout = ntimeout * HZ; | ||
| 514 | |||
| 515 | return 0; | ||
| 516 | } | ||
| 517 | #endif | ||
| 518 | |||
| 495 | static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi, | 519 | static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi, |
| 496 | unsigned long __user *p) | 520 | unsigned long __user *p) |
| 497 | { | 521 | { |
| @@ -546,7 +570,7 @@ static inline int autofs_expire_run(struct super_block *sb, | |||
| 546 | * ioctl()'s on the root directory is the chief method for the daemon to | 570 | * ioctl()'s on the root directory is the chief method for the daemon to |
| 547 | * generate kernel reactions | 571 | * generate kernel reactions |
| 548 | */ | 572 | */ |
| 549 | static int autofs_root_ioctl(struct inode *inode, struct file *filp, | 573 | static int autofs_do_root_ioctl(struct inode *inode, struct file *filp, |
| 550 | unsigned int cmd, unsigned long arg) | 574 | unsigned int cmd, unsigned long arg) |
| 551 | { | 575 | { |
| 552 | struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb); | 576 | struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb); |
| @@ -571,6 +595,10 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp, | |||
| 571 | return 0; | 595 | return 0; |
| 572 | case AUTOFS_IOC_PROTOVER: /* Get protocol version */ | 596 | case AUTOFS_IOC_PROTOVER: /* Get protocol version */ |
| 573 | return autofs_get_protover(argp); | 597 | return autofs_get_protover(argp); |
| 598 | #ifdef CONFIG_COMPAT | ||
| 599 | case AUTOFS_IOC_SETTIMEOUT32: | ||
| 600 | return autofs_compat_get_set_timeout(sbi, argp); | ||
| 601 | #endif | ||
| 574 | case AUTOFS_IOC_SETTIMEOUT: | 602 | case AUTOFS_IOC_SETTIMEOUT: |
| 575 | return autofs_get_set_timeout(sbi, argp); | 603 | return autofs_get_set_timeout(sbi, argp); |
| 576 | case AUTOFS_IOC_EXPIRE: | 604 | case AUTOFS_IOC_EXPIRE: |
| @@ -579,4 +607,37 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp, | |||
| 579 | default: | 607 | default: |
| 580 | return -ENOSYS; | 608 | return -ENOSYS; |
| 581 | } | 609 | } |
| 610 | |||
| 611 | } | ||
| 612 | |||
| 613 | static long autofs_root_ioctl(struct file *filp, | ||
| 614 | unsigned int cmd, unsigned long arg) | ||
| 615 | { | ||
| 616 | int ret; | ||
| 617 | |||
| 618 | lock_kernel(); | ||
| 619 | ret = autofs_do_root_ioctl(filp->f_path.dentry->d_inode, | ||
| 620 | filp, cmd, arg); | ||
| 621 | unlock_kernel(); | ||
| 622 | |||
| 623 | return ret; | ||
| 624 | } | ||
| 625 | |||
| 626 | #ifdef CONFIG_COMPAT | ||
| 627 | static long autofs_root_compat_ioctl(struct file *filp, | ||
| 628 | unsigned int cmd, unsigned long arg) | ||
| 629 | { | ||
| 630 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
| 631 | int ret; | ||
| 632 | |||
| 633 | lock_kernel(); | ||
| 634 | if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL) | ||
| 635 | ret = autofs_do_root_ioctl(inode, filp, cmd, arg); | ||
| 636 | else | ||
| 637 | ret = autofs_do_root_ioctl(inode, filp, cmd, | ||
| 638 | (unsigned long)compat_ptr(arg)); | ||
| 639 | unlock_kernel(); | ||
| 640 | |||
| 641 | return ret; | ||
| 582 | } | 642 | } |
| 643 | #endif | ||
