Commit 34e6c59af06cbca07b1490ec0015ea2d303470d3
Committed by
Joel Becker
1 parent
cd34edd8cf
Exists in
master
and in
4 other branches
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
fs/ocfs2/ioctl.c
... | ... | @@ -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 | } |