diff options
| author | John Kacur <jkacur@redhat.com> | 2010-05-05 15:15:39 +0200 | 
|---|---|---|
| committer | Jan Kara <jack@suse.cz> | 2010-05-05 16:36:17 +0200 | 
| commit | 2f07a88b30f510c7625d75cdf286903b465350a0 (patch) | |
| tree | 5869affff304e0090e1aa59f94b77e183f278eb3 /fs | |
| parent | 7ebd467551ed6ae200d7835a84bbda0dcadaa511 (diff) | |
| download | olio-linux-3.10-2f07a88b30f510c7625d75cdf286903b465350a0.tar.xz olio-linux-3.10-2f07a88b30f510c7625d75cdf286903b465350a0.zip  | |
udf: BKL ioctl pushdown
Convert udf_ioctl to an unlocked_ioctl and push the BKL down into it.
Signed-off-by: John Kacur <jkacur@redhat.com
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/udf/dir.c | 2 | ||||
| -rw-r--r-- | fs/udf/file.c | 43 | ||||
| -rw-r--r-- | fs/udf/udfdecl.h | 3 | 
3 files changed, 29 insertions, 19 deletions
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index f0f2a436251..3a84455c2a7 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c @@ -209,6 +209,6 @@ static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)  const struct file_operations udf_dir_operations = {  	.read			= generic_read_dir,  	.readdir		= udf_readdir, -	.ioctl			= udf_ioctl, +	.unlocked_ioctl		= udf_ioctl,  	.fsync			= simple_fsync,  }; diff --git a/fs/udf/file.c b/fs/udf/file.c index 4b6a46ccbf4..83092fb025e 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -37,6 +37,7 @@  #include <linux/quotaops.h>  #include <linux/buffer_head.h>  #include <linux/aio.h> +#include <linux/smp_lock.h>  #include "udf_i.h"  #include "udf_sb.h" @@ -144,50 +145,60 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,  	return retval;  } -int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, -	      unsigned long arg) +long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)  { +	struct inode *inode = filp->f_dentry->d_inode;  	long old_block, new_block;  	int result = -EINVAL; +	lock_kernel(); +  	if (file_permission(filp, MAY_READ) != 0) { -		udf_debug("no permission to access inode %lu\n", -			  inode->i_ino); -		return -EPERM; +		udf_debug("no permission to access inode %lu\n", inode->i_ino); +		result = -EPERM; +		goto out;  	}  	if (!arg) {  		udf_debug("invalid argument to udf_ioctl\n"); -		return -EINVAL; +		result = -EINVAL; +		goto out;  	}  	switch (cmd) {  	case UDF_GETVOLIDENT:  		if (copy_to_user((char __user *)arg,  				 UDF_SB(inode->i_sb)->s_volume_ident, 32)) -			return -EFAULT; +			result = -EFAULT;  		else -			return 0; +			result = 0; +		goto out;  	case UDF_RELOCATE_BLOCKS: -		if (!capable(CAP_SYS_ADMIN)) -			return -EACCES; -		if (get_user(old_block, (long __user *)arg)) -			return -EFAULT; +		if (!capable(CAP_SYS_ADMIN)) { +			result = -EACCES; +			goto out; +		} +		if (get_user(old_block, (long __user *)arg)) { +			result = -EFAULT; +			goto out; +		}  		result = udf_relocate_blocks(inode->i_sb,  						old_block, &new_block);  		if (result == 0)  			result = put_user(new_block, (long __user *)arg); -		return result; +		goto out;  	case UDF_GETEASIZE:  		result = put_user(UDF_I(inode)->i_lenEAttr, (int __user *)arg); -		break; +		goto out;  	case UDF_GETEABLOCK:  		result = copy_to_user((char __user *)arg,  				      UDF_I(inode)->i_ext.i_data,  				      UDF_I(inode)->i_lenEAttr) ? -EFAULT : 0; -		break; +		goto out;  	} +out: +	unlock_kernel();  	return result;  } @@ -207,7 +218,7 @@ static int udf_release_file(struct inode *inode, struct file *filp)  const struct file_operations udf_file_operations = {  	.read			= do_sync_read,  	.aio_read		= generic_file_aio_read, -	.ioctl			= udf_ioctl, +	.unlocked_ioctl		= udf_ioctl,  	.open			= dquot_file_open,  	.mmap			= generic_file_mmap,  	.write			= do_sync_write, diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 702a1148e70..9079ff7d625 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -130,8 +130,7 @@ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,  			uint8_t *, uint8_t *);  /* file.c */ -extern int udf_ioctl(struct inode *, struct file *, unsigned int, -		     unsigned long); +extern long udf_ioctl(struct file *, unsigned int, unsigned long);  extern int udf_setattr(struct dentry *dentry, struct iattr *iattr);  /* inode.c */  extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *);  |