Hi Sunil, On Sun, 2010-12-19 at 00:16 -0800, ccmail111 wrote: > Hi Miklos/Greg, > > IMHO, I see 3 diffs/patches for same issue below. > I have posted initial patch, then Miklos had updated patch (which I was in > process of testing), then I see one below.
Yes, the patch was further simplified before submitting to mainline. I also did some testing but further testing is very welcome on this updated patch as well. Thanks, Miklos > > --- On Fri, 12/17/10, [email protected] <[email protected]> wrote: > > > From: [email protected] <[email protected]> > > Subject: Patch "fuse: fix ioctl when server is 32bit" has been added to the > > 2.6.32-longterm tree > > To: [email protected], [email protected], [email protected], [email protected] > > Cc: [email protected], [email protected] > > Date: Friday, December 17, 2010, 6:34 PM > > > > This is a note to let you know that I've just added the > > patch titled > > > > fuse: fix ioctl when server is 32bit > > > > to the 2.6.32-longterm tree which can be found at: > > > > http://www.kernel.org/git/?p=linux/kernel/git/longterm/longterm-queue-2.6.32.git;a=summary > > > > The filename of the patch is: > > > > fuse-fix-ioctl-when-server-is-32bit.patch > > and it can be found in the queue-2.6.32 subdirectory. > > > > If you, or anyone else, feels it should not be added to the > > 2.6.32 longterm tree, > > please let <[email protected]> > > know about it. > > > > > > From d9d318d39dd5cb686660504a3565aac453709ccc Mon Sep 17 > > 00:00:00 2001 > > From: Miklos Szeredi <[email protected]> > > Date: Tue, 30 Nov 2010 16:39:27 +0100 > > Subject: fuse: fix ioctl when server is 32bit > > > > From: Miklos Szeredi <[email protected]> > > > > commit d9d318d39dd5cb686660504a3565aac453709ccc upstream. > > > > If a 32bit CUSE server is run on 64bit this results in EIO > > being > > returned to the caller. > > > > The reason is that FUSE_IOCTL_RETRY reply was defined to > > use 'struct > > iovec', which is different on 32bit and 64bit archs. > > > > Work around this by looking at the size of the reply to > > determine > > which struct was used. This is only needed if > > CONFIG_COMPAT is > > defined. > > > > A more permanent fix for the interface will be to use the > > same struct > > on both 32bit and 64bit. > > > > Reported-by: "ccmail111" <[email protected]> > > Signed-off-by: Miklos Szeredi <[email protected]> > > CC: Tejun Heo <[email protected]> > > Signed-off-by: Greg Kroah-Hartman <[email protected]> > > > > --- > > fs/fuse/file.c | 50 > > ++++++++++++++++++++++++++++++++++++++++++++------ > > 1 file changed, 44 insertions(+), 6 deletions(-) > > > > --- a/fs/fuse/file.c > > +++ b/fs/fuse/file.c > > @@ -13,6 +13,7 @@ > > #include <linux/kernel.h> > > #include <linux/sched.h> > > #include <linux/module.h> > > +#include <linux/compat.h> > > > > static const struct file_operations > > fuse_direct_io_file_operations; > > > > @@ -1634,6 +1635,44 @@ static int > > fuse_verify_ioctl_iov(struct > > } > > > > /* > > + * CUSE servers compiled on 32bit broke on 64bit kernels > > because the > > + * ABI was defined to be 'struct iovec' which is different > > on 32bit > > + * and 64bit. Fortunately we can determine which > > structure the server > > + * used from the size of the reply. > > + */ > > +static int fuse_copy_ioctl_iovec(struct iovec *dst, void > > *src, > > + > > size_t transferred, unsigned > > count, > > + > > bool is_compat) > > +{ > > +#ifdef CONFIG_COMPAT > > + if (count * sizeof(struct compat_iovec) > > == transferred) { > > + struct compat_iovec > > *ciov = src; > > + unsigned i; > > + > > + /* > > + * With > > this interface a 32bit server cannot support > > + * > > non-compat (i.e. ones coming from 64bit apps) ioctl > > + * > > requests > > + */ > > + if (!is_compat) > > + > > return -EINVAL; > > + > > + for (i = 0; i < > > count; i++) { > > + > > dst[i].iov_base = compat_ptr(ciov[i].iov_base); > > + > > dst[i].iov_len = ciov[i].iov_len; > > + } > > + return 0; > > + } > > +#endif > > + > > + if (count * sizeof(struct iovec) != > > transferred) > > + return -EIO; > > + > > + memcpy(dst, src, transferred); > > + return 0; > > +} > > + > > +/* > > * For ioctls, there is no generic way to determine > > how much memory > > * needs to be read and/or written. > > Furthermore, ioctls are allowed > > * to dereference the passed pointer, so the > > parameter requires deep > > @@ -1814,14 +1853,13 @@ long fuse_do_ioctl(struct file > > *file, un > > > > in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV) > > > > goto out; > > > > - err = -EIO; > > - if ((in_iovs + > > out_iovs) * sizeof(struct iovec) != transferred) > > - > > goto out; > > - > > - /* okay, copy in > > iovs and retry */ > > vaddr = > > kmap_atomic(pages[0], KM_USER0); > > - > > memcpy(page_address(iov_page), vaddr, transferred); > > + err = > > fuse_copy_ioctl_iovec(page_address(iov_page), vaddr, > > + > > > > transferred, in_iovs + out_iovs, > > + > > (flags > > & FUSE_IOCTL_COMPAT) != 0); > > kunmap_atomic(vaddr, > > KM_USER0); > > + if (err) > > + > > goto out; > > > > in_iov = > > page_address(iov_page); > > out_iov = in_iov + > > in_iovs; > > > > > > Patches currently in longterm-queue-2.6.32 which might be > > from [email protected] > > are > > > > > > > _______________________________________________ stable mailing list [email protected] http://linux.kernel.org/mailman/listinfo/stable
