/* * 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 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* pioctl ops */ static int coda_ioctl_permission(struct inode *inode, int mask); static int coda_ioctl_open(struct inode *i, struct file *f); static int coda_ioctl_release(struct inode *i, struct file *f); static int coda_pioctl(struct inode * inode, struct file * filp, unsigned int cmd, unsigned long arg); /* exported from this file */ struct inode_operations coda_ioctl_inode_operations = { &coda_ioctl_operations, NULL, /* create */ NULL, /* lookup */ NULL, /* link */ NULL, /* unlink */ NULL, /* symlink */ NULL, /* mkdir */ NULL, /* rmdir */ NULL, /* mknod */ NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ NULL, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ coda_ioctl_permission, /* permission */ NULL, /* smap */ NULL, /* update page */ NULL /* revalidate */ }; struct file_operations coda_ioctl_operations = { NULL, /* lseek - default should work for coda */ NULL, /* read */ NULL, /* write */ NULL, /* readdir */ NULL, /* select - default */ coda_pioctl, /* ioctl */ NULL, /* mmap */ coda_ioctl_open, /* open */ coda_ioctl_release, /* release */ NULL, /* fsync */ }; /* the coda pioctl inode ops */ static int coda_ioctl_permission(struct inode *inode, int mask) { ENTRY; return 0; } /* The pioctl file ops*/ int coda_ioctl_open(struct inode *i, struct file *f) { ENTRY; CDEBUG(D_PIOCTL, "File inode number: %ld\n", f->f_dentry->d_inode->i_ino); EXIT; return 0; } int coda_ioctl_release(struct inode *i, struct file *f) { return 0; } static int coda_pioctl(struct inode * inode, struct file * filp, unsigned int cmd, unsigned long user_data) { struct dentry *target_de; int error; struct PioctlData data; struct inode *target_inode = NULL; struct cnode *cnp; ENTRY; /* get the Pioctl data arguments from user space */ if (copy_from_user(&data, (int *)user_data, sizeof(data))) { return -EINVAL; } /* * Look up the pathname. Note that the pathname is in * user memory, and namei takes care of this */ CDEBUG(D_PIOCTL, "namei, data.follow = %d\n", data.follow); if ( data.follow ) { target_de = namei(data.path); } else { target_de = lnamei(data.path); } if (!target_de) { CDEBUG(D_PIOCTL, "error: lookup fails.\n"); return -EINVAL; } else { target_inode = target_de->d_inode; } CDEBUG(D_PIOCTL, "target ino: 0x%ld, dev: 0x%d\n", target_inode->i_ino, target_inode->i_dev); /* return if it is not a Coda inode */ if ( target_inode->i_sb != inode->i_sb ) { if ( target_de ) dput(target_de); return -EINVAL; } /* now proceed to make the upcall */ cnp = ITOC(target_inode); CHECK_CNODE(cnp); error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data); CDEBUG(D_PIOCTL, "ioctl on inode %ld\n", target_inode->i_ino); if ( target_de ) dput(target_de); return error; }