Index: src/afs/afs_call.c =================================================================== RCS file: /cvs/openafs/src/afs/afs_call.c,v retrieving revision 1.14.2.18 diff -u -r1.14.2.18 afs_call.c --- src/afs/afs_call.c 23 Mar 2003 19:47:53 -0000 1.14.2.18 +++ src/afs/afs_call.c 7 Apr 2003 18:32:52 -0000 @@ -731,8 +731,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 24 Apr 2002 01:41:22 -0000 1.4.2.1 +++ src/afs/DARWIN/osi_vfsops.c 7 Apr 2003 18:32:52 -0000 @@ -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,51 @@ (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 { + struct cell *localcell = afs_GetPrimaryCell(READ_LOCK); + if (localcell == NULL) { + AFS_GUNLOCK(); + return ENODEV; + } + + /* Set the volume identifier to "AFS:volume.name" */ + snprintf(mp->mnt_stat.f_mntfromname, MNAMELEN-1, "AFS:%s", + volName); + tvp = afs_GetVolumeByName(volName, localcell->cellNum, 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->cellNum; + 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 +140,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 +177,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 +204,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 +232,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.6 diff -u -r1.4.2.6 osi_vnodeops.c --- src/afs/DARWIN/osi_vnodeops.c 26 Jan 2003 00:02:28 -0000 1.4.2.6 +++ src/afs/DARWIN/osi_vnodeops.c 7 Apr 2003 18:32:53 -0000 @@ -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)) @@ -810,11 +812,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; @@ -859,25 +856,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()) @@ -885,7 +863,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. */ @@ -968,6 +957,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; Index: src/afsd/Makefile.in =================================================================== RCS file: /cvs/openafs/src/afsd/Makefile.in,v retrieving revision 1.6.2.3 diff -u -r1.6.2.3 Makefile.in --- src/afsd/Makefile.in 13 Jan 2003 23:47:18 -0000 1.6.2.3 +++ src/afsd/Makefile.in 7 Apr 2003 18:32:53 -0000 @@ -52,6 +52,8 @@ ${CC} ${CFLAGS} -g -o afsd afsd.o $(NON_SHARED) $(LDFLAGS) $(AFSLIBS) ${XLIBS} /usr/lib/libdwarf.a /usr/lib/libelf.a ;; \ sgi_64 | sgi_65 ) \ ${CC} ${CFLAGS} -g -o afsd afsd.o $(NON_SHARED) $(LDFLAGS) $(AFSLIBS) ${XLIBS} /usr/lib32/libdwarf.a /usr/lib32/libelf.a ;; \ + ppc_darwin* ) \ + ${CC} ${CFLAGS} -g -o afsd afsd.o $(NON_SHARED) $(LDFLAGS) $(AFSLIBS) ${XLIBS} -F/System/Library/PrivateFrameworks -framework DiskArbitration ;; \ * ) \ ${CC} ${CFLAGS} -g -o afsd afsd.o $(NON_SHARED) $(LDFLAGS) $(AFSLIBS) ${XLIBS} ;; \ esac Index: src/afsd/afsd.c =================================================================== RCS file: /cvs/openafs/src/afsd/afsd.c,v retrieving revision 1.13.2.13 diff -u -r1.13.2.13 afsd.c --- src/afsd/afsd.c 23 Mar 2003 19:47:55 -0000 1.13.2.13 +++ src/afsd/afsd.c 7 Apr 2003 18:32:59 -0000 @@ -146,6 +146,27 @@ #ifdef AFS_LINUX20_ENV #include #endif +#ifdef AFS_DARWIN_ENV +#include +/* Relevant definitions from DiskArbitration.h (not included with Mac OS X) */ +#ifndef __DISKARBITRATION_H +typedef char DiskArbDiskIdentifier[1024]; +typedef char DiskArbMountpoint[1024]; +kern_return_t DiskArbStart(mach_port_t * portPtr); +kern_return_t DiskArbDiskAppearedWithMountpointPing_auto( + DiskArbDiskIdentifier diskIdentifier, + unsigned flags, + DiskArbMountpoint mountpoint); +kern_return_t DiskArbDiskDisappearedPing_auto( + DiskArbDiskIdentifier diskIdentifier, + unsigned flags); +enum { + kDiskArbDiskAppearedNoFlags = 0x00000000, + kDiskArbDiskAppearedEjectableMask = 1 << 1, + kDiskArbDiskAppearedNetworkDiskMask = 1 << 3 +}; +#endif /* __DISKARBITRATION_H */ +#endif /* AFS_DARWIN_ENV */ #ifndef MOUNT_AFS #define MOUNT_AFS AFS_MOUNT_AFS @@ -246,6 +267,7 @@ #endif static int enable_dynroot = 0; /* enable dynroot support */ static int enable_fakestat = 0; /* enable fakestat support */ +static int enable_nomount = 0; /* do not mount */ #ifdef notdef static int inodes = 60; /* VERY conservative, but has to be */ #endif @@ -1343,6 +1365,10 @@ /* -fakestat-all */ enable_fakestat = 1; } + if (as->parms[29].items) { + /* -nomount */ + enable_nomount = 1; + } /* * Pull out all the configuration info for the workstation's AFS cache and @@ -1811,6 +1837,8 @@ exit(1); } + if (!enable_nomount) { + mountFlags = 0; /* Read/write file system, can do setuid() */ #if defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV) #ifdef AFS_SUN5_ENV @@ -1893,6 +1921,8 @@ HandleMTab(); + } + if (afsd_rmtsys) { if (afsd_verbose) printf("%s: Forking 'rmtsys' daemon.\n", rn); @@ -1956,6 +1986,7 @@ cmd_AddParm(ts, "-dynroot", CMD_FLAG, CMD_OPTIONAL, "Enable dynroot support"); cmd_AddParm(ts, "-fakestat", CMD_FLAG, CMD_OPTIONAL, "Enable fakestat support for cross-cell mounts"); cmd_AddParm(ts, "-fakestat-all", CMD_FLAG, CMD_OPTIONAL, "Enable fakestat support for all mounts"); + cmd_AddParm(ts, "-nomount", CMD_FLAG, CMD_OPTIONAL, "Do not mount AFS"); return (cmd_Dispatch(argc, argv)); } @@ -2029,6 +2060,18 @@ #endif /* AFS_SGI_ENV */ #endif /* AFS_SUN5_ENV */ #endif /* unreasonable systems */ +#ifdef AFS_DARWIN_ENV + mach_port_t diskarb_port; + kern_return_t status; + + status = DiskArbStart(&diskarb_port); + if (status == KERN_SUCCESS) { + status = DiskArbDiskAppearedWithMountpointPing_auto("AFS", + kDiskArbDiskAppearedNetworkDiskMask, cacheMountDir); + } + + return status; +#endif /* AFS_DARWIN_ENV */ return 0; }