forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.2 KiB
88 lines
2.2 KiB
// SPDX-License-Identifier: GPL-2.0 |
|
/* |
|
* 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 <[email protected]>. |
|
*/ |
|
|
|
#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 <linux/uaccess.h> |
|
|
|
#include <linux/coda.h> |
|
#include "coda_psdev.h" |
|
#include "coda_linux.h" |
|
|
|
/* pioctl ops */ |
|
static int coda_ioctl_permission(struct user_namespace *mnt_userns, |
|
struct inode *inode, int mask); |
|
static long coda_pioctl(struct file *filp, unsigned int cmd, |
|
unsigned long user_data); |
|
|
|
/* exported from this file */ |
|
const struct inode_operations coda_ioctl_inode_operations = { |
|
.permission = coda_ioctl_permission, |
|
.setattr = coda_setattr, |
|
}; |
|
|
|
const struct file_operations coda_ioctl_operations = { |
|
.unlocked_ioctl = coda_pioctl, |
|
.llseek = noop_llseek, |
|
}; |
|
|
|
/* the coda pioctl inode ops */ |
|
static int coda_ioctl_permission(struct user_namespace *mnt_userns, |
|
struct inode *inode, int mask) |
|
{ |
|
return (mask & MAY_EXEC) ? -EACCES : 0; |
|
} |
|
|
|
static long coda_pioctl(struct file *filp, unsigned int cmd, |
|
unsigned long user_data) |
|
{ |
|
struct path path; |
|
int error; |
|
struct PioctlData data; |
|
struct inode *inode = file_inode(filp); |
|
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 |
|
*/ |
|
error = user_path_at(AT_FDCWD, data.path, |
|
data.follow ? LOOKUP_FOLLOW : 0, &path); |
|
if (error) |
|
return error; |
|
|
|
target_inode = d_inode(path.dentry); |
|
|
|
/* return if it is not a Coda inode */ |
|
if (target_inode->i_sb != inode->i_sb) { |
|
error = -EINVAL; |
|
goto out; |
|
} |
|
|
|
/* now proceed to make the upcall */ |
|
cnp = ITOC(target_inode); |
|
|
|
error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data); |
|
out: |
|
path_put(&path); |
|
return error; |
|
}
|
|
|