pioctl.c 2.4 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 * 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 */
27
static int coda_ioctl_permission(struct inode *inode, int mask);
L
Linus Torvalds 已提交
28 29 30 31
static int coda_pioctl(struct inode * inode, struct file * filp, 
                       unsigned int cmd, unsigned long user_data);

/* exported from this file */
32
const struct inode_operations coda_ioctl_inode_operations =
L
Linus Torvalds 已提交
33 34 35 36 37
{
	.permission	= coda_ioctl_permission,
	.setattr	= coda_setattr,
};

38
const struct file_operations coda_ioctl_operations = {
L
Linus Torvalds 已提交
39 40 41 42 43
	.owner		= THIS_MODULE,
	.ioctl		= coda_pioctl,
};

/* the coda pioctl inode ops */
44
static int coda_ioctl_permission(struct inode *inode, int mask)
L
Linus Torvalds 已提交
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
{
        return 0;
}

static int coda_pioctl(struct inode * inode, struct file * filp, 
                       unsigned int cmd, unsigned long user_data)
{
	struct nameidata nd;
        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
         */
        if ( data.follow ) {
                error = user_path_walk(data.path, &nd);
	} else {
	        error = user_path_walk_link(data.path, &nd);
	}
		
	if ( error ) {
		return error;
        } else {
76
		target_inode = nd.path.dentry->d_inode;
L
Linus Torvalds 已提交
77 78 79 80
	}
	
	/* return if it is not a Coda inode */
	if ( target_inode->i_sb != inode->i_sb ) {
J
Jan Blunck 已提交
81
		path_put(&nd.path);
L
Linus Torvalds 已提交
82 83 84 85 86 87 88 89
	        return  -EINVAL;
	}

	/* now proceed to make the upcall */
        cnp = ITOC(target_inode);

	error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data);

J
Jan Blunck 已提交
90
	path_put(&nd.path);
L
Linus Torvalds 已提交
91 92 93
        return error;
}