summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-11-13 23:37:29 +0000
committerphk <phk@FreeBSD.org>2004-11-13 23:37:29 +0000
commitaa4f69ad30ccfea502f5583cf30f1277e32e779c (patch)
treed4476d5aad05886118cdb1c9f870b73d8aa961df
parent437fa9589772c401f29639a3c42c5e9dfa6426a6 (diff)
downloadFreeBSD-src-aa4f69ad30ccfea502f5583cf30f1277e32e779c.zip
FreeBSD-src-aa4f69ad30ccfea502f5583cf30f1277e32e779c.tar.gz
Integrate most of vop_revoke() into devfs_revoke() where it belongs.
-rw-r--r--sys/fs/devfs/devfs_vnops.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index c3d8ba6..00b0443 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -1240,11 +1240,34 @@ devfs_revoke(ap)
} */ *ap;
{
struct vnode *vp = ap->a_vp;
+ struct vnode *vq;
struct devfs_dirent *de;
+ struct cdev *dev;
+ KASSERT((ap->a_flags & REVOKEALL) != 0, ("devfs_revoke !REVOKEALL"));
de = vp->v_data;
de->de_vnode = NULL;
- vop_revoke(ap);
+
+ VI_LOCK(vp);
+ /*
+ * If a vgone (or vclean) is already in progress,
+ * wait until it is done and return.
+ */
+ if (vp->v_iflag & VI_XLOCK) {
+ vp->v_iflag |= VI_XWANT;
+ msleep(vp, VI_MTX(vp), PINOD | PDROP, "vop_revokeall", 0);
+ return (0);
+ }
+ VI_UNLOCK(vp);
+ dev = vp->v_rdev;
+ for (;;) {
+ dev_lock();
+ vq = SLIST_FIRST(&dev->si_hlist);
+ dev_unlock();
+ if (vq == NULL)
+ break;
+ vgone(vq);
+ }
return (0);
}
OpenPOWER on IntegriCloud