svn commit: r363721 - head/sys/kern
Conrad Meyer
cem at FreeBSD.org
Fri Jul 31 00:07:02 UTC 2020
Author: cem
Date: Fri Jul 31 00:07:01 2020
New Revision: 363721
URL: https://svnweb.freebsd.org/changeset/base/363721
Log:
getblk: Avoid sleeping on wrong buf in lockless path
If the buffer identity changed during lookup, sleeping could introduce a
lock order reversal. Since we do not know if the identity changed until we
get the lock, we must try-lock (LK_NOWAIT) only. EINTR and ERESTART error
handling becomes irrelevant, as we no longer sleep.
Reported by: kib
Reviewed by: kib
X-MFC-With: r363482
Sponsored by: Dell EMC Isilon
Differential Revision: https://reviews.freebsd.org/D25898
Modified:
head/sys/kern/vfs_bio.c
Modified: head/sys/kern/vfs_bio.c
==============================================================================
--- head/sys/kern/vfs_bio.c Thu Jul 30 23:54:25 2020 (r363720)
+++ head/sys/kern/vfs_bio.c Fri Jul 31 00:07:01 2020 (r363721)
@@ -3844,7 +3844,7 @@ getblkx(struct vnode *vp, daddr_t blkno, daddr_t dblkn
struct buf *bp;
struct bufobj *bo;
daddr_t d_blkno;
- int bsize, error, maxsize, vmio, lockflags;
+ int bsize, error, maxsize, vmio;
off_t offset;
CTR3(KTR_BUF, "getblk(%p, %ld, %d)", vp, (long)blkno, size);
@@ -3865,14 +3865,9 @@ getblkx(struct vnode *vp, daddr_t blkno, daddr_t dblkn
if (bp == NULL)
goto newbuf_unlocked;
- lockflags = LK_EXCLUSIVE | LK_SLEEPFAIL |
- ((flags & GB_LOCK_NOWAIT) ? LK_NOWAIT : 0);
-
- error = BUF_TIMELOCK(bp, lockflags, NULL, "getblku", slpflag,
- slptimeo);
- if (error == EINTR || error == ERESTART)
- return (error);
- else if (error != 0)
+ error = BUF_TIMELOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL, "getblku", 0,
+ 0);
+ if (error != 0)
goto loop;
/* Verify buf identify has not changed since lookup. */
@@ -3886,6 +3881,8 @@ loop:
BO_RLOCK(bo);
bp = gbincore(bo, blkno);
if (bp != NULL) {
+ int lockflags;
+
/*
* Buffer is in-core. If the buffer is not busy nor managed,
* it must be on a queue.
More information about the svn-src-head
mailing list