The bcache source here contains the following line:
schedule_delayed_work(&dc->writeback_rate_update,
dc->writeback_rate_update_seconds * HZ);
writeback_rate_update_seconds
is defined as unsigned int
, which appears to be 32 bit on x86_64, and I am not sure what type HZ
has but I believe the value is 1000 and assume it is 32-bit or less.
If I set writeback_rate_update_seconds
to 2147483647, what value actually gets passed to schedule_delayed_work
? The second parameter of schedule_delayed_work
appears to be a long
, but that won't mean the operands are promoted to long prior to the multiplication overflow, will it?
Given:
#include <stdio.h>
#include <stdlib.h>
int schedule_delayed_work( unsigned long param )
{
printf("value: %lu\n", param);
return 0;
}
int main(int argc, char **argv)
{
unsigned int writeback_rate_update_seconds;
unsigned int HZ;
writeback_rate_update_seconds = 2147483647;
HZ = 1000;
schedule_delayed_work( writeback_rate_update_seconds * HZ );
return 0;
}
You will get 4294966296
passed to the function.
If you change the function call to cast:
schedule_delayed_work( (unsigned long) writeback_rate_update_seconds * HZ );
... you will get 2147483647000
passed to the function.
I've not looked in the C standard to see what the standard behaviour is, but this was tested with:
Apple LLVM version 8.1.0 (clang-802.0.38)
Target: x86_64-apple-darwin16.7.0