diff options
| -rw-r--r-- | include/linux/uio.h | 4 | ||||
| -rw-r--r-- | lib/iov_iter.c | 22 |
2 files changed, 26 insertions, 0 deletions
diff --git a/include/linux/uio.h b/include/linux/uio.h index 5885daeae721..e67e12adb136 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h | |||
| @@ -244,4 +244,8 @@ int compat_import_iovec(int type, const struct compat_iovec __user * uvector, | |||
| 244 | int import_single_range(int type, void __user *buf, size_t len, | 244 | int import_single_range(int type, void __user *buf, size_t len, |
| 245 | struct iovec *iov, struct iov_iter *i); | 245 | struct iovec *iov, struct iov_iter *i); |
| 246 | 246 | ||
| 247 | int iov_iter_for_each_range(struct iov_iter *i, size_t bytes, | ||
| 248 | int (*f)(struct kvec *vec, void *context), | ||
| 249 | void *context); | ||
| 250 | |||
| 247 | #endif | 251 | #endif |
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 1c1c06ddc20a..970212670b6a 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c | |||
| @@ -1446,3 +1446,25 @@ int import_single_range(int rw, void __user *buf, size_t len, | |||
| 1446 | return 0; | 1446 | return 0; |
| 1447 | } | 1447 | } |
| 1448 | EXPORT_SYMBOL(import_single_range); | 1448 | EXPORT_SYMBOL(import_single_range); |
| 1449 | |||
| 1450 | int iov_iter_for_each_range(struct iov_iter *i, size_t bytes, | ||
| 1451 | int (*f)(struct kvec *vec, void *context), | ||
| 1452 | void *context) | ||
| 1453 | { | ||
| 1454 | struct kvec w; | ||
| 1455 | int err = -EINVAL; | ||
| 1456 | if (!bytes) | ||
| 1457 | return 0; | ||
| 1458 | |||
| 1459 | iterate_all_kinds(i, bytes, v, -EINVAL, ({ | ||
| 1460 | w.iov_base = kmap(v.bv_page) + v.bv_offset; | ||
| 1461 | w.iov_len = v.bv_len; | ||
| 1462 | err = f(&w, context); | ||
| 1463 | kunmap(v.bv_page); | ||
| 1464 | err;}), ({ | ||
| 1465 | w = v; | ||
| 1466 | err = f(&w, context);}) | ||
| 1467 | ) | ||
| 1468 | return err; | ||
| 1469 | } | ||
| 1470 | EXPORT_SYMBOL(iov_iter_for_each_range); | ||
