Add a function to scan a buffer and indicate if all of the bytes contained therein are zero. Signed-off-by: David Howells <dhowells@xxxxxxxxxx> --- include/linux/uio.h | 1 + lib/iov_iter.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/include/linux/uio.h b/include/linux/uio.h index ff81e5ccaef2..49de7b8a8890 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h @@ -264,6 +264,7 @@ static inline bool iov_iter_is_copy_mc(const struct iov_iter *i) #endif size_t iov_iter_zero(size_t bytes, struct iov_iter *); +bool iov_iter_is_zero(const struct iov_iter *i, size_t count); bool iov_iter_is_aligned(const struct iov_iter *i, unsigned addr_mask, unsigned len_mask); unsigned long iov_iter_alignment(const struct iov_iter *i); diff --git a/lib/iov_iter.c b/lib/iov_iter.c index b667b1e2f688..ec9e3e1a11a9 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -566,6 +566,28 @@ size_t iov_iter_zero(size_t bytes, struct iov_iter *i) } EXPORT_SYMBOL(iov_iter_zero); +/** + * iov_iter_is_zero - Return true if the buffer is entirely zeroed + * @i: The iterator describing the buffer + * @count: Amount of buffer to scan + * + * Scans the specified amount of the supplied buffer and returns true if only + * zero bytes are found therein and false otherwise. + */ +bool iov_iter_is_zero(const struct iov_iter *i, size_t count) +{ + struct iov_iter j = *i, *pj = &j; + void *p; + + iterate_and_advance(pj, count, base, len, count, + ({ p = memchr_inv(base, 0, len); p ? p - base : len; }), + ({ p = memchr_inv(base, 0, len); p ? p - base : len; }) + ) + + return !count; +} +EXPORT_SYMBOL(iov_iter_is_zero); + size_t copy_page_from_iter_atomic(struct page *page, unsigned offset, size_t bytes, struct iov_iter *i) {