2025-08-10 01:34:16 +02:00

77 lines
2.2 KiB
C

#include <app/App.h>
#include <net/filesystem/FhgfsOpsRemoting.h>
#include "StatFsCache.h"
/**
* If caching is enabled and cache is not expired, this will return the cached values. Otherwise
* FhgfsOpsRemoting_statStoragePath() will be called for fresh values.
*
* @param outSizeTotal in bytes.
* @param outSizeFree in bytes.
* @return if remoting fails, the error code from FhgfsOpsRemoting_statStoragePath() will be
* returned.
*/
FhgfsOpsErr StatFsCache_getFreeSpace(StatFsCache* this, int64_t* outSizeTotal,
int64_t* outSizeFree)
{
Config* cfg = App_getConfig(this->app);
unsigned tuneStatFsCacheSecs = Config_getTuneStatFsCacheSecs(cfg); // zero means disable caching
if(tuneStatFsCacheSecs)
{ // caching enabled, test if cache values expired
RWLock_readLock(&this->rwlock); // L O C K (read)
if(!Time_getIsZero(&this->lastUpdateTime) && // zero time means cache values are uninitialized
(Time_elapsedMS(&this->lastUpdateTime) <= (tuneStatFsCacheSecs*1000) ) ) // *1000 for MS
{ // cache values are still valid
*outSizeTotal = this->cachedSizeTotal;
*outSizeFree = this->cachedSizeFree;
RWLock_readUnlock(&this->rwlock); // U N L O C K (read)
return FhgfsOpsErr_SUCCESS;
}
// cache values not valid
RWLock_readUnlock(&this->rwlock); // U N L O C K (read)
}
// get fresh values from servers
{
FhgfsOpsErr retVal = FhgfsOpsRemoting_statStoragePath(this->app, true,
outSizeTotal, outSizeFree);
if(retVal != FhgfsOpsErr_SUCCESS)
{
*outSizeTotal = 0;
*outSizeFree = 0;
return retVal;
}
}
// update cached values
/* note: as we don't hold a write-lock during remoting (to allow parallelism), it's possible that
multiple threads are racing with different values on the update below, but that's uncritical
for free space info */
if(tuneStatFsCacheSecs)
{
RWLock_writeLock(&this->rwlock); // L O C K (write)
this->cachedSizeTotal = *outSizeTotal;
this->cachedSizeFree = *outSizeFree;
Time_setToNow(&this->lastUpdateTime);
RWLock_writeUnlock(&this->rwlock); // U N L O C K (write)
}
return FhgfsOpsErr_SUCCESS;
}