Commit 34e6c59af06cbca07b1490ec0015ea2d303470d3

Authored by Tao Ma
Committed by Joel Becker
1 parent cd34edd8cf

ocfs2: Use compat_ptr in reflink_arguments.

Although we use u64 to pass userspace pointers to the kernel
to avoid compat_ioctl, it doesn't work in some ppc platform.
So wrap them with compat_ptr and add compat_ioctl.

The detailed discussion about compat_ptr can be found in thread
http://lkml.org/lkml/2009/10/27/423.

We indeed met with a bug when testing on ppc(-EFAULT is returned
when using old_path). This patch try to fix this.
I have tested in ppc64(with 32 bit reflink) and x86_64(with i686
reflink), both works.

Signed-off-by: Tao Ma <tao.ma@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>

Showing 1 changed file with 13 additions and 1 deletions Side-by-side Diff

... ... @@ -7,6 +7,7 @@
7 7  
8 8 #include <linux/fs.h>
9 9 #include <linux/mount.h>
  10 +#include <linux/compat.h>
10 11  
11 12 #define MLOG_MASK_PREFIX ML_INODE
12 13 #include <cluster/masklog.h>
... ... @@ -181,6 +182,10 @@
181 182 #ifdef CONFIG_COMPAT
182 183 long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
183 184 {
  185 + bool preserve;
  186 + struct reflink_arguments args;
  187 + struct inode *inode = file->f_path.dentry->d_inode;
  188 +
184 189 switch (cmd) {
185 190 case OCFS2_IOC32_GETFLAGS:
186 191 cmd = OCFS2_IOC_GETFLAGS;
187 192  
... ... @@ -195,8 +200,15 @@
195 200 case OCFS2_IOC_GROUP_EXTEND:
196 201 case OCFS2_IOC_GROUP_ADD:
197 202 case OCFS2_IOC_GROUP_ADD64:
198   - case OCFS2_IOC_REFLINK:
199 203 break;
  204 + case OCFS2_IOC_REFLINK:
  205 + if (copy_from_user(&args, (struct reflink_arguments *)arg,
  206 + sizeof(args)))
  207 + return -EFAULT;
  208 + preserve = (args.preserve != 0);
  209 +
  210 + return ocfs2_reflink_ioctl(inode, compat_ptr(args.old_path),
  211 + compat_ptr(args.new_path), preserve);
200 212 default:
201 213 return -ENOIOCTLCMD;
202 214 }