mirror of
https://git.openafs.org/openafs.git
synced 2025-01-31 13:38:01 +00:00
linux26-unlocked-ioctl-20050413
FIXES 18224 add unlocked_ioctl support and compat_ioctl support
This commit is contained in:
parent
c7774aa117
commit
12df63ce9a
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user