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,  	return 0;  } +static int nilfs_ioctl_resize(struct inode *inode, struct file *filp, +			      void __user *argp) +{ +	__u64 newsize; +	int ret = -EPERM; + +	if (!capable(CAP_SYS_ADMIN)) +		goto out; + +	ret = mnt_want_write(filp->f_path.mnt); +	if (ret) +		goto out; + +	ret = -EFAULT; +	if (copy_from_user(&newsize, argp, sizeof(newsize))) +		goto out_drop_write; + +	ret = nilfs_resize_fs(inode->i_sb, newsize); + +out_drop_write: +	mnt_drop_write(filp->f_path.mnt); +out: +	return ret; +} + +static int nilfs_ioctl_set_alloc_range(struct inode *inode, void __user *argp) +{ +	struct the_nilfs *nilfs = inode->i_sb->s_fs_info; +	__u64 range[2]; +	__u64 minseg, maxseg; +	unsigned long segbytes; +	int ret = -EPERM; + +	if (!capable(CAP_SYS_ADMIN)) +		goto out; + +	ret = -EFAULT; +	if (copy_from_user(range, argp, sizeof(__u64[2]))) +		goto out; + +	ret = -ERANGE; +	if (range[1] > i_size_read(inode->i_sb->s_bdev->bd_inode)) +		goto out; + +	segbytes = nilfs->ns_blocks_per_segment * nilfs->ns_blocksize; + +	minseg = range[0] + segbytes - 1; +	do_div(minseg, segbytes); +	maxseg = NILFS_SB2_OFFSET_BYTES(range[1]); +	do_div(maxseg, segbytes); +	maxseg--; + +	ret = nilfs_sufile_set_alloc_range(nilfs->ns_sufile, minseg, maxseg); +out: +	return ret; +} +  static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,  				unsigned int cmd, void __user *argp,  				size_t membsz, @@ -763,6 +820,10 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)  		return nilfs_ioctl_clean_segments(inode, filp, cmd, argp);  	case NILFS_IOCTL_SYNC:  		return nilfs_ioctl_sync(inode, filp, cmd, argp); +	case NILFS_IOCTL_RESIZE: +		return nilfs_ioctl_resize(inode, filp, argp); +	case NILFS_IOCTL_SET_ALLOC_RANGE: +		return nilfs_ioctl_set_alloc_range(inode, argp);  	default:  		return -ENOTTY;  	}  |