+/*
+ * Page or buffer structure gets a reference.
+ */
+vhold(vp)
+ register struct vnode *vp;
+{
+
+ vp->v_holdcnt++;
+}
+
+/*
+ * Page or buffer structure frees a reference.
+ */
+holdrele(vp)
+ register struct vnode *vp;
+{
+
+ if (vp->v_holdcnt <= 0)
+ panic("holdrele: holdcnt");
+ vp->v_holdcnt--;
+}
+
+/*
+ * Remove any vnodes in the vnode table belonging to mount point mp.
+ *
+ * If MNT_NOFORCE is specified, there should not be any active ones,
+ * return error if any are found (nb: this is a user error, not a
+ * system error). If MNT_FORCE is specified, detach any active vnodes
+ * that are found.
+ */
+int busyprt = 0; /* patch to print out busy vnodes */
+
+vflush(mp, skipvp, flags)
+ struct mount *mp;
+ struct vnode *skipvp;
+ int flags;
+{
+ register struct vnode *vp, *nvp;
+ int busy = 0;
+
+ for (vp = mp->m_mounth; vp; vp = nvp) {
+ nvp = vp->v_mountf;
+ /*
+ * Skip over a selected vnode.
+ * Used by ufs to skip over the quota structure inode.
+ */
+ if (vp == skipvp)
+ continue;
+ /*
+ * With v_usecount == 0, all we need to do is clear
+ * out the vnode data structures and we are done.
+ */
+ if (vp->v_usecount == 0) {
+ vgone(vp);
+ continue;
+ }
+ /*
+ * For block or character devices, revert to an
+ * anonymous device. For all other files, just kill them.
+ */
+ if (flags & MNT_FORCE) {
+ if (vp->v_type != VBLK && vp->v_type != VCHR) {
+ vgone(vp);
+ } else {
+ vclean(vp, 0);
+ vp->v_op = &spec_vnodeops;
+ insmntque(vp, (struct mount *)0);
+ }
+ continue;
+ }
+ if (busyprt)
+ vprint("vflush: busy vnode", vp);
+ busy++;
+ }
+ if (busy)
+ return (EBUSY);
+ return (0);
+}
+