Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

new primitive: iov_iter_for_each_range()

For kvec and bvec: feeds segments to given callback as long as it
returns 0. For iovec and pipe: fails.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 09cf698a 6d1ff4d6

+26
+4
include/linux/uio.h
··· 244 244 int import_single_range(int type, void __user *buf, size_t len, 245 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 251 #endif
+22
lib/iov_iter.c
··· 1446 1446 return 0; 1447 1447 } 1448 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);