/* Adjust number of segments and amount of bytes to write (nr_segs should be properly initialized first). Returns appropriate error code that caller should return or zero in case that write should be allowed.  */
int generic_segment_checks(const struct iovec *iov, unsigned long *nr_segs, size_t *count, int access_flags)
/* Adjust number of segments and amount of bytes to write (nr_segs should be properly initialized first). Returns appropriate error code that caller should return or zero in case that write should be allowed.  */
int generic_segment_checks(const struct iovec *iov, unsigned long *nr_segs, size_t *count, int access_flags)
{
	unsigned long   seg;
	size_t cnt = 0;
	for (seg = 0; seg < *nr_segs; seg++) {
		const struct iovec *iv = &iov[seg];
		cnt += iv->iov_len;
		if (unlikely((ssize_t)(cnt|iv->iov_len) < 0))
			return -EINVAL;
		if (access_ok(access_flags, iv->iov_base, iv->iov_len))
			continue;
		if (seg == 0)
			return -EFAULT;
		*nr_segs = seg;
		cnt -= iv->iov_len;
		break;
	}
	*count = cnt;
	return 0;
}