]> xenbits.xensource.com Git - freebsd.git/commitdiff
rangelock: add rangelock_cookie_assert
authorkevans <kevans@FreeBSD.org>
Sun, 15 Sep 2019 02:59:53 +0000 (02:59 +0000)
committerkevans <kevans@FreeBSD.org>
Sun, 15 Sep 2019 02:59:53 +0000 (02:59 +0000)
A future change to posixshm to add file sealing (in DIFF_21391[0] and child)
will move locking out of shm_dotruncate as kern_shm_open() will require the
lock to be held across the dotruncate until the seal is actually applied.
For this, the cookie is passed into shm_dotruncate_locked which asserts
RCA_WLOCKED.

[0] Name changed to protect the innocent, hopefully, from getting autoclosed
due to this reference...

Reviewed by: kib
Differential Revision: https://reviews.freebsd.org/D21628

sys/kern/kern_rangelock.c
sys/sys/rangelock.h

index b434ac4b4c1c7086465b54affc4e50dad8748152..2983abbbdb5a562682c100a2116fccb51cd0594c 100644 (file)
@@ -299,3 +299,35 @@ rangelock_trywlock(struct rangelock *lock, off_t start, off_t end,
 
        return (rangelock_enqueue(lock, start, end, RL_LOCK_WRITE, ilk, true));
 }
+
+#ifdef INVARIANT_SUPPORT
+void
+_rangelock_cookie_assert(void *cookie, int what, const char *file, int line)
+{
+       struct rl_q_entry *entry;
+       int flags;
+
+       MPASS(cookie != NULL);
+       entry = cookie;
+       flags = entry->rl_q_flags;
+       switch (what) {
+       case RCA_LOCKED:
+               if ((flags & RL_LOCK_GRANTED) == 0)
+                       panic("rangelock not held @ %s:%d\n", file, line);
+               break;
+       case RCA_RLOCKED:
+               if ((flags & (RL_LOCK_GRANTED | RL_LOCK_READ)) !=
+                   (RL_LOCK_GRANTED | RL_LOCK_READ))
+                       panic("rangelock not rlocked @ %s:%d\n", file, line);
+               break;
+       case RCA_WLOCKED:
+               if ((flags & (RL_LOCK_GRANTED | RL_LOCK_WRITE)) !=
+                   (RL_LOCK_GRANTED | RL_LOCK_WRITE))
+                       panic("rangelock not wlocked @ %s:%d\n", file, line);
+               break;
+       default:
+               panic("Unknown rangelock assertion: %d @ %s:%d", what, file,
+                   line);
+       }
+}
+#endif /* INVARIANT_SUPPORT */
index 9a8a107aed8f4bb3e1c0411933471b9da2110584..128a87918f4fd6cdfffb4ce703b0628f7e979e3d 100644 (file)
@@ -82,6 +82,29 @@ void *rangelock_wlock(struct rangelock *lock, off_t start, off_t end,
 void   *rangelock_trywlock(struct rangelock *lock, off_t start, off_t end,
            struct mtx *ilk);
 void    rlqentry_free(struct rl_q_entry *rlqe);
+#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
+void   _rangelock_cookie_assert(void *cookie, int what, const char *file,
+    int line);
+#endif
+
+#ifdef INVARIANTS
+#define        rangelock_cookie_assert_(cookie, what, file, line)      \
+       _rangelock_cookie_assert((cookie), (what), (file), (line))
+#else
+#define        rangelock_cookie_assert_(cookie, what, file, line)              (void)0
+#endif
+
+#define        rangelock_cookie_assert(cookie, what)   \
+       rangelock_cookie_assert_((cookie), (what), __FILE__, __LINE__)
+
+/*
+ * Assertion flags.
+ */
+#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
+#define        RCA_LOCKED      0x0001
+#define        RCA_RLOCKED     0x0002
+#define        RCA_WLOCKED     0x0004
+#endif
 
 #endif /* _KERNEL */