diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-22 22:43:01 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-22 22:43:01 -0700 |
commit | caebc160ce3f76761cc62ad96ef6d6f30f54e3dd (patch) | |
tree | 6bedd4a62d65a4ba121a0c170d1ca657d922d352 /fs/nilfs2/ioctl.c | |
parent | d798f7f080805ad7e15fc37a43d8c6f91edb6dda (diff) | |
parent | 5fc7b14177b1a1c2f2511aed62a4ca870d0332e7 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2:
nilfs2: use mark_buffer_dirty to mark btnode or meta data dirty
nilfs2: always set back pointer to host inode in mapping->host
nilfs2: get rid of NILFS_I_NILFS
nilfs2: use list_first_entry
nilfs2: use empty_aops for gc-inodes
nilfs2: implement resize ioctl
nilfs2: add truncation routine of segment usage file
nilfs2: add routine to move secondary super block
nilfs2: add ioctl which limits range of segment to be allocated
nilfs2: zero fill unused portion of super root block
nilfs2: super root size should change depending on inode size
nilfs2: get rid of private page allocator
nilfs2: merge list_del()/list_add_tail() to list_move_tail()
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; } |