One of the problems I'm running into is a deadlock where I have threads
blocked on newbuf (with vnode lock held) due to buffer shortage and
bufdaemon unable to flush buffers because it can't get the exclusive
lock for the vnode. From the code:

struct buf *
getblk(struct vnode * vp, daddr_t blkno, int size, int slpflag, int
int flags)

* Buffer is not in-core, create new buffer. The buffer
* returned by getnewbuf() is locked. Note that the
* buffer is also considered valid (not marked B_INVAL).
bp = getnewbuf(slpflag, slptimeo, size, maxsize,
if (bp == NULL) {
* This code is used to make sure that a buffer is not
* created while the getnewbuf routine is blocked.
* This can be a problem whether the vnode is locked or
* If the buffer is created out from under us, we have
* throw away the one we just created.
* Note: this must occur before we associate the buffer
* with the vp especially considering limitations in
* the splay tree implementation when dealing with
* lblkno's.
if (gbincore(bo, blkno)) {
bp->b_flags |= B_INVAL;
goto loop;

Given that this code rechecks if a buffer has already been created with
the possibility that this thread might have blocked on getnewbuf (), Is
there really
any need to hold the vnode lock across getnewbuf call?


_______________________________________________ mailing list
To unsubscribe, send any mail to ""