kernels/linux-2.4.0/net/core/iovec.c
/*
 *	And now for the all-in-one: copy and checksum from a user iovec
 *	directly to a datagram
 *	Calls to csum_partial but the last must be in 32 bit chunks
 *
 *	ip_build_xmit must ensure that when fragmenting only the last
 *	call to this function will be unaligned also.
 */
And now for the all-in-one: copy and checksum from a user iovec
directly to a datagram
Calls to csum_partial but the last must be in 32 bit chunks

ip_build_xmit must ensure that when fragmenting only the last
call to this function will be unaligned also.
And now for the all - in - one : copy and checksum from a user iovec directly to a datagram Calls to csum_partial but the last must be in 32 bit chunks ip_build_xmit must ensure that when fragmenting only the last call to this function will be unaligned also .
int csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov,
				 int offset, unsigned int len, int *csump)
{
	int csum = *csump;
	int partial_cnt = 0, err = 0;
	while (offset >= iov->iov_len)
	{
		offset -= iov->iov_len;
		iov++;
	}
	while (len > 0)
	{
		u8 *base = iov->iov_base + offset;
		unsigned int copy = min(len, iov->iov_len - offset);
		offset = 0;
		if (partial_cnt)
		{
			int par_len = 4 - partial_cnt;
			if (par_len > copy) {
				if (copy_from_user(kdata, base, copy))
					goto out_fault;
				kdata += copy;
				base  += copy;
				partial_cnt += copy;
				len   -= copy;
				iov++;
				if (len)
					continue;
				*csump = csum_partial(kdata - partial_cnt,
							 partial_cnt, csum);
				goto out;
			}
			if (copy_from_user(kdata, base, par_len))
				goto out_fault;
			csum = csum_partial(kdata - partial_cnt, 4, csum);
			kdata += par_len;
			base  += par_len;
			copy  -= par_len;
			len   -= par_len;
			partial_cnt = 0;
		}
		if (len > copy)
		{
			partial_cnt = copy % 4;
			if (partial_cnt)
			{
				copy -= partial_cnt;
				if (copy_from_user(kdata + copy, base + copy,
				 		partial_cnt))
					goto out_fault;
			}
		}
		if (copy) {
			csum = csum_and_copy_from_user(base, kdata, copy,
							csum, &err);
			if (err)
				goto out;
		}
		len   -= copy + partial_cnt;
		kdata += copy + partial_cnt;
		iov++;
	}
        *csump = csum;
out:
	return err;
out_fault:
	err = -EFAULT;
	goto out;
}
int csum_partial_copy_fromiovecend ( unsigned char * kdata , struct iovec * iov , int offset , unsigned int len , int * csump ) { int csum = * csump ; int partial_cnt = 0 , err = 0 ; while ( offset >= iov -> iov_len ) { offset -= iov -> iov_len ; iov ++ ; } while ( len > 0 ) { u8 * base = iov -> iov_base + offset ; unsigned int copy = min ( len , iov -> iov_len - offset ) ; offset = 0 ; if ( partial_cnt ) { int par_len = 4 - partial_cnt ; if ( par_len > copy ) { if ( copy_from_user ( kdata , base , copy ) ) goto out_fault ; kdata += copy ; base += copy ; partial_cnt += copy ; len -= copy ; iov ++ ; if ( len ) continue ; * csump = csum_partial ( kdata - partial_cnt , partial_cnt , csum ) ; goto out ; } if ( copy_from_user ( kdata , base , par_len ) ) goto out_fault ; csum = csum_partial ( kdata - partial_cnt , 4 , csum ) ; kdata += par_len ; base += par_len ; copy -= par_len ; len -= par_len ; partial_cnt = 0 ; } if ( len > copy ) { partial_cnt = copy % 4 ; if ( partial_cnt ) { copy -= partial_cnt ; if ( copy_from_user ( kdata + copy , base + copy , partial_cnt ) ) goto out_fault ; } } if ( copy ) { csum = csum_and_copy_from_user ( base , kdata , copy , csum , & err ) ; if ( err ) goto out ; } len -= copy + partial_cnt ; kdata += copy + partial_cnt ; iov ++ ; } * csump = csum ; out : return err ; out_fault : err = - EFAULT ; goto out ; }
And now for the all-in-one: copy and checksum from a user iovec
      directly to a datagram
      Calls to csum_partial but the last must be in 32 bit chunks
And now for the all - in - one : copy and checksum from a user iovec directly to a datagram Calls to csum_partial but the last must be in 32 bit chunks
/* Skip over the finished iovecs */ /* There is a remnant from previous iov. */ /* iov component is too short ... */