]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-linux26-unlocked-ioctl-20050413
authorChaskiel M Grundman <cg2v@andrew.cmu.edu>
Sun, 24 Apr 2005 21:12:39 +0000 (21:12 +0000)
committerDerrick Brashear <shadow@dementia.org>
Sun, 24 Apr 2005 21:12:39 +0000 (21:12 +0000)
FIXES 18224

add unlocked_ioctl support and compat_ioctl support

(cherry picked from commit 12df63ce9a626dded034e90f92ec9f15326ab96c)

src/afs/LINUX/osi_machdep.h
src/afs/LINUX/osi_module.c
src/afs/LINUX/osi_vnodeops.c
src/afs/afs_pioctl.c

index 142389e4607adbd748df243d71800fbcabd85396..1ff8d5925b6eab07434034b753f6bd9e312b906f 100644 (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
index 86da2b5616a15fd550c9bf77841b2e7c8bd49087..bb7555d1488bfc19ede351a9ee8bf80f5fc69b99 100644 (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
@@ -166,7 +175,7 @@ csdbproc_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
 
@@ -186,7 +195,7 @@ afsproc_init(void)
 
     entry2 = create_proc_info_entry(PROC_CELLSERVDB_NAME, (S_IFREG|S_IRUGO), openafs_procfs, csdbproc_info);
 
-#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
@@ -199,7 +208,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
@@ -215,11 +224,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)
@@ -264,6 +275,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
index b20c33e299288668c56a2c04a57a32ea055b935b..03c4de82d2bb1e4a46f277d80b1fcd9dc07309d3 100644 (file)
@@ -425,6 +425,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
@@ -732,7 +739,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,
 };
@@ -740,7 +754,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,
index a85298b0b0dd8e5784344b515a5fdfa2d4832a9c..1d6a65ea056b399e8360630985a0330d18283c5b 100644 (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();