Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 21 Feb 1999 00:11:21 +0000 (GMT)
From:      Terry Lambert <tlambert@primenet.com>
To:        dfr@nlsystems.com (Doug Rabson)
Cc:        tlambert@primenet.com, dillon@apollo.backplane.com, freebsd-hackers@FreeBSD.ORG
Subject:   Re: Panic in FFS/4.0 as of yesterday
Message-ID:  <199902210011.RAA22231@usr08.primenet.com>
In-Reply-To: <Pine.BSF.4.05.9902202305130.82049-100000@herring.nlsystems.com> from "Doug Rabson" at Feb 20, 99 11:12:45 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> > I swear I saw code in NFS to do this.  Maybe it was pre-BSD4.4.
> 
> I'm pretty sure it has never done this as long as I have been involved
> with NFS.  I remember a (probably private) discussion with Rick Macklem a
> long time ago where he explained some of the problems with using exclusive
> node locks in NFS.  I'm not sure how a filesystem can unilaterally decide
> to release an asserted lock.  It seems to me that this policy can only
> happen at the level of the client code (otherwise the value of the lock
> disappears).

I think you can return ESTALE/EAGAIN from the conflicting assertions.

I'm afraid that I might have been referencing the SVR4 NFS code.  I'm
fuzzy on the date, but I definitely remember the code because I asked
myself "Why the heck is it doing this?", and running down the answer.
It couldn't have been more than 5 years ago, which puts it right on
the line.


> > It should be pretty easy to do this kludge by (1) deciding how many
> > waiters is "too many", and (2) checking if the mount is async.  This
> > would avoid propagating the changes up.
> 
> Deciding how many is "too many" is the hard part.  It needs feedback from
> the driver really.

Or knowledge of queue depth at the time it's enqueued.  Be kind of
strange to call a sync write from the top of the async write queue,
but that's where you'd want to do it, if you did it.


> > I personally like the name "EXPEDITE" for the flag.  8-).
> 
> I think promoting directory writes (and directory reads probably) might be
> the simplest solution.

Hum.  This is trivial...

Let's see... is there a free flag?  Yes...

OK, here's code to add the ability to expedite placement of async
writes.  It' doesn't insert them in order behind other expedited
writes, so it turns the expedited stuff LIFO.  This is probably
suboptimal, but can't happen in dependent operations, so what the
heck...

When you use the code, be sure to *not* set the flag if soft updates
are in effect (I think that's a caller issue, not a callee issue, since
it would complicate the bdwrite code, probably unacceptably.


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.
============================================================================
Index: buf.h
===================================================================
RCS file: /cvs/freebsd/src/sys/sys/buf.h,v
retrieving revision 1.61
diff -c -r1.61 buf.h
*** buf.h	1998/11/13 01:01:44	1.61
--- buf.h	1999/02/21 00:01:24
***************
*** 141,147 ****
  #define	B_DONE		0x00000200	/* I/O completed. */
  #define	B_EINTR		0x00000400	/* I/O was interrupted */
  #define	B_ERROR		0x00000800	/* I/O error occurred. */
! #define	B_AVAIL2	0x00001000	/* Available flag */
  #define	B_INVAL		0x00002000	/* Does not contain valid info. */
  #define	B_LOCKED	0x00004000	/* Locked in core (not reusable). */
  #define	B_NOCACHE	0x00008000	/* Do not cache block after use. */
--- 141,147 ----
  #define	B_DONE		0x00000200	/* I/O completed. */
  #define	B_EINTR		0x00000400	/* I/O was interrupted */
  #define	B_ERROR		0x00000800	/* I/O error occurred. */
! #define	B_EXPEDITE	0x00001000	/* Expedite operation */
  #define	B_INVAL		0x00002000	/* Does not contain valid info. */
  #define	B_LOCKED	0x00004000	/* Locked in core (not reusable). */
  #define	B_NOCACHE	0x00008000	/* Do not cache block after use. */
Index: vfs_bio.c
===================================================================
RCS file: /cvs/freebsd/src/sys/kern/vfs_bio.c,v
retrieving revision 1.193.2.2
diff -c -r1.193.2.2 vfs_bio.c
*** vfs_bio.c	1999/01/25 01:59:26	1.193.2.2
--- vfs_bio.c	1999/02/21 00:04:48
***************
*** 793,803 ****
  	if (bp->b_flags & B_LOCKED) {
  		bp->b_flags &= ~B_ERROR;
  		bp->b_qindex = QUEUE_LOCKED;
! 		TAILQ_INSERT_TAIL(&bufqueues[QUEUE_LOCKED], bp, b_freelist);
  		/* buffers with stale but valid contents */
  	} else {
  		bp->b_qindex = QUEUE_LRU;
! 		TAILQ_INSERT_TAIL(&bufqueues[QUEUE_LRU], bp, b_freelist);
  	}
  
  	if ((bp->b_flags & (B_LOCKED|B_DELWRI)) == 0) {
--- 793,809 ----
  	if (bp->b_flags & B_LOCKED) {
  		bp->b_flags &= ~B_ERROR;
  		bp->b_qindex = QUEUE_LOCKED;
! 		if (bp->b_flags & B_EXPEDITE)
! 			TAILQ_INSERT_HEAD(&bufqueues[QUEUE_LOCKED], bp, b_freelist);
! 		else
! 			TAILQ_INSERT_TAIL(&bufqueues[QUEUE_LOCKED], bp, b_freelist);
  		/* buffers with stale but valid contents */
  	} else {
  		bp->b_qindex = QUEUE_LRU;
! 		if (bp->b_flags & B_EXPEDITE)
! 			TAILQ_INSERT_HEAD(&bufqueues[QUEUE_LRU], bp, b_freelist);
! 		else
! 			TAILQ_INSERT_TAIL(&bufqueues[QUEUE_LRU], bp, b_freelist);
  	}
  
  	if ((bp->b_flags & (B_LOCKED|B_DELWRI)) == 0) {
***************
*** 806,812 ****
  
  	/* unlock */
  	bp->b_flags &= ~(B_ORDERED | B_WANTED | B_BUSY |
! 		B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF);
  	splx(s);
  }
  
--- 812,818 ----
  
  	/* unlock */
  	bp->b_flags &= ~(B_ORDERED | B_WANTED | B_BUSY |
! 		B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF | B_EXPEDITE);
  	splx(s);
  }
  
============================================================================


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




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