Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F110457328
D20645.id58680.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D20645.id58680.diff
View Options
Index: kern/kern_rangelock.c
===================================================================
--- kern/kern_rangelock.c
+++ kern/kern_rangelock.c
@@ -141,7 +141,7 @@
static void
rangelock_unlock_locked(struct rangelock *lock, struct rl_q_entry *entry,
- struct mtx *ilk)
+ struct mtx *ilk, int do_calc_block)
{
MPASS(lock != NULL && entry != NULL && ilk != NULL);
@@ -149,7 +149,8 @@
KASSERT(entry != lock->rl_currdep, ("stuck currdep"));
TAILQ_REMOVE(&lock->rl_waiters, entry, rl_q_link);
- rangelock_calc_block(lock);
+ if (do_calc_block != 0)
+ rangelock_calc_block(lock);
mtx_unlock(ilk);
if (curthread->td_rlqe == NULL)
curthread->td_rlqe = entry;
@@ -164,7 +165,7 @@
MPASS(lock != NULL && cookie != NULL && ilk != NULL);
mtx_lock(ilk);
- rangelock_unlock_locked(lock, cookie, ilk);
+ rangelock_unlock_locked(lock, cookie, ilk, 1);
}
/*
@@ -185,7 +186,7 @@
mtx_lock(ilk);
if (entry->rl_q_end == end) {
- rangelock_unlock_locked(lock, cookie, ilk);
+ rangelock_unlock_locked(lock, cookie, ilk, 1);
return (NULL);
}
entry->rl_q_end = end;
@@ -196,11 +197,11 @@
/*
* Add the lock request to the queue of the pending requests for
- * rangelock. Sleep until the request can be granted.
+ * rangelock. Sleep until the request can be granted unless trylock != 0.
*/
static void *
rangelock_enqueue(struct rangelock *lock, off_t start, off_t end, int mode,
- struct mtx *ilk)
+ struct mtx *ilk, int trylock)
{
struct rl_q_entry *entry;
struct thread *td;
@@ -226,11 +227,40 @@
*/
TAILQ_INSERT_TAIL(&lock->rl_waiters, entry, rl_q_link);
+ /*
+ * If rl_currdep == NULL, there is no entry waiting for a conflicting
+ * range to be resolved, so set rl_currdep to this entry. If there is
+ * no conflicting entry for this entry, rl_currdep will be set back to
+ * NULL by rangelock_calc_block().
+ */
if (lock->rl_currdep == NULL)
lock->rl_currdep = entry;
rangelock_calc_block(lock);
- while (!(entry->rl_q_flags & RL_LOCK_GRANTED))
+ while (!(entry->rl_q_flags & RL_LOCK_GRANTED)) {
+ if (trylock != 0) {
+ /*
+ * If rl_currdep is this entry, rl_currdep needs to
+ * be set to the next entry in the rl_waiters list.
+ * However, since this entry is the last entry in the
+ * list, the next entry is NULL.
+ */
+ if (lock->rl_currdep == entry) {
+ KASSERT(TAILQ_NEXT(lock->rl_currdep,
+ rl_q_link) == NULL,
+ ("rangelock_enqueue: next entry not NULL"));
+ lock->rl_currdep = NULL;
+ }
+ /*
+ * For this case, the range is not actually locked
+ * yet, but removal from the list requires the same
+ * steps, except for not doing a rangelock_calc_block()
+ * call, since rangelock_calc_block() was called above.
+ */
+ rangelock_unlock_locked(lock, entry, ilk, 0);
+ return (NULL);
+ }
msleep(entry, ilk, 0, "range", 0);
+ }
mtx_unlock(ilk);
return (entry);
}
@@ -239,12 +269,28 @@
rangelock_rlock(struct rangelock *lock, off_t start, off_t end, struct mtx *ilk)
{
- return (rangelock_enqueue(lock, start, end, RL_LOCK_READ, ilk));
+ return (rangelock_enqueue(lock, start, end, RL_LOCK_READ, ilk, 0));
}
void *
+rangelock_rlock_trylock(struct rangelock *lock, off_t start, off_t end,
+ struct mtx *ilk)
+{
+
+ return (rangelock_enqueue(lock, start, end, RL_LOCK_READ, ilk, 1));
+}
+
+void *
rangelock_wlock(struct rangelock *lock, off_t start, off_t end, struct mtx *ilk)
{
- return (rangelock_enqueue(lock, start, end, RL_LOCK_WRITE, ilk));
+ return (rangelock_enqueue(lock, start, end, RL_LOCK_WRITE, ilk, 0));
+}
+
+void *
+rangelock_wlock_trylock(struct rangelock *lock, off_t start, off_t end,
+ struct mtx *ilk)
+{
+
+ return (rangelock_enqueue(lock, start, end, RL_LOCK_WRITE, ilk, 1));
}
Index: sys/rangelock.h
===================================================================
--- sys/rangelock.h
+++ sys/rangelock.h
@@ -75,8 +75,12 @@
off_t start, off_t end, struct mtx *ilk);
void *rangelock_rlock(struct rangelock *lock, off_t start, off_t end,
struct mtx *ilk);
+void *rangelock_rlock_trylock(struct rangelock *lock, off_t start,
+ off_t end, struct mtx *ilk);
void *rangelock_wlock(struct rangelock *lock, off_t start, off_t end,
struct mtx *ilk);
+void *rangelock_wlock_trylock(struct rangelock *lock, off_t start,
+ off_t end, struct mtx *ilk);
void rlqentry_free(struct rl_q_entry *rlqe);
#endif /* _KERNEL */
Index: sys/vnode.h
===================================================================
--- sys/vnode.h
+++ sys/vnode.h
@@ -723,8 +723,12 @@
VI_MTX(vp))
#define vn_rangelock_rlock(vp, start, end) \
rangelock_rlock(&(vp)->v_rl, (start), (end), VI_MTX(vp))
+#define vn_rangelock_rlock_trylock(vp, start, end) \
+ rangelock_rlock_trylock(&(vp)->v_rl, (start), (end), VI_MTX(vp))
#define vn_rangelock_wlock(vp, start, end) \
rangelock_wlock(&(vp)->v_rl, (start), (end), VI_MTX(vp))
+#define vn_rangelock_wlock_trylock(vp, start, end) \
+ rangelock_wlock_trylock(&(vp)->v_rl, (start), (end), VI_MTX(vp))
int vfs_cache_lookup(struct vop_lookup_args *ap);
void vfs_timestamp(struct timespec *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Feb 19, 5:29 PM (20 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16724869
Default Alt Text
D20645.id58680.diff (5 KB)
Attached To
Mode
D20645: add non-blocking variants of rangelock_rlock() and rangelock_wlock()
Attached
Detach File
Event Timeline
Log In to Comment