Index: src/afs/afs_call.c =================================================================== RCS file: /cvs/openafs/src/afs/afs_call.c,v retrieving revision 1.14.2.14 diff -u -r1.14.2.14 afs_call.c --- src/afs/afs_call.c 2002/09/11 16:17:31 1.14.2.14 +++ src/afs/afs_call.c 2002/11/09 14:18:01 @@ -718,8 +718,10 @@ #endif afs_cold_shutdown = 0; if (parm == 1) afs_cold_shutdown = 1; +#ifndef AFS_DARWIN_ENV if (afs_globalVFS != 0) afs_warn("AFS isn't unmounted yet!\n"); +#endif afs_shutdown(); } Index: src/afs/DARWIN/osi_vfsops.c =================================================================== RCS file: /cvs/openafs/src/afs/DARWIN/osi_vfsops.c,v retrieving revision 1.4.2.1 diff -u -r1.4.2.1 osi_vfsops.c --- src/afs/DARWIN/osi_vfsops.c 2002/04/24 01:41:22 1.4.2.1 +++ src/afs/DARWIN/osi_vfsops.c 2002/11/09 14:18:01 @@ -67,7 +67,7 @@ AFS_GLOCK(); AFS_STATCNT(afs_mount); - if (afs_globalVFS) { /* Don't allow remounts. */ + if (data == NULL && afs_globalVFS) { /* Don't allow remounts. */ AFS_GUNLOCK(); return (EBUSY); } @@ -80,8 +80,45 @@ (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN-1, &size); memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size); memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN); - strcpy(mp->mnt_stat.f_mntfromname, "AFS"); - /* null terminated string "AFS" will fit, just leave it be. */ + + if (data == NULL) { + strcpy(mp->mnt_stat.f_mntfromname, "AFS"); + /* null terminated string "AFS" will fit, just leave it be. */ + mp->mnt_data = (qaddr_t)NULL; + } else { + struct VenusFid *rootFid = NULL; + struct volume *tvp; + char volName[MNAMELEN]; + + (void) copyinstr((char *)data, volName, MNAMELEN-1, &size); + memset(volName + size, 0, MNAMELEN - size); + + if (volName[0] == 0) { + strcpy(mp->mnt_stat.f_mntfromname, "AFS"); + mp->mnt_data = (qaddr_t)&afs_rootFid; + } else { + /* Set the volume identifier to "AFS:volume.name" */ + snprintf(mp->mnt_stat.f_mntfromname, MNAMELEN-1, "AFS:%s", + volName); + tvp = afs_GetVolumeByName(volName, LOCALCELL, 1, + (struct vrequest *)0, READ_LOCK); + + if (tvp) { + int volid = (tvp->roVol ? tvp->roVol : tvp->volume); + MALLOC(rootFid, struct VenusFid *, sizeof(*rootFid), + M_UFSMNT, M_WAITOK); + rootFid->Cell = LOCALCELL; + rootFid->Fid.Volume = volid; + rootFid->Fid.Vnode = 1; + rootFid->Fid.Unique = 1; + } else { + AFS_GUNLOCK(); + return ENODEV; + } + + mp->mnt_data = (qaddr_t)rootFid; + } + } strcpy(mp->mnt_stat.f_fstypename, "afs"); AFS_GUNLOCK(); (void) afs_statfs(mp, &mp->mnt_stat, p); @@ -97,8 +134,23 @@ AFS_GLOCK(); AFS_STATCNT(afs_unmount); - afs_globalVFS = 0; - afs_shutdown(); + + if (mp->mnt_data != (qaddr_t)-1) { + if (mp->mnt_data != NULL) { + FREE(mp->mnt_data, M_UFSMNT); + mp->mnt_data = (qaddr_t)-1; + } else { + if (flags & MNT_FORCE) { + afs_globalVFS = 0; + afs_shutdown(); + } else { + AFS_GUNLOCK(); + return EBUSY; + } + } + mp->mnt_flag &= ~MNT_LOCAL; + } + AFS_GUNLOCK(); return 0; @@ -119,18 +171,24 @@ pcred_unlock(p); AFS_GLOCK(); AFS_STATCNT(afs_root); - if (afs_globalVp && (afs_globalVp->states & CStatd)) { + if (mp->mnt_data == NULL + && afs_globalVp && (afs_globalVp->states & CStatd)) { tvp = afs_globalVp; error=0; + } else if (mp->mnt_data == (qaddr_t)-1) { + error = ENOENT; } else { + struct VenusFid *rootFid = (mp->mnt_data == NULL) + ? &afs_rootFid : (struct VenusFid *)mp->mnt_data; if (!(error = afs_InitReq(&treq, &cr)) && !(error = afs_CheckInit())) { - tvp = afs_GetVCache(&afs_rootFid, &treq, (afs_int32 *)0, + tvp = afs_GetVCache(rootFid, &treq, (afs_int32 *)0, (struct vcache*)0, WRITE_LOCK); /* we really want this to stay around */ if (tvp) { - afs_globalVp = tvp; + if (mp->mnt_data == NULL) + afs_globalVp = tvp; } else error = ENOENT; } @@ -140,9 +198,12 @@ AFS_GUNLOCK(); vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, p); AFS_GLOCK(); - afs_globalVFS = mp; + if (mp->mnt_data == NULL) { + afs_globalVFS = mp; + } *vpp = AFSTOV(tvp); AFSTOV(tvp)->v_flag |= VROOT; + AFSTOV(tvp)->v_vfsp = mp; } afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *vpp, @@ -165,7 +226,7 @@ } error = vget(vp, lfl, current_proc()); if (!error) - insmntque(vp, afs_globalVFS); /* take off free list */ + insmntque(vp, mp); /* take off free list */ return error; } Index: src/afs/DARWIN/osi_vnodeops.c =================================================================== RCS file: /cvs/openafs/src/afs/DARWIN/osi_vnodeops.c,v retrieving revision 1.4.2.4 diff -u -r1.4.2.4 osi_vnodeops.c --- src/afs/DARWIN/osi_vnodeops.c 2002/08/21 20:53:22 1.4.2.4 +++ src/afs/DARWIN/osi_vnodeops.c 2002/11/09 14:18:02 @@ -173,6 +173,7 @@ return (error); } vp = AFSTOV(vcp); /* always get a node if no error */ + vp->v_vfsp = dvp->v_vfsp; /* The parent directory comes in locked. We unlock it on return unless the caller wants it left locked. @@ -237,6 +238,7 @@ if (vcp) { *ap->a_vpp = AFSTOV(vcp); + (*ap->a_vpp)->v_vfsp = dvp->v_vfsp; vn_lock(*ap->a_vpp, LK_EXCLUSIVE| LK_RETRY, p); if (UBCINFOMISSING(*ap->a_vpp) || UBCINFORECLAIMED(*ap->a_vpp)) @@ -805,11 +807,6 @@ GETNAME(); p=cnp->cn_proc; - if (dvp->v_mount != vp->v_mount) { - VOP_ABORTOP(vp, cnp); - error = EXDEV; - goto out; - } if (vp->v_type == VDIR) { VOP_ABORTOP(vp, cnp); error = EISDIR; @@ -854,25 +851,6 @@ struct proc *p=fcnp->cn_proc; /* - * Check for cross-device rename. - */ - if ((fvp->v_mount != tdvp->v_mount) || - (tvp && (fvp->v_mount != tvp->v_mount))) { - error = EXDEV; -abortit: - VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */ - if (tdvp == tvp) - vrele(tdvp); - else - vput(tdvp); - if (tvp) - vput(tvp); - VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */ - vrele(fdvp); - vrele(fvp); - return (error); - } - /* * if fvp == tvp, we're just removing one name of a pair of * directory entries for the same element. convert call into rename. ( (pinched from NetBSD 1.0's ufs_rename()) @@ -880,7 +858,18 @@ if (fvp == tvp) { if (fvp->v_type == VDIR) { error = EINVAL; - goto abortit; + abortit: + VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */ + if (tdvp == tvp) + vrele(tdvp); + else + vput(tdvp); + if (tvp) + vput(tvp); + VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */ + vrele(fdvp); + vrele(fvp); + return (error); } /* Release destination completely. */ @@ -963,6 +952,7 @@ } if (vcp) { *ap->a_vpp = AFSTOV(vcp); + (*ap->a_vpp)->v_vfsp = dvp->v_vfsp; vn_lock(*ap->a_vpp, LK_EXCLUSIVE|LK_RETRY, p); } else *ap->a_vpp = 0;