CVSROOT:        /cvs/cluster
Module name:    cluster
Changes by:     [EMAIL PROTECTED]       2008-01-24 20:54:31

Modified files:
        gfs-kernel/src/gfs: gfs_ioctl.h ioctl.c ioctl.h ops_file.c 

Log message:
        Resolves: bz 429633: gfs_tool doesn't recognize GFS file sytem

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/gfs_ioctl.h.diff?cvsroot=cluster&r1=1.11&r2=1.12
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/ioctl.c.diff?cvsroot=cluster&r1=1.17&r2=1.18
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/ioctl.h.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/ops_file.c.diff?cvsroot=cluster&r1=1.36&r2=1.37

--- cluster/gfs-kernel/src/gfs/gfs_ioctl.h      2006/07/10 23:22:34     1.11
+++ cluster/gfs-kernel/src/gfs/gfs_ioctl.h      2008/01/24 20:54:31     1.12
@@ -22,12 +22,23 @@
 #define GFS_IOCTL_SUPER         _GFSC_(45)
 
 struct gfs_ioctl {
-       unsigned int gi_argc;
-       char **gi_argv;
+        unsigned int gi_argc;
+        char **gi_argv;
 
         char __user *gi_data;
+        unsigned int gi_size;
+        uint64_t gi_offset;
+};
+
+#ifdef CONFIG_COMPAT
+struct gfs_ioctl_compat {
+       unsigned int gi_argc;
+       uint32_t gi_argv;
+
+       uint32_t gi_data;
        unsigned int gi_size;
        uint64_t gi_offset;
 };
+#endif
 
 #endif /* ___GFS_IOCTL_DOT_H__ */
--- cluster/gfs-kernel/src/gfs/ioctl.c  2007/06/19 21:26:11     1.17
+++ cluster/gfs-kernel/src/gfs/ioctl.c  2008/01/24 20:54:31     1.18
@@ -19,6 +19,7 @@
 #include <linux/completion.h>
 #include <linux/buffer_head.h>
 #include <asm/uaccess.h>
+#include <linux/compat.h>
 
 #include "gfs_ioctl.h"
 #include "gfs.h"
@@ -509,7 +510,7 @@
  */
 
 static int
