Date: Fri, 12 Apr 2002 16:39:52 -0700 From: David Schultz <dschultz@uclink.Berkeley.EDU> To: "Vladislav V. Zhuk" <admin@dru.dn.ua> Cc: stable@FreeBSD.ORG Subject: Re: very old bug [patch] Message-ID: <20020412163952.A480@HAL9000.wox.org> In-Reply-To: <20020410110605.GJ82820@dru.dn.ua>; from admin@dru.dn.ua on Wed, Apr 10, 2002 at 02:06:05PM %2B0300 References: <20020410110605.GJ82820@dru.dn.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
Thus spake Vladislav V. Zhuk <admin@dru.dn.ua>: > After attempt to write data to write-protected floppy > (or diskette with bad blocks) FreeBSD die. The following patch seems to fix the lockups. The main issue, it seems, was that msdosfs_readdir() incorrectly handled short reads. It tried to make do with what it had and then try again, which causes it to loop forever if the amount read is 0. In other places where it uses bread(), the msdosfs code doesn't even check for short reads; I think that's wrong, but I don't want to fix it unless someone more experienced can confirm this. Note that the UFS code never suffered from this bug in the first place, but there are still some open issues with the semantics of the buffer cache. Perhaps someone could clarify if I have misunderstood something: - The kernel does not give up on the buffers it can't write even after the floppy is unmounted. It won't stop until you insert a writable floppy. - An attempt to bread() a block that is in the buffer cache because it could not be written to disk returns successfully with a buffer that has b_count == b_resid. I'm guessing that the b_resid value refers to the write, but then how is the FS supposed to know how much of the buffer is valid? Index: msdosfs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/fs/msdosfs/msdosfs_vnops.c,v retrieving revision 1.119 diff -u -r1.119 msdosfs_vnops.c --- msdosfs_vnops.c 2002/04/05 14:01:04 1.119 +++ msdosfs_vnops.c 2002/04/12 23:12:27 @@ -1603,7 +1603,16 @@ brelse(bp); return (error); } + + /* + * If a short read occurred, the buffer may contain + * less valid data than expected. + */ n = min(n, blsize - bp->b_resid); + if (n == 0) { + brelse(bp); + break; + } /* * Convert from dos directory entries to fs-independent To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-stable" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020412163952.A480>