Date: Fri, 01 Feb 2008 12:00:16 +0200 From: Andriy Gapon <avg@icyb.net.ua> To: Remko Lodder <remko@FreeBSD.org>, scottl@FreeBSD.org, freebsd-fs@freebsd.org Cc: Bruce Evans <bde@zeta.org.au> Subject: Re: kern/84983: [udf] [patch] udf filesystem: stat-ting files could randomly fail Message-ID: <47A2EDB0.8000801@icyb.net.ua> In-Reply-To: <200612221824.kBMIOhfM049471@freefall.freebsd.org> References: <200612221824.kBMIOhfM049471@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
on 22/12/2006 20:24 Pav Lucistnik said the following: > Synopsis: [udf] [patch] udf filesystem: stat-ting files could randomly fail > > State-Changed-From-To: open->closed > State-Changed-By: pav > State-Changed-When: Fri Dec 22 18:24:14 UTC 2006 > State-Changed-Why: > Fixed in 6.1 and up > > http://www.freebsd.org/cgi/query-pr.cgi?pr=84983 I found a bug in the patch. I got a panic in real situation when testing a UDF fs with a directory with a huge number of files (~10^4), but this can be easily shown in the code too: static int udf_readatoffset(struct udf_node *node, int *size, off_t offset, struct buf **bp, uint8_t **data) { ... *size = min(*size, MAXBSIZE); if ((error = udf_readlblks(udfmp, sector, *size + (offset & udfmp->bmask), bp))) { If it so happens that *size gets MAXBSIZ value and (offset & udfmp->bmask) is not zero, then a value > MAXBSIZ would be passed to udf_readlblks->bread->breadn->getblk and the latter will panic because it has an explicit assert for size <= MAXBSIZ. I think there should be something in the code like the following: *size = min(*size, MAXBSIZE - (offset & udfmp->bmask)); ---- a different, under-debugged problem ----- BTW, on some smaller directories (but still large ones) I get some very strange problems with reading a directory too. It seems like some bad interaction between udf and buffer cache system. I added a lot of debugging prints and the problems looks like the following: read starting at physical sector (2048-byte one) N, size is ~20K, N%4=0 bread(4 * N, some_big_size) correct data is read repeat the above couple dozen times read starting at physical sector (2048-byte one) N+1, size is ~20K bread(4 * (N+1), some_big_size) data is read from physical sector N+4 (instead of N+1) I remember that Bruce Evance warned me that something like this could happen but I couldn't understand him, because I don't understand VM/buffer subsystem. I'll try to dig up the email. -- Andriy Gapon
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?47A2EDB0.8000801>