version 1.192.6.2, 2017/08/28 17:53:08 |
version 1.193, 2017/01/11 09:08:59 |
Line 227 genfs_eopnotsupp(void *v) |
|
Line 227 genfs_eopnotsupp(void *v) |
|
vp_last = vp; |
vp_last = vp; |
} |
} |
break; |
break; |
|
case VDESC_VP0_WILLUNLOCK: |
|
VOP_UNLOCK(vp); |
|
break; |
case VDESC_VP0_WILLRELE: |
case VDESC_VP0_WILLRELE: |
vrele(vp); |
vrele(vp); |
break; |
break; |
Line 288 genfs_deadlock(void *v) |
|
Line 291 genfs_deadlock(void *v) |
|
vnode_impl_t *vip = VNODE_TO_VIMPL(vp); |
vnode_impl_t *vip = VNODE_TO_VIMPL(vp); |
int flags = ap->a_flags; |
int flags = ap->a_flags; |
krw_t op; |
krw_t op; |
|
int error; |
if (! ISSET(flags, LK_RETRY)) |
|
return ENOENT; |
|
|
|
op = (ISSET(flags, LK_EXCLUSIVE) ? RW_WRITER : RW_READER); |
op = (ISSET(flags, LK_EXCLUSIVE) ? RW_WRITER : RW_READER); |
if (ISSET(flags, LK_NOWAIT)) { |
if (ISSET(flags, LK_NOWAIT)) { |
if (! rw_tryenter(&vip->vi_lock, op)) |
if (! rw_tryenter(&vip->vi_lock, op)) |
return EBUSY; |
return EBUSY; |
} else { |
if (mutex_tryenter(vp->v_interlock)) { |
|
error = vdead_check(vp, VDEAD_NOWAIT); |
|
if (error == ENOENT && ISSET(flags, LK_RETRY)) |
|
error = 0; |
|
mutex_exit(vp->v_interlock); |
|
} else |
|
error = EBUSY; |
|
if (error) |
|
rw_exit(&vip->vi_lock); |
|
return error; |
|
} |
|
|
|
rw_enter(&vip->vi_lock, op); |
|
mutex_enter(vp->v_interlock); |
|
error = vdead_check(vp, VDEAD_NOWAIT); |
|
if (error == EBUSY) { |
|
rw_exit(&vip->vi_lock); |
|
error = vdead_check(vp, 0); |
|
KASSERT(error == ENOENT); |
|
mutex_exit(vp->v_interlock); |
rw_enter(&vip->vi_lock, op); |
rw_enter(&vip->vi_lock, op); |
|
mutex_enter(vp->v_interlock); |
|
} |
|
KASSERT(error == ENOENT); |
|
mutex_exit(vp->v_interlock); |
|
if (! ISSET(flags, LK_RETRY)) { |
|
rw_exit(&vip->vi_lock); |
|
return ENOENT; |
} |
} |
VSTATE_ASSERT_UNLOCKED(vp, VS_RECLAIMED); |
|
return 0; |
return 0; |
} |
} |
|
|
Line 332 genfs_lock(void *v) |
|
Line 358 genfs_lock(void *v) |
|
} */ *ap = v; |
} */ *ap = v; |
vnode_t *vp = ap->a_vp; |
vnode_t *vp = ap->a_vp; |
vnode_impl_t *vip = VNODE_TO_VIMPL(vp); |
vnode_impl_t *vip = VNODE_TO_VIMPL(vp); |
|
struct mount *mp = vp->v_mount; |
int flags = ap->a_flags; |
int flags = ap->a_flags; |
krw_t op; |
krw_t op; |
|
int error; |
|
|
op = (ISSET(flags, LK_EXCLUSIVE) ? RW_WRITER : RW_READER); |
op = (ISSET(flags, LK_EXCLUSIVE) ? RW_WRITER : RW_READER); |
if (ISSET(flags, LK_NOWAIT)) { |
if (ISSET(flags, LK_NOWAIT)) { |
if (! rw_tryenter(&vip->vi_lock, op)) |
if (fstrans_start_nowait(mp, FSTRANS_SHARED)) |
return EBUSY; |
return EBUSY; |
} else { |
if (! rw_tryenter(&vip->vi_lock, op)) { |
rw_enter(&vip->vi_lock, op); |
fstrans_done(mp); |
|
return EBUSY; |
|
} |
|
if (mutex_tryenter(vp->v_interlock)) { |
|
error = vdead_check(vp, VDEAD_NOWAIT); |
|
mutex_exit(vp->v_interlock); |
|
} else |
|
error = EBUSY; |
|
if (error) { |
|
rw_exit(&vip->vi_lock); |
|
fstrans_done(mp); |
|
} |
|
return error; |
} |
} |
VSTATE_ASSERT_UNLOCKED(vp, VS_ACTIVE); |
|
return 0; |
fstrans_start(mp, FSTRANS_SHARED); |
|
rw_enter(&vip->vi_lock, op); |
|
mutex_enter(vp->v_interlock); |
|
error = vdead_check(vp, VDEAD_NOWAIT); |
|
if (error) { |
|
rw_exit(&vip->vi_lock); |
|
fstrans_done(mp); |
|
error = vdead_check(vp, 0); |
|
KASSERT(error == ENOENT); |
|
} |
|
mutex_exit(vp->v_interlock); |
|
return error; |
} |
} |
|
|
/* |
/* |
Line 357 genfs_unlock(void *v) |
|
Line 408 genfs_unlock(void *v) |
|
} */ *ap = v; |
} */ *ap = v; |
vnode_t *vp = ap->a_vp; |
vnode_t *vp = ap->a_vp; |
vnode_impl_t *vip = VNODE_TO_VIMPL(vp); |
vnode_impl_t *vip = VNODE_TO_VIMPL(vp); |
|
struct mount *mp = vp->v_mount; |
|
|
rw_exit(&vip->vi_lock); |
rw_exit(&vip->vi_lock); |
|
fstrans_done(mp); |
|
|
return 0; |
return 0; |
} |
} |
Line 500 filt_genfsread(struct knote *kn, long hi |
|
Line 553 filt_genfsread(struct knote *kn, long hi |
|
} |
} |
|
|
static int |
static int |
filt_genfswrite(struct knote *kn, long hint) |
|
{ |
|
struct vnode *vp = (struct vnode *)kn->kn_hook; |
|
|
|
/* |
|
* filesystem is gone, so set the EOF flag and schedule |
|
* the knote for deletion. |
|
*/ |
|
switch (hint) { |
|
case NOTE_REVOKE: |
|
KASSERT(mutex_owned(vp->v_interlock)); |
|
kn->kn_flags |= (EV_EOF | EV_ONESHOT); |
|
return (1); |
|
case 0: |
|
mutex_enter(vp->v_interlock); |
|
kn->kn_data = 0; |
|
mutex_exit(vp->v_interlock); |
|
return 1; |
|
default: |
|
KASSERT(mutex_owned(vp->v_interlock)); |
|
kn->kn_data = 0; |
|
return 1; |
|
} |
|
} |
|
|
|
static int |
|
filt_genfsvnode(struct knote *kn, long hint) |
filt_genfsvnode(struct knote *kn, long hint) |
{ |
{ |
struct vnode *vp = (struct vnode *)kn->kn_hook; |
struct vnode *vp = (struct vnode *)kn->kn_hook; |
Line 556 filt_genfsvnode(struct knote *kn, long h |
|
Line 583 filt_genfsvnode(struct knote *kn, long h |
|
|
|
static const struct filterops genfsread_filtops = |
static const struct filterops genfsread_filtops = |
{ 1, NULL, filt_genfsdetach, filt_genfsread }; |
{ 1, NULL, filt_genfsdetach, filt_genfsread }; |
static const struct filterops genfswrite_filtops = |
|
{ 1, NULL, filt_genfsdetach, filt_genfswrite }; |
|
static const struct filterops genfsvnode_filtops = |
static const struct filterops genfsvnode_filtops = |
{ 1, NULL, filt_genfsdetach, filt_genfsvnode }; |
{ 1, NULL, filt_genfsdetach, filt_genfsvnode }; |
|
|
Line 577 genfs_kqfilter(void *v) |
|
Line 602 genfs_kqfilter(void *v) |
|
case EVFILT_READ: |
case EVFILT_READ: |
kn->kn_fop = &genfsread_filtops; |
kn->kn_fop = &genfsread_filtops; |
break; |
break; |
case EVFILT_WRITE: |
|
kn->kn_fop = &genfswrite_filtops; |
|
break; |
|
case EVFILT_VNODE: |
case EVFILT_VNODE: |
kn->kn_fop = &genfsvnode_filtops; |
kn->kn_fop = &genfsvnode_filtops; |
break; |
break; |