diff options
author | Tao Ma <tao.ma@oracle.com> | 2010-01-26 21:21:52 -0500 |
---|---|---|
committer | Joel Becker <joel.becker@oracle.com> | 2010-02-02 21:56:37 -0500 |
commit | 34e6c59af06cbca07b1490ec0015ea2d303470d3 (patch) | |
tree | 1b1199825cf9f658d1abd433ff0d6b0d9f22c1de /fs/ocfs2/ioctl.c | |
parent | cd34edd8cf80b507bb84b3f0c2988fe05099ffb5 (diff) |
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>
Diffstat (limited to 'fs/ocfs2/ioctl.c')
-rw-r--r-- | fs/ocfs2/ioctl.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index 31fbb0619510..7d9d9c132cef 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c | |||
@@ -7,6 +7,7 @@ | |||
7 | 7 | ||
8 | #include <linux/fs.h> | 8 | #include <linux/fs.h> |
9 | #include <linux/mount.h> | 9 | #include <linux/mount.h> |
10 | #include <linux/compat.h> | ||
10 | 11 | ||
11 | #define MLOG_MASK_PREFIX ML_INODE | 12 | #define MLOG_MASK_PREFIX ML_INODE |
12 | #include <cluster/masklog.h> | 13 | #include <cluster/masklog.h> |
@@ -181,6 +182,10 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
181 | #ifdef CONFIG_COMPAT | 182 | #ifdef CONFIG_COMPAT |
182 | long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg) | 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 | switch (cmd) { | 189 | switch (cmd) { |
185 | case OCFS2_IOC32_GETFLAGS: | 190 | case OCFS2_IOC32_GETFLAGS: |
186 | cmd = OCFS2_IOC_GETFLAGS; | 191 | cmd = OCFS2_IOC_GETFLAGS; |
@@ -195,8 +200,15 @@ long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
195 | case OCFS2_IOC_GROUP_EXTEND: | 200 | case OCFS2_IOC_GROUP_EXTEND: |
196 | case OCFS2_IOC_GROUP_ADD: | 201 | case OCFS2_IOC_GROUP_ADD: |
197 | case OCFS2_IOC_GROUP_ADD64: | 202 | case OCFS2_IOC_GROUP_ADD64: |
198 | case OCFS2_IOC_REFLINK: | ||
199 | break; | 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 | default: | 212 | default: |
201 | return -ENOIOCTLCMD; | 213 | return -ENOIOCTLCMD; |
202 | } | 214 | } |