Skip to content

Commit

Permalink
Merge branch 'iov_iter' into for-davem
Browse files Browse the repository at this point in the history
  • Loading branch information
Al Viro committed Apr 9, 2015
2 parents 237dae8 + bc917be commit fe3cce2
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
14 changes: 14 additions & 0 deletions include/linux/uio.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,18 @@ static inline void iov_iter_reexpand(struct iov_iter *i, size_t count)
size_t csum_and_copy_to_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i);
size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i);

int import_iovec(int type, const struct iovec __user * uvector,
unsigned nr_segs, unsigned fast_segs,
struct iovec **iov, struct iov_iter *i);

#ifdef CONFIG_COMPAT
struct compat_iovec;
int compat_import_iovec(int type, const struct compat_iovec __user * uvector,
unsigned nr_segs, unsigned fast_segs,
struct iovec **iov, struct iov_iter *i);
#endif

int import_single_range(int type, void __user *buf, size_t len,
struct iovec *iov, struct iov_iter *i);

#endif
57 changes: 57 additions & 0 deletions lib/iov_iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -766,3 +766,60 @@ const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags)
flags);
}
EXPORT_SYMBOL(dup_iter);

int import_iovec(int type, const struct iovec __user * uvector,
unsigned nr_segs, unsigned fast_segs,
struct iovec **iov, struct iov_iter *i)
{
ssize_t n;
struct iovec *p;
n = rw_copy_check_uvector(type, uvector, nr_segs, fast_segs,
*iov, &p);
if (n < 0) {
if (p != *iov)
kfree(p);
*iov = NULL;
return n;
}
iov_iter_init(i, type, p, nr_segs, n);
*iov = p == *iov ? NULL : p;
return 0;
}
EXPORT_SYMBOL(import_iovec);

#ifdef CONFIG_COMPAT
#include <linux/compat.h>

int compat_import_iovec(int type, const struct compat_iovec __user * uvector,
unsigned nr_segs, unsigned fast_segs,
struct iovec **iov, struct iov_iter *i)
{
ssize_t n;
struct iovec *p;
n = compat_rw_copy_check_uvector(type, uvector, nr_segs, fast_segs,
*iov, &p);
if (n < 0) {
if (p != *iov)
kfree(p);
*iov = NULL;
return n;
}
iov_iter_init(i, type, p, nr_segs, n);
*iov = p == *iov ? NULL : p;
return 0;
}
#endif

int import_single_range(int rw, void __user *buf, size_t len,
struct iovec *iov, struct iov_iter *i)
{
if (len > MAX_RW_COUNT)
len = MAX_RW_COUNT;
if (unlikely(!access_ok(!rw, buf, len)))
return -EFAULT;

iov->iov_base = buf;
iov->iov_len = len;
iov_iter_init(i, rw, iov, 1, len);
return 0;
}

0 comments on commit fe3cce2

Please sign in to comment.