Subject: Re: Reading past device size (/dev/vnd v.s. /dev/cd)
To: None <reinoud@netbsd.org>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: tech-kern
Date: 01/21/2006 19:23:53
> Index: vfs_bio.c
> ===================================================================
> RCS file: /cvsroot/src/sys/kern/vfs_bio.c,v
> retrieving revision 1.154
> diff -u -r1.154 vfs_bio.c
> --- vfs_bio.c	15 Jan 2006 09:01:02 -0000	1.154
> +++ vfs_bio.c	20 Jan 2006 20:00:44 -0000
> @@ -1787,10 +1787,18 @@
>  {
>  	struct buf *mbp = bp->b_private;
>  	int error;
> -	int donebytes = bp->b_bcount; /* XXX ignore b_resid */
> +	int donebytes;
>  
> -	KASSERT(bp->b_bufsize == bp->b_bcount);
> +	KASSERT(bp->b_bufsize >= bp->b_bcount);
>  	KASSERT(mbp != bp);
> +	if (bp->b_bcount < bp->b_bufsize || bp->b_resid > 0) {
> +		/* not all got transfered, raise an error */
> +		bp->b_flags |= B_ERROR;
> +		bp->b_error = EIO;
> +	};
> +
> +	donebytes = bp->b_bufsize; /* XXX ignore b_resid */
> +
>  	if ((bp->b_flags & B_ERROR) != 0) {
>  		error = bp->b_error;
>  	} else {

it's better to preserve an explicit error if any.
so i'd suggest:

	if ((bp->b_flags & B_ERROR) != 0) {
		if (bp->b_error != 0) {
			error = bp->b_error;
		} else {
			error = EIO;
		}
	} else if (bp->b_bcount < bp->b_bufsize || bp->b_resid > 0) {
		/*
		 * we have no way to propagate these conditions to mbp.
		 * be conservative.
		 */
		error = EIO;
	} else {
		error = 0;
	}

YAMAMOTO Takashi