18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Pioctl operations for Coda. 48c2ecf20Sopenharmony_ci * Original version: (C) 1996 Peter Braam 58c2ecf20Sopenharmony_ci * Rewritten for Linux 2.1: (C) 1997 Carnegie Mellon University 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Carnegie Mellon encourages users of this code to contribute improvements 88c2ecf20Sopenharmony_ci * to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/types.h> 128c2ecf20Sopenharmony_ci#include <linux/kernel.h> 138c2ecf20Sopenharmony_ci#include <linux/time.h> 148c2ecf20Sopenharmony_ci#include <linux/fs.h> 158c2ecf20Sopenharmony_ci#include <linux/stat.h> 168c2ecf20Sopenharmony_ci#include <linux/errno.h> 178c2ecf20Sopenharmony_ci#include <linux/string.h> 188c2ecf20Sopenharmony_ci#include <linux/namei.h> 198c2ecf20Sopenharmony_ci#include <linux/module.h> 208c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#include <linux/coda.h> 238c2ecf20Sopenharmony_ci#include "coda_psdev.h" 248c2ecf20Sopenharmony_ci#include "coda_linux.h" 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* pioctl ops */ 278c2ecf20Sopenharmony_cistatic int coda_ioctl_permission(struct inode *inode, int mask); 288c2ecf20Sopenharmony_cistatic long coda_pioctl(struct file *filp, unsigned int cmd, 298c2ecf20Sopenharmony_ci unsigned long user_data); 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* exported from this file */ 328c2ecf20Sopenharmony_ciconst struct inode_operations coda_ioctl_inode_operations = { 338c2ecf20Sopenharmony_ci .permission = coda_ioctl_permission, 348c2ecf20Sopenharmony_ci .setattr = coda_setattr, 358c2ecf20Sopenharmony_ci}; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ciconst struct file_operations coda_ioctl_operations = { 388c2ecf20Sopenharmony_ci .unlocked_ioctl = coda_pioctl, 398c2ecf20Sopenharmony_ci .llseek = noop_llseek, 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* the coda pioctl inode ops */ 438c2ecf20Sopenharmony_cistatic int coda_ioctl_permission(struct inode *inode, int mask) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci return (mask & MAY_EXEC) ? -EACCES : 0; 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic long coda_pioctl(struct file *filp, unsigned int cmd, 498c2ecf20Sopenharmony_ci unsigned long user_data) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci struct path path; 528c2ecf20Sopenharmony_ci int error; 538c2ecf20Sopenharmony_ci struct PioctlData data; 548c2ecf20Sopenharmony_ci struct inode *inode = file_inode(filp); 558c2ecf20Sopenharmony_ci struct inode *target_inode = NULL; 568c2ecf20Sopenharmony_ci struct coda_inode_info *cnp; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci /* get the Pioctl data arguments from user space */ 598c2ecf20Sopenharmony_ci if (copy_from_user(&data, (void __user *)user_data, sizeof(data))) 608c2ecf20Sopenharmony_ci return -EINVAL; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci /* 638c2ecf20Sopenharmony_ci * Look up the pathname. Note that the pathname is in 648c2ecf20Sopenharmony_ci * user memory, and namei takes care of this 658c2ecf20Sopenharmony_ci */ 668c2ecf20Sopenharmony_ci error = user_path_at(AT_FDCWD, data.path, 678c2ecf20Sopenharmony_ci data.follow ? LOOKUP_FOLLOW : 0, &path); 688c2ecf20Sopenharmony_ci if (error) 698c2ecf20Sopenharmony_ci return error; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci target_inode = d_inode(path.dentry); 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci /* return if it is not a Coda inode */ 748c2ecf20Sopenharmony_ci if (target_inode->i_sb != inode->i_sb) { 758c2ecf20Sopenharmony_ci error = -EINVAL; 768c2ecf20Sopenharmony_ci goto out; 778c2ecf20Sopenharmony_ci } 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci /* now proceed to make the upcall */ 808c2ecf20Sopenharmony_ci cnp = ITOC(target_inode); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data); 838c2ecf20Sopenharmony_ciout: 848c2ecf20Sopenharmony_ci path_put(&path); 858c2ecf20Sopenharmony_ci return error; 868c2ecf20Sopenharmony_ci} 87