#include <linux/highmem.h>
#include <linux/pagemap.h>
-static size_t __iovec_copy_from_user_inatomic(char *vaddr,
- const struct iovec *iov, size_t base, size_t bytes)
+static size_t __iovec_copy_from_user(char *vaddr, const struct iovec *iov,
+ size_t base, size_t bytes, int atomic)
{
size_t copied = 0, left = 0;
int copy = min(bytes, iov->iov_len - base);
base = 0;
- left = __copy_from_user_inatomic(vaddr, buf, copy);
+ if (atomic)
+ left = __copy_from_user_inatomic(vaddr, buf, copy);
+ else
+ left = __copy_from_user(vaddr, buf, copy);
copied += copy;
bytes -= copy;
vaddr += copy;
left = __copy_from_user_inatomic(kaddr + offset, buf, bytes);
copied = bytes - left;
} else {
- copied = __iovec_copy_from_user_inatomic(kaddr + offset,
- i->iov, i->iov_offset, bytes);
+ copied = __iovec_copy_from_user(kaddr + offset, i->iov,
+ i->iov_offset, bytes, 1);
}
kunmap_atomic(kaddr);
left = __copy_from_user(kaddr + offset, buf, bytes);
copied = bytes - left;
} else {
- copied = __iovec_copy_from_user_inatomic(kaddr + offset,
- i->iov, i->iov_offset, bytes);
+ copied = __iovec_copy_from_user(kaddr + offset, i->iov,
+ i->iov_offset, bytes, 0);
}
kunmap(page);
return copied;