From 9d3214ef2e1beec590deb590c03c2e9d04d8199d Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Mon, 11 Feb 2008 04:00:47 +0000 Subject: [PATCH] DEVEL15-magic-vnodes-20080210 LICENSE IPL10 add magic vnodes like the magic mounts we already have. you can now cons up any afs vnode if you know the cell and fid. (cherry picked from commit a5dbdd03b8187f0c2c146f330e9adc42e103432c) --- src/afs/DARWIN/osi_vnodeops.c | 16 ++++++++++-- src/afs/VNOPS/afs_vnop_lookup.c | 43 +++++++++++++++++++++++++++------ src/afs/afs_prototypes.h | 3 +++ src/afs/afs_util.c | 13 ++++++++++ 4 files changed, 66 insertions(+), 9 deletions(-) diff --git a/src/afs/DARWIN/osi_vnodeops.c b/src/afs/DARWIN/osi_vnodeops.c index ba7197f0e..c5ae14eea 100644 --- a/src/afs/DARWIN/osi_vnodeops.c +++ b/src/afs/DARWIN/osi_vnodeops.c @@ -1420,8 +1420,18 @@ afs_vop_rename(ap) #if !defined(AFS_DARWIN80_ENV) VOP_UNLOCK(fvp, 0, p); #endif - FREE(fname, M_TEMP); - FREE(tname, M_TEMP); +#ifdef notdef + if (error == EXDEV) { + /* The idea would be to have a userspace handler like afsdb to + * run mv as the user, thus: + */ + printf("su %d -c /bin/mv /afs/.:mount/%d:%d:%d:%d/%s /afs/.:mount/%d:%d:%d:%d/%s\n", + (cn_cred(tcnp))->cr_uid, fvc->fid.Cell, fvc->fid.Fid.Volume, + fvc->fid.Fid.Vnode, fvc->fid.Fid.Unique, fname, + tvc->fid.Cell, tvc->fid.Fid.Volume, tvc->fid.Fid.Vnode, + tvc->fid.Fid.Unique, tname); + } +#endif #ifdef AFS_DARWIN80_ENV cache_purge(fdvp); cache_purge(fvp); @@ -1446,6 +1456,8 @@ afs_vop_rename(ap) vrele(fdvp); vrele(fvp); #endif + FREE(fname, M_TEMP); + FREE(tname, M_TEMP); return error; } diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index 02955ae70..32f0e8824 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -57,7 +57,7 @@ int afs_fakestat_enable = 0; /* 1: fakestat-all, 2: fakestat-crosscell */ static int EvalMountData(char type, char *data, afs_uint32 states, afs_uint32 cellnum, struct volume **avolpp, register struct vrequest *areq, - afs_uint32 *acellidxp, afs_uint32 *avolnump) + afs_uint32 *acellidxp, afs_uint32 *avolnump, afs_uint32 *avnoidp) { struct volume *tvp = 0; struct VenusFid tfid; @@ -67,13 +67,21 @@ EvalMountData(char type, char *data, afs_uint32 states, afs_uint32 cellnum, afs_int32 prefetch; /* 1=>None 2=>RO 3=>BK */ afs_int32 mtptCell, assocCell = 0, hac = 0; afs_int32 samecell, roname, len; - afs_uint32 volid, cellidx; + afs_uint32 volid, cellidx, vnoid = 0; cpos = afs_strchr(data, ':'); /* if cell name present */ if (cpos) { + cellnum = 0; volnamep = cpos + 1; *cpos = 0; - tcell = afs_GetCellByName(data, READ_LOCK); + for (x = data; *x >= '0' && *x <= '9'; x++) + cellnum = (cellnum * 10) + (*x - '0'); + if (cellnum && !*x) + tcell = afs_GetCell(cellnum, READ_LOCK); + else { + tcell = afs_GetCellByName(data, READ_LOCK); + cellnum = 0; + } *cpos = ':'; } else if (cellnum) { volnamep = data; @@ -92,10 +100,22 @@ EvalMountData(char type, char *data, afs_uint32 states, afs_uint32 cellnum, } afs_PutCell(tcell, READ_LOCK); + cpos = afs_strrchr(volnamep, ':'); /* if vno present */ + if (cpos) + *cpos = 0; /* Look for an all-numeric volume ID */ volid = 0; for (x = volnamep; *x >= '0' && *x <= '9'; x++) volid = (volid * 10) + (*x - '0'); + if (cpos) { + *cpos = ':'; + vnoid = 0; + if (!*x) /* allow vno with numeric volid only */ + for (x = (cpos + 1); *x >= '0' && *x <= '9'; x++) + vnoid = (vnoid * 10) + (*x - '0'); + if (*x) + vnoid = 0; + } /* * If the volume ID was all-numeric, and they didn't ask for a @@ -108,6 +128,8 @@ EvalMountData(char type, char *data, afs_uint32 states, afs_uint32 cellnum, *acellidxp = cellidx; if (avolnump) *avolnump = volid; + if (avnoidp) + *avnoidp = vnoid; return 0; } @@ -221,6 +243,8 @@ done: *acellidxp = cellidx; if (avolnump) *avolnump = tvp->volume; + if (avnoidp) + *avnoidp = vnoid; if (avolpp) *avolpp = tvp; else @@ -233,6 +257,7 @@ EvalMountPoint(register struct vcache *avc, struct vcache *advc, struct volume **avolpp, register struct vrequest *areq) { afs_int32 code; + afs_uint32 avnoid; AFS_STATCNT(EvalMountPoint); #ifdef notdef @@ -246,15 +271,19 @@ EvalMountPoint(register struct vcache *avc, struct vcache *advc, /* Determine which cell and volume the mointpoint goes to */ code = EvalMountData(avc->linkData[0], avc->linkData + 1, - avc->states, avc->fid.Cell, avolpp, areq, 0, 0); + avc->states, avc->fid.Cell, avolpp, areq, 0, 0, + &avnoid); if (code) return code; + if (!avnoid) + avnoid = 1; + if (avc->mvid == 0) avc->mvid = (struct VenusFid *)osi_AllocSmallSpace(sizeof(struct VenusFid)); avc->mvid->Cell = (*avolpp)->cell; avc->mvid->Fid.Volume = (*avolpp)->volume; - avc->mvid->Fid.Vnode = 1; + avc->mvid->Fid.Vnode = avnoid; avc->mvid->Fid.Unique = 1; avc->states |= CMValid; @@ -1334,9 +1363,9 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED */ if (afs_IsDynrootMount(adp)) { struct VenusFid tfid; - afs_uint32 cellidx, volid; + afs_uint32 cellidx, volid, vnoid; - code = EvalMountData('%', aname, 0, 0, NULL, &treq, &cellidx, &volid); + code = EvalMountData('%', aname, 0, 0, NULL, &treq, &cellidx, &volid, &vnoid); if (code) goto done; afs_GetDynrootMountFid(&tfid); diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 2d57f421b..182db7733 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -850,6 +850,9 @@ extern char *afs_strcpy(char *s1, char *s2); #ifndef afs_strchr extern char *afs_strchr(char *s, int c); #endif +#ifndef afs_strrchr +extern char *afs_strrchr(char *s, int c); +#endif extern char *afs_strdup(char *s); extern void print_internet_address(char *preamble, struct srvAddr *sa, char *postamble, int flag); diff --git a/src/afs/afs_util.c b/src/afs/afs_util.c index e8721d18d..6c3731678 100644 --- a/src/afs/afs_util.c +++ b/src/afs/afs_util.c @@ -136,6 +136,19 @@ afs_strchr(char *s, int c) return NULL; } #endif +#ifndef afs_strrchr +char * +afs_strrchr(char *s, int c) +{ + char *p = NULL; + + do { + if (*s == c) + p = (char*) s; + } while (*s++); + return p; +} +#endif char * afs_strdup(char *s) -- 2.39.5