diff --git a/src/vol/volume.c b/src/vol/volume.c index c8884db136..d5c45adee3 100644 --- a/src/vol/volume.c +++ b/src/vol/volume.c @@ -512,6 +512,8 @@ VOptDefaults(ProgramType pt, VolumePackageOptions *opts) opts->canUseSALVSYNC = 0; opts->interrupt_rxcall = NULL; + opts->usage_threshold = 128; + opts->usage_rate_limit = 5; #ifdef FAST_RESTART opts->unsafe_attach = 1; @@ -6533,10 +6535,16 @@ VBumpVolumeUsage_r(Volume * vp) if (now - V_dayUseDate(vp) > OneDay) VAdjustVolumeStatistics_r(vp); /* - * Save the volume header image to disk after every 128 bumps to dayUse. + * Save the volume header image to disk after a threshold of bumps to dayUse, + * at most every usage_rate_limit seconds. */ - if ((V_dayUse(vp)++ & 127) == 0) { + V_dayUse(vp)++; + vp->usage_bumps_outstanding++; + if (vp->usage_bumps_outstanding >= vol_opts.usage_threshold + && vp->usage_bumps_next_write <= now) { Error error; + vp->usage_bumps_outstanding = 0; + vp->usage_bumps_next_write = now + vol_opts.usage_rate_limit; VUpdateVolume_r(&error, vp, VOL_UPDATE_WAIT); } } diff --git a/src/vol/volume.h b/src/vol/volume.h index c551764431..6468d6dae6 100644 --- a/src/vol/volume.h +++ b/src/vol/volume.h @@ -255,6 +255,9 @@ typedef struct VolumePackageOptions { void (*interrupt_rxcall) (struct rx_call *call, afs_int32 error); /**< callback to interrupt RX calls accessing * a going-offline volume */ + afs_int32 usage_threshold; /*< number of accesses before writing volume header */ + afs_int32 usage_rate_limit; /*< minimum number of seconds before writing volume + * header, after usage_threshold is exceeded */ } VolumePackageOptions; /* Magic numbers and version stamps for each type of file */ @@ -701,6 +704,8 @@ typedef struct Volume { VolumeVLRUState vlru; /* state specific to the VLRU */ FSSYNC_VolOp_info * pending_vol_op; /* fssync command info for any pending vol ops */ #endif /* AFS_DEMAND_ATTACH_FS */ + int usage_bumps_outstanding; /**< to rate limit the usage update i/o by accesses */ + int usage_bumps_next_write; /**< to rate limit the usage update i/o by time */ } Volume; struct volHeader {