On Fri, May 27, 2022 at 11:44:09AM +0100, David Howells wrote: > Add a function, iov_iter_scan(), to iterate over the buffers described by > an I/O iterator, kmapping and passing each contiguous chunk the supplied > scanner function in turn, up to the requested amount of data or until the > scanner function returns an error. > > This can be used, for example, to hash all the data in an iterator by > having the scanner function call the appropriate crypto update function. > +ssize_t iov_iter_scan(struct iov_iter *i, size_t bytes, > + ssize_t (*scanner)(struct iov_iter *i, const void *p, > + size_t len, size_t off, void *priv), > + void *priv) > +{ > + ssize_t ret = 0, scanned = 0; > + > + if (!bytes) > + return 0; > + if (iter_is_iovec(i)) > + might_fault(); > + > + iterate_and_advance( > + i, bytes, base, len, off, ({ > + ret = scanner(i, base, len, off, priv); > + if (ret < 0) > + break; > + scanned += ret; > + }), ({ > + ret = scanner(i, base, len, off, priv); > + if (ret < 0) > + break; > + scanned += ret; > + }) > + ); > + return ret < 0 ? ret : scanned; > +} Have you even tried to run sparse on that? How could that possibly work? You are feeding the same callback both userland and kernel pointers; that makes no sense. NAK.