Skip to content

Commit

Permalink
- copy to and from user buffer was incorrect in the read/write, fix t…
Browse files Browse the repository at this point in the history
…o handle

  page faults correctly.
- partial fix to export filesystems
  • Loading branch information
Anand Mitra committed Sep 23, 2010
1 parent 81c3a7b commit b539461
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 45 deletions.
8 changes: 0 additions & 8 deletions include/sys/lzfs_exportfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@
#include <linux/exportfs.h>
#include <linux/stddef.h>

struct lzfs_fid {
u64 ino;
u32 gen;

u64 parent_ino;
u32 parent_gen;
} __attribute__((packed));

extern const struct export_operations zfs_export_ops;

#define LZFS_FILEID_INO64_GEN 4
Expand Down
6 changes: 5 additions & 1 deletion include/sys/vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ typedef uint64_t vfs_feature_t;

#ifdef HAVE_ZPL
typedef struct fid {
#else
typedef struct lzfs_fid {
#endif
union {
long fid_pad;
struct {
Expand All @@ -84,7 +87,8 @@ typedef struct fid {
} un;
} fid_t;

#endif /* HAVE_ZPL */
#define fid_len un._fid.len
#define fid_data un._fid.data

#ifndef FSTYPSZ
#define FSTYPSZ 16 /* max size of fs identifier */
Expand Down
66 changes: 30 additions & 36 deletions module/spl/spl-move.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ uiomove(void *p, size_t n, enum uio_rw rw, struct uio *uio)
struct iovec *iov;
ulong_t cnt;

/* Currently uiomove only for copy data in the sysspace.
*/
ASSERT(uio->uio_segflg == UIO_SYSSPACE);

while (n && uio->uio_resid) {
iov = uio->uio_iov;
cnt = MIN(iov->iov_len, n);
Expand All @@ -28,20 +24,23 @@ uiomove(void *p, size_t n, enum uio_rw rw, struct uio *uio)
switch (uio->uio_segflg) {
case UIO_USERSPACE:
case UIO_USERISPACE:
ASSERT(0);
#ifdef HAVE_ZPL
/* p = kernel data pointer
* iov->iov_base = user data pointer */

if (rw == UIO_READ) {
error = xcopyout_nta(p, iov->iov_base, cnt,
(uio->uio_extflg & UIO_COPY_CACHED));
/* * UIO_READ = copy data from kernel to user * */
if (copy_to_user(iov->iov_base, p, cnt))
return EFAULT;
/* error = xcopyout_nta(p, iov->iov_base, cnt,
* (uio->uio_extflg & UIO_COPY_CACHED)); */
} else {
error = xcopyin_nta(iov->iov_base, p, cnt,
(uio->uio_extflg & UIO_COPY_CACHED));
/* * UIO_WRITE = copy data from user to kernel * */
/* error = xcopyin_nta(iov->iov_base, p, cnt,
* (uio->uio_extflg & UIO_COPY_CACHED)); */
if (copy_from_user(p, iov->iov_base, cnt))
return EFAULT;
}

if (error)
return (error);
break;
#endif /* HAVE_ZPL */
case UIO_SYSSPACE:
if (rw == UIO_READ)
bcopy(p, iov->iov_base, cnt);
Expand All @@ -60,6 +59,8 @@ uiomove(void *p, size_t n, enum uio_rw rw, struct uio *uio)
}
EXPORT_SYMBOL(uiomove);

#define fuword8(uptr, vptr) get_user((*vptr), (uptr))

/*
* Fault in the pages of the first n bytes specified by the uio structure.
* 1 byte in each page is touched and the uio struct is unmodified. Any
Expand All @@ -78,8 +79,6 @@ uio_prefaultpages(ssize_t n, struct uio *uio)
iov = uio->uio_iov;
iovcnt = uio->uio_iovcnt;

ASSERT(uio->uio_segflg == UIO_SYSSPACE);

while ((n > 0) && (iovcnt > 0)) {
cnt = MIN(iov->iov_len, n);
if (cnt == 0) {
Expand All @@ -97,11 +96,8 @@ uio_prefaultpages(ssize_t n, struct uio *uio)
switch (uio->uio_segflg) {
case UIO_USERSPACE:
case UIO_USERISPACE:
ASSERT(0);
#ifdef HAVE_ZPL
if (fuword8(p, &tmp))
if (fuword8((uint8_t *) p, &tmp))
return;
#endif /*HAVE_ZPL*/
break;
case UIO_SYSSPACE:
bcopy(p, &tmp, 1);
Expand All @@ -118,11 +114,8 @@ uio_prefaultpages(ssize_t n, struct uio *uio)
switch (uio->uio_segflg) {
case UIO_USERSPACE:
case UIO_USERISPACE:
ASSERT(0);
#ifdef HAVE_ZPL
if (fuword8(p, &tmp))
if (fuword8((uint8_t *) p, &tmp))
return;
#endif /*HAVE_ZPL*/
break;
case UIO_SYSSPACE:
bcopy(p, &tmp, 1);
Expand All @@ -145,8 +138,6 @@ uiocopy(void *p, size_t n, enum uio_rw rw, struct uio *uio, size_t *cbytes)
ulong_t cnt;
int iovcnt;

ASSERT(uio->uio_segflg == UIO_SYSSPACE);

iovcnt = uio->uio_iovcnt;
*cbytes = 0;

Expand All @@ -159,19 +150,22 @@ uiocopy(void *p, size_t n, enum uio_rw rw, struct uio *uio, size_t *cbytes)

case UIO_USERSPACE:
case UIO_USERISPACE:
ASSERT(0);
#ifdef HAVE_ZPL
/* p = kernel data pointer
* iov->iov_base = user data pointer */

if (rw == UIO_READ) {
error = xcopyout_nta(p, iov->iov_base, cnt,
(uio->uio_extflg & UIO_COPY_CACHED));
/* * UIO_READ = copy data from kernel to user * */
if (copy_to_user(iov->iov_base, p, cnt))
return EFAULT;
/* error = xcopyout_nta(p, iov->iov_base, cnt,
* (uio->uio_extflg & UIO_COPY_CACHED)); */
} else {
error = xcopyin_nta(iov->iov_base, p, cnt,
(uio->uio_extflg & UIO_COPY_CACHED));
/* * UIO_WRITE = copy data from user to kernel * */
/* error = xcopyin_nta(iov->iov_base, p, cnt,
* (uio->uio_extflg & UIO_COPY_CACHED)); */
if (copy_from_user(p, iov->iov_base, cnt))
return EFAULT;
}

if (error)
return (error);
#endif /*HAVE_ZPL*/
break;

case UIO_SYSSPACE:
Expand Down

0 comments on commit b539461

Please sign in to comment.