27 #include <sys/cdefs.h>
30 #include <sys/param.h>
31 #include <sys/kernel.h>
33 #include <sys/mutex.h>
35 #include <sys/rangelock.h>
36 #include <sys/systm.h>
42 off_t rl_q_start, rl_q_end;
53 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
75 TAILQ_INIT(&lock->rl_waiters);
76 lock->rl_currdep = NULL;
83 KASSERT(TAILQ_EMPTY(&lock->rl_waiters), (
"Dangling waiters"));
98 if ((e1->rl_q_flags & RL_LOCK_TYPE_MASK) == RL_LOCK_READ &&
99 (e2->rl_q_flags & RL_LOCK_TYPE_MASK) == RL_LOCK_READ)
101 if (e1->rl_q_start < e2->rl_q_end && e1->rl_q_end > e2->rl_q_start)
114 if (lock->rl_currdep == TAILQ_FIRST(&lock->rl_waiters) &&
115 lock->rl_currdep != NULL)
116 lock->rl_currdep = TAILQ_NEXT(lock->rl_currdep, rl_q_link);
117 for (entry = lock->rl_currdep; entry != NULL;
118 entry = TAILQ_NEXT(entry, rl_q_link)) {
119 TAILQ_FOREACH(entry1, &lock->rl_waiters, rl_q_link) {
127 lock->rl_currdep = entry;
128 TAILQ_FOREACH(whead, &lock->rl_waiters, rl_q_link) {
129 if (whead == lock->rl_currdep)
131 if (!(whead->rl_q_flags & RL_LOCK_GRANTED)) {
132 whead->rl_q_flags |= RL_LOCK_GRANTED;
143 MPASS(lock != NULL && entry != NULL && ilk != NULL);
144 mtx_assert(ilk, MA_OWNED);
145 KASSERT(entry != lock->rl_currdep, (
"stuck currdep"));
147 TAILQ_REMOVE(&lock->rl_waiters, entry, rl_q_link);
150 if (curthread->td_rlqe == NULL)
151 curthread->td_rlqe = entry;
160 MPASS(lock != NULL && cookie != NULL && ilk != NULL);
171 off_t end,
struct mtx *ilk)
175 MPASS(lock != NULL && cookie != NULL && ilk != NULL);
177 KASSERT(entry->rl_q_flags & RL_LOCK_GRANTED,
178 (
"Unlocking non-granted lock"));
179 KASSERT(entry->rl_q_start == start, (
"wrong start"));
180 KASSERT(entry->rl_q_end >= end, (
"wrong end"));
183 if (entry->rl_q_end == end) {
187 entry->rl_q_end = end;
204 MPASS(lock != NULL && ilk != NULL);
207 if (td->td_rlqe != NULL) {
212 MPASS(entry != NULL);
213 entry->rl_q_flags =
mode;
214 entry->rl_q_start =
start;
215 entry->rl_q_end = end;
224 TAILQ_INSERT_TAIL(&lock->rl_waiters, entry, rl_q_link);
225 if (lock->rl_currdep == NULL)
226 lock->rl_currdep = entry;
228 while (!(entry->rl_q_flags & RL_LOCK_GRANTED))
229 msleep(entry, ilk, 0,
"range", 0);
static void rangelock_calc_block(struct rangelock *lock)
void * rangelock_unlock_range(struct rangelock *lock, void *cookie, off_t start, off_t end, struct mtx *ilk)
static void rangelock_unlock_locked(struct rangelock *lock, struct rl_q_entry *entry, struct mtx *ilk)
void rangelock_destroy(struct rangelock *lock)
void rangelock_unlock(struct rangelock *lock, void *cookie, struct mtx *ilk)
SYSINIT(vfs, SI_SUB_LOCK, SI_ORDER_ANY, rangelock_sys_init, NULL)
static uma_zone_t rl_entry_zone
void * rangelock_wlock(struct rangelock *lock, off_t start, off_t end, struct mtx *ilk)
static struct rl_q_entry * rlqentry_alloc(void)
void rlqentry_free(struct rl_q_entry *rleq)
void * rangelock_rlock(struct rangelock *lock, off_t start, off_t end, struct mtx *ilk)
void rangelock_init(struct rangelock *lock)
static int rangelock_incompatible(const struct rl_q_entry *e1, const struct rl_q_entry *e2)
static void rangelock_sys_init(void)
static void * rangelock_enqueue(struct rangelock *lock, off_t start, off_t end, int mode, struct mtx *ilk)