- unsigned i;
- struct iovec __user *iov;
- if (nr_segs > UIO_MAXIOV)
- return -EINVAL;
- iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec));
- for (i = 0; i < nr_segs; i++) {
- struct compat_iovec v;
- if (get_user(v.iov_base, &iov32[i].iov_base) ||
- get_user(v.iov_len, &iov32[i].iov_len) ||
- put_user(compat_ptr(v.iov_base), &iov[i].iov_base) ||
- put_user(v.iov_len, &iov[i].iov_len))
- return -EFAULT;
+ struct iovec iovstack[UIO_FASTIOV];
+ struct iovec *iov = iovstack;
+ struct iov_iter iter;
+ long error;
+ struct fd f;
+ int type;
+
+ f = fdget(fd);
+ error = vmsplice_type(f, &type);
+ if (error)
+ return error;
+
+ error = compat_import_iovec(type, iov32, nr_segs,
+ ARRAY_SIZE(iovstack), &iov, &iter);
+ if (!error) {
+ error = do_vmsplice(f.file, &iter, flags);
+ kfree(iov);