Tags: patch Hi,
The attached patch from Wes Chow <[EMAIL PROTECTED]> fixes the various places where afs_cacheBlocks having a large value will overflow an int32 and cause the multiplication to be incorrect. Instead of basically doing: (95*afs_cacheBlocks) / 100 all over the place, we instead do 95 * (afs_cacheBlocks/100) Obviously, this will cause a loss of precision; however, the worst it could possibly be is 99k (if using a value like 80000099 in your cacheinfo). This should be an acceptable loss, I would imagine. The patch also fixes one place where afs_cacheFiles does basically the same thing (in afs.h). It is included in the patch for completeness; if you disagree w/ it, I can understand. I'm not sure of any real world scenarios where that would overflow (it's -5*afs_cacheFiles, and afs_cacheFiles default in debian only goes as high as 80000 aiui). It also causes a loss of precision. The patch is attached.
diff -r -u openafs.orig/openafs-1.4.0/src/afs/afs_dcache.c openafs.new/openafs-1.4.0/src/afs/afs_dcache.c --- openafs.orig/openafs-1.4.0/src/afs/afs_dcache.c 2005-08-04 16:45:14.000000000 -0400 +++ openafs.new/openafs-1.4.0/src/afs/afs_dcache.c 2006-03-30 15:54:14.308241504 -0500 @@ -231,8 +231,8 @@ osi_GetuTime(&CTD_stats.CTD_afterSleep); afs_TruncateDaemonRunning = 1; while (1) { - cb_lowat = ((CM_DCACHESPACEFREEPCT - CM_DCACHEEXTRAPCT) - * afs_cacheBlocks) / 100; + cb_lowat = (CM_DCACHESPACEFREEPCT - CM_DCACHEEXTRAPCT) + * (afs_cacheBlocks / 100); MObtainWriteLock(&afs_xdcache, 266); if (afs_CacheTooFull) { int space_needed, slots_needed; @@ -777,7 +777,7 @@ if (afs_WaitForCacheDrain) { if (afs_blocksUsed <= - (CM_CACHESIZEDRAINEDPCT * afs_cacheBlocks) / 100) { + CM_CACHESIZEDRAINEDPCT * (afs_cacheBlocks / 100)) { afs_WaitForCacheDrain = 0; afs_osi_Wakeup(&afs_WaitForCacheDrain); } @@ -810,7 +810,7 @@ if (afs_WaitForCacheDrain) { if ((afs_blocksUsed - afs_blocksDiscarded) <= - (CM_CACHESIZEDRAINEDPCT * afs_cacheBlocks) / 100) { + CM_CACHESIZEDRAINEDPCT * (afs_cacheBlocks / 100)) { afs_WaitForCacheDrain = 0; afs_osi_Wakeup(&afs_WaitForCacheDrain); } @@ -860,7 +860,7 @@ if (afs_WaitForCacheDrain) { if ((afs_blocksUsed - afs_blocksDiscarded) <= - (CM_CACHESIZEDRAINEDPCT * afs_cacheBlocks) / 100) { + CM_CACHESIZEDRAINEDPCT * (afs_cacheBlocks / 100)) { afs_WaitForCacheDrain = 0; afs_osi_Wakeup(&afs_WaitForCacheDrain); } @@ -943,7 +943,7 @@ while (afs_blocksDiscarded && (afs_blocksUsed > - (CM_WAITFORDRAINPCT * afs_cacheBlocks) / 100)) { + CM_WAITFORDRAINPCT * (afs_cacheBlocks / 100))) { afs_FreeDiscardedDCache(); } return 0; @@ -1967,7 +1967,7 @@ /* Sleep here when cache needs to be drained. */ if (setLocks && !slowPass && (afs_blocksUsed > - (CM_WAITFORDRAINPCT * afs_cacheBlocks) / 100)) { + CM_WAITFORDRAINPCT * (afs_cacheBlocks / 100))) { /* Make sure truncate daemon is running */ afs_MaybeWakeupTruncateDaemon(); ObtainWriteLock(&tdc->tlock, 614); @@ -1976,7 +1976,7 @@ ReleaseWriteLock(&tdc->lock); ReleaseReadLock(&avc->lock); while ((afs_blocksUsed - afs_blocksDiscarded) > - (CM_WAITFORDRAINPCT * afs_cacheBlocks) / 100) { + CM_WAITFORDRAINPCT * (afs_cacheBlocks / 100)) { afs_WaitForCacheDrain = 1; afs_osi_Sleep(&afs_WaitForCacheDrain); } diff -r -u openafs.orig/openafs-1.4.0/src/afs/afs.h openafs.new/openafs-1.4.0/src/afs/afs.h --- openafs.orig/openafs-1.4.0/src/afs/afs.h 2005-07-11 15:29:55.000000000 -0400 +++ openafs.new/openafs-1.4.0/src/afs/afs.h 2006-03-30 15:54:14.309241352 -0500 @@ -1114,9 +1114,9 @@ #define afs_CacheIsTooFull() \ (afs_blocksUsed - afs_blocksDiscarded > \ - (CM_DCACHECOUNTFREEPCT*afs_cacheBlocks)/100 || \ + CM_DCACHECOUNTFREEPCT*(afs_cacheBlocks/100) || \ afs_freeDCCount - afs_discardDCCount < \ - ((100-CM_DCACHECOUNTFREEPCT)*afs_cacheFiles)/100) + (100-CM_DCACHECOUNTFREEPCT)*(afs_cacheFiles/100)) /* Handy max length of a numeric string. */ #define CVBS 12 /* max afs_int32 is 2^32 ~ 4*10^9, +1 for NULL, +luck */ diff -r -u openafs.orig/openafs-1.4.0/src/afs/SOLARIS/osi_vnodeops.c openafs.new/openafs-1.4.0/src/afs/SOLARIS/osi_vnodeops.c --- openafs.orig/openafs-1.4.0/src/afs/SOLARIS/osi_vnodeops.c 2005-10-12 02:06:47.000000000 -0400 +++ openafs.new/openafs-1.4.0/src/afs/SOLARIS/osi_vnodeops.c 2006-03-30 15:54:14.311241048 -0500 @@ -762,9 +762,9 @@ */ afs_MaybeWakeupTruncateDaemon(); while ((arw == UIO_WRITE) - && (afs_blocksUsed > (CM_WAITFORDRAINPCT * afs_cacheBlocks) / 100)) { + && (afs_blocksUsed > CM_WAITFORDRAINPCT * (afs_cacheBlocks / 100))) { if (afs_blocksUsed - afs_blocksDiscarded > - (CM_WAITFORDRAINPCT * afs_cacheBlocks) / 100) { + CM_WAITFORDRAINPCT * (afs_cacheBlocks / 100)) { afs_WaitForCacheDrain = 1; afs_osi_Sleep(&afs_WaitForCacheDrain); } diff -r -u openafs.orig/openafs-1.4.0/src/afs/VNOPS/afs_vnop_write.c openafs.new/openafs-1.4.0/src/afs/VNOPS/afs_vnop_write.c --- openafs.orig/openafs-1.4.0/src/afs/VNOPS/afs_vnop_write.c 2005-10-02 22:55:33.000000000 -0400 +++ openafs.new/openafs-1.4.0/src/afs/VNOPS/afs_vnop_write.c 2006-03-30 15:54:14.312240896 -0500 @@ -198,7 +198,7 @@ if (tdc) ObtainWriteLock(&tdc->lock, 653); } else if (afs_blocksUsed > - (CM_WAITFORDRAINPCT * afs_cacheBlocks) / 100) { + CM_WAITFORDRAINPCT * (afs_cacheBlocks / 100)) { tdc = afs_FindDCache(avc, filePos); if (tdc) { ObtainWriteLock(&tdc->lock, 654); @@ -212,10 +212,10 @@ if (!tdc) { afs_MaybeWakeupTruncateDaemon(); while (afs_blocksUsed > - (CM_WAITFORDRAINPCT * afs_cacheBlocks) / 100) { + CM_WAITFORDRAINPCT * (afs_cacheBlocks / 100)) { ReleaseWriteLock(&avc->lock); if (afs_blocksUsed - afs_blocksDiscarded > - (CM_WAITFORDRAINPCT * afs_cacheBlocks) / 100) { + CM_WAITFORDRAINPCT * (afs_cacheBlocks / 100)) { afs_WaitForCacheDrain = 1; afs_osi_Sleep(&afs_WaitForCacheDrain); } @@ -442,7 +442,7 @@ if (tdc) ObtainWriteLock(&tdc->lock, 657); } else if (afs_blocksUsed > - (CM_WAITFORDRAINPCT * afs_cacheBlocks) / 100) { + CM_WAITFORDRAINPCT * (afs_cacheBlocks / 100)) { tdc = afs_FindDCache(avc, filePos); if (tdc) { ObtainWriteLock(&tdc->lock, 658); @@ -456,10 +456,10 @@ if (!tdc) { afs_MaybeWakeupTruncateDaemon(); while (afs_blocksUsed > - (CM_WAITFORDRAINPCT * afs_cacheBlocks) / 100) { + CM_WAITFORDRAINPCT * (afs_cacheBlocks / 100)) { ReleaseWriteLock(&avc->lock); if (afs_blocksUsed - afs_blocksDiscarded > - (CM_WAITFORDRAINPCT * afs_cacheBlocks) / 100) { + CM_WAITFORDRAINPCT * (afs_cacheBlocks / 100)) { afs_WaitForCacheDrain = 1; afs_osi_Sleep(&afs_WaitForCacheDrain); }