2005-04-16 15:20:36 -07:00
/*
* Pioctl operations for Coda .
* Original version : ( C ) 1996 Peter Braam
* 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>
/* pioctl 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
static int coda_pioctl ( struct inode * inode , struct file * filp ,
unsigned int cmd , unsigned long user_data ) ;
/* exported from this file */
2007-02-12 00:55:38 -08: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 ,
. ioctl = coda_pioctl ,
} ;
/* 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
}
static int coda_pioctl ( struct inode * inode , struct file * filp ,
unsigned int cmd , unsigned long user_data )
{
2008-07-22 09:59:21 -04:00
struct path path ;
2005-04-16 15:20:36 -07:00
int error ;
struct PioctlData data ;
struct inode * target_inode = NULL ;
struct coda_inode_info * cnp ;
/* get the Pioctl data arguments from user space */
if ( copy_from_user ( & data , ( void __user * ) user_data , sizeof ( data ) ) ) {
return - EINVAL ;
}
/*
* Look up the pathname . Note that the pathname is in
* user memory , and namei takes care of this
*/
2008-07-22 09:59:21 -04:00
if ( data . follow ) {
error = user_path ( data . path , & path ) ;
2005-04-16 15:20:36 -07:00
} else {
2008-07-22 09:59:21 -04:00
error = user_lpath ( data . path , & path ) ;
2005-04-16 15:20:36 -07:00
}
if ( error ) {
return error ;
} else {
2008-07-22 09:59:21 -04:00
target_inode = path . dentry - > d_inode ;
2005-04-16 15:20:36 -07:00
}
/* return if it is not a Coda inode */
if ( target_inode - > i_sb ! = inode - > i_sb ) {
2008-07-22 09:59:21 -04:00
path_put ( & path ) ;
2005-04-16 15:20:36 -07:00
return - EINVAL ;
}
/* now proceed to make the upcall */
cnp = ITOC ( target_inode ) ;
error = venus_pioctl ( inode - > i_sb , & ( cnp - > c_fid ) , cmd , & data ) ;
2008-07-22 09:59:21 -04:00
path_put ( & path ) ;
2005-04-16 15:20:36 -07:00
return error ;
}