linux26-unlocked-ioctl-20050413

FIXES 18224

add unlocked_ioctl support and compat_ioctl support
This commit is contained in:
Chaskiel M Grundman 2005-04-14 03:18:33 +00:00 committed by Derrick Brashear
parent c7774aa117
commit 12df63ce9a
4 changed files with 49 additions and 9 deletions

View File

@ -179,6 +179,9 @@ typedef struct uio {
/* Get/set the inode in the osifile struct. */
#define FILE_INODE(F) (F)->f_dentry->d_inode
#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
#define NEED_IOCTL32
#endif
/* page offset is obtained and stored here during module initialization
* We need a variable to do this because, the PAGE_OFFSET macro defined in

View File

@ -50,12 +50,21 @@ int afs_global_owner = 0;
unsigned long afs_linux_page_offset = 0; /* contains the PAGE_OFFSET value */
#endif
static int afs_ioctl(struct inode *, struct file *, unsigned int,
static inline int afs_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
#if defined(HAVE_UNLOCKED_IOCTL) || defined(HAVE_COMPAT_IOCTL)
static long afs_unlocked_ioctl(struct file *, unsigned int, unsigned long);
#endif
static struct file_operations afs_syscall_fops = {
#ifdef HAVE_UNLOCKED_IOCTL
.unlocked_ioctl = afs_unlocked_ioctl,
#else
.ioctl = afs_ioctl,
#endif
#ifdef HAVE_COMPAT_IOCTL
.compat_ioctl = afs_unlocked_ioctl,
#endif
};
int
@ -423,7 +432,7 @@ callproc_read(char *buffer, char **start, off_t offset, int count,
}
static struct proc_dir_entry *openafs_procfs;
#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
#if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
static int ioctl32_done;
#endif
@ -454,7 +463,7 @@ afsproc_init(void)
entry = create_proc_read_entry(PROC_SERVICES_NAME, (S_IFREG|S_IRUGO), openafs_procfs, servicesproc_read, NULL);
entry = create_proc_read_entry(PROC_RXSTATS_NAME, (S_IFREG|S_IRUGO), openafs_procfs, rxstatsproc_read, NULL);
#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
#if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
if (register_ioctl32_conversion(VIOC_SYSCALL32, NULL) == 0)
ioctl32_done = 1;
#endif
@ -474,7 +483,7 @@ afsproc_exit(void)
remove_proc_entry(PROC_CELLSERVDB_NAME, openafs_procfs);
remove_proc_entry(PROC_SYSCALL_NAME, openafs_procfs);
remove_proc_entry(PROC_FSDIRNAME, proc_root_fs);
#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
#if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
if (ioctl32_done)
unregister_ioctl32_conversion(VIOC_SYSCALL32);
#endif
@ -490,11 +499,13 @@ afs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
{
struct afsprocdata sysargs;
#ifdef NEED_IOCTL32
struct afsprocdata32 sysargs32;
#endif
if (cmd != VIOC_SYSCALL && cmd != VIOC_SYSCALL32) return -EINVAL;
#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
#ifdef NEED_IOCTL32
#ifdef AFS_SPARC64_LINUX24_ENV
if (current->thread.flags & SPARC_FLAG_32BIT)
#elif defined(AFS_SPARC64_LINUX20_ENV)
@ -539,6 +550,12 @@ afs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}
}
#if defined(HAVE_UNLOCKED_IOCTL) || defined(HAVE_COMPAT_IOCTL)
static long afs_unlocked_ioctl(struct file *file, unsigned int cmd,
unsigned long arg) {
return afs_ioctl(FILE_INODE(file), file, cmd, arg);
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
int __init

View File

@ -426,6 +426,13 @@ out1:
extern int afs_xioctl(struct inode *ip, struct file *fp, unsigned int com,
unsigned long arg);
#if defined(HAVE_UNLOCKED_IOCTL) || defined(HAVE_COMPAT_IOCTL)
static long afs_unlocked_xioctl(struct file *fp, unsigned int com,
unsigned long arg) {
return afs_xioctl(FILE_INODE(fp), fp, com, arg);
}
#endif
/* We need to detect unmap's after close. To do that, we need our own
* vm_operations_struct's. And we need to set them up for both the
@ -733,7 +740,14 @@ struct file_operations afs_dir_fops = {
.read = generic_read_dir,
#endif
.readdir = afs_linux_readdir,
#ifdef HAVE_UNLOCKED_IOCTL
.unlocked_ioctl = afs_unlocked_xioctl,
#else
.ioctl = afs_xioctl,
#endif
#ifdef HAVE_COMPAT_IOCTL
.compat_ioctl = afs_unlocked_xioctl,
#endif
.open = afs_linux_open,
.release = afs_linux_release,
};
@ -741,7 +755,14 @@ struct file_operations afs_dir_fops = {
struct file_operations afs_file_fops = {
.read = afs_linux_read,
.write = afs_linux_write,
#ifdef HAVE_UNLOCKED_IOCTL
.unlocked_ioctl = afs_unlocked_xioctl,
#else
.ioctl = afs_xioctl,
#endif
#ifdef HAVE_COMPAT_IOCTL
.compat_ioctl = afs_unlocked_xioctl,
#endif
.mmap = afs_linux_mmap,
.open = afs_linux_open,
.flush = afs_linux_flush,

View File

@ -195,7 +195,7 @@ static int (*(CpioctlSw[])) () = {
#define PSetClientContext 99 /* Special pioctl to setup caller's creds */
int afs_nobody = NFS_NOBODY;
#if (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)) || defined(AFS_HPUX_64BIT_ENV) || defined(AFS_SUN57_64BIT_ENV) || (defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64)) || (defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV))
#if (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)) || defined(AFS_HPUX_64BIT_ENV) || defined(AFS_SUN57_64BIT_ENV) || (defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64)) || defined(NEED_IOCTL32)
static void
afs_ioctl32_to_afs_ioctl(const struct afs_ioctl32 *src, struct afs_ioctl *dst)
{
@ -603,8 +603,7 @@ afs_xioctl(void)
AFS_GLOCK();
datap =
(struct afs_ioctl *)osi_AllocSmallSpace(AFS_SMALLOCSIZ);
AFS_COPYIN((char *)uap->arg, (caddr_t) datap,
sizeof(struct afs_ioctl), code);
code=copyin_afs_ioctl((char *)uap->arg, datap);
if (code) {
osi_FreeSmallSpace(datap);
AFS_GUNLOCK();