Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Pioctl operations for Coda.
0004  * Original version: (C) 1996 Peter Braam
0005  * Rewritten for Linux 2.1: (C) 1997 Carnegie Mellon University
0006  *
0007  * Carnegie Mellon encourages users of this code to contribute improvements
0008  * to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
0009  */
0010 
0011 #include <linux/types.h>
0012 #include <linux/kernel.h>
0013 #include <linux/time.h>
0014 #include <linux/fs.h>
0015 #include <linux/stat.h>
0016 #include <linux/errno.h>
0017 #include <linux/string.h>
0018 #include <linux/namei.h>
0019 #include <linux/module.h>
0020 #include <linux/uaccess.h>
0021 
0022 #include <linux/coda.h>
0023 #include "coda_psdev.h"
0024 #include "coda_linux.h"
0025 
0026 /* pioctl ops */
0027 static int coda_ioctl_permission(struct user_namespace *mnt_userns,
0028                  struct inode *inode, int mask);
0029 static long coda_pioctl(struct file *filp, unsigned int cmd,
0030             unsigned long user_data);
0031 
0032 /* exported from this file */
0033 const struct inode_operations coda_ioctl_inode_operations = {
0034     .permission = coda_ioctl_permission,
0035     .setattr    = coda_setattr,
0036 };
0037 
0038 const struct file_operations coda_ioctl_operations = {
0039     .unlocked_ioctl = coda_pioctl,
0040     .llseek     = noop_llseek,
0041 };
0042 
0043 /* the coda pioctl inode ops */
0044 static int coda_ioctl_permission(struct user_namespace *mnt_userns,
0045                  struct inode *inode, int mask)
0046 {
0047     return (mask & MAY_EXEC) ? -EACCES : 0;
0048 }
0049 
0050 static long coda_pioctl(struct file *filp, unsigned int cmd,
0051             unsigned long user_data)
0052 {
0053     struct path path;
0054     int error;
0055     struct PioctlData data;
0056     struct inode *inode = file_inode(filp);
0057     struct inode *target_inode = NULL;
0058     struct coda_inode_info *cnp;
0059 
0060     /* get the Pioctl data arguments from user space */
0061     if (copy_from_user(&data, (void __user *)user_data, sizeof(data)))
0062         return -EINVAL;
0063 
0064     /*
0065      * Look up the pathname. Note that the pathname is in
0066      * user memory, and namei takes care of this
0067      */
0068     error = user_path_at(AT_FDCWD, data.path,
0069                  data.follow ? LOOKUP_FOLLOW : 0, &path);
0070     if (error)
0071         return error;
0072 
0073     target_inode = d_inode(path.dentry);
0074 
0075     /* return if it is not a Coda inode */
0076     if (target_inode->i_sb != inode->i_sb) {
0077         error = -EINVAL;
0078         goto out;
0079     }
0080 
0081     /* now proceed to make the upcall */
0082     cnp = ITOC(target_inode);
0083 
0084     error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data);
0085 out:
0086     path_put(&path);
0087     return error;
0088 }