Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Sep 1998 20:52:57 -0400 (EDT)
From:      Luoqi Chen <luoqi@watermarkgroup.com>
To:        dillon@backplane.com, luoqi@watermarkgroup.com
Cc:        committers@FreeBSD.ORG
Subject:   Re:  Kernel is hitting my debugging printf's
Message-ID:  <199809250052.UAA29657@lor.watermarkgroup.com>

next in thread | raw e-mail | index | archive | help
Bingo! That's it! I think this is the one that's responsible for the data loss.
After the page is put on the page cache queue, it could be reclaimed for
other use. The next time you write to the same disk block, the data has to be
reread from the disk which doesn't have latest modifications.

To fix this problem, you either could change to if statements to check for
B_DELWRI bit, or clear B_RELBUF if B_DELWRI is set earlier in the function.
I prefer the latter because it doesn't make much sense carrying the B_RELBUF
bit around.

-lq

> brelse-A: releasing BP marked B_DELWRI 204202b0
> vfs_vmio_release: releasing BP marked B_DELWRI 204202b0
> 						^^^^
> 						bp->b_flags
> 
> 						B_DELWRI
> 						B_CACHE
> 						B_BUSY
> 						D_BONE
> 						B_CLUSTEROK
> 						B_RELBUF
> 						B_VMIO
> 
> brelse-A: releasing BP marked B_DELWRI 204202b0
> vfs_vmio_release: releasing BP marked B_DELWRI 204202b0
> brelse-A: releasing BP marked B_DELWRI 204202b0
> vfs_vmio_release: releasing BP marked B_DELWRI 204202b0
> 
>     I stuck this printf in kern/vfs_bio.c around line 671, in brelse():
> 	
> 		...
> 
>                 /* MATT HACK */
>                 if ((bp->b_flags & (B_INVAL|B_RELBUF)) && (bp->b_flags & B_DELWRI))
>                         printf("brelse-A: releasing BP marked B_DELWRI %08lx\n", (long)bp->b_flags);
> 
>                 if (bp->b_flags & (B_INVAL | B_RELBUF))
>                         vfs_vmio_release(bp);
>         } else if (bp->b_flags & B_VMIO) {
>                 /* MATT HACK */
>                 if ((bp->b_flags & (B_INVAL|B_RELBUF)) && (bp->b_flags & B_DELWRI))
>                         printf("brelse-B: releasing BP marked B_DELWRI %08lx\n", (long)bp->b_flags);
> 
> 
>     If I understand the code correctly, this is illegal.  Here's the sequence
>     of events as I understand it:
> 
> 	* small write is made, page associated with bp and modified.  page is
> 	  now dirty.
> 
> 	* bdwrite() is called
> 
> 	* bp is marked B_DELWRI and page is remarked clean (this turns out to
> 	  be necessary so we can detect if the page is modified again)
> 
> 	* page is *required* to remain associated with the bp until it is
> 	  written out by the VFS system, because if the page is disassociated
> 	  from the bp the fact that it has been marked clean can cause it to
> 	  be thrown away, thus we lose the write() we did.
> 
> 	* The logs above show that the page is being disassociated while 
> 	  B_DELWRI is still set in the bp.  I believe this to be illegal.
> 	  From looking at the code it appears that B_DELWRI is cleared when
> 	  actual I/O is initiated on the bp.  The logs above show that that
> 	  has not occured (B_DELWRI is still set).
> 
>     So, can any experts out there tell me if I'm barking up the right tree or
>     not?  I don't want to bug John too much since he has other projects going
>     on.  Luoqi?  Anyone else ?
> 
> 					-Matt
> 
>     Matthew Dillon  Engineering, HiWay Technologies, Inc. & BEST Internet 
>                     Communications & God knows what else.
>     <dillon@backplane.com> (Please include original email in any response)    
> 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199809250052.UAA29657>