mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 07:12:09 +00:00
nfs: use time64_t internally
The timestamps for the cache are all in boottime seconds, so they don't overflow 32-bit values, but the use of time_t is deprecated because it generally does overflow when used with wall-clock time. There are multiple possible ways of avoiding it: - leave time_t, which is safe here, but forces others to look into this code to determine that it is over and over. - use a more generic type, like 'int' or 'long', which is known to be sufficient here but loses the documentation of referring to timestamps - use ktime_t everywhere, and convert into seconds in the few places where we want realtime-seconds. The conversion is sometimes expensive, but not more so than the conversion we do today. - use time64_t to clarify that this code is safe. Nothing would change for 64-bit architectures, but it is slightly less efficient on 32-bit architectures. Without a clear winner of the three approaches above, this picks the last one, favouring readability over a small performance loss on 32-bit architectures. Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
parent
294ec5b87a
commit
f559935e7c
4 changed files with 37 additions and 33 deletions
|
@ -45,8 +45,8 @@
|
|||
*/
|
||||
struct cache_head {
|
||||
struct hlist_node cache_list;
|
||||
time_t expiry_time; /* After time time, don't use the data */
|
||||
time_t last_refresh; /* If CACHE_PENDING, this is when upcall was
|
||||
time64_t expiry_time; /* After time time, don't use the data */
|
||||
time64_t last_refresh; /* If CACHE_PENDING, this is when upcall was
|
||||
* sent, else this is when update was
|
||||
* received, though it is alway set to
|
||||
* be *after* ->flush_time.
|
||||
|
@ -95,22 +95,22 @@ struct cache_detail {
|
|||
/* fields below this comment are for internal use
|
||||
* and should not be touched by cache owners
|
||||
*/
|
||||
time_t flush_time; /* flush all cache items with
|
||||
time64_t flush_time; /* flush all cache items with
|
||||
* last_refresh at or earlier
|
||||
* than this. last_refresh
|
||||
* is never set at or earlier
|
||||
* than this.
|
||||
*/
|
||||
struct list_head others;
|
||||
time_t nextcheck;
|
||||
time64_t nextcheck;
|
||||
int entries;
|
||||
|
||||
/* fields for communication over channel */
|
||||
struct list_head queue;
|
||||
|
||||
atomic_t writers; /* how many time is /channel open */
|
||||
time_t last_close; /* if no writers, when did last close */
|
||||
time_t last_warn; /* when we last warned about no writers */
|
||||
time64_t last_close; /* if no writers, when did last close */
|
||||
time64_t last_warn; /* when we last warned about no writers */
|
||||
|
||||
union {
|
||||
struct proc_dir_entry *procfs;
|
||||
|
@ -147,18 +147,22 @@ struct cache_deferred_req {
|
|||
* timestamps kept in the cache are expressed in seconds
|
||||
* since boot. This is the best for measuring differences in
|
||||
* real time.
|
||||
* This reimplemnts ktime_get_boottime_seconds() in a slightly
|
||||
* faster but less accurate way. When we end up converting
|
||||
* back to wallclock (CLOCK_REALTIME), that error often
|
||||
* cancels out during the reverse operation.
|
||||
*/
|
||||
static inline time_t seconds_since_boot(void)
|
||||
static inline time64_t seconds_since_boot(void)
|
||||
{
|
||||
struct timespec boot;
|
||||
getboottime(&boot);
|
||||
return get_seconds() - boot.tv_sec;
|
||||
struct timespec64 boot;
|
||||
getboottime64(&boot);
|
||||
return ktime_get_real_seconds() - boot.tv_sec;
|
||||
}
|
||||
|
||||
static inline time_t convert_to_wallclock(time_t sinceboot)
|
||||
static inline time64_t convert_to_wallclock(time64_t sinceboot)
|
||||
{
|
||||
struct timespec boot;
|
||||
getboottime(&boot);
|
||||
struct timespec64 boot;
|
||||
getboottime64(&boot);
|
||||
return boot.tv_sec + sinceboot;
|
||||
}
|
||||
|
||||
|
@ -273,7 +277,7 @@ static inline int get_uint(char **bpp, unsigned int *anint)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int get_time(char **bpp, time_t *time)
|
||||
static inline int get_time(char **bpp, time64_t *time)
|
||||
{
|
||||
char buf[50];
|
||||
long long ll;
|
||||
|
@ -287,20 +291,20 @@ static inline int get_time(char **bpp, time_t *time)
|
|||
if (kstrtoll(buf, 0, &ll))
|
||||
return -EINVAL;
|
||||
|
||||
*time = (time_t)ll;
|
||||
*time = ll;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline time_t get_expiry(char **bpp)
|
||||
static inline time64_t get_expiry(char **bpp)
|
||||
{
|
||||
time_t rv;
|
||||
struct timespec boot;
|
||||
time64_t rv;
|
||||
struct timespec64 boot;
|
||||
|
||||
if (get_time(bpp, &rv))
|
||||
return 0;
|
||||
if (rv < 0)
|
||||
return 0;
|
||||
getboottime(&boot);
|
||||
getboottime64(&boot);
|
||||
return rv - boot.tv_sec;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue