diff options
Diffstat (limited to 'fs/ext3/ioctl.c')
| -rw-r--r-- | fs/ext3/ioctl.c | 87 | 
1 files changed, 42 insertions, 45 deletions
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c index 88974814783..4d96e9a6453 100644 --- a/fs/ext3/ioctl.c +++ b/fs/ext3/ioctl.c @@ -7,19 +7,14 @@   * Universite Pierre et Marie Curie (Paris VI)   */ -#include <linux/fs.h> -#include <linux/jbd.h> -#include <linux/capability.h> -#include <linux/ext3_fs.h> -#include <linux/ext3_jbd.h>  #include <linux/mount.h> -#include <linux/time.h>  #include <linux/compat.h>  #include <asm/uaccess.h> +#include "ext3.h"  long ext3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)  { -	struct inode *inode = filp->f_dentry->d_inode; +	struct inode *inode = file_inode(filp);  	struct ext3_inode_info *ei = EXT3_I(inode);  	unsigned int flags;  	unsigned short rsv_window_size; @@ -38,13 +33,13 @@ long ext3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)  		unsigned int oldflags;  		unsigned int jflag; -		if (!is_owner_or_cap(inode)) +		if (!inode_owner_or_capable(inode))  			return -EACCES;  		if (get_user(flags, (int __user *) arg))  			return -EFAULT; -		err = mnt_want_write(filp->f_path.mnt); +		err = mnt_want_write_file(filp);  		if (err)  			return err; @@ -110,7 +105,7 @@ flags_err:  			err = ext3_change_inode_journal_flag(inode, jflag);  flags_out:  		mutex_unlock(&inode->i_mutex); -		mnt_drop_write(filp->f_path.mnt); +		mnt_drop_write_file(filp);  		return err;  	}  	case EXT3_IOC_GETVERSION: @@ -123,10 +118,10 @@ flags_out:  		__u32 generation;  		int err; -		if (!is_owner_or_cap(inode)) +		if (!inode_owner_or_capable(inode))  			return -EPERM; -		err = mnt_want_write(filp->f_path.mnt); +		err = mnt_want_write_file(filp);  		if (err)  			return err;  		if (get_user(generation, (int __user *) arg)) { @@ -134,10 +129,11 @@ flags_out:  			goto setversion_out;  		} +		mutex_lock(&inode->i_mutex);  		handle = ext3_journal_start(inode, 1);  		if (IS_ERR(handle)) {  			err = PTR_ERR(handle); -			goto setversion_out; +			goto unlock_out;  		}  		err = ext3_reserve_inode_write(handle, inode, &iloc);  		if (err == 0) { @@ -146,34 +142,13 @@ flags_out:  			err = ext3_mark_iloc_dirty(handle, inode, &iloc);  		}  		ext3_journal_stop(handle); + +unlock_out: +		mutex_unlock(&inode->i_mutex);  setversion_out: -		mnt_drop_write(filp->f_path.mnt); +		mnt_drop_write_file(filp);  		return err;  	} -#ifdef CONFIG_JBD_DEBUG -	case EXT3_IOC_WAIT_FOR_READONLY: -		/* -		 * This is racy - by the time we're woken up and running, -		 * the superblock could be released.  And the module could -		 * have been unloaded.  So sue me. -		 * -		 * Returns 1 if it slept, else zero. -		 */ -		{ -			struct super_block *sb = inode->i_sb; -			DECLARE_WAITQUEUE(wait, current); -			int ret = 0; - -			set_current_state(TASK_INTERRUPTIBLE); -			add_wait_queue(&EXT3_SB(sb)->ro_wait_queue, &wait); -			if (timer_pending(&EXT3_SB(sb)->turn_ro_timer)) { -				schedule(); -				ret = 1; -			} -			remove_wait_queue(&EXT3_SB(sb)->ro_wait_queue, &wait); -			return ret; -		} -#endif  	case EXT3_IOC_GETRSVSZ:  		if (test_opt(inode->i_sb, RESERVATION)  			&& S_ISREG(inode->i_mode) @@ -188,11 +163,11 @@ setversion_out:  		if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))  			return -ENOTTY; -		err = mnt_want_write(filp->f_path.mnt); +		err = mnt_want_write_file(filp);  		if (err)  			return err; -		if (!is_owner_or_cap(inode)) { +		if (!inode_owner_or_capable(inode)) {  			err = -EACCES;  			goto setrsvsz_out;  		} @@ -219,7 +194,7 @@ setversion_out:  		}  		mutex_unlock(&ei->truncate_mutex);  setrsvsz_out: -		mnt_drop_write(filp->f_path.mnt); +		mnt_drop_write_file(filp);  		return err;  	}  	case EXT3_IOC_GROUP_EXTEND: { @@ -230,7 +205,7 @@ setrsvsz_out:  		if (!capable(CAP_SYS_RESOURCE))  			return -EPERM; -		err = mnt_want_write(filp->f_path.mnt); +		err = mnt_want_write_file(filp);  		if (err)  			return err; @@ -245,7 +220,7 @@ setrsvsz_out:  		if (err == 0)  			err = err2;  group_extend_out: -		mnt_drop_write(filp->f_path.mnt); +		mnt_drop_write_file(filp);  		return err;  	}  	case EXT3_IOC_GROUP_ADD: { @@ -256,7 +231,7 @@ group_extend_out:  		if (!capable(CAP_SYS_RESOURCE))  			return -EPERM; -		err = mnt_want_write(filp->f_path.mnt); +		err = mnt_want_write_file(filp);  		if (err)  			return err; @@ -273,10 +248,32 @@ group_extend_out:  		if (err == 0)  			err = err2;  group_add_out: -		mnt_drop_write(filp->f_path.mnt); +		mnt_drop_write_file(filp);  		return err;  	} +	case FITRIM: { +		struct super_block *sb = inode->i_sb; +		struct fstrim_range range; +		int ret = 0; + +		if (!capable(CAP_SYS_ADMIN)) +			return -EPERM; + +		if (copy_from_user(&range, (struct fstrim_range __user *)arg, +				   sizeof(range))) +			return -EFAULT; + +		ret = ext3_trim_fs(sb, &range); +		if (ret < 0) +			return ret; + +		if (copy_to_user((struct fstrim_range __user *)arg, &range, +				 sizeof(range))) +			return -EFAULT; + +		return 0; +	}  	default:  		return -ENOTTY;  | 