-gi_set_tune(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_set_tune(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
 {
        struct gfs_tune *gt = &sdp->sd_tune;
        char param[ARG_SIZE], value[ARG_SIZE];
@@ -521,12 +522,21 @@
        if (gi->gi_argc != 3)
                return -EINVAL;
 
-       if (strncpy_from_user(param, gi->gi_argv[1], ARG_SIZE) < 0)
-               return -EFAULT;
+       if (from_user) {
+               if (strncpy_from_user(param, gi->gi_argv[1], ARG_SIZE) < 0)
+                       return -EFAULT;
+       } else {
+               strncpy(param, gi->gi_argv[1], ARG_SIZE);
+       }
        param[ARG_SIZE - 1] = 0;
 
-       if (strncpy_from_user(value, gi->gi_argv[2], ARG_SIZE) < 0)
-               return -EFAULT;
+       if (from_user) {
+               if (strncpy_from_user(value, gi->gi_argv[2], ARG_SIZE) < 0)
+                       return -EFAULT;
+       } else {
+               strncpy(value, gi->gi_argv[2], ARG_SIZE);
+       }
+
        value[ARG_SIZE - 1] = 0;
 
        if (strcmp(param, "ilimit1") == 0) {
@@ -884,7 +894,7 @@
  */
 
 static int
-gi_set_file_flag(struct gfs_inode *ip, struct gfs_ioctl *gi)
+gi_set_file_flag(struct gfs_inode *ip, struct gfs_ioctl *gi, int from_user)
 {
        char buf[ARG_SIZE];
        int set;
@@ -896,8 +906,12 @@
        if (gi->gi_argc != 3)
                return -EINVAL;
 
-       if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
-               return -EFAULT;
+       if (from_user) {
+               if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
+                       return -EFAULT;
+       } else {
+               strncpy(buf, gi->gi_argv[1], ARG_SIZE);
+       }
        buf[ARG_SIZE - 1] = 0;
 
        if (strcmp(buf, "set") == 0)
@@ -907,8 +921,12 @@
        else
                return -EINVAL;
 
-        if (strncpy_from_user(buf, gi->gi_argv[2], ARG_SIZE) < 0)
-                return -EFAULT;
+       if (from_user) {
+               if (strncpy_from_user(buf, gi->gi_argv[2], ARG_SIZE) < 0)
+                       return -EFAULT;
+       } else {
+               strncpy(buf, gi->gi_argv[2], ARG_SIZE);
+       }
         buf[ARG_SIZE - 1] = 0;
 
        error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
@@ -1065,15 +1083,19 @@
  */
 
 static struct gfs_inode *
-gi2hip(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi2hip(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
 {
        char buf[ARG_SIZE];
 
        if (gi->gi_argc != 2)
                return ERR_PTR(-EINVAL);
 
-        if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
-                return ERR_PTR(-EFAULT);
+       if (from_user) {
+               if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
+                       return ERR_PTR(-EFAULT);
+       } else {
+               strncpy(buf, gi->gi_argv[1], ARG_SIZE);
+       }
         buf[ARG_SIZE - 1] = 0;
 
        if (strcmp(buf, "jindex") == 0)
@@ -1097,14 +1119,14 @@
  */
 
 static int
-gi_get_hfile_stat(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_get_hfile_stat(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
 {
        struct gfs_inode *ip;
        struct gfs_dinode *di;
        struct gfs_holder i_gh;
        int error;
 
-       ip = gi2hip(sdp, gi);
+       ip = gi2hip(sdp, gi, from_user);
        if (IS_ERR(ip))
                return PTR_ERR(ip);
 
@@ -1142,7 +1164,7 @@
  */
 
 static int
-gi_do_hfile_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_do_hfile_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
 {
        struct gfs_inode *ip;
        struct gfs_holder i_gh;
@@ -1151,7 +1173,7 @@
         if (!capable(CAP_SYS_ADMIN))
                 return -EACCES;
 
-       ip = gi2hip(sdp, gi);
+       ip = gi2hip(sdp, gi, from_user);
        if (IS_ERR(ip))
                return PTR_ERR(ip);
 
@@ -1179,7 +1201,7 @@
  */
 
 static int
-gi_do_hfile_write(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_do_hfile_write(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
 {
        struct gfs_inode *ip;
        struct gfs_alloc *al = NULL;
@@ -1191,7 +1213,7 @@
         if (!capable(CAP_SYS_ADMIN))
                 return -EACCES;
 
-       ip = gi2hip(sdp, gi);
+       ip = gi2hip(sdp, gi, from_user);
        if (IS_ERR(ip))
                return PTR_ERR(ip);
 
@@ -1248,8 +1270,12 @@
                        goto out_relse;
        }
 
-       error = gfs_writei(ip, gi->gi_data, gi->gi_offset, gi->gi_size,
-                          gfs_copy_from_user, NULL);
+       if (from_user)
+               error = gfs_writei(ip, gi->gi_data, gi->gi_offset, gi->gi_size,
+                                  gfs_copy_from_user, NULL);
+       else
+               error = gfs_writei(ip, gi->gi_data, gi->gi_offset, gi->gi_size,
+                                  gfs_copy_from_mem, NULL);
 
        gfs_trans_end(sdp);
 
@@ -1283,7 +1309,7 @@
  */
 
 static int
-gi_do_hfile_trunc(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_do_hfile_trunc(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
 {
        struct gfs_inode *ip;
        struct gfs_holder i_gh;
@@ -1292,7 +1318,7 @@
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
 
-       ip = gi2hip(sdp, gi);
+       ip = gi2hip(sdp, gi, from_user);
        if (IS_ERR(ip))
                return PTR_ERR(ip);
 
@@ -1335,7 +1361,7 @@
  */
 
 static int
-gi_do_quota_refresh(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_do_quota_refresh(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
 {
        char buf[ARG_SIZE];
        int user;
@@ -1346,8 +1372,12 @@
        if (gi->gi_argc != 2)
                return -EINVAL;
 
-        if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
-                return -EFAULT;
+       if (from_user) {
+               if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
+                       return -EFAULT;
+       } else {
+               strncpy(buf, gi->gi_argv[1], ARG_SIZE);
+       }
         buf[ARG_SIZE - 1] = 0;
 
        switch (buf[0]) {
@@ -1379,7 +1409,7 @@
  */
 
 static int
-gi_do_quota_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_do_quota_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
 {
        char buf[ARG_SIZE];
        int user;
@@ -1392,8 +1422,12 @@
        if (gi->gi_size != sizeof(struct gfs_quota))
                return -EINVAL;
 
-        if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
-                return -EFAULT;
+       if (from_user) {
+               if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
+                       return -EFAULT;
+       } else {
+               strncpy(buf, gi->gi_argv[1], ARG_SIZE);
+       }
         buf[ARG_SIZE - 1] = 0;
 
        switch (buf[0]) {
@@ -1423,8 +1457,64 @@
        return 0;
 }
 
+int
+gfs_ioctl_i_local(struct gfs_inode *ip, struct gfs_ioctl *gi, const char *arg0,
+       int from_user)
+{
+       int error = -EFAULT;
+
+       if (strcmp(arg0, "get_cookie") == 0)
+               error = gi_skeleton(ip, gi, gi_get_cookie);
+       else if (strcmp(arg0, "get_super") == 0)
+               error = gi_get_super(ip->i_sbd, gi);
+       else if (strcmp(arg0, "get_args") == 0)
+               error = gi_skeleton(ip, gi, gi_get_args);
+       else if (strcmp(arg0, "get_lockstruct") == 0)
+               error = gi_skeleton(ip, gi, gi_get_lockstruct);
+       else if (strcmp(arg0, "get_stat_gfs") == 0)
+               error = gi_skeleton(ip, gi, gi_get_stat_gfs);
+       else if (strcmp(arg0, "get_counters") == 0)
+               error = gi_skeleton(ip, gi, gi_get_counters);
+       else if (strcmp(arg0, "get_tune") == 0)
+               error = gi_skeleton(ip, gi, gi_get_tune);
+       else if (strcmp(arg0, "set_tune") == 0)
+               error = gi_set_tune(ip->i_sbd, gi, from_user);
+       else if (strcmp(arg0, "do_reclaim") == 0)
+               error = gi_skeleton(ip, gi, gi_do_reclaim);
+       else if (strcmp(arg0, "do_shrink") == 0)
+               error = gi_do_shrink(ip->i_sbd, gi);
+       else if (strcmp(arg0, "get_file_stat") == 0)
+               error = gi_get_file_stat(ip, gi);
+       else if (strcmp(arg0, "set_file_flag") == 0)
+               error = gi_set_file_flag(ip, gi, from_user);
+       else if (strcmp(arg0, "get_file_meta") == 0)
+               error = gi_get_file_meta(ip, gi);
+       else if (strcmp(arg0, "get_file_meta_quota") == 0)
+               error = gi_get_file_meta(ip->i_sbd->sd_qinode, &gi);
+       else if (strcmp(arg0, "do_file_flush") == 0)
+               error = gi_do_file_flush(ip, gi);
+       else if (strcmp(arg0, "get_hfile_stat") == 0)
+               error = gi_get_hfile_stat(ip->i_sbd, gi, from_user);
+       else if (strcmp(arg0, "do_hfile_read") == 0)
+               error = gi_do_hfile_read(ip->i_sbd, gi, from_user);
+       else if (strcmp(arg0, "do_hfile_write") == 0)
+               error = gi_do_hfile_write(ip->i_sbd, gi, from_user);
+       else if (strcmp(arg0, "do_hfile_trunc") == 0)
+               error = gi_do_hfile_trunc(ip->i_sbd, gi, from_user);
+       else if (strcmp(arg0, "do_quota_sync") == 0)
+               error = gi_do_quota_sync(ip->i_sbd, gi);
+       else if (strcmp(arg0, "do_quota_refresh") == 0)
+               error = gi_do_quota_refresh(ip->i_sbd, gi, from_user);
+       else if (strcmp(arg0, "do_quota_read") == 0)
+               error = gi_do_quota_read(ip->i_sbd, gi, from_user);
+       else
+               error = -ENOTTY;
+
+       return error;
+}
+
 /**
- * gfs_ioctl_i -
+ * gfs_ioctl_i - Normal ioctls
  * @ip:
  * @arg:
  *
@@ -1455,58 +1545,73 @@
        if (strncpy_from_user(arg0, argv[0], ARG_SIZE) < 0)
                goto out;
        arg0[ARG_SIZE - 1] = 0;
-
-       if (strcmp(arg0, "get_cookie") == 0)
-                error = gi_skeleton(ip, &gi, gi_get_cookie);
-       else if (strcmp(arg0, "get_super") == 0)
-               error = gi_get_super(ip->i_sbd, &gi);
-       else if (strcmp(arg0, "get_args") == 0)
-               error = gi_skeleton(ip, &gi, gi_get_args);
-       else if (strcmp(arg0, "get_lockstruct") == 0)
-               error = gi_skeleton(ip, &gi, gi_get_lockstruct);
-        else if (strcmp(arg0, "get_stat_gfs") == 0)
-                error = gi_skeleton(ip, &gi, gi_get_stat_gfs);
-        else if (strcmp(arg0, "get_counters") == 0)
-                error = gi_skeleton(ip, &gi, gi_get_counters);
-        else if (strcmp(arg0, "get_tune") == 0)
-                error = gi_skeleton(ip, &gi, gi_get_tune);
-       else if (strcmp(arg0, "set_tune") == 0)
-               error = gi_set_tune(ip->i_sbd, &gi);
-       else if (strcmp(arg0, "do_reclaim") == 0)
-               error = gi_skeleton(ip, &gi, gi_do_reclaim);
-       else if (strcmp(arg0, "do_shrink") == 0)
-               error = gi_do_shrink(ip->i_sbd, &gi);
-       else if (strcmp(arg0, "get_file_stat") == 0)
-               error = gi_get_file_stat(ip, &gi);
-       else if (strcmp(arg0, "set_file_flag") == 0)
-               error = gi_set_file_flag(ip, &gi);
-       else if (strcmp(arg0, "get_file_meta") == 0)
-               error = gi_get_file_meta(ip, &gi);
-       else if (strcmp(arg0, "get_file_meta_quota") == 0)
-               error = gi_get_file_meta(ip->i_sbd->sd_qinode, &gi);
-       else if (strcmp(arg0, "do_file_flush") == 0)
-               error = gi_do_file_flush(ip, &gi);
-       else if (strcmp(arg0, "get_hfile_stat") == 0)
-               error = gi_get_hfile_stat(ip->i_sbd, &gi);
-       else if (strcmp(arg0, "do_hfile_read") == 0)
-               error = gi_do_hfile_read(ip->i_sbd, &gi);
-       else if (strcmp(arg0, "do_hfile_write") == 0)
-               error = gi_do_hfile_write(ip->i_sbd, &gi);
-       else if (strcmp(arg0, "do_hfile_trunc") == 0)
-               error = gi_do_hfile_trunc(ip->i_sbd, &gi);
-       else if (strcmp(arg0, "do_quota_sync") == 0)
-               error = gi_do_quota_sync(ip->i_sbd, &gi);
-       else if (strcmp(arg0, "do_quota_refresh") == 0)
-               error = gi_do_quota_refresh(ip->i_sbd, &gi);
-       else if (strcmp(arg0, "do_quota_read") == 0)
-               error = gi_do_quota_read(ip->i_sbd, &gi);
-       else
-               error = -ENOTTY;
-
+       error = gfs_ioctl_i_local(ip, &gi, arg0, 1);
  out:
        kfree(argv);
 
        return error;
 }
 
+#ifdef CONFIG_COMPAT
+/**
+ * gfs_ioctl_i_compat - compatibility ioctls
+ *                      These ioctls are used to provide ioctls for situations
+ *                      where userland and kernel arch is different.
+ *                      For example, userland may be 32-bit ppc whereas the
+ *                      kernel may be ppc64.  In this case, we need to do
+ *                      extra translation between the addresses.
+ * @ip:
+ * @arg:
+ *
+ * Returns: -errno or positive byte count
+ */
+
+int
+gfs_ioctl_i_compat(struct gfs_inode *ip, unsigned long arg)
+{
+       struct gfs_ioctl_compat *src;
+       struct gfs_ioctl dst;
+       char **argv, *argptr;
+       uint32_t *ptr;
+       char arg0[ARG_SIZE];
+       char *tmparg;
+       int i;
+       int error = -EFAULT;
+
+       src = (struct gfs_ioctl_compat *)compat_ptr(arg);
+
+       memset(&dst, 0, sizeof(dst));
+       dst.gi_argc = src->gi_argc;
+       dst.gi_size = src->gi_size;
+       dst.gi_offset = src->gi_offset;
+
+       argv = kmalloc(dst.gi_argc * sizeof(char *), GFP_KERNEL);
+       if (!argv)
+               return -ENOMEM;
+
+       memset(argv, 0, dst.gi_argc * sizeof(char *));
+       ptr = (uint32_t *)compat_ptr(src->gi_argv);
+
+       for (i = 0; i < dst.gi_argc; i++) { /* for each parm */
+               tmparg = kmalloc(ARG_SIZE * sizeof(char *), GFP_KERNEL);
+               if (!tmparg)
+                       goto out;
+               argptr = (char *)compat_ptr(*ptr);
+               if (strncpy_from_user(tmparg, argptr, ARG_SIZE) < 0)
+                       goto out;
+               argv[i] = tmparg;
+               ptr++;
+       }
 
+       strncpy(arg0, argv[0], ARG_SIZE);
+       arg0[ARG_SIZE - 1] = 0;
+       dst.gi_argv = argv;
+       dst.gi_data = compat_ptr(src->gi_data);
+       error = gfs_ioctl_i_local(ip, &dst, arg0, 0);
+ out:
+       for (i = 0; i < dst.gi_argc; i++)
+               kfree(argv[i]);
+       kfree(argv);
+       return error;
+}
+#endif
--- cluster/gfs-kernel/src/gfs/ioctl.h  2006/07/10 23:22:34     1.3
+++ cluster/gfs-kernel/src/gfs/ioctl.h  2008/01/24 20:54:31     1.4
@@ -14,6 +14,9 @@
 #ifndef __IOCTL_DOT_H__
 #define __IOCTL_DOT_H__
 
+int gfs_ioctl_i_local(struct gfs_inode *ip, struct gfs_ioctl *gi,
+                     const char *arg0, int from_user);
+int gfs_ioctl_i_compat(struct gfs_inode *ip, unsigned long arg);
 int gfs_ioctl_i(struct gfs_inode *ip, void *arg);
 
 #endif /* __IOCTL_DOT_H__ */
--- cluster/gfs-kernel/src/gfs/ops_file.c       2007/07/13 15:19:16     1.36
+++ cluster/gfs-kernel/src/gfs/ops_file.c       2008/01/24 20:54:31     1.37
@@ -26,6 +26,7 @@
 #include <linux/aio.h>
 #include <linux/writeback.h>
 #include <asm/uaccess.h>
+#include <linux/compat.h>
 
 #include "gfs_ioctl.h"
 #include "gfs.h"
@@ -333,17 +334,17 @@
                        goto out_gunlock;
 
                count = do_read_readi(file, buf, size & ~mask, offset, iocb);
-       }
-       else {
-               if (!iocb)
-                       count = do_sync_read(file, buf, size, offset);
-               else {
-                       struct iovec local_iov = { .iov_base = buf, .iov_len = 
size};
-
-                       count = generic_file_aio_read(iocb, &local_iov, 1, 
*offset);
-                       iocb->ki_pos = *offset;
-               }
-       }
+        }
+        else {
+                if (!iocb) 
+                        count = do_sync_read(file, buf, size, offset);
+                else {
+                        struct iovec local_iov = { .iov_base = buf, .iov_len = 
size};
+
+                        count = generic_file_aio_read(iocb, &local_iov, 1, 
*offset);
+                        iocb->ki_pos = *offset;
+                }
+        }
 
        error = 0;
 
@@ -387,17 +388,17 @@
 
        if (gfs_is_jdata(ip) ||
            (gfs_is_stuffed(ip) && !test_bit(GIF_PAGED, &ip->i_flags)))
-               count = do_read_readi(file, buf, size, offset, iocb);
-       else {
-               if (!iocb) {
-                       count = do_sync_read(file, buf, size, offset);
-               } else {
-                       struct iovec local_iov = { .iov_base = buf, .iov_len = 
size};
-
-                       count = generic_file_aio_read(iocb, &local_iov, 1, 
*offset);
-                       iocb->ki_pos = *offset;
-               }
-       }
+                count = do_read_readi(file, buf, size, offset, iocb);
+        else {
+                if (!iocb) {
+                        count = do_sync_read(file, buf, size, offset);
+                } else {
+                        struct iovec local_iov = { .iov_base = buf, .iov_len = 
size};
+
+                        count = generic_file_aio_read(iocb, &local_iov, 1, 
*offset);
+                        iocb->ki_pos = *offset;
+                }
+        }
 
        gfs_glock_dq_m(num_gh + 1, ghs);
 
@@ -438,16 +439,16 @@
 
 /*
  * gfs_aio_read: match with vfs generic_file_aio_read as:
- *     (struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
+ *      (struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
  */
 static ssize_t
 gfs_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long count,
-                        loff_t pos)
+                         loff_t pos)
 {
-       struct file *filp = iocb->ki_filp;
+        struct file *filp = iocb->ki_filp;
 
-       BUG_ON(iocb->ki_pos != pos);
-       return(__gfs_read(filp, iov->iov_base, iov->iov_len, &iocb->ki_pos, 
iocb));
+        BUG_ON(iocb->ki_pos != pos);
+        return(__gfs_read(filp, iov->iov_base, iov->iov_len, &iocb->ki_pos, 
iocb));
 }
 
 /**
@@ -493,27 +494,27 @@
  */
 static ssize_t
 gfs_file_aio_write_nolock(struct file *file, char *buf, size_t size,
-                                                 loff_t *offset, struct kiocb 
*iocb)
+                                                  loff_t *offset, struct kiocb 
*iocb)
 {
-       struct iovec local_iov = { .iov_base = buf, .iov_len = size };
-       struct kiocb local_iocb, *kiocb = NULL;
-       ssize_t count;
-
-       if (!iocb) {
-               init_sync_kiocb(&local_iocb, file);
-               local_iocb.ki_nr_segs = 1;
-               kiocb = &local_iocb;
-       }
-       else
-               kiocb = iocb;
-       
-       kiocb->ki_pos = *offset;
-       count = generic_file_aio_write_nolock(kiocb, &local_iov, 
kiocb->ki_nr_segs,
-                                                                               
  kiocb->ki_pos);
-       *offset = kiocb->ki_pos;
-       if (kiocb == &local_iocb && count == -EIOCBQUEUED)
-               count = wait_on_sync_kiocb(kiocb);
-       return count;
+        struct iovec local_iov = { .iov_base = buf, .iov_len = size };
+        struct kiocb local_iocb, *kiocb = NULL;
+        ssize_t count;
+
+        if (!iocb) {
+                init_sync_kiocb(&local_iocb, file);
+                local_iocb.ki_nr_segs = 1;
+                kiocb = &local_iocb;
+        }
+        else
+                kiocb = iocb;
+        
+        kiocb->ki_pos = *offset;
+        count = generic_file_aio_write_nolock(kiocb, &local_iov, 
kiocb->ki_nr_segs,
+                                                                               
   kiocb->ki_pos);
+        *offset = kiocb->ki_pos;
+        if (kiocb == &local_iocb && count == -EIOCBQUEUED)
+                count = wait_on_sync_kiocb(kiocb);
+        return count;
 }
 
 /**
@@ -533,12 +534,12 @@
                        struct kiocb *iocb)
 {
        struct inode *inode = file->f_mapping->host;
-       struct gfs_inode *ip = get_v2ip(inode);
-       struct gfs_sbd *sdp = ip->i_sbd;
-       struct gfs_alloc *al = NULL;
-       struct buffer_head *dibh;
-       unsigned int data_blocks, ind_blocks;
-       ssize_t count;
+        struct gfs_inode *ip = get_v2ip(inode);
+        struct gfs_sbd *sdp = ip->i_sbd;
+        struct gfs_alloc *al = NULL;
+        struct buffer_head *dibh;
+        unsigned int data_blocks, ind_blocks;
+        ssize_t count;
        int error;
 
        gfs_write_calc_reserv(ip, size, &data_blocks, &ind_blocks);
@@ -583,13 +584,13 @@
        }
 
        if (gfs_is_stuffed(ip)) { error = gfs_unstuff_dinode(ip, 
gfs_unstuffer_sync, NULL); if (error)
-                       goto fail_end_trans;
-       }
+                        goto fail_end_trans;
+        }
 
-       count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb);
-       if (count < 0) {
-               error = count;
-               goto fail_end_trans;
+        count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb);
+        if (count < 0) {
+                error = count;
+                goto fail_end_trans;
        }
 
        error = gfs_get_inode_buffer(ip, &dibh);
@@ -747,23 +748,23 @@
 
                        buf += error;
                        size -= error;
-                       count += error;
-               }
-       } else {
-               struct gfs_holder t_gh;
+                        count += error;
+                }
+        } else {
+                struct gfs_holder t_gh;
 
-               clear_bit(GFF_DID_DIRECT_ALLOC, &fp->f_flags);
+                clear_bit(GFF_DID_DIRECT_ALLOC, &fp->f_flags);
 
                error = gfs_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, 
&t_gh);
                if (error)
                        goto out_gunlock;
 
-               /* Todo: It would be nice if init_sync_kiocb is exported.
-                *  .. wcheng
-                */
-               count = gfs_file_aio_write_nolock(file, buf, size, offset, 
iocb);
-               gfs_glock_dq_uninit(&t_gh);
-       }
+                /* Todo: It would be nice if init_sync_kiocb is exported.
+                 *  .. wcheng
+                 */
+                count = gfs_file_aio_write_nolock(file, buf, size, offset, 
iocb);
+                gfs_glock_dq_uninit(&t_gh);
+        }
 
 out_iocb_write:
        error = 0;
@@ -881,13 +882,13 @@
                                ClearPageUptodate(page);
                                page_cache_release(page);
                        }
-               }
-               *offset += count;
-       } else {
-               count = gfs_file_aio_write_nolock(file, buf, size, offset, 
iocb);
-               if (count < 0) {
-                       error = count;
-                       goto fail_end_trans;
+                }
+                *offset += count;
+        } else {
+                count = gfs_file_aio_write_nolock(file, buf, size, offset, 
iocb);
+                if (count < 0) {
+                        error = count;
+                        goto fail_end_trans;
                }
 
                error = gfs_get_inode_buffer(ip, &dibh);
@@ -1061,14 +1062,14 @@
 
 static ssize_t
 gfs_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long segs,
-                         loff_t pos)
+                          loff_t pos)
 {
-       struct file *file = iocb->ki_filp;
+        struct file *file = iocb->ki_filp;
 
-       BUG_ON(iocb->ki_pos != pos);
+        BUG_ON(iocb->ki_pos != pos);
 
-       return(__gfs_write(file, iov->iov_base, iov->iov_len, &iocb->ki_pos, 
-                                          iocb));
+        return(__gfs_write(file, iov->iov_base, iov->iov_len, &iocb->ki_pos, 
+                                           iocb));
 }
 
 /**
@@ -1373,6 +1374,41 @@
        }
 }
 
+#ifdef CONFIG_COMPAT
+/**
+ * gfs_compat_ioctl - do an ioctl on a file - compatible between 32-64 bit
+ * @inode: the inode
+ * @file: the file pointer
+ * @cmd: the ioctl command
+ * @arg: the argument
+ *
+ * Returns: errno
+ */
+
+static long
+gfs_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+{
+        struct gfs_inode *ip = get_v2ip(file->f_mapping->host);
+
+       atomic_inc(&ip->i_sbd->sd_ops_file);
+
+       switch (cmd) {
+       case GFS_IOCTL_IDENTIFY: {
+                unsigned int x = GFS_MAGIC;
+                if (copy_to_user((unsigned int *)arg, &x, sizeof(unsigned 
int)))
+                        return -EFAULT;
+               return 0;
+        }
+
+        case GFS_IOCTL_SUPER:
+                return gfs_ioctl_i_compat(ip, arg);
+
+        default:
+                return -ENOTTY;
+       }
+}
+#endif
+
 /**
  * gfs_mmap - We don't support shared writable mappings right now
  * @file: The file to map
@@ -1577,24 +1613,24 @@
 
        if (!(fl->fl_flags & FL_POSIX))
                return -ENOLCK;
-       if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
-               return -ENOLCK;
+        if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+                return -ENOLCK;
 
-       if (sdp->sd_args.ar_localflocks) {
-               if (IS_GETLK(cmd)) {
-                       posix_test_lock(file, fl);
-                       return 0;
-               } else {
-                       return posix_lock_file_wait(file, fl);
-               }
-       }
+        if (sdp->sd_args.ar_localflocks) {
+                if (IS_GETLK(cmd)) {
+                        posix_test_lock(file, fl);
+                        return 0;
+                } else {
+                        return posix_lock_file_wait(file, fl);
+                }
+        }
 
-       if (IS_GETLK(cmd))
-               return gfs_lm_plock_get(sdp, &name, file, fl);
-       else if (fl->fl_type == F_UNLCK)
+        if (IS_GETLK(cmd))
+                return gfs_lm_plock_get(sdp, &name, file, fl);
+        else if (fl->fl_type == F_UNLCK)
                return gfs_lm_punlock(sdp, &name, file, fl);
        else
-               return gfs_lm_plock(sdp, &name, file, cmd, fl);
+                return gfs_lm_plock(sdp, &name, file, cmd, fl);
 }
 
 #if 0
@@ -1635,7 +1671,7 @@
  out:
        gfs_holder_uninit(&gh);
 
-       return retval;
+        return retval;
 }
 #endif
 
@@ -1731,22 +1767,22 @@
 static int
 gfs_flock(struct file *file, int cmd, struct file_lock *fl)
 {
-       struct gfs_inode *ip = get_v2ip(file->f_mapping->host);
-       struct gfs_sbd *sdp = ip->i_sbd;
+        struct gfs_inode *ip = get_v2ip(file->f_mapping->host);
+        struct gfs_sbd *sdp = ip->i_sbd;
 
-       atomic_inc(&ip->i_sbd->sd_ops_file);
+        atomic_inc(&ip->i_sbd->sd_ops_file);
 
        if (!(fl->fl_flags & FL_FLOCK))
                return -ENOLCK;
-       if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
-               return -ENOLCK;
+        if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+                return -ENOLCK;
 
-       if (sdp->sd_args.ar_localflocks)
-               return flock_lock_file_wait(file, fl);
+        if (sdp->sd_args.ar_localflocks)
+                return flock_lock_file_wait(file, fl);
 
-       if (fl->fl_type == F_UNLCK) {
-               do_unflock(file, fl);
-               return 0;
+        if (fl->fl_type == F_UNLCK) {
+                do_unflock(file, fl);
+                return 0;
        } else
                return do_flock(file, cmd, fl);
 }
@@ -1758,21 +1794,27 @@
         .aio_read = gfs_aio_read,
         .aio_write = gfs_aio_write,
        .ioctl = gfs_ioctl,
+#ifdef CONFIG_COMPAT
+        .compat_ioctl   = gfs_compat_ioctl,
+#endif
        .mmap = gfs_mmap,
        .open = gfs_open,
-       .release = gfs_close,
-       .fsync = gfs_fsync,
-       .lock = gfs_lock,
-       /* .sendfile = gfs_sendfile, */
-       .flock = gfs_flock,
+        .release = gfs_close,
+        .fsync = gfs_fsync,
+        .lock = gfs_lock,
+        /* .sendfile = gfs_sendfile, */
+        .flock = gfs_flock,
 };
 
 struct file_operations gfs_dir_fops = {
        .readdir = gfs_readdir,
        .ioctl = gfs_ioctl,
+#ifdef CONFIG_COMPAT
+        .compat_ioctl   = gfs_compat_ioctl,
+#endif
        .open = gfs_open,
        .release = gfs_close,
        .fsync = gfs_fsync,
-       .lock = gfs_lock,
-       .flock = gfs_flock,
+        .lock = gfs_lock,
+        .flock = gfs_flock,
 };

Reply via email to