Page MenuHomeFreeBSD

D45571.id139793.diff
No OneTemporary

D45571.id139793.diff

diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -4002,9 +4002,16 @@
/*
* With GB_NOCREAT we must be sure about not finding the buffer
* as it may have been reassigned during unlocked lookup.
+ * If BO_NONSTERILE is still unset, no reassign has occurred.
*/
- if ((flags & GB_NOCREAT) != 0)
+ if ((flags & GB_NOCREAT) != 0) {
+ /* Ensure bo_flag is loaded after gbincore_unlocked. */
+ atomic_thread_fence_acq();
+ if ((atomic_load_int(&bo->bo_flag) & BO_NONSTERILE) ==
+ 0)
+ return (EEXIST);
goto loop;
+ }
goto newbuf_unlocked;
}
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -3207,6 +3207,15 @@
bp, bp->b_vp, bp->b_flags);
BO_LOCK(bo);
+ if ((bo->bo_flag & BO_NONSTERILE) == 0) {
+ /*
+ * Corrdinate with getblk's unlocked lookup. Make
+ * BO_NONSTERILE visible before the first reassignbuf produces
+ * any side effect. This could be outside the bo lock if we
+ * used a separate atomic flag field.
+ */
+ atomic_set_acq_int(&bo->bo_flag, BO_NONSTERILE);
+ }
buf_vlist_remove(bp);
/*
diff --git a/sys/sys/bufobj.h b/sys/sys/bufobj.h
--- a/sys/sys/bufobj.h
+++ b/sys/sys/bufobj.h
@@ -116,6 +116,7 @@
#define BO_WWAIT (1 << 1) /* Wait for output to complete */
#define BO_DEAD (1 << 2) /* Dead; only with INVARIANTS */
#define BO_NOBUFS (1 << 3) /* No bufs allowed */
+#define BO_NONSTERILE (1 << 4) /* Ever called reassignbuf() */
#define BO_LOCKPTR(bo) (&(bo)->bo_lock)
#define BO_LOCK(bo) rw_wlock(BO_LOCKPTR((bo)))

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 8, 4:23 AM (20 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31075460
Default Alt Text
D45571.id139793.diff (1 KB)

Event Timeline