Unlocked getblk: Fix new false-positive assertion

A free buf's lock may be held (temporarily) due to unlocked lookup, so
buf_alloc() must acquire it without LK_NOWAIT.  The unlocked getblk path
should unlock it promptly once it realizes the identity does not match
the buffer it was searching for.

Reported by:	gallatin
Reviewed by:	kib
Tested by:	pho
X-MFC-With:	r363482
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D25914
This commit is contained in:
Conrad Meyer 2020-08-02 16:34:27 +00:00
parent 936c24faba
commit 9da903e5d3

View File

@ -1637,7 +1637,7 @@ static struct buf *
buf_alloc(struct bufdomain *bd)
{
struct buf *bp;
int freebufs;
int freebufs, error;
/*
* We can only run out of bufs in the buf zone if the average buf
@ -1660,8 +1660,10 @@ buf_alloc(struct bufdomain *bd)
if (freebufs == bd->bd_lofreebuffers)
bufspace_daemon_wakeup(bd);
if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL) != 0)
panic("getnewbuf_empty: Locked buf %p on free queue.", bp);
error = BUF_LOCK(bp, LK_EXCLUSIVE, NULL);
KASSERT(error == 0, ("%s: BUF_LOCK on free buf %p: %d.", __func__, bp,
error));
(void)error;
KASSERT(bp->b_vp == NULL,
("bp: %p still has vnode %p.", bp, bp->b_vp));