0001
0002
0003
0004
0005
0006
0007
0008
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
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
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
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
0061 if (copy_from_user(&data, (void __user *)user_data, sizeof(data)))
0062 return -EINVAL;
0063
0064
0065
0066
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
0076 if (target_inode->i_sb != inode->i_sb) {
0077 error = -EINVAL;
0078 goto out;
0079 }
0080
0081
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 }