#undef afs_osi_Alloc_NoSleep
extern void *afs_osi_Alloc_NoSleep(size_t size);
-#define osi_vnhold(avc, r) do { VN_HOLD(AFSTOV(avc)); } while(0)
+#ifdef AFS_SUN58_ENV
+# define osi_vnhold(avc, r) do { \
+ struct vnode *vp = AFSTOV(avc); \
+ uint_t prevcount; \
+ \
+ mutex_enter(&vp->v_lock); \
+ prevcount = vp->v_count++; \
+ mutex_exit(&vp->v_lock); \
+ \
+ if (prevcount == 0) { \
+ VFS_HOLD(afs_globalVFS); \
+ } \
+} while(0)
+#else /* !AFS_SUN58_ENV */
+# define osi_vnhold(avc, r) do { VN_HOLD(AFSTOV(avc)); } while(0)
+#endif /* !AFS_SUN58_ENV */
+
#define gop_rdwr(rw,gp,base,len,offset,segflg,ioflag,ulimit,cr,aresid) \
vn_rdwr((rw),(gp),(base),(len),(offset),(segflg),(ioflag),(ulimit),(cr),(aresid))
#define gop_lookupname(fnamep,segflg,followlink,compvpp) \
AFSTOV(avc)->v_op = afs_ops;
AFSTOV(avc)->v_vfsp = afs_globalVFS;
vSetType(avc, VREG);
+
+#ifdef AFS_SUN58_ENV
+ /* Normally we do this in osi_vnhold when we notice the ref count went from
+ * 0 -> 1. But if we just setup or reused a vcache, we set the refcount to
+ * 1 directly. So, we must explicitly VFS_HOLD here. */
+ VFS_HOLD(afs_globalVFS);
+#endif
}
AFS_GUNLOCK();
return ENOTSUP;
}
+
+ /* We should have one reference from the caller, and one reference for the
+ * root vnode; any more and someone is still referencing something */
+ if (afsp->vfs_count > 2) {
+ AFS_GUNLOCK();
+ return EBUSY;
+ }
+
+ /* The root vnode should have one ref for the mount; any more, and someone
+ * else is using the root vnode */
+ if (afs_globalVp && VREFCOUNT_GT(afs_globalVp, 1)) {
+ AFS_GUNLOCK();
+ return EBUSY;
+ }
#endif /* AFS_SUN58_ENV */
afs_globalVFS = 0;