11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Pioctl operations for Coda. 31977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur * Original version: (C) 1996 Peter Braam 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Rewritten for Linux 2.1: (C) 1997 Carnegie Mellon University 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Carnegie Mellon encourages users of this code to contribute improvements 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>. 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/time.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fs.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/stat.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/namei.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/coda.h> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/coda_psdev.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2431a203df9c109480fc6d48ba0a68763e89199acbAl Viro#include "coda_linux.h" 2531a203df9c109480fc6d48ba0a68763e89199acbAl Viro 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* pioctl ops */ 2710556cb21a0d0b24d95f00ea6df16f599a3345b2Al Virostatic int coda_ioctl_permission(struct inode *inode, int mask); 282ff82f852189226cda3cb192985a4a7fc750ab26John Kacurstatic long coda_pioctl(struct file *filp, unsigned int cmd, 292ff82f852189226cda3cb192985a4a7fc750ab26John Kacur unsigned long user_data); 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* exported from this file */ 321977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacurconst struct inode_operations coda_ioctl_inode_operations = { 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .permission = coda_ioctl_permission, 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setattr = coda_setattr, 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 374b6f5d20b04dcbc3d888555522b90ba6d36c4106Arjan van de Venconst struct file_operations coda_ioctl_operations = { 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 392ff82f852189226cda3cb192985a4a7fc750ab26John Kacur .unlocked_ioctl = coda_pioctl, 406038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann .llseek = noop_llseek, 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* the coda pioctl inode ops */ 4410556cb21a0d0b24d95f00ea6df16f599a3345b2Al Virostatic int coda_ioctl_permission(struct inode *inode, int mask) 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 46f696a3659fc4b3a3bf4bc83d9dbec5e5a2ffd929Miklos Szeredi return (mask & MAY_EXEC) ? -EACCES : 0; 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 492ff82f852189226cda3cb192985a4a7fc750ab26John Kacurstatic long coda_pioctl(struct file *filp, unsigned int cmd, 502ff82f852189226cda3cb192985a4a7fc750ab26John Kacur unsigned long user_data) 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 522d8f30380ab8c706f4e0a8f1aaa22b5886e9ac8aAl Viro struct path path; 531977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur int error; 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PioctlData data; 552ff82f852189226cda3cb192985a4a7fc750ab26John Kacur struct inode *inode = filp->f_dentry->d_inode; 561977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur struct inode *target_inode = NULL; 571977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur struct coda_inode_info *cnp; 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 591977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur /* get the Pioctl data arguments from user space */ 60f7cc02b8715618e179242ba9cc10bdc5146ae565Yoshihisa Abe if (copy_from_user(&data, (void __user *)user_data, sizeof(data))) 61f7cc02b8715618e179242ba9cc10bdc5146ae565Yoshihisa Abe return -EINVAL; 621977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur 631977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur /* 641977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur * Look up the pathname. Note that the pathname is in 651977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur * user memory, and namei takes care of this 661977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur */ 672ff82f852189226cda3cb192985a4a7fc750ab26John Kacur if (data.follow) 681977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur error = user_path(data.path, &path); 692ff82f852189226cda3cb192985a4a7fc750ab26John Kacur else 701977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur error = user_lpath(data.path, &path); 712ff82f852189226cda3cb192985a4a7fc750ab26John Kacur 722ff82f852189226cda3cb192985a4a7fc750ab26John Kacur if (error) 73f7cc02b8715618e179242ba9cc10bdc5146ae565Yoshihisa Abe return error; 74f7cc02b8715618e179242ba9cc10bdc5146ae565Yoshihisa Abe 75f7cc02b8715618e179242ba9cc10bdc5146ae565Yoshihisa Abe target_inode = path.dentry->d_inode; 762ff82f852189226cda3cb192985a4a7fc750ab26John Kacur 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* return if it is not a Coda inode */ 781977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur if (target_inode->i_sb != inode->i_sb) { 792ff82f852189226cda3cb192985a4a7fc750ab26John Kacur error = -EINVAL; 802ff82f852189226cda3cb192985a4a7fc750ab26John Kacur goto out; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* now proceed to make the upcall */ 841977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur cnp = ITOC(target_inode); 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data); 872ff82f852189226cda3cb192985a4a7fc750ab26John Kacurout: 88f7cc02b8715618e179242ba9cc10bdc5146ae565Yoshihisa Abe path_put(&path); 891977bb2ed8ffdd161fe1c9eef1f9fd283e41d4b5John Kacur return error; 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 91