--- comparison/sys/kern/kern_rangelock.c 2010-07-17 00:48:49.000000000 +0200 +++ vm6/sys/kern/kern_rangelock.c 2010-07-17 07:54:04.000000000 +0200 @@ -29,10 +29,13 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #include #include -#include + +#include struct rl_q_entry { TAILQ_ENTRY(rl_q_entry) rl_q_link; @@ -127,14 +130,17 @@ out: } static void -rangelock_unlock_vp_locked(struct vnode *vp, struct rl_q_entry *entry) +rangelock_unlock_locked(struct rangelock *lock, struct rl_q_entry *entry, + struct mtx *ilk) { - ASSERT_VI_LOCKED(vp, "rangelock"); - KASSERT(entry != vp->v_rl.rl_currdep, ("stuck currdep")); - TAILQ_REMOVE(&vp->v_rl.rl_waiters, entry, rl_q_link); - rangelock_calc_block(&vp->v_rl); - VI_UNLOCK(vp); + MPASS(lock != NULL && entry != NULL && ilk != NULL); + mtx_assert(ilk, MA_OWNED); + KASSERT(entry != lock->rl_currdep, ("stuck currdep")); + + TAILQ_REMOVE(&lock->rl_waiters, entry, rl_q_link); + rangelock_calc_block(lock); + mtx_unlock(ilk); if (curthread->td_rlqe == NULL) curthread->td_rlqe = entry; else @@ -142,52 +148,60 @@ rangelock_unlock_vp_locked(struct vnode } void -rangelock_unlock(struct vnode *vp, void *cookie) +rangelock_unlock(struct rangelock *lock, void *cookie, struct mtx *ilk) { struct rl_q_entry *entry; + MPASS(lock != NULL && cookie != NULL && ilk != NULL); + entry = cookie; - VI_LOCK(vp); - rangelock_unlock_vp_locked(vp, entry); + mtx_lock(ilk); + rangelock_unlock_locked(lock, entry, ilk); } void * -rangelock_unlock_range(struct vnode *vp, void *cookie, off_t base, size_t len) +rangelock_unlock_range(struct rangelock *lock, void *cookie, off_t base, + size_t len, struct mtx *ilk) { struct rl_q_entry *entry; + MPASS(lock != NULL && cookie != NULL && ilk != NULL); + + mtx_lock(ilk); entry = cookie; - VI_LOCK(vp); KASSERT(entry->rl_q_flags & RL_LOCK_GRANTED, ("XXX")); KASSERT(entry->rl_q_start == base, ("XXX")); KASSERT(entry->rl_q_end >= base + len, ("XXX")); if (entry->rl_q_end == base + len) { - rangelock_unlock_vp_locked(vp, cookie); + rangelock_unlock_locked(lock, cookie, ilk); return (NULL); } entry->rl_q_end = base + len; - rangelock_calc_block(&vp->v_rl); - VI_UNLOCK(vp); + rangelock_calc_block(lock); + mtx_unlock(ilk); return (cookie); } static void * -rangelock_enqueue(struct vnode *vp, struct rl_q_entry *entry) +rangelock_enqueue(struct rangelock *lock, struct rl_q_entry *entry, + struct mtx *ilk) { - VI_LOCK(vp); - TAILQ_INSERT_TAIL(&vp->v_rl.rl_waiters, entry, rl_q_link); - if (vp->v_rl.rl_currdep == NULL) - vp->v_rl.rl_currdep = entry; - rangelock_calc_block(&vp->v_rl); + MPASS(lock != NULL && entry != NULL && ilk != NULL); + + mtx_lock(ilk); + TAILQ_INSERT_TAIL(&lock->rl_waiters, entry, rl_q_link); + if (lock->rl_currdep == NULL) + lock->rl_currdep = entry; + rangelock_calc_block(lock); while (!(entry->rl_q_flags & RL_LOCK_GRANTED)) - msleep(entry, &vp->v_interlock, 0, "range", 0); - VI_UNLOCK(vp); + msleep(entry, ilk, 0, "range", 0); + mtx_unlock(ilk); return (entry); } void * -rangelock_rlock(struct vnode *vp, off_t base, size_t len) +rangelock_rlock(struct rangelock *lock, off_t base, size_t len, struct mtx *ilk) { struct rl_q_entry *entry; struct thread *td; @@ -201,11 +215,11 @@ rangelock_rlock(struct vnode *vp, off_t entry->rl_q_flags = RL_LOCK_READ; entry->rl_q_start = base; entry->rl_q_end = base + len; - return (rangelock_enqueue(vp, entry)); + return (rangelock_enqueue(lock, entry, ilk)); } void * -rangelock_wlock(struct vnode *vp, off_t base, size_t len) +rangelock_wlock(struct rangelock *lock, off_t base, size_t len, struct mtx *ilk) { struct rl_q_entry *entry; struct thread *td; @@ -219,5 +233,5 @@ rangelock_wlock(struct vnode *vp, off_t entry->rl_q_flags = RL_LOCK_WRITE; entry->rl_q_start = base; entry->rl_q_end = base + len; - return (rangelock_enqueue(vp, entry)); + return (rangelock_enqueue(lock, entry, ilk)); } --- comparison/sys/kern/vfs_vnops.c 2010-07-12 04:56:21.000000000 +0200 +++ vm6/sys/kern/vfs_vnops.c 2010-07-16 23:07:20.000000000 +0200 @@ -391,9 +391,9 @@ vn_rdwr(enum uio_rw rw, struct vnode *vp if ((ioflg & IO_NODELOCKED) == 0) { if (rw == UIO_READ) - rl_cookie = rangelock_rlock(vp, offset, len); + rl_cookie = vn_rangelock_rlock(vp, offset, len); else - rl_cookie = rangelock_wlock(vp, offset, len); + rl_cookie = vn_rangelock_wlock(vp, offset, len); mp = NULL; if (rw == UIO_WRITE) { if (vp->v_type != VCHR && @@ -443,7 +443,7 @@ vn_rdwr(enum uio_rw rw, struct vnode *vp } out: if (rl_cookie != NULL) - rangelock_unlock(vp, rl_cookie); + vn_rangelock_unlock(vp, rl_cookie); return (error); } @@ -595,7 +595,7 @@ vn_read(struct file *fp, struct uio *uio } else mtxp = NULL; /* gcc */ if (vp->v_type == VREG) - rl_cookie = rangelock_rlock(vp, uio->uio_offset, + rl_cookie = vn_rangelock_rlock(vp, uio->uio_offset, uio->uio_resid); else rl_cookie = NULL; @@ -603,7 +603,7 @@ vn_read(struct file *fp, struct uio *uio error = vn_read_chunk(vp, uio, active_cred, fp->f_cred, ioflag); fp->f_nextoff = uio->uio_offset; if (rl_cookie != NULL) - rangelock_unlock(vp, rl_cookie); + vn_rangelock_unlock(vp, rl_cookie); if ((flags & FOF_OFFSET) == 0) { fp->f_offset = uio->uio_offset; vn_unlock_foffset(fp, mtxp); @@ -688,15 +688,15 @@ vn_write(struct file *fp, struct uio *ui * For appenders, punt and lock the whole * range. It also protects f_offset. */ - rl_cookie = rangelock_wlock(vp, 0, (size_t)-1); + rl_cookie = vn_rangelock_wlock(vp, 0, (size_t)-1); else - rl_cookie = rangelock_wlock(vp, uio->uio_offset, + rl_cookie = vn_rangelock_wlock(vp, uio->uio_offset, uio->uio_resid); } else rl_cookie = NULL; error = vn_write_chunk(vp, uio, active_cred, fp->f_cred, ioflag); if (rl_cookie != NULL) - rangelock_unlock(vp, rl_cookie); + vn_rangelock_unlock(vp, rl_cookie); if ((flags & FOF_OFFSET) == 0) { fp->f_offset = uio->uio_offset; vn_unlock_foffset(fp, mtxp); @@ -727,7 +727,7 @@ vn_truncate(struct file *fp, off_t lengt * the range then call VOP_GETATTR to get the current size and * deal with races. */ - rl_cookie = rangelock_wlock(vp, length, -1); + rl_cookie = vn_rangelock_wlock(vp, length, -1); vfslocked = VFS_LOCK_GIANT(vp->v_mount); error = vn_start_write(vp, &mp, V_WAIT | PCATCH); if (error) @@ -753,7 +753,7 @@ out: vn_finished_write(mp); out1: VFS_UNLOCK_GIANT(vfslocked); - rangelock_unlock(vp, rl_cookie); + vn_rangelock_unlock(vp, rl_cookie); return (error); } --- comparison/sys/sys/rangelock.h 2010-07-17 00:51:56.000000000 +0200 +++ vm6/sys/sys/rangelock.h 2010-07-17 07:49:50.000000000 +0200 @@ -8,11 +8,7 @@ #ifndef _SYS_RANGELOCK_H #define _SYS_RANGELOCK_H -#include -#include -#include #include -#include #ifdef _KERNEL @@ -23,23 +19,27 @@ struct vnode; struct rl_q_entry; +struct mtx; -struct rangelock -{ +struct rangelock { TAILQ_HEAD(, rl_q_entry) rl_waiters; struct rl_q_entry *rl_currdep; }; void rangelock_init(struct rangelock *lock); void rangelock_destroy(struct rangelock *lock); -void rangelock_unlock(struct vnode *vp, void *cookie); -void *rangelock_unlock_range(struct vnode *vp, void *cookie, off_t base, - size_t len); -void *rangelock_rlock(struct vnode *vp, off_t base, size_t len); -void *rangelock_wlock(struct vnode *vp, off_t base, size_t len); +void rangelock_unlock(struct rangelock *lock, void *cookie, + struct mtx *ilk); +void *rangelock_unlock_range(struct rangelock *lock, void *cookie, + off_t base, size_t len, struct mtx *ilk); +void *rangelock_rlock(struct rangelock *lock, off_t base, size_t len, + struct mtx *ilk); +void *rangelock_wlock(struct rangelock *lock, off_t base, size_t len, + struct mtx *ilk); struct rl_q_entry *rlqentry_alloc(void); void rlqentry_free(struct rl_q_entry *rlqe); -#endif -#endif +#endif /* _KERNEL */ + +#endif /* _SYS_RANGELOCK_H */ --- comparison/sys/sys/vnode.h 2010-07-12 04:56:22.000000000 +0200 +++ vm6/sys/sys/vnode.h 2010-07-17 07:55:36.000000000 +0200 @@ -676,6 +676,14 @@ int vn_extattr_rm(struct vnode *vp, int int vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags, struct vnode **rvp); +#define vn_rangelock_unlock(vp, cookie) \ + rangelock_unlock(&(vp)->v_rl, (cookie), VI_MTX(vp)) +#define vn_rangelock_unlock_range(vp, cookie, base, len) \ + rangelock_unlock_range(&(vp)->v_rl, (cookie), (base), (len), VI_MTX(vp)) +#define vn_rangelock_rlock(vp, base, len) \ + rangelock_rlock(&(vp)->v_rl, (base), (len), VI_MTX(vp)) +#define vn_rangelock_wlock(vp, base, len) \ + rangelock_wlock(&(vp)->v_rl, (base), (len), VI_MTX(vp)) int vfs_cache_lookup(struct vop_lookup_args *ap); void vfs_timestamp(struct timespec *);