2005-04-16 15:20:36 -07:00
/*
* Pioctl operations for Coda .
2010-05-05 15:15:35 +02:00
* Original version : ( C ) 1996 Peter Braam
2005-04-16 15:20:36 -07:00
* Rewritten for Linux 2.1 : ( C ) 1997 Carnegie Mellon University
*
* Carnegie Mellon encourages users of this code to contribute improvements
* to the Coda project . Contact Peter Braam < coda @ cs . cmu . edu > .
*/
# include <linux/types.h>
# include <linux/kernel.h>
# include <linux/time.h>
# include <linux/fs.h>
# include <linux/stat.h>
# include <linux/errno.h>
# include <linux/string.h>
# include <linux/namei.h>
# include <linux/module.h>
# include <asm/uaccess.h>
# include <linux/coda.h>
# include <linux/coda_linux.h>
# include <linux/coda_fs_i.h>
# include <linux/coda_psdev.h>
2010-05-05 15:15:34 +02:00
# include <linux/smp_lock.h>
2005-04-16 15:20:36 -07:00
/* pioctl ops */
2008-07-15 21:03:57 -04:00
static int coda_ioctl_permission ( struct inode * inode , int mask ) ;
2010-05-05 15:15:34 +02:00
static long coda_pioctl ( struct file * filp , unsigned int cmd ,
unsigned long user_data ) ;
2005-04-16 15:20:36 -07:00
/* exported from this file */
2010-05-05 15:15:35 +02:00
const struct inode_operations coda_ioctl_inode_operations = {
2005-04-16 15:20:36 -07:00
. permission = coda_ioctl_permission ,
. setattr = coda_setattr ,
} ;
2006-03-28 01:56:42 -08:00
const struct file_operations coda_ioctl_operations = {
2005-04-16 15:20:36 -07:00
. owner = THIS_MODULE ,
2010-05-05 15:15:34 +02:00
. unlocked_ioctl = coda_pioctl ,
2005-04-16 15:20:36 -07:00
} ;
/* the coda pioctl inode ops */
2008-07-15 21:03:57 -04:00
static int coda_ioctl_permission ( struct inode * inode , int mask )
2005-04-16 15:20:36 -07:00
{
2008-07-31 13:41:58 +02:00
return ( mask & MAY_EXEC ) ? - EACCES : 0 ;
2005-04-16 15:20:36 -07:00
}
2010-05-05 15:15:34 +02:00
static long coda_pioctl ( struct file * filp , unsigned int cmd ,
unsigned long user_data )
2005-04-16 15:20:36 -07:00
{
2008-07-22 09:59:21 -04:00
struct path path ;
2010-05-05 15:15:35 +02:00
int error ;
2005-04-16 15:20:36 -07:00
struct PioctlData data ;
2010-05-05 15:15:34 +02:00
struct inode * inode = filp - > f_dentry - > d_inode ;
2010-05-05 15:15:35 +02:00
struct inode * target_inode = NULL ;
struct coda_inode_info * cnp ;
2005-04-16 15:20:36 -07:00
2010-05-05 15:15:34 +02:00
lock_kernel ( ) ;
2010-05-05 15:15:35 +02:00
/* get the Pioctl data arguments from user space */
if ( copy_from_user ( & data , ( void __user * ) user_data , sizeof ( data ) ) ) {
2010-05-05 15:15:34 +02:00
error = - EINVAL ;
goto out ;
2005-04-16 15:20:36 -07:00
}
2010-05-05 15:15:35 +02:00
/*
* Look up the pathname . Note that the pathname is in
* user memory , and namei takes care of this
*/
2010-05-05 15:15:34 +02:00
if ( data . follow )
2010-05-05 15:15:35 +02:00
error = user_path ( data . path , & path ) ;
2010-05-05 15:15:34 +02:00
else
2010-05-05 15:15:35 +02:00
error = user_lpath ( data . path , & path ) ;
2010-05-05 15:15:34 +02:00
if ( error )
goto out ;
else
2008-07-22 09:59:21 -04:00
target_inode = path . dentry - > d_inode ;
2010-05-05 15:15:34 +02:00
2005-04-16 15:20:36 -07:00
/* return if it is not a Coda inode */
2010-05-05 15:15:35 +02:00
if ( target_inode - > i_sb ! = inode - > i_sb ) {
2008-07-22 09:59:21 -04:00
path_put ( & path ) ;
2010-05-05 15:15:34 +02:00
error = - EINVAL ;
goto out ;
2005-04-16 15:20:36 -07:00
}
/* now proceed to make the upcall */
2010-05-05 15:15:35 +02:00
cnp = ITOC ( target_inode ) ;
2005-04-16 15:20:36 -07:00
error = venus_pioctl ( inode - > i_sb , & ( cnp - > c_fid ) , cmd , & data ) ;
2008-07-22 09:59:21 -04:00
path_put ( & path ) ;
2010-05-05 15:15:34 +02:00
out :
unlock_kernel ( ) ;
2010-05-05 15:15:35 +02:00
return error ;
2005-04-16 15:20:36 -07:00
}