Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 31 Jul 2020 00:07:01 +0000 (UTC)
From:      Conrad Meyer <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r363721 - head/sys/kern
Message-ID:  <202007310007.06V071Kv015082@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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.



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