diff options
Diffstat (limited to 'fs/nilfs2/ioctl.c')
-rw-r--r-- | fs/nilfs2/ioctl.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index f2469ba6246..41d6743d303 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
@@ -698,6 +698,63 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp, | |||
698 | return 0; | 698 | return 0; |
699 | } | 699 | } |
700 | 700 | ||
701 | static int nilfs_ioctl_resize(struct inode *inode, struct file *filp, | ||
702 | void __user *argp) | ||
703 | { | ||
704 | __u64 newsize; | ||
705 | int ret = -EPERM; | ||
706 | |||
707 | if (!capable(CAP_SYS_ADMIN)) | ||
708 | goto out; | ||
709 | |||
710 | ret = mnt_want_write(filp->f_path.mnt); | ||
711 | if (ret) | ||
712 | goto out; | ||
713 | |||
714 | ret = -EFAULT; | ||
715 | if (copy_from_user(&newsize, argp, sizeof(newsize))) | ||
716 | goto out_drop_write; | ||
717 | |||
718 | ret = nilfs_resize_fs(inode->i_sb, newsize); | ||
719 | |||
720 | out_drop_write: | ||
721 | mnt_drop_write(filp->f_path.mnt); | ||
722 | out: | ||
723 | return ret; | ||
724 | } | ||
725 | |||
726 | static int nilfs_ioctl_set_alloc_range(struct inode *inode, void __user *argp) | ||
727 | { | ||
728 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; | ||
729 | __u64 range[2]; | ||
730 | __u64 minseg, maxseg; | ||
731 | unsigned long segbytes; | ||
732 | int ret = -EPERM; | ||
733 | |||
734 | if (!capable(CAP_SYS_ADMIN)) | ||
735 | goto out; | ||
736 | |||
737 | ret = -EFAULT; | ||
738 | if (copy_from_user(range, argp, sizeof(__u64[2]))) | ||
739 | goto out; | ||
740 | |||
741 | ret = -ERANGE; | ||
742 | if (range[1] > i_size_read(inode->i_sb->s_bdev->bd_inode)) | ||
743 | goto out; | ||
744 | |||
745 | segbytes = nilfs->ns_blocks_per_segment * nilfs->ns_blocksize; | ||
746 | |||
747 | minseg = range[0] + segbytes - 1; | ||
748 | do_div(minseg, segbytes); | ||
749 | maxseg = NILFS_SB2_OFFSET_BYTES(range[1]); | ||
750 | do_div(maxseg, segbytes); | ||
751 | maxseg--; | ||
752 | |||
753 | ret = nilfs_sufile_set_alloc_range(nilfs->ns_sufile, minseg, maxseg); | ||
754 | out: | ||
755 | return ret; | ||
756 | } | ||
757 | |||
701 | static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp, | 758 | static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp, |
702 | unsigned int cmd, void __user *argp, | 759 | unsigned int cmd, void __user *argp, |
703 | size_t membsz, | 760 | size_t membsz, |
@@ -763,6 +820,10 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
763 | return nilfs_ioctl_clean_segments(inode, filp, cmd, argp); | 820 | return nilfs_ioctl_clean_segments(inode, filp, cmd, argp); |
764 | case NILFS_IOCTL_SYNC: | 821 | case NILFS_IOCTL_SYNC: |
765 | return nilfs_ioctl_sync(inode, filp, cmd, argp); | 822 | return nilfs_ioctl_sync(inode, filp, cmd, argp); |
823 | case NILFS_IOCTL_RESIZE: | ||
824 | return nilfs_ioctl_resize(inode, filp, argp); | ||
825 | case NILFS_IOCTL_SET_ALLOC_RANGE: | ||
826 | return nilfs_ioctl_set_alloc_range(inode, argp); | ||
766 | default: | 827 | default: |
767 | return -ENOTTY; | 828 | return -ENOTTY; |
768 | } | 829 | } |