Wrapfs: support ->unlocked_ioctl and ->compat_ioctl
authorErez Zadok <ezk@cs.sunysb.edu>
Sat, 11 Sep 2010 19:49:33 +0000 (15:49 -0400)
committerErez Zadok <ezk@cs.sunysb.edu>
Mon, 30 Jan 2012 00:16:23 +0000 (19:16 -0500)
Old ->ioctl was split into ->unlocked_ioctl and ->compat_ioctl.  Compat
version doesn't need to lock_kernel any longer.

Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
fs/wrapfs/file.c

index 2cfac795c700d2e7477ab9bded8e9792d6a506cf..2ac8f4dd071e7698b658fad0e2c26b7e2c69ba4c 100644 (file)
@@ -63,7 +63,8 @@ static int wrapfs_readdir(struct file *file, void *dirent, filldir_t filldir)
        return err;
 }
 
-static long wrapfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long wrapfs_unlocked_ioctl(struct file *file, unsigned int cmd,
+                                 unsigned long arg)
 {
        long err = -ENOTTY;
        struct file *lower_file;
@@ -73,20 +74,33 @@ static long wrapfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        /* XXX: use vfs_ioctl if/when VFS exports it */
        if (!lower_file || !lower_file->f_op)
                goto out;
-       if (lower_file->f_op->unlocked_ioctl) {
+       if (lower_file->f_op->unlocked_ioctl)
                err = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg);
-       } else if (lower_file->f_op->ioctl) {
-               lock_kernel();
-               err = lower_file->f_op->ioctl(
-                       lower_file->f_path.dentry->d_inode,
-                       lower_file, cmd, arg);
-               unlock_kernel();
-       }
 
 out:
        return err;
 }
 
+#ifdef CONFIG_COMPAT
+static long wrapfs_compat_ioctl(struct file *file, unsigned int cmd,
+                               unsigned long arg)
+{
+       long err = -ENOTTY;
+       struct file *lower_file;
+
+       lower_file = wrapfs_lower_file(file);
+
+       /* XXX: use vfs_ioctl if/when VFS exports it */
+       if (!lower_file || !lower_file->f_op)
+               goto out;
+       if (lower_file->f_op->compat_ioctl)
+               err = lower_file->f_op->compat_ioctl(lower_file, cmd, arg);
+
+out:
+       return err;
+}
+#endif
+
 static int wrapfs_mmap(struct file *file, struct vm_area_struct *vma)
 {
        int err = 0;
@@ -253,7 +267,10 @@ const struct file_operations wrapfs_main_fops = {
        .llseek         = generic_file_llseek,
        .read           = wrapfs_read,
        .write          = wrapfs_write,
-       .unlocked_ioctl = wrapfs_ioctl,
+       .unlocked_ioctl = wrapfs_unlocked_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = wrapfs_compat_ioctl,
+#endif
        .mmap           = wrapfs_mmap,
        .open           = wrapfs_open,
        .flush          = wrapfs_flush,
@@ -267,7 +284,10 @@ const struct file_operations wrapfs_dir_fops = {
        .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
        .readdir        = wrapfs_readdir,
-       .unlocked_ioctl = wrapfs_ioctl,
+       .unlocked_ioctl = wrapfs_unlocked_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = wrapfs_compat_ioctl,
+#endif
        .open           = wrapfs_open,
        .release        = wrapfs_file_release,
        .flush          = wrapfs_flush,