From f53ebe3ef466ef736adcd1d6744ba2d9d4731d95 Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Fri, 2 Aug 2002 04:57:39 +0000 Subject: [PATCH] Merge conflicts --- Makefile.in | 4 +- src/afs/LINUX/osi_machdep.h | 1 + src/afs/LINUX/osi_misc.c | 10 +- src/afs/LINUX/osi_vnodeops.c | 79 +++++++++++- src/afs/Makefile.in | 4 +- src/afs/VNOPS/afs_vnop_lookup.c | 196 +++++++++++++++++++++++++++-- src/afs/VNOPS/afs_vnop_readdir.c | 18 ++- src/afs/afs.h | 15 ++- src/afs/afs_call.c | 6 +- src/afs/afs_pioctl.c | 64 +++++----- src/config/param.i386_linux22.h | 5 +- src/config/param.i386_linux24.h | 4 +- src/config/param.ppc_linux22.h | 5 +- src/config/param.ppc_linux24.h | 5 +- src/config/param.sparc64_linux22.h | 2 +- src/config/param.sparc_linux22.h | 4 +- src/libafs/Makefile.common | 3 - src/vol/partition.c | 9 +- 18 files changed, 356 insertions(+), 78 deletions(-) diff --git a/Makefile.in b/Makefile.in index 3297bdb43..3452d72d1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -240,7 +240,7 @@ viced: project vlserver audit tviced: project viced vlserver libafsrpc libafsauthent case ${SYS_NAME} in \ - alpha_dux*|sgi_*|sun4x_*|rs_aix*|*linux*|hp_ux110) \ + alpha_dux*|sgi_*|sun*_*|rs_aix*|*linux*|hp_ux110) \ ${COMPILE_PART1} tviced ${COMPILE_PART2} ;; \ *) \ echo Not building MT viced for ${SYS_NAME} ;; \ @@ -742,7 +742,7 @@ package.files: package ntp: project volser @case ${WITH_OBSOLETE} in \ YES) case ${SYS_NAME} in \ - sun4x_58 | *linux* | *fbsd* | ppc_darwin* ) echo skipping ntp for ${SYS_NAME} ;; \ + sun4x_58 | sunx86_* | *linux* | *fbsd* | ppc_darwin* ) echo skipping ntp for ${SYS_NAME} ;; \ * ) ${COMPILE_PART1} ntp ${COMPILE_PART2} ;; \ esac ;; \ *) echo skipping deprecated target: ntp ;; \ diff --git a/src/afs/LINUX/osi_machdep.h b/src/afs/LINUX/osi_machdep.h index 993424b37..9c14afef4 100644 --- a/src/afs/LINUX/osi_machdep.h +++ b/src/afs/LINUX/osi_machdep.h @@ -108,6 +108,7 @@ typedef struct cred { /* maps to task field: */ int cr_ngroups; } cred_t; #define AFS_UCRED cred +#define AFS_PROC struct task_struct #define crhold(c) (c)->cr_ref++ /* UIO manipulation */ diff --git a/src/afs/LINUX/osi_misc.c b/src/afs/LINUX/osi_misc.c index fefc6e9f8..6523df5cc 100644 --- a/src/afs/LINUX/osi_misc.c +++ b/src/afs/LINUX/osi_misc.c @@ -14,7 +14,7 @@ #include #include "../afs/param.h" -RCSID("$Header: /tmp/cvstemp/openafs/src/afs/LINUX/osi_misc.c,v 1.10 2002/05/18 20:11:52 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/afs/LINUX/osi_misc.c,v 1.11 2002/08/02 04:57:38 hartmans Exp $"); #include "../afs/sysincludes.h" #include "../afs/afsincludes.h" @@ -329,7 +329,7 @@ void osi_linux_free_inode_pages(void) void osi_clear_inode(struct inode *ip) { cred_t *credp = crref(); - struct vcache *vc = ITOAFS(ip); + struct vcache *vcp = ITOAFS(ip); #if defined(AFS_LINUX24_ENV) if (atomic_read(&ip->i_count) > 1) @@ -338,15 +338,15 @@ void osi_clear_inode(struct inode *ip) #endif printf("afs_put_inode: ino %d (0x%x) has count %d\n", ip->i_ino, ip); - ObtainWriteLock(&vc->lock, 504); - afs_InactiveVCache(vc, credp); - ReleaseWriteLock(&vc->lock); + afs_InactiveVCache(vcp, credp); + ObtainWriteLock(&vcp->lock, 504); #if defined(AFS_LINUX24_ENV) atomic_set(&ip->i_count, 0); #else ip->i_count = 0; #endif ip->i_nlink = 0; /* iput checks this after calling this routine. */ + ReleaseWriteLock(&vcp->lock); crfree(credp); } diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 4da2070ee..52dbf2de3 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -23,7 +23,7 @@ #include #include "../afs/param.h" -RCSID("$Header: /tmp/cvstemp/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.12 2002/05/12 05:50:42 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.13 2002/08/02 04:57:38 hartmans Exp $"); #include "../afs/sysincludes.h" #include "../afs/afsincludes.h" @@ -42,6 +42,7 @@ RCSID("$Header: /tmp/cvstemp/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.12 2002/05 #endif extern struct vcache *afs_globalVp; +extern afs_rwlock_t afs_xvcache; extern struct dentry_operations *afs_dops; #if defined(AFS_LINUX24_ENV) @@ -169,6 +170,7 @@ static int afs_linux_readdir(struct file *fp, int len; int origOffset; cred_t *credp = crref(); + struct afs_fakestat_state fakestat; AFS_GLOCK(); AFS_STATCNT(afs_readdir); @@ -180,10 +182,19 @@ static int afs_linux_readdir(struct file *fp, return -code; } + afs_InitFakeStat(&fakestat); + code = afs_EvalFakeStat(&avc, &fakestat, &treq); + if (code) { + afs_PutFakeStat(&fakestat); + AFS_GUNLOCK(); + return -code; + } + /* update the cache entry */ tagain: code = afs_VerifyVCache(avc, &treq); if (code) { + afs_PutFakeStat(&fakestat); AFS_GUNLOCK(); return -code; } @@ -191,6 +202,7 @@ tagain: /* get a reference to the entire directory */ tdc = afs_GetDCache(avc, 0, &treq, &origOffset, &len, 1); if (!tdc) { + afs_PutFakeStat(&fakestat); AFS_GUNLOCK(); return -ENOENT; } @@ -284,6 +296,7 @@ tagain: afs_PutDCache(tdc); ReleaseReadLock(&avc->lock); + afs_PutFakeStat(&fakestat); AFS_GUNLOCK(); return 0; } @@ -530,6 +543,13 @@ static int afs_linux_lock(struct file *fp, int cmd, struct file_lock *flp) AFS_GLOCK(); code = afs_lockctl(vcp, &flock, cmd, credp); AFS_GUNLOCK(); + + /* Convert flock back to Linux's file_lock */ + flp->fl_type = flock.l_type; + flp->fl_pid = flock.l_pid; + flp->fl_start = flock.l_start; + flp->fl_end = flock.l_start + flock.l_len; + crfree(credp); return -code; @@ -654,20 +674,33 @@ static int afs_linux_revalidate(struct dentry *dp) cred_t *credp; struct vrequest treq; struct vcache *vcp = ITOAFS(dp->d_inode); + struct vcache *rootvp = NULL; AFS_GLOCK(); + + if (afs_fakestat_enable && vcp->mvstat == 1 && vcp->mvid && + (vcp->states & CMValid) && (vcp->states & CStatd)) { + ObtainSharedLock(&afs_xvcache, 680); + rootvp = afs_FindVCache(vcp->mvid, 0, 0, 0, 0); + ReleaseSharedLock(&afs_xvcache); + } + #ifdef AFS_LINUX24_ENV lock_kernel(); #endif /* Make this a fast path (no crref), since it's called so often. */ if (vcp->states & CStatd) { - if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */ + if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */ check_bad_parent(dp); /* check and correct mvid */ - vcache2inode(vcp); + if (rootvp) + vcache2fakeinode(rootvp, vcp); + else + vcache2inode(vcp); #ifdef AFS_LINUX24_ENV unlock_kernel(); #endif + if (rootvp) afs_PutVCache(rootvp); AFS_GUNLOCK(); return 0; } @@ -808,13 +841,39 @@ static int afs_linux_dentry_revalidate(struct dentry *dp) /* afs_dentry_iput */ static void afs_dentry_iput(struct dentry *dp, struct inode *ip) { + if (ICL_SETACTIVE(afs_iclSetp)) { + AFS_GLOCK(); + afs_Trace3(afs_iclSetp, CM_TRACE_DENTRYIPUT, + ICL_TYPE_POINTER, ip, + ICL_TYPE_STRING, dp->d_parent->d_name.name, + ICL_TYPE_STRING, dp->d_name.name); + AFS_GUNLOCK(); + } + osi_iput(ip); } +static int afs_dentry_delete(struct dentry *dp) +{ + if (ICL_SETACTIVE(afs_iclSetp)) { + AFS_GLOCK(); + afs_Trace3(afs_iclSetp, CM_TRACE_DENTRYDELETE, ICL_TYPE_POINTER, + dp->d_inode, ICL_TYPE_STRING, dp->d_parent->d_name.name, + ICL_TYPE_STRING, dp->d_name.name); + AFS_GUNLOCK(); + } + + if (dp->d_inode && (ITOAFS(dp->d_inode)->states & CUnlinked)) + return 1; /* bad inode? */ + + return 0; +} + #if defined(AFS_LINUX24_ENV) struct dentry_operations afs_dentry_operations = { d_revalidate: afs_linux_dentry_revalidate, d_iput: afs_dentry_iput, + d_delete: afs_dentry_delete, }; struct dentry_operations *afs_dops = &afs_dentry_operations; #else @@ -822,7 +881,7 @@ struct dentry_operations afs_dentry_operations = { afs_linux_dentry_revalidate, /* d_validate(struct dentry *) */ NULL, /* d_hash */ NULL, /* d_compare */ - NULL, /* d_delete(struct dentry *) */ + afs_dentry_delete, /* d_delete(struct dentry *) */ NULL, /* d_release(struct dentry *) */ afs_dentry_iput /* d_iput(struct dentry *, struct inode *) */ }; @@ -977,7 +1036,6 @@ int afs_linux_unlink(struct inode *dip, struct dentry *dp) int code; cred_t *credp = crref(); const char *name = dp->d_name.name; - int putback = 0; AFS_GLOCK(); code = afs_remove(ITOAFS(dip), name, credp); @@ -1347,13 +1405,24 @@ int afs_linux_writepage_sync(struct inode *ip, struct page *pp, ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, atomic_read(&pp->count), ICL_TYPE_INT32, 99999); + setup_uio(&tuio, &iovec, buffer, base, count, UIO_WRITE, AFS_UIOSYS); code = afs_write(vcp, &tuio, f_flags, credp, 0); vcache2inode(vcp); + if (!code && afs_stats_cmperf.cacheCurrDirtyChunks > + afs_stats_cmperf.cacheMaxDirtyChunks) { + struct vrequest treq; + + ObtainWriteLock(&vcp->lock, 533); + if (!afs_InitReq(&treq, credp)) + code = afs_DoPartialWrite(vcp, &treq); + ReleaseWriteLock(&vcp->lock); + } code = code ? -code : count - tuio.uio_resid; + afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp, ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, atomic_read(&pp->count), diff --git a/src/afs/Makefile.in b/src/afs/Makefile.in index 2126df289..bc594922b 100644 --- a/src/afs/Makefile.in +++ b/src/afs/Makefile.in @@ -76,7 +76,7 @@ install: ${DESTDIR}${includedir}/afs/afs.h ${DESTDIR}${includedir}/afs/osi_in esac case ${SYS_NAME} in \ *linux* ) \ - ${INSTALL} ${AFS_OSTYPE}/osi_vfs.h ${DESTDIR}${includedir}/afs ;;\ + ${INSTALL} ${AFS_OSTYPE}/osi_vfs.h ${DESTDIR}${includedir}/afs || true ;;\ * ) \ echo No vfs headers to install for ${SYS_NAME};; \ esac @@ -152,7 +152,7 @@ dest: ${DEST}/include/afs/afs.h ${DEST}/include/afs/osi_inode.h ${DEST}/includ esac -case ${SYS_NAME} in \ *linux* ) \ - ${INSTALL} ${AFS_OSTYPE}/osi_vfs.h ${DEST}/include/afs ;;\ + ${INSTALL} ${AFS_OSTYPE}/osi_vfs.h ${DEST}/include/afs || true ;;\ * ) \ echo No vfs headers to install for ${SYS_NAME};; \ esac diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index 09df8edfb..24e27eeee 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -22,7 +22,7 @@ #include #include "../afs/param.h" -RCSID("$Header: /tmp/cvstemp/openafs/src/afs/VNOPS/afs_vnop_lookup.c,v 1.10 2002/05/12 05:50:43 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/afs/VNOPS/afs_vnop_lookup.c,v 1.11 2002/08/02 04:57:38 hartmans Exp $"); #include "../afs/sysincludes.h" /* Standard vendor system headers */ #include "../afs/afsincludes.h" /* Afs-based standard headers */ @@ -54,6 +54,7 @@ extern struct inode_operations afs_symlink_iops, afs_dir_iops; afs_int32 afs_bulkStatsDone; static int bulkStatCounter = 0; /* counter for bulk stat seq. numbers */ +int afs_fakestat_enable = 0; /* this would be faster if it did comparison as int32word, but would be @@ -90,8 +91,9 @@ char *afs_index(a, c) } /* call under write lock, evaluate mvid field from a mt pt. - * avc is the vnode of the mount point object. - * advc is the vnode of the containing directory + * avc is the vnode of the mount point object; must be write-locked. + * advc is the vnode of the containing directory (optional; if NULL and + * EvalMountPoint succeeds, caller must initialize *avolpp->dotdot) * avolpp is where we return a pointer to the volume named by the mount pt, if success * areq is the identity of the caller. * @@ -231,11 +233,175 @@ EvalMountPoint(avc, advc, avolpp, areq) * to the new path. */ tvp->mtpoint = avc->fid; /* setup back pointer to mtpoint */ - tvp->dotdot = advc->fid; + if (advc) tvp->dotdot = advc->fid; *avolpp = tvp; return 0; } + +/* + * afs_InitFakeStat + * + * Must be called on an afs_fakestat_state object before calling + * afs_EvalFakeStat or afs_PutFakeStat. Calling afs_PutFakeStat + * without calling afs_EvalFakeStat is legal, as long as this + * function is called. + */ + +void +afs_InitFakeStat(state) + struct afs_fakestat_state *state; +{ + state->valid = 1; + state->did_eval = 0; + state->need_release = 0; +} + +/* + * afs_EvalFakeStat_int + * + * The actual implementation of afs_EvalFakeStat and afs_TryEvalFakeStat, + * which is called by those wrapper functions. + * + * Only issues RPCs if canblock is non-zero. + */ +static int +afs_EvalFakeStat_int(avcp, state, areq, canblock) + struct vcache **avcp; + struct afs_fakestat_state *state; + struct vrequest *areq; + int canblock; +{ + struct vcache *tvc, *root_vp; + struct volume *tvolp = NULL; + int code = 0; + + osi_Assert(state->valid == 1); + osi_Assert(state->did_eval == 0); + state->did_eval = 1; + if (!afs_fakestat_enable) + return 0; + tvc = *avcp; + if (tvc->mvstat != 1) + return 0; + + /* Is the call to VerifyVCache really necessary? */ + code = afs_VerifyVCache(tvc, areq); + if (code) + goto done; + if (canblock) { + ObtainWriteLock(&tvc->lock, 599); + code = EvalMountPoint(tvc, NULL, &tvolp, areq); + ReleaseWriteLock(&tvc->lock); + if (code) + goto done; + if (tvolp) { + tvolp->dotdot = tvc->fid; + tvolp->dotdot.Fid.Vnode = tvc->parentVnode; + tvolp->dotdot.Fid.Unique = tvc->parentUnique; + } + } + if (tvc->mvid && (tvc->states & CMValid)) { + if (!canblock) { + afs_int32 retry; + + do { + retry = 0; + ObtainWriteLock(&afs_xvcache, 597); + root_vp = afs_FindVCache(tvc->mvid, 0, 0, &retry, 0); + if (root_vp && retry) { + ReleaseWriteLock(&afs_xvcache); + afs_PutVCache(root_vp, 0); + } + } while (root_vp && retry); + ReleaseWriteLock(&afs_xvcache); + } else { + root_vp = afs_GetVCache(tvc->mvid, areq, NULL, NULL, WRITE_LOCK); + } + if (!root_vp) { + code = canblock ? ENOENT : 0; + goto done; + } + if (tvolp) { + /* Is this always kosher? Perhaps we should instead use + * NBObtainWriteLock to avoid potential deadlock. + */ + ObtainWriteLock(&root_vp->lock, 598); + if (!root_vp->mvid) + root_vp->mvid = osi_AllocSmallSpace(sizeof(struct VenusFid)); + *root_vp->mvid = tvolp->dotdot; + ReleaseWriteLock(&root_vp->lock); + } + state->need_release = 1; + state->root_vp = root_vp; + *avcp = root_vp; + code = 0; + } else { + code = canblock ? ENOENT : 0; + } + +done: + if (tvolp) + afs_PutVolume(tvolp, WRITE_LOCK); + return code; +} + +/* + * afs_EvalFakeStat + * + * Automatically does the equivalent of EvalMountPoint for vcache entries + * which are mount points. Remembers enough state to properly release + * the volume root vcache when afs_PutFakeStat() is called. + * + * State variable must be initialized by afs_InitFakeState() beforehand. + * + * Returns 0 when everything succeeds and *avcp points to the vcache entry + * that should be used for the real vnode operation. Returns non-zero if + * something goes wrong and the error code should be returned to the user. + */ +int +afs_EvalFakeStat(avcp, state, areq) + struct vcache **avcp; + struct afs_fakestat_state *state; + struct vrequest *areq; +{ + return afs_EvalFakeStat_int(avcp, state, areq, 1); +} + +/* + * afs_TryEvalFakeStat + * + * Same as afs_EvalFakeStat, but tries not to talk to remote servers + * and only evaluate the mount point if all the data is already in + * local caches. + * + * Returns 0 if everything succeeds and *avcp points to a valid + * vcache entry (possibly evaluated). + */ +int +afs_TryEvalFakeStat(avcp, state, areq) + struct vcache **avcp; + struct afs_fakestat_state *state; + struct vrequest *areq; +{ + return afs_EvalFakeStat_int(avcp, state, areq, 0); +} + +/* + * afs_PutFakeStat + * + * Perform any necessary cleanup at the end of a vnode op, given that + * afs_InitFakeStat was previously called with this state. + */ +void +afs_PutFakeStat(state) + struct afs_fakestat_state *state; +{ + osi_Assert(state->valid == 1); + if (state->need_release) + afs_PutVCache(state->root_vp, 0); + state->valid = 0; +} afs_ENameOK(aname) register char *aname; { @@ -921,8 +1087,17 @@ afs_lookup(adp, aname, avcp, acred) int no_read_access = 0; struct sysname_info sysState; /* used only for @sys checking */ int dynrootRetry = 1; + struct afs_fakestat_state fakestate; AFS_STATCNT(afs_lookup); + afs_InitFakeStat(&fakestate); + + if (code = afs_InitReq(&treq, acred)) + goto done; + + code = afs_EvalFakeStat(&adp, &fakestate, &treq); + if (code) + goto done; #ifdef AFS_OSF_ENV ndp->ni_dvp = AFSTOV(adp); memcpy(aname, ndp->ni_ptr, ndp->ni_namelen); @@ -931,10 +1106,6 @@ afs_lookup(adp, aname, avcp, acred) *avcp = (struct vcache *) 0; /* Since some callers don't initialize it */ - if (code = afs_InitReq(&treq, acred)) { - goto done; - } - /* come back to here if we encounter a non-existent object in a read-only volume's directory */ @@ -1217,9 +1388,9 @@ afs_lookup(adp, aname, avcp, acred) if (!(flags & AFS_LOOKUP_NOEVAL)) /* don't eval mount points */ #endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */ - if (tvc->mvstat == 1) { - /* a mt point, possibly unevaluated */ - struct volume *tvolp; + if (!afs_fakestat_enable && tvc->mvstat == 1) { + /* a mt point, possibly unevaluated */ + struct volume *tvolp; ObtainWriteLock(&tvc->lock,133); code = EvalMountPoint(tvc, adp, &tvolp, &treq); @@ -1319,6 +1490,7 @@ done: if (!FidCmp(&(tvc->fid), &(adp->fid))) { afs_PutVCache(*avcp, WRITE_LOCK); *avcp = NULL; + afs_PutFakeStat(&fakestate); return afs_CheckCode(EISDIR, &treq, 18); } } @@ -1342,6 +1514,7 @@ done: /* So Linux inode cache is up to date. */ code = afs_VerifyVCache(tvc, &treq); #else + afs_PutFakeStat(&fakestate); return 0; /* can't have been any errors if hit and !code */ #endif } @@ -1355,5 +1528,6 @@ done: *avcp = (struct vcache *)0; } + afs_PutFakeStat(&fakestate); return code; } diff --git a/src/afs/VNOPS/afs_vnop_readdir.c b/src/afs/VNOPS/afs_vnop_readdir.c index 3d86fa166..cc185b71d 100644 --- a/src/afs/VNOPS/afs_vnop_readdir.c +++ b/src/afs/VNOPS/afs_vnop_readdir.c @@ -22,7 +22,7 @@ #include #include "../afs/param.h" -RCSID("$Header: /tmp/cvstemp/openafs/src/afs/VNOPS/afs_vnop_readdir.c,v 1.7 2001/07/15 07:22:27 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/afs/VNOPS/afs_vnop_readdir.c,v 1.8 2002/08/02 04:57:38 hartmans Exp $"); #include "../afs/sysincludes.h" /* Standard vendor system headers */ #include "../afs/afsincludes.h" /* Afs-based standard headers */ @@ -443,6 +443,7 @@ afs_readdir(OSI_VC_ARG(avc), auio, acred) struct DirEntry *ode = 0, *nde = 0; int o_slen = 0, n_slen = 0; afs_uint32 us; + struct afs_fakestat_state fakestate; #if defined(AFS_SGI53_ENV) afs_int32 use64BitDirent; #endif /* defined(AFS_SGI53_ENV) */ @@ -495,6 +496,9 @@ afs_readdir(OSI_VC_ARG(avc), auio, acred) return code; } /* update the cache entry */ + afs_InitFakeStat(&fakestate); + code = afs_EvalFakeStat(&avc, &fakestate, &treq); + if (code) goto done; tagain: code = afs_VerifyVCache(avc, &treq); if (code) goto done; @@ -729,6 +733,7 @@ done: #ifdef AFS_HPUX_ENV osi_FreeSmallSpace((char *)sdirEntry); #endif + afs_PutFakeStat(&fakestate); code = afs_CheckCode(code, &treq, 28); return code; } @@ -759,6 +764,7 @@ afs1_readdir(avc, auio, acred) struct minnfs_direct *sdirEntry = (struct minnfs_direct *)osi_AllocSmallSpace(sizeof(struct min_direct)); afs_int32 rlen; #endif + struct afs_fakestat_state fakestate; AFS_STATCNT(afs_readdir); #if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV) @@ -770,6 +776,15 @@ afs1_readdir(avc, auio, acred) #endif return code; } + afs_InitFakeStat(&fakestate); + code = afs_EvalFakeStat(&avc, &fakestate, &treq); + if (code) { +#ifdef AFS_HPUX_ENV + osi_FreeSmallSpace((char *)sdirEntry); +#endif + afs_PutFakeStat(&fakestate); + return code; + } /* update the cache entry */ tagain: code = afs_VerifyVCache(avc, &treq); @@ -955,6 +970,7 @@ done: #if defined(AFS_HPUX_ENV) || defined(AFS_OSF_ENV) osi_FreeSmallSpace((char *)sdirEntry); #endif + afs_PutFakeStat(&fakestate); code = afs_CheckCode(code, &treq, 29); return code; } diff --git a/src/afs/afs.h b/src/afs/afs.h index 0f03fcda6..210544d7c 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -201,6 +201,7 @@ struct cell { u_short vlport; /* volume server port */ short states; /* state flags */ short cellIndex; /* relative index number per cell */ + short realcellIndex; /* as above but ignoring aliases */ time_t timeout; /* data expire time, if non-zero */ char *realName; /* who this cell is an alias for */ }; @@ -616,7 +617,7 @@ struct vcache { #ifdef AFS_DARWIN_ENV struct lock__bsd__ rwlock; #endif - afs_int32 parentVnode; /* Parent dir, if a file. */ + afs_int32 parentVnode; /* Parent dir, if a file. */ afs_int32 parentUnique; struct VenusFid *mvid; /* Either parent dir (if root) or root (if mt pt) */ char *linkData; /* Link data if a symlink. */ @@ -1141,5 +1142,17 @@ extern int afs_norefpanic; #endif /* AFS_SGI62_ENV */ #endif +/* fakestat support: opaque storage for afs_EvalFakeStat to remember + * what vcache should be released. + */ +struct afs_fakestat_state { + char valid; + char did_eval; + char need_release; + struct vcache *root_vp; +}; + +extern int afs_fakestat_enable; + #endif /* _AFS_H_ */ diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index e31a7604f..a5e7eb3dc 100644 --- a/src/afs/afs_call.c +++ b/src/afs/afs_call.c @@ -10,7 +10,7 @@ #include #include "../afs/param.h" -RCSID("$Header: /tmp/cvstemp/openafs/src/afs/afs_call.c,v 1.12 2002/06/10 12:02:02 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/afs/afs_call.c,v 1.13 2002/08/02 04:57:37 hartmans Exp $"); #include "../afs/sysincludes.h" /* Standard vendor system headers */ #include "../afs/afsincludes.h" /* Afs-based standard headers */ @@ -660,6 +660,10 @@ long parm, parm2, parm3, parm4, parm5, parm6; else if (parm == AFSOP_SET_DYNROOT) { code = afs_SetDynrootEnable(parm2); } + else if (parm == AFSOP_SET_FAKESTAT) { + afs_fakestat_enable = parm2; + code = 0; + } else code = EINVAL; diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index 038108363..040c30e6e 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -10,7 +10,7 @@ #include #include "../afs/param.h" -RCSID("$Header: /tmp/cvstemp/openafs/src/afs/afs_pioctl.c,v 1.13 2002/06/10 12:02:03 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/afs/afs_pioctl.c,v 1.14 2002/08/02 04:57:37 hartmans Exp $"); #include "../afs/sysincludes.h" /* Standard vendor system headers */ #include "../afs/afsincludes.h" /* Afs-based standard headers */ @@ -131,18 +131,18 @@ static int (*(VpioctlSw[]))() = { PRxStatPeer, /* 54 - control peer RX statistics */ PGetRxkcrypt, /* 55 -- Get rxkad encryption flag */ PSetRxkcrypt, /* 56 -- Set rxkad encryption flag */ - PNoop, /* 57 -- arla: set file prio */ - PNoop, /* 58 -- arla: fallback getfh */ - PNoop, /* 59 -- arla: fallback fhopen */ - PNoop, /* 60 -- arla: controls xfsdebug */ - PNoop, /* 61 -- arla: controls arla debug */ - PNoop, /* 62 -- arla: debug interface */ - PNoop, /* 63 -- arla: print xfs status */ - PNoop, /* 64 -- arla: force cache check */ - PNoop, /* 65 -- arla: break callback */ + PBogus, /* 57 -- arla: set file prio */ + PBogus, /* 58 -- arla: fallback getfh */ + PBogus, /* 59 -- arla: fallback fhopen */ + PBogus, /* 60 -- arla: controls xfsdebug */ + PBogus, /* 61 -- arla: controls arla debug */ + PBogus, /* 62 -- arla: debug interface */ + PBogus, /* 63 -- arla: print xfs status */ + PBogus, /* 64 -- arla: force cache check */ + PBogus, /* 65 -- arla: break callback */ PPrefetchFromTape, /* 66 -- MR-AFS: prefetch file from tape */ PResidencyCmd, /* 67 -- MR-AFS: generic commnd interface */ - PNoop, /* 68 -- arla: fetch stats */ + PBogus, /* 68 -- arla: fetch stats */ }; static int (*(CpioctlSw[]))() = { @@ -1021,7 +1021,7 @@ afs_syscall_pioctl(path, com, cmarg, follow) afs_HandlePioctl(avc, acom, ablob, afollow, acred) - register struct vcache *avc; + struct vcache *avc; afs_int32 acom; struct AFS_UCRED **acred; register struct afs_ioctl *ablob; @@ -1034,11 +1034,20 @@ afs_HandlePioctl(avc, acom, ablob, afollow, acred) char *inData, *outData; int (*(*pioctlSw))(); int pioctlSwSize; + struct afs_fakestat_state fakestate; afs_Trace3(afs_iclSetp, CM_TRACE_PIOCTL, ICL_TYPE_INT32, acom & 0xff, ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, afollow); AFS_STATCNT(HandlePioctl); if (code = afs_InitReq(&treq, *acred)) return code; + afs_InitFakeStat(&fakestate); + if (avc) { + code = afs_EvalFakeStat(&avc, &fakestate, &treq); + if (code) { + afs_PutFakeStat(&fakestate); + return code; + } + } device = (acom & 0xff00) >> 8; switch (device) { case 'V': /* Original pioctl's */ @@ -1050,11 +1059,13 @@ afs_HandlePioctl(avc, acom, ablob, afollow, acred) pioctlSwSize = sizeof(CpioctlSw); break; default: + afs_PutFakeStat(&fakestate); return EINVAL; } function = acom & 0xff; if (function >= (pioctlSwSize / sizeof(char *))) { - return EINVAL; /* out of range */ + afs_PutFakeStat(&fakestate); + return EINVAL; /* out of range */ } inSize = ablob->in_size; if (inSize >= PIGGYSIZE) return E2BIG; @@ -1064,8 +1075,9 @@ afs_HandlePioctl(avc, acom, ablob, afollow, acred) } else code = 0; if (code) { - osi_FreeLargeSpace(inData); - return code; + osi_FreeLargeSpace(inData); + afs_PutFakeStat(&fakestate); + return code; } outData = osi_AllocLargeSpace(AFS_LRALLOCSIZ); outSize = 0; @@ -1081,6 +1093,7 @@ afs_HandlePioctl(avc, acom, ablob, afollow, acred) AFS_COPYOUT(outData, ablob->out, outSize, code); } osi_FreeLargeSpace(outData); + afs_PutFakeStat(&fakestate); return afs_CheckCode(code, &treq, 41); } @@ -1415,7 +1428,7 @@ static PGCPAGs(avc, afun, areq, ain, aout, ainSize, aoutSize, acred) ain += sizeof(afs_int32); /* skip id field */ /* rest is cell name, look it up */ /* some versions of gcc appear to need != 0 in order to get this right */ - if (flag & 0x8000 != 0) { /* XXX Use Constant XXX */ + if ((flag & 0x8000) != 0) { /* XXX Use Constant XXX */ flag &= ~0x8000; set_parent_pag = 1; } @@ -1715,7 +1728,7 @@ static PNewStatMount(avc, afun, areq, ain, aout, ainSize, aoutSize) code = ENOENT; goto out; } - if (vType(tvc) != VLNK) { + if (tvc->mvstat != 1) { afs_PutVCache(tvc, WRITE_LOCK); code = EINVAL; goto out; @@ -2374,17 +2387,7 @@ static PListCells(avc, afun, areq, ain, aout, ainSize, aoutSize) memcpy((char *)&whichCell, tp, sizeof(afs_int32)); tp += sizeof(afs_int32); - ObtainReadLock(&afs_xcell); - for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { - tcell = QTOC(cq); tq = QNext(cq); - if (tcell->states & CAlias) { - tcell = 0; - continue; - } - if (whichCell == 0) break; - tcell = 0; - whichCell--; - } + tcell = afs_GetRealCellByIndex(whichCell, READ_LOCK, 0); if (tcell) { cp = aout; memset(cp, 0, MAXCELLHOSTS * sizeof(afs_int32)); @@ -2398,7 +2401,6 @@ static PListCells(avc, afun, areq, ain, aout, ainSize, aoutSize) cp += strlen(tcell->cellName)+1; *aoutSize = cp - aout; } - ReleaseReadLock(&afs_xcell); if (tcell) return 0; else return EDOM; } @@ -2501,7 +2503,7 @@ static PRemoveMount(avc, afun, areq, ain, aout, ainSize, aoutSize) afs_PutDCache(tdc); goto out; } - if (vType(tvc) != VLNK) { + if (tvc->mvstat != 1) { afs_PutDCache(tdc); afs_PutVCache(tvc, WRITE_LOCK); code = EINVAL; @@ -3698,7 +3700,7 @@ static PFlushMount(avc, afun, areq, ain, aout, ainSize, aoutSize, acred) code = ENOENT; goto out; } - if (vType(tvc) != VLNK) { + if (tvc->mvstat != 1) { afs_PutVCache(tvc, WRITE_LOCK); code = EINVAL; goto out; diff --git a/src/config/param.i386_linux22.h b/src/config/param.i386_linux22.h index b09d35a7d..0a845bcf2 100644 --- a/src/config/param.i386_linux22.h +++ b/src/config/param.i386_linux22.h @@ -37,7 +37,7 @@ * MP to compile for Linux */ #ifdef AFS_SMP -#define CONFIG_SMP +#define CONFIG_SMP 1 #ifndef CONFIG_X86_LOCAL_APIC #define CONFIG_X86_LOCAL_APIC #endif @@ -58,7 +58,8 @@ #define AFS_USERSPACE_IP_ADDR 1 #define RXK_LISTENER_ENV 1 -#define AFS_GCPAGS 0 /* if nonzero, garbage collect PAGs */ +#define AFS_GCPAGS 2 /* Set to Userdisabled, allow sysctl to override */ + /* Machine / Operating system information */ #define SYS_NAME "i386_linux22" diff --git a/src/config/param.i386_linux24.h b/src/config/param.i386_linux24.h index 2fcf24713..467437726 100644 --- a/src/config/param.i386_linux24.h +++ b/src/config/param.i386_linux24.h @@ -30,7 +30,7 @@ * MP to compile for Linux */ #ifdef AFS_SMP -#define CONFIG_SMP +#define CONFIG_SMP 1 #ifndef CONFIG_X86_LOCAL_APIC #define CONFIG_X86_LOCAL_APIC #endif @@ -50,7 +50,7 @@ #include #define AFS_USERSPACE_IP_ADDR 1 #define RXK_LISTENER_ENV 1 -#define AFS_GCPAGS 0 /* if nonzero, garbage collect PAGs */ +#define AFS_GCPAGS 2 /* Set to Userdisabled, allow sysctl to override */ #define AFSLITTLE_ENDIAN 1 #define AFS_HAVE_FFS 1 /* Use system's ffs. */ diff --git a/src/config/param.ppc_linux22.h b/src/config/param.ppc_linux22.h index 32a1e9fbe..e1a48cc78 100644 --- a/src/config/param.ppc_linux22.h +++ b/src/config/param.ppc_linux22.h @@ -28,7 +28,7 @@ * MP to compile for Linux */ #ifdef AFS_SMP -#define CONFIG_SMP +#define CONFIG_SMP 1 #ifndef __SMP__ #define __SMP__ #endif @@ -46,8 +46,7 @@ #define AFS_USERSPACE_IP_ADDR 1 #define RXK_LISTENER_ENV 1 -#define AFS_GCPAGS 0 /* if nonzero, garbage collect PAGs */ - +#define AFS_GCPAGS 2 /* Set to Userdisabled, allow sysctl to override */ /* Machine / Operating system information */ #define SYS_NAME "ppc_linux22" diff --git a/src/config/param.ppc_linux24.h b/src/config/param.ppc_linux24.h index c1cfd6515..c5161af29 100644 --- a/src/config/param.ppc_linux24.h +++ b/src/config/param.ppc_linux24.h @@ -30,7 +30,7 @@ * MP to compile for Linux */ #ifdef AFS_SMP -#define CONFIG_SMP +#define CONFIG_SMP 1 #ifndef __SMP__ #define __SMP__ #endif @@ -47,8 +47,7 @@ #define AFS_USERSPACE_IP_ADDR 1 #define RXK_LISTENER_ENV 1 -#define AFS_GCPAGS 0 /* if nonzero, garbage collect PAGs */ - +#define AFS_GCPAGS 2 /* Set to Userdisabled, allow sysctl to override */ /* Machine / Operating system information */ #define SYS_NAME "ppc_linux24" diff --git a/src/config/param.sparc64_linux22.h b/src/config/param.sparc64_linux22.h index 3e4a44a2a..c4010e231 100644 --- a/src/config/param.sparc64_linux22.h +++ b/src/config/param.sparc64_linux22.h @@ -36,7 +36,7 @@ * MP to compile for Linux */ #ifdef AFS_SMP -#define CONFIG_SMP +#define CONFIG_SMP 1 #ifndef __SMP__ #define __SMP__ #endif diff --git a/src/config/param.sparc_linux22.h b/src/config/param.sparc_linux22.h index 0a2a79797..56cf4b5e5 100644 --- a/src/config/param.sparc_linux22.h +++ b/src/config/param.sparc_linux22.h @@ -31,7 +31,7 @@ * MP to compile for Linux */ #ifdef AFS_SMP -#define CONFIG_SMP +#define CONFIG_SMP 1 #ifndef __SMP__ #define __SMP__ #endif @@ -48,7 +48,7 @@ #define AFS_USERSPACE_IP_ADDR 1 #define RXK_LISTENER_ENV 1 -#define AFS_GCPAGS 0 /* if nonzero, garbage collect PAGs */ +#define AFS_GCPAGS 2 /* Set to Userdisabled, allow sysctl to override */ /* Machine / Operating system information */ #define SYS_NAME "sparc_linux22" diff --git a/src/libafs/Makefile.common b/src/libafs/Makefile.common index d3c68d1cc..73a84c64d 100644 --- a/src/libafs/Makefile.common +++ b/src/libafs/Makefile.common @@ -127,7 +127,6 @@ AFSAOBJS = \ AFSNFSOBJS = \ afs_nfsclnt.o \ afs_nfsdisp.o \ - afs_nfsdisp_v3.o \ afs_call_nfs.o \ afs_pioctl_nfs.o \ $(AFS_OS_NFSOBJS) @@ -262,8 +261,6 @@ afs_nfsclnt.o: $(AFS)/afs_nfsclnt.c $(CRULE1); afs_nfsdisp.o: $(AFS)/afs_nfsdisp.c $(CRULE1); -afs_nfsdisp_v3.o: $(AFS)/afs_nfsdisp_v3.c - $(CRULE1); rx.o: $(RX)/rx.c $(CRULE1); rx_clock.o: $(RX)/rx_clock.c diff --git a/src/vol/partition.c b/src/vol/partition.c index f4c396970..24ea226ce 100644 --- a/src/vol/partition.c +++ b/src/vol/partition.c @@ -18,7 +18,7 @@ #include #include -RCSID("$Header: /tmp/cvstemp/openafs/src/vol/partition.c,v 1.10 2002/05/12 05:50:44 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/vol/partition.c,v 1.11 2002/08/02 04:57:39 hartmans Exp $"); #include #ifdef AFS_NT40_ENV @@ -194,9 +194,11 @@ static void VInitPartition_r(char *path, char *devname, Device dev) else DiskPartitionList = dp; dp->next = 0; - strcpy(dp->name, path); + dp->name = (char *)malloc(strlen(path) + 1); + strncpy(dp->name, path, strlen(path) + 1); #if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV) /* Create a lockfile for the partition, of the form /vicepa/Lock/vicepa */ + dp->devName = (char *)malloc(2 * strlen(path) + 6); strcpy(dp->devName, path); strcat(dp->devName, "/"); strcat(dp->devName, "Lock"); @@ -205,7 +207,8 @@ static void VInitPartition_r(char *path, char *devname, Device dev) close(open(dp->devName, O_RDWR | O_CREAT, 0600)); dp->device = volutil_GetPartitionID(path); #else - strcpy(dp->devName, devname); + dp->devName = (char *)malloc(strlen(devname) + 1); + strncpy(dp->devName, devname, strlen(devname) + 1); dp->device = dev; #endif dp->lock_fd = -1; -- 2.39.5