git: c926114f2ff2 - main - Fix getblk() with GB_NOCREAT returning false-negatives.

Bryan Drewery bdrewery at FreeBSD.org
Thu Jan 28 19:24:52 UTC 2021


The branch main has been updated by bdrewery:

URL: https://cgit.FreeBSD.org/src/commit/?id=c926114f2ff20d7c3e5a157f1618b6228f391bf7

commit c926114f2ff20d7c3e5a157f1618b6228f391bf7
Author:     Bryan Drewery <bdrewery at FreeBSD.org>
AuthorDate: 2021-01-27 17:59:50 +0000
Commit:     Bryan Drewery <bdrewery at FreeBSD.org>
CommitDate: 2021-01-28 19:24:24 +0000

    Fix getblk() with GB_NOCREAT returning false-negatives.
    
    It is possible for a buf to be reassigned between the dirty and clean
    lists while gbincore_unlocked() looks in each list.  Avoid creating
    a buffer in that case and fallback to a locked lookup.
    
    This fixes a regression from r363482.
    
    More discussion on potential improvements to the clean and dirty lists
    handling is in the review.
    
    Reviewed by:    cem, kib, markj, vangyzen, rlibby
    Reported by:    Suraj.Raju at dell.com
    Submitted by:   Suraj.Raju at dell.com, cem, [based on both]
    MFC after:      2 weeks
    Sponsored by:   Dell EMC
    Differential Revision:  https://reviews.freebsd.org/D28375
---
 sys/kern/vfs_bio.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 2f18221e9270..ff25e5b0043c 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -3888,8 +3888,15 @@ getblkx(struct vnode *vp, daddr_t blkno, daddr_t dblkno, int size, int slpflag,
 
 	/* Attempt lockless lookup first. */
 	bp = gbincore_unlocked(bo, blkno);
-	if (bp == NULL)
+	if (bp == NULL) {
+		/*
+		 * With GB_NOCREAT we must be sure about not finding the buffer
+		 * as it may have been reassigned during unlocked lookup.
+		 */
+		if ((flags & GB_NOCREAT) != 0)
+			goto loop;
 		goto newbuf_unlocked;
+	}
 
 	error = BUF_TIMELOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL, "getblku", 0,
 	    0);


More information about the dev-commits-src-all mailing list