Linux: Refactor test for 32bit compat
[openafs.git] / src / afs / LINUX / osi_ioctl.c
index 364241a..7d35567 100644 (file)
 #include <afsconfig.h>
 #include "afs/param.h"
 
-RCSID
-    ("$Header$");
 
 #include <linux/module.h> /* early to avoid printf->printk mapping */
 #include "afs/sysincludes.h"
 #include "afsincludes.h"
-#include "h/unistd.h"          /* For syscall numbers. */
-#include "h/mm.h"
+#include <linux/unistd.h>              /* For syscall numbers. */
+#include <linux/mm.h>
 
 #ifdef AFS_AMD64_LINUX20_ENV
 #include <asm/ia32_unistd.h>
 #endif
-#ifdef AFS_SPARC64_LINUX20_ENV
-#include <linux/ioctl32.h>
-#endif
 
-#include <linux/proc_fs.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 
+#include "osi_compat.h"
+
 extern struct proc_dir_entry *openafs_procfs;
-#if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
-static int ioctl32_done;
-#endif
 
 extern asmlinkage long
 afs_syscall(long syscall, long parm1, long parm2, long parm3, long parm4);
@@ -50,37 +43,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;
 
 #ifdef NEED_IOCTL32
-#ifdef AFS_LINUX26_ENV 
-#ifdef AFS_S390X_LINUX26_ENV
-    if (test_thread_flag(TIF_31BIT))
-#elif AFS_AMD64_LINUX20_ENV
-    if (test_thread_flag(TIF_IA32))
-#else
-    if (test_thread_flag(TIF_32BIT))
-#endif /* AFS_S390X_LINUX26_ENV */
-#else
-#ifdef AFS_SPARC64_LINUX24_ENV
-    if (current->thread.flags & SPARC_FLAG_32BIT)
-#elif defined(AFS_SPARC64_LINUX20_ENV)
-    if (current->tss.flags & SPARC_FLAG_32BIT)
-#elif defined(AFS_AMD64_LINUX20_ENV)
-    if (current->thread.flags & THREAD_IA32)
-#elif defined(AFS_PPC64_LINUX20_ENV)
-    if (current->thread.flags & PPC_FLAG_32BIT)
-#elif defined(AFS_S390X_LINUX20_ENV)
-    if (current->thread.flags & S390_FLAG_31BIT)
-#else
-#error Not done for this linux type
-#endif /* AFS_LINUX26_ENV */
-#endif /* NEED_IOCTL32 */
-    {
+    if (afs_in_compat_syscall()) {
+       struct afsprocdata32 sysargs32;
+
        if (copy_from_user(&sysargs32, (void *)arg,
                           sizeof(struct afsprocdata32)))
            return -EFAULT;
@@ -91,7 +60,7 @@ afs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                           (unsigned long)sysargs32.param3,
                           (unsigned long)sysargs32.param4);
     } else
-#endif
+#endif /* NEED_IOCTL32 */
     {
        if (copy_from_user(&sysargs, (void *)arg, sizeof(struct afsprocdata)))
            return -EFAULT;
@@ -101,45 +70,40 @@ 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
 
-static struct file_operations afs_syscall_fops = {
-#ifdef HAVE_UNLOCKED_IOCTL
-    .unlocked_ioctl = afs_unlocked_ioctl,
+#if defined(HAVE_LINUX_STRUCT_PROC_OPS)
+static struct proc_ops afs_syscall_ops = {
+    .proc_ioctl = afs_unlocked_ioctl,
+# ifdef STRUCT_PROC_OPS_HAS_PROC_COMPAT_IOCTL
+    .proc_compat_ioctl = afs_unlocked_ioctl,
+# endif
+};
 #else
-    .ioctl = afs_ioctl,
-#endif
-#ifdef HAVE_COMPAT_IOCTL
+static struct file_operations afs_syscall_ops = {
+    .unlocked_ioctl = afs_unlocked_ioctl,
     .compat_ioctl = afs_unlocked_ioctl,
-#endif
 };
+#endif /* HAVE_LINUX_STRUCT_PROC_OPS */
 
 void
 osi_ioctl_init(void)
 {
     struct proc_dir_entry *entry;
 
-    entry = create_proc_entry(PROC_SYSCALL_NAME, 0666, openafs_procfs);
-    entry->proc_fops = &afs_syscall_fops;
-    entry->owner = THIS_MODULE;
-
-#if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
-    if (register_ioctl32_conversion(VIOC_SYSCALL32, NULL) == 0) 
-       ioctl32_done = 1;
+    entry = afs_proc_create(PROC_SYSCALL_NAME, 0666, openafs_procfs, &afs_syscall_ops);
+#if defined(STRUCT_PROC_DIR_ENTRY_HAS_OWNER)
+    if (entry)
+       entry->owner = THIS_MODULE;
 #endif
+
 }
 
 void
 osi_ioctl_clean(void)
 {
     remove_proc_entry(PROC_SYSCALL_NAME, openafs_procfs);
-#if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
-    if (ioctl32_done)
-           unregister_ioctl32_conversion(VIOC_SYSCALL32);
-#endif
 }