From e59b81c984652f7570708831d8b36bdd42f98cf8 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Fri, 20 Mar 2009 02:30:49 +0000 Subject: [PATCH] dynamic-vcache-allocation-20090319 LICENSE IPL10 FIXES 124334 add dynamic allocation of vcaches when possible (currently just for linux) --- doc/man-pages/pod8/afsd.pod | 8 ++ src/afs/afs_call.c | 3 +- src/afs/afs_cbqueue.c | 2 +- src/afs/afs_daemons.c | 20 ++- src/afs/afs_init.c | 12 +- src/afs/afs_prototypes.h | 2 +- src/afs/afs_vcache.c | 295 ++++++++++++++++++++++----------------- src/afsd/afsd.c | 26 ++++ src/config/afs_args.h | 1 + src/config/param.amd64_linux26.h | 1 + src/config/param.ia64_linux26.h | 1 + src/config/param.linux26.h | 1 + 12 files changed, 236 insertions(+), 136 deletions(-) diff --git a/doc/man-pages/pod8/afsd.pod b/doc/man-pages/pod8/afsd.pod index 8d0f54e..d46c35e 100644 --- a/doc/man-pages/pod8/afsd.pod +++ b/doc/man-pages/pod8/afsd.pod @@ -29,6 +29,7 @@ B [B<-afsdb>] [B<-backuptree>] [B<-settime>] [B<-shutdown>] S<<< [B<-splitcache> >] >>> S<<< [B<-stat> >] >>> [B<-verbose>] + [B<-disable-dynamic-vcaches>] S<<< [B<-volumes> >] >>> [B<-waitclose>] @@ -669,6 +670,13 @@ standard output stream. Specifies the number of memory structures to allocate for storing volume location information. The default value is C<50>. +=item B<-disable-dynamic-vcaches> + +By default, dynamic vcache overrides the B<-stat> option by using the value of +B<-stat> (or the default) as the initial size of the stat (or vcache) pool and +increases the pool dynamically as needed on supported platforms. This flag will +disable this new functionality and honor the '-stat' setting. + =item B<-waitclose> Has no effect on the operation of the Cache Manager. The behavior it diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index bccb764..04610ef 100644 --- a/src/afs/afs_call.c +++ b/src/afs/afs_call.c @@ -794,7 +794,8 @@ afs_syscall_call(long parm, long parm2, long parm3, long parm4, long parm5, long afs_CacheInit(cparms.cacheScaches, cparms.cacheFiles, cparms.cacheBlocks, cparms.cacheDcaches, cparms.cacheVolumes, cparms.chunkSize, - cparms.memCacheFlag, cparms.inodes, cparms.users); + cparms.memCacheFlag, cparms.inodes, cparms.users, + cparms.dynamic_vcaches); } else if (parm == AFSOP_CACHEINODE) { ino_t ainode = parm2; diff --git a/src/afs/afs_cbqueue.c b/src/afs/afs_cbqueue.c index e9628f2..7264f15 100644 --- a/src/afs/afs_cbqueue.c +++ b/src/afs/afs_cbqueue.c @@ -180,7 +180,7 @@ afs_DequeueCallback(struct vcache *avc) */ /* Sanity check on the callback queue. Allow for slop in the computation. */ -#ifdef AFS_OSF_ENV +#if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV) #define CBQ_LIMIT (afs_maxvcount + 10) #else #define CBQ_LIMIT (afs_cacheStats + afs_stats_cmperf.vcacheXAllocs + 10) diff --git a/src/afs/afs_daemons.c b/src/afs/afs_daemons.c index 7de581e..c459d81 100644 --- a/src/afs/afs_daemons.c +++ b/src/afs/afs_daemons.c @@ -42,6 +42,8 @@ static int rxepoch_checked = 0; #define afs_CheckRXEpoch() {if (rxepoch_checked == 0 && rxkad_EpochWasSet) { \ rxepoch_checked = 1; afs_GCUserData(/* force flag */ 1); } } +extern int afsd_dynamic_vcaches; + /* PAG garbage collection */ /* We induce a compile error if param.h does not define AFS_GCPAGS */ afs_int32 afs_gcpags = AFS_GCPAGS; @@ -136,13 +138,13 @@ afs_Daemon(void) struct afs_exporter *exporter; afs_int32 now; afs_int32 last3MinCheck, last10MinCheck, last60MinCheck, lastNMinCheck; - afs_int32 last1MinCheck; + afs_int32 last1MinCheck, last5MinCheck; afs_uint32 lastCBSlotBump; char cs_warned = 0; AFS_STATCNT(afs_Daemon); last1MinCheck = last3MinCheck = last60MinCheck = last10MinCheck = - lastNMinCheck = 0; + last5MinCheck = lastNMinCheck = 0; afs_rootFid.Fid.Volume = 0; while (afs_initState < 101) @@ -168,6 +170,7 @@ afs_Daemon(void) last3MinCheck = now - 90 + ((afs_random() & 0x7fffffff) % 180); last60MinCheck = now - 1800 + ((afs_random() & 0x7fffffff) % 3600); last10MinCheck = now - 300 + ((afs_random() & 0x7fffffff) % 600); + last5MinCheck = now - 150 + ((afs_random() & 0x7fffffff) % 300); lastNMinCheck = now - 90 + ((afs_random() & 0x7fffffff) % 180); /* start off with afs_initState >= 101 (basic init done) */ @@ -211,6 +214,19 @@ afs_Daemon(void) * tickets */ last3MinCheck = now; } +#ifdef AFS_MAXVCOUNT_ENV + if (afsd_dynamic_vcaches && (last5MinCheck + 300 < now)) { + /* start with trying to drop us back to our base usage */ + int anumber; + if (afs_maxvcount <= afs_cacheStats) + anumber = VCACHE_FREE; + else + anumber = VCACHE_FREE + (afs_maxvcount - afs_cacheStats); + + afs_ShakeLooseVCaches(anumber); + last5MinCheck = now; + } +#endif if (!afs_CheckServerDaemonStarted) { /* Do the check here if the correct afsd is not installed. */ if (!cs_warned) { diff --git a/src/afs/afs_init.c b/src/afs/afs_init.c index fd79310..b59db08 100644 --- a/src/afs/afs_init.c +++ b/src/afs/afs_init.c @@ -50,6 +50,9 @@ afs_rwlock_t afs_discon_lock; extern afs_rwlock_t afs_disconDirtyLock; #endif +/* This is the kernel side of the dynamic vcache setting */ +int afsd_dynamic_vcaches = 0; /* Enable dynamic-vcache support */ + /* * Initialization order is important. Must first call afs_CacheInit, * then cache file and volume file initialization routines. Next, the @@ -86,7 +89,7 @@ static int afs_cacheinit_flag = 0; int afs_CacheInit(afs_int32 astatSize, afs_int32 afiles, afs_int32 ablocks, afs_int32 aDentries, afs_int32 aVolumes, afs_int32 achunk, - afs_int32 aflags, afs_int32 ninodes, afs_int32 nusers) + afs_int32 aflags, afs_int32 ninodes, afs_int32 nusers, afs_int32 dynamic_vcaches) { register afs_int32 i; register struct volume *tv; @@ -103,6 +106,13 @@ afs_CacheInit(afs_int32 astatSize, afs_int32 afiles, afs_int32 ablocks, afs_stats_cmperf.sysName_ID = SYS_NAME_ID_UNDEFINED; #endif /* SYS_NAME_ID */ +#ifdef AFS_MAXVCOUNT_ENV + afsd_dynamic_vcaches = dynamic_vcaches; + printf("%s dynamically allocated vcaches\n", ( afsd_dynamic_vcaches ? "enabling" : "disabling" )); +#else + afsd_dynamic_vcaches = 0; +#endif + printf("Starting AFS cache scan..."); if (afs_cacheinit_flag) return 0; diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 450403f..0e8b3fe 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -419,7 +419,7 @@ extern int afs_CacheInit(afs_int32 astatSize, afs_int32 afiles, afs_int32 ablocks, afs_int32 aDentries, afs_int32 aVolumes, afs_int32 achunk, afs_int32 aflags, afs_int32 ninodes, - afs_int32 nusers); + afs_int32 nusers, afs_int32 dynamic_vcaches); extern void afs_ComputeCacheParms(void); extern int afs_InitCacheInfo(register char *afile); extern int afs_InitVolumeInfo(char *afile); diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 1992d2e..a8c5c32 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -82,6 +82,7 @@ struct afs_q afs_vhashTV[VCSIZE]; static struct afs_cbr *afs_cbrHashT[CBRSIZE]; afs_int32 afs_bulkStatsLost; int afs_norefpanic = 0; +extern int afsd_dynamic_vcaches; /* Disk backed vcache definitions @@ -261,6 +262,7 @@ afs_FlushVCache(struct vcache *avc, int *slept) VN_UNLOCK(AFSTOV(avc)); #endif AFS_RELE(AFSTOV(avc)); + afs_stats_cmperf.vcacheXAllocs--; } else { if (afs_norefpanic) { printf("flush vc refcnt < 1"); @@ -621,52 +623,29 @@ afs_FlushReclaimedVcaches(void) #endif } -/*! - * This routine is responsible for allocating a new cache entry - * from the free list. It formats the cache entry and inserts it - * into the appropriate hash tables. It must be called with - * afs_xvcache write-locked so as to prevent several processes from - * trying to create a new cache entry simultaneously. - * - * LOCK: afs_NewVCache afs_xvcache W - * - * \param afid The file id of the file whose cache entry is being created. - * - * \return The new vcache struct. - */ -struct vcache * -afs_NewVCache(struct VenusFid *afid, struct server *serverp) +static int +afs_ShakeLooseVCaches(afs_int32 anumber) { - struct vcache *tvc; +#if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV) afs_int32 i, j; - afs_int32 anumber = VCACHE_FREE; -#ifdef AFS_AIX_ENV - struct gnode *gnodepnt; -#endif -#ifdef AFS_OSF_ENV - struct vcache *nvc; -#endif /* AFS_OSF_ENV */ + struct vcache *tvc; struct afs_q *tq, *uq; int code, fv_slept; + afs_int32 target = anumber; + int haveGlock = 1; - AFS_STATCNT(afs_NewVCache); - - afs_FlushReclaimedVcaches(); + /* Should probably deal better */ + if (!ISAFS_GLOCK()) { + haveGlock = 0; + AFS_GLOCK(); + } -#if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV) -# if defined(AFS_OSF30_ENV) || defined(AFS_LINUX22_ENV) - if (afs_vcount >= afs_maxvcount) -# else - /* - * If we are using > 33 % of the total system vnodes for AFS vcache - * entries or we are using the maximum number of vcache entries, - * then free some. (if our usage is > 33% we should free some, if - * our usage is > afs_maxvcount, set elsewhere to 0.5*nvnode, - * we _must_ free some -- no choice). - */ - if (((3 * afs_vcount) > nvnode) || (afs_vcount >= afs_maxvcount)) -# endif - { + if ( +#ifdef AFS_MAXVCOUNT_ENV + afsd_dynamic_vcaches || /* Always run if dynamic vcaches are enabled. */ +#endif + afs_vcount >= afs_maxvcount + ) { int i; i = 0; @@ -675,7 +654,11 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) uq = QPrev(tq); if (tvc->f.states & CVFlushed) { refpanic("CVFlushed on VLRU"); - } else if (i++ > afs_maxvcount) { + } else if ( +#ifdef AFS_MAXVCOUNT_ENV + ! afsd_dynamic_vcaches && +#endif + i++ > afs_maxvcount) { refpanic("Exceeded pool of AFS vnodes(VLRU cycle?)"); } else if (QNext(uq) != tq) { refpanic("VLRU inconsistent"); @@ -683,14 +666,14 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) refpanic("refcnt 0 on VLRU"); } -# if defined(AFS_LINUX22_ENV) +#if defined(AFS_LINUX22_ENV) if (tvc != afs_globalVp && VREFCOUNT(tvc) > 1 && tvc->opens == 0) { struct dentry *dentry; struct list_head *cur, *head; AFS_GUNLOCK(); -# if defined(AFS_LINUX24_ENV) +#if defined(AFS_LINUX24_ENV) spin_lock(&dcache_lock); -# endif /* AFS_LINUX24_ENV */ +#endif /* AFS_LINUX24_ENV */ head = &(AFSTOV(tvc))->i_dentry; restart: @@ -703,27 +686,27 @@ restart: dget_locked(dentry); -# if defined(AFS_LINUX24_ENV) +#if defined(AFS_LINUX24_ENV) spin_unlock(&dcache_lock); -# endif /* AFS_LINUX24_ENV */ +#endif /* AFS_LINUX24_ENV */ if (d_invalidate(dentry) == -EBUSY) { dput(dentry); /* perhaps lock and try to continue? (use cur as head?) */ goto inuse; } dput(dentry); -# if defined(AFS_LINUX24_ENV) +#if defined(AFS_LINUX24_ENV) spin_lock(&dcache_lock); -# endif /* AFS_LINUX24_ENV */ +#endif /* AFS_LINUX24_ENV */ goto restart; } -# if defined(AFS_LINUX24_ENV) +#if defined(AFS_LINUX24_ENV) spin_unlock(&dcache_lock); -# endif /* AFS_LINUX24_ENV */ +#endif /* AFS_LINUX24_ENV */ inuse: AFS_GLOCK(); } -# endif /* AFS_LINUX22_ENV */ +#endif /* AFS_LINUX22_ENV */ if (VREFCOUNT_GT(tvc,0) && !VREFCOUNT_GT(tvc,1) && tvc->opens == 0 @@ -741,47 +724,96 @@ restart: if (tq == uq) break; } - if (anumber == VCACHE_FREE) { - printf("afs_NewVCache: warning none freed, using %d of %d\n", + if ( +#ifdef AFS_MAXVCOUNT_ENV + !afsd_dynamic_vcaches && +#endif + anumber == target) { + printf("afs_ShakeLooseVCaches: warning none freed, using %d of %d\n", afs_vcount, afs_maxvcount); - if (afs_vcount >= afs_maxvcount) { - printf("afs_NewVCache - none freed\n"); - return NULL; - } } } /* finished freeing up space */ +/* + printf("recycled %d entries\n", target-anumber); +*/ + if (!haveGlock) + AFS_GUNLOCK(); +#endif + return 0; +} /* Alloc new vnode. */ -#if defined(AFS_LINUX22_ENV) + +static struct vcache * +afs_AllocVCache(void) { + struct vcache *tvc; +#if defined(AFS_OSF30_ENV) + struct vcache *nvc; + AFS_GUNLOCK(); + if (getnewvnode(MOUNT_AFS, &Afs_vnodeops, &nvc)) { + /* What should we do ???? */ + osi_Panic("afs_AllocVCache: no more vnodes"); + } + AFS_GLOCK(); + + tvc = nvc; + tvc->nextfree = NULL; + afs_vcount++; +#elif defined(AFS_LINUX22_ENV) struct inode *ip; AFS_GUNLOCK(); ip = new_inode(afs_globalVFS); if (!ip) - osi_Panic("afs_NewVCache: no more inodes"); + osi_Panic("afs_AllocVCache: no more inodes"); AFS_GLOCK(); -# if defined(STRUCT_SUPER_HAS_ALLOC_INODE) +#if defined(STRUCT_SUPER_HAS_ALLOC_INODE) tvc = VTOAFS(ip); -# else +#else tvc = afs_osi_Alloc(sizeof(struct vcache)); ip->u.generic_ip = tvc; tvc->v = ip; -# endif -} -# else - AFS_GUNLOCK(); - if (getnewvnode(MOUNT_AFS, &Afs_vnodeops, &nvc)) { - /* What should we do ???? */ - osi_Panic("afs_NewVCache: no more vnodes"); - } - AFS_GLOCK(); +#endif - tvc = nvc; - tvc->nextfree = NULL; -# endif afs_vcount++; - +#ifdef AFS_MAXVCOUNT_ENV + /* track the peak */ + if (afsd_dynamic_vcaches && afs_maxvcount < afs_vcount) { + afs_maxvcount = afs_vcount; + printf("peak vnodes: %d\n", afs_maxvcount); + } +#endif + afs_stats_cmperf.vcacheXAllocs++; /* count in case we have a leak */ +#else + /* none free, making one is better than a panic */ + afs_stats_cmperf.vcacheXAllocs++; /* count in case we have a leak */ + tvc = (struct vcache *)afs_osi_Alloc(sizeof(struct vcache)); +#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL) + tvc->v = NULL; /* important to clean this, or use memset 0 */ +#endif +#ifdef KERNEL_HAVE_PIN + pin((char *)tvc, sizeof(struct vcache)); /* XXX */ +#endif +#if defined(AFS_SGI_ENV) + { + char name[METER_NAMSZ]; + memset(tvc, 0, sizeof(struct vcache)); + tvc->v.v_number = ++afsvnumbers; + tvc->vc_rwlockid = OSI_NO_LOCKID; + initnsema(&tvc->vc_rwlock, 1, + makesname(name, "vrw", tvc->v.v_number)); +#ifndef AFS_SGI53_ENV + initnsema(&tvc->v.v_sync, 0, + makesname(name, "vsy", tvc->v.v_number)); +#endif +#ifndef AFS_SGI62_ENV + initnlock(&tvc->v.v_lock, + makesname(name, "vlk", tvc->v.v_number)); +#endif + } +#endif /* AFS_SGI_ENV */ +#endif #ifdef AFS_DISCON_ENV /* If we create a new inode, we either give it a new slot number, * or if one's available, use a slot number from the slot free list @@ -798,7 +830,52 @@ restart: } #endif -#else /* AFS_OSF_ENV || AFS_LINUX22_ENV */ + return tvc; +} + +/*! + * This routine is responsible for allocating a new cache entry + * from the free list. It formats the cache entry and inserts it + * into the appropriate hash tables. It must be called with + * afs_xvcache write-locked so as to prevent several processes from + * trying to create a new cache entry simultaneously. + * + * LOCK: afs_NewVCache afs_xvcache W + * + * \param afid The file id of the file whose cache entry is being created. + * + * \return The new vcache struct. + */ +struct vcache * +afs_NewVCache(struct VenusFid *afid, struct server *serverp) +{ + struct vcache *tvc; + afs_int32 i, j; + afs_int32 anumber = VCACHE_FREE; +#ifdef AFS_AIX_ENV + struct gnode *gnodepnt; +#endif + struct afs_q *tq, *uq; + int code, fv_slept; + + AFS_STATCNT(afs_NewVCache); + + afs_FlushReclaimedVcaches(); + +#if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV) +#ifdef AFS_MAXVCOUNT_ENV + if(!afsd_dynamic_vcaches) { +#endif + afs_ShakeLooseVCaches(anumber); + if (afs_vcount >= afs_maxvcount) { + printf("afs_NewVCache - none freed\n"); + return NULL; + } +#ifdef AFS_MAXVCOUNT_ENV + } +#endif + tvc = afs_AllocVCache(); +#else /* AFS_OSF_ENV */ /* pull out a free cache entry */ if (!freeVCList) { int loop = 0; @@ -818,13 +895,13 @@ restart: } if (!VREFCOUNT_GT(tvc,0) -# if defined(AFS_DARWIN_ENV) && !defined(UKERNEL) && !defined(AFS_DARWIN80_ENV) +#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL) && !defined(AFS_DARWIN80_ENV) || ((VREFCOUNT(tvc) == 1) && (UBCINFOEXISTS(AFSTOV(tvc)))) -# endif +#endif && tvc->opens == 0 && (tvc->f.states & CUnlinkedDel) == 0) { -# if defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) -# ifdef AFS_DARWIN80_ENV +#if defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) +#ifdef AFS_DARWIN80_ENV vnode_t tvp = AFSTOV(tvc); /* VREFCOUNT_GT only sees usecounts, not iocounts */ /* so this may fail to actually recycle the vnode now */ @@ -852,7 +929,7 @@ restart: code = EBUSY; } else code = 0; -# else /* AFS_DARWIN80_ENV */ +#else /* AFS_DARWIN80_ENV */ /* * vgone() reclaims the vnode, which calls afs_FlushVCache(), * then it puts the vnode on the free list. @@ -865,10 +942,10 @@ restart: fv_slept = 0; code = 0; AFS_GLOCK(); -# endif -# else /* AFS_DARWIN80_ENV || AFS_XBSD_ENV */ +#endif +#else /* AFS_DARWIN80_ENV || AFS_XBSD_ENV */ code = afs_FlushVCache(tvc, &fv_slept); -# endif /* AFS_DARWIN80_ENV || AFS_XBSD_ENV */ +#endif /* AFS_DARWIN80_ENV || AFS_XBSD_ENV */ if (code == 0) { anumber--; } @@ -886,49 +963,7 @@ restart: } /* end of if (!freeVCList) */ if (!freeVCList) { - /* none free, making one is better than a panic */ - afs_stats_cmperf.vcacheXAllocs++; /* count in case we have a leak */ - tvc = (struct vcache *)afs_osi_Alloc(sizeof(struct vcache)); -# if defined(AFS_DARWIN_ENV) && !defined(UKERNEL) - tvc->v = NULL; /* important to clean this, or use memset 0 */ -# endif -# ifdef KERNEL_HAVE_PIN - pin((char *)tvc, sizeof(struct vcache)); /* XXX */ -# endif - -#ifdef AFS_DISCON_ENV - /* If we create a new inode, we either give it a new slot number, - * or if one's available, use a slot number from the slot free list - */ - if (afs_freeSlotList != NULL) { - struct afs_slotlist *tmp; - - tvc->diskSlot = afs_freeSlotList->slot; - tmp = afs_freeSlotList; - afs_freeSlotList = tmp->next; - afs_osi_Free(tmp, sizeof(struct afs_slotlist)); - } else { - tvc->diskSlot = afs_nextVcacheSlot++; - } -#endif -# if defined(AFS_SGI_ENV) - { - char name[METER_NAMSZ]; - memset(tvc, 0, sizeof(struct vcache)); - tvc->v.v_number = ++afsvnumbers; - tvc->vc_rwlockid = OSI_NO_LOCKID; - initnsema(&tvc->vc_rwlock, 1, - makesname(name, "vrw", tvc->v.v_number)); -#ifndef AFS_SGI53_ENV - initnsema(&tvc->v.v_sync, 0, - makesname(name, "vsy", tvc->v.v_number)); -#endif -#ifndef AFS_SGI62_ENV - initnlock(&tvc->v.v_lock, - makesname(name, "vlk", tvc->v.v_number)); -#endif - } -#endif /* AFS_SGI_ENV */ + tvc = afs_AllocVCache(); } else { tvc = freeVCList; /* take from free list */ freeVCList = tvc->nextfree; @@ -944,7 +979,7 @@ restart: #if !defined(AFS_SGI_ENV) && !defined(AFS_OSF_ENV) && !defined(AFS_LINUX22_ENV) -# if AFS_DISCON_ENV +#if defined(AFS_DISCON_ENV) /* We need to preserve the slot that we're being stored into on * disk */ { @@ -953,9 +988,9 @@ restart: memset((char *)tvc, 0, sizeof(struct vcache)); tvc->diskSlot = slot; } -# else +#else memset((char *)tvc, 0, sizeof(struct vcache)); -# endif +#endif #else tvc->uncred = 0; @@ -1909,7 +1944,7 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq, newvcache = 1; ConvertWToSLock(&afs_xvcache); - if (!tvc) + if (tvc == NULL) { ReleaseSharedLock(&afs_xvcache); return NULL; diff --git a/src/afsd/afsd.c b/src/afsd/afsd.c index 53784b8..11ac16d 100644 --- a/src/afsd/afsd.c +++ b/src/afsd/afsd.c @@ -32,6 +32,9 @@ * -nosettime Don't keep checking the time to avoid drift (default). * -settime Keep checking the time to avoid drift. * -verbose Be chatty. + * -disable-dynamic-vcaches Disable the use of -stat value as the starting size of + * the size of the vcache/stat cache pool, + * but increase that pool dynamically as needed. * -debug Print out additional debugging info. * -kerndev [OBSOLETE] The kernel device for AFS. * -dontfork [OBSOLETE] Don't fork off as a new process. @@ -320,6 +323,7 @@ static int enable_splitcache = 0; #ifdef notdef static int inodes = 60; /* VERY conservative, but has to be */ #endif +int afsd_dynamic_vcaches = 0; /* Enable dynamic-vcache support */ int afsd_verbose = 0; /*Are we being chatty? */ int afsd_debug = 0; /*Are we printing debugging info? */ int afsd_CloseSynch = 0; /*Are closes synchronous or not? */ @@ -1747,6 +1751,25 @@ mainproc(struct cmd_syndesc *as, void *arock) } } } + if (as->parms[35].items) { +#ifdef AFS_MAXVCOUNT_ENV + /* -disable-dynamic-vcaches */ + afsd_dynamic_vcaches = FALSE; +#else + printf("afsd: Error toggling flag, dynamically allocated vcaches not supported on your platform\n"); + exit(1); +#endif + } +#ifdef AFS_MAXVCOUNT_ENV + else { + /* -dynamic-vcaches */ + afsd_dynamic_vcaches = TRUE; + } + + if (afsd_verbose) + printf("afsd: %s dynamically allocated vcaches\n", ( afsd_dynamic_vcaches ? "enabling" : "disabling" )); +#endif + /* * Pull out all the configuration info for the workstation's AFS cache and * the cellular community we're willing to let our users see. @@ -2085,6 +2108,7 @@ mainproc(struct cmd_syndesc *as, void *arock) cparams.chunkSize = chunkSize; cparams.setTimeFlag = cacheSetTime; cparams.memCacheFlag = cacheFlags; + cparams.dynamic_vcaches = afsd_dynamic_vcaches; #ifdef notdef cparams.inodes = inodes; #endif @@ -2473,6 +2497,8 @@ main(int argc, char **argv) "set rx_extraPackets to this value"); cmd_AddParm(ts, "-splitcache", CMD_SINGLE, CMD_OPTIONAL, "Percentage RW versus RO in cache (specify as 60/40)"); + cmd_AddParm(ts, "-disable-dynamic-vcaches", CMD_FLAG, CMD_OPTIONAL, + "disable stat/vcache cache growing as needed"); return (cmd_Dispatch(argc, argv)); } diff --git a/src/config/afs_args.h b/src/config/afs_args.h index 2db7d34..1983cb5 100644 --- a/src/config/afs_args.h +++ b/src/config/afs_args.h @@ -142,6 +142,7 @@ struct afs_cacheParams { afs_int32 memCacheFlag; afs_int32 inodes; afs_int32 users; + afs_int32 dynamic_vcaches; }; /* diff --git a/src/config/param.amd64_linux26.h b/src/config/param.amd64_linux26.h index 2ad1196..42ce403 100644 --- a/src/config/param.amd64_linux26.h +++ b/src/config/param.amd64_linux26.h @@ -19,6 +19,7 @@ #define AFS_AMD64_LINUX26_ENV 1 #define AFS_LINUX_64BIT_KERNEL 1 #define AFS_64BITPOINTER_ENV 1 /* pointers are 64 bits */ +#define AFS_MAXVCOUNT_ENV 1 #else /* !defined(UKERNEL) */ diff --git a/src/config/param.ia64_linux26.h b/src/config/param.ia64_linux26.h index 8d67d2a..5ae045e 100644 --- a/src/config/param.ia64_linux26.h +++ b/src/config/param.ia64_linux26.h @@ -19,6 +19,7 @@ #define AFS_IA64_LINUX26_ENV 1 #define AFS_LINUX_64BIT_KERNEL 1 #define AFS_64BITPOINTER_ENV 1 /* pointers are 64 bits. */ +#define AFS_MAXVCOUNT_ENV 1 #else /* !defined(UKERNEL) */ diff --git a/src/config/param.linux26.h b/src/config/param.linux26.h index 6b9d869..1a05b08 100644 --- a/src/config/param.linux26.h +++ b/src/config/param.linux26.h @@ -31,6 +31,7 @@ #define AFS_HAVE_STATVFS 0 /* System doesn't support statvfs */ #define AFS_VM_RDWR_ENV 1 /* read/write implemented via VM */ #define AFS_USE_GETTIMEOFDAY 1 /* use gettimeofday to implement rx clock */ +#define AFS_MAXVCOUNT_ENV 1 #if defined(__KERNEL__) && !defined(KDUMP_KERNEL) #define AFS_GLOBAL_SUNLOCK -- 1.9.4