mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-16 20:07:38 +07: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
@ -45,8 +45,8 @@
|
|||||||
*/
|
*/
|
||||||
struct cache_head {
|
struct cache_head {
|
||||||
struct hlist_node cache_list;
|
struct hlist_node cache_list;
|
||||||
time_t expiry_time; /* After time time, don't use the data */
|
time64_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 last_refresh; /* If CACHE_PENDING, this is when upcall was
|
||||||
* sent, else this is when update was
|
* sent, else this is when update was
|
||||||
* received, though it is alway set to
|
* received, though it is alway set to
|
||||||
* be *after* ->flush_time.
|
* be *after* ->flush_time.
|
||||||
@ -95,22 +95,22 @@ struct cache_detail {
|
|||||||
/* fields below this comment are for internal use
|
/* fields below this comment are for internal use
|
||||||
* and should not be touched by cache owners
|
* 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
|
* last_refresh at or earlier
|
||||||
* than this. last_refresh
|
* than this. last_refresh
|
||||||
* is never set at or earlier
|
* is never set at or earlier
|
||||||
* than this.
|
* than this.
|
||||||
*/
|
*/
|
||||||
struct list_head others;
|
struct list_head others;
|
||||||
time_t nextcheck;
|
time64_t nextcheck;
|
||||||
int entries;
|
int entries;
|
||||||
|
|
||||||
/* fields for communication over channel */
|
/* fields for communication over channel */
|
||||||
struct list_head queue;
|
struct list_head queue;
|
||||||
|
|
||||||
atomic_t writers; /* how many time is /channel open */
|
atomic_t writers; /* how many time is /channel open */
|
||||||
time_t last_close; /* if no writers, when did last close */
|
time64_t last_close; /* if no writers, when did last close */
|
||||||
time_t last_warn; /* when we last warned about no writers */
|
time64_t last_warn; /* when we last warned about no writers */
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct proc_dir_entry *procfs;
|
struct proc_dir_entry *procfs;
|
||||||
@ -147,18 +147,22 @@ struct cache_deferred_req {
|
|||||||
* timestamps kept in the cache are expressed in seconds
|
* timestamps kept in the cache are expressed in seconds
|
||||||
* since boot. This is the best for measuring differences in
|
* since boot. This is the best for measuring differences in
|
||||||
* real time.
|
* 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;
|
struct timespec64 boot;
|
||||||
getboottime(&boot);
|
getboottime64(&boot);
|
||||||
return get_seconds() - boot.tv_sec;
|
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;
|
struct timespec64 boot;
|
||||||
getboottime(&boot);
|
getboottime64(&boot);
|
||||||
return boot.tv_sec + sinceboot;
|
return boot.tv_sec + sinceboot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +277,7 @@ static inline int get_uint(char **bpp, unsigned int *anint)
|
|||||||
return 0;
|
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];
|
char buf[50];
|
||||||
long long ll;
|
long long ll;
|
||||||
@ -287,20 +291,20 @@ static inline int get_time(char **bpp, time_t *time)
|
|||||||
if (kstrtoll(buf, 0, &ll))
|
if (kstrtoll(buf, 0, &ll))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
*time = (time_t)ll;
|
*time = ll;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline time_t get_expiry(char **bpp)
|
static inline time64_t get_expiry(char **bpp)
|
||||||
{
|
{
|
||||||
time_t rv;
|
time64_t rv;
|
||||||
struct timespec boot;
|
struct timespec64 boot;
|
||||||
|
|
||||||
if (get_time(bpp, &rv))
|
if (get_time(bpp, &rv))
|
||||||
return 0;
|
return 0;
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
return 0;
|
return 0;
|
||||||
getboottime(&boot);
|
getboottime64(&boot);
|
||||||
return rv - boot.tv_sec;
|
return rv - boot.tv_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ static int rsi_parse(struct cache_detail *cd,
|
|||||||
char *ep;
|
char *ep;
|
||||||
int len;
|
int len;
|
||||||
struct rsi rsii, *rsip = NULL;
|
struct rsi rsii, *rsip = NULL;
|
||||||
time_t expiry;
|
time64_t expiry;
|
||||||
int status = -EINVAL;
|
int status = -EINVAL;
|
||||||
|
|
||||||
memset(&rsii, 0, sizeof(rsii));
|
memset(&rsii, 0, sizeof(rsii));
|
||||||
|
@ -42,7 +42,7 @@ static bool cache_listeners_exist(struct cache_detail *detail);
|
|||||||
|
|
||||||
static void cache_init(struct cache_head *h, struct cache_detail *detail)
|
static void cache_init(struct cache_head *h, struct cache_detail *detail)
|
||||||
{
|
{
|
||||||
time_t now = seconds_since_boot();
|
time64_t now = seconds_since_boot();
|
||||||
INIT_HLIST_NODE(&h->cache_list);
|
INIT_HLIST_NODE(&h->cache_list);
|
||||||
h->flags = 0;
|
h->flags = 0;
|
||||||
kref_init(&h->ref);
|
kref_init(&h->ref);
|
||||||
@ -139,10 +139,10 @@ EXPORT_SYMBOL_GPL(sunrpc_cache_lookup_rcu);
|
|||||||
|
|
||||||
static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch);
|
static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch);
|
||||||
|
|
||||||
static void cache_fresh_locked(struct cache_head *head, time_t expiry,
|
static void cache_fresh_locked(struct cache_head *head, time64_t expiry,
|
||||||
struct cache_detail *detail)
|
struct cache_detail *detail)
|
||||||
{
|
{
|
||||||
time_t now = seconds_since_boot();
|
time64_t now = seconds_since_boot();
|
||||||
if (now <= detail->flush_time)
|
if (now <= detail->flush_time)
|
||||||
/* ensure it isn't immediately treated as expired */
|
/* ensure it isn't immediately treated as expired */
|
||||||
now = detail->flush_time + 1;
|
now = detail->flush_time + 1;
|
||||||
@ -274,7 +274,7 @@ int cache_check(struct cache_detail *detail,
|
|||||||
struct cache_head *h, struct cache_req *rqstp)
|
struct cache_head *h, struct cache_req *rqstp)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
long refresh_age, age;
|
time64_t refresh_age, age;
|
||||||
|
|
||||||
/* First decide return status as best we can */
|
/* First decide return status as best we can */
|
||||||
rv = cache_is_valid(h);
|
rv = cache_is_valid(h);
|
||||||
@ -288,7 +288,7 @@ int cache_check(struct cache_detail *detail,
|
|||||||
rv = -ENOENT;
|
rv = -ENOENT;
|
||||||
} else if (rv == -EAGAIN ||
|
} else if (rv == -EAGAIN ||
|
||||||
(h->expiry_time != 0 && age > refresh_age/2)) {
|
(h->expiry_time != 0 && age > refresh_age/2)) {
|
||||||
dprintk("RPC: Want update, refage=%ld, age=%ld\n",
|
dprintk("RPC: Want update, refage=%lld, age=%lld\n",
|
||||||
refresh_age, age);
|
refresh_age, age);
|
||||||
if (!test_and_set_bit(CACHE_PENDING, &h->flags)) {
|
if (!test_and_set_bit(CACHE_PENDING, &h->flags)) {
|
||||||
switch (cache_make_upcall(detail, h)) {
|
switch (cache_make_upcall(detail, h)) {
|
||||||
@ -1404,7 +1404,7 @@ static int c_show(struct seq_file *m, void *p)
|
|||||||
return cd->cache_show(m, cd, NULL);
|
return cd->cache_show(m, cd, NULL);
|
||||||
|
|
||||||
ifdebug(CACHE)
|
ifdebug(CACHE)
|
||||||
seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n",
|
seq_printf(m, "# expiry=%lld refcnt=%d flags=%lx\n",
|
||||||
convert_to_wallclock(cp->expiry_time),
|
convert_to_wallclock(cp->expiry_time),
|
||||||
kref_read(&cp->ref), cp->flags);
|
kref_read(&cp->ref), cp->flags);
|
||||||
cache_get(cp);
|
cache_get(cp);
|
||||||
@ -1477,7 +1477,7 @@ static ssize_t read_flush(struct file *file, char __user *buf,
|
|||||||
char tbuf[22];
|
char tbuf[22];
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
len = snprintf(tbuf, sizeof(tbuf), "%lu\n",
|
len = snprintf(tbuf, sizeof(tbuf), "%llu\n",
|
||||||
convert_to_wallclock(cd->flush_time));
|
convert_to_wallclock(cd->flush_time));
|
||||||
return simple_read_from_buffer(buf, count, ppos, tbuf, len);
|
return simple_read_from_buffer(buf, count, ppos, tbuf, len);
|
||||||
}
|
}
|
||||||
@ -1488,7 +1488,7 @@ static ssize_t write_flush(struct file *file, const char __user *buf,
|
|||||||
{
|
{
|
||||||
char tbuf[20];
|
char tbuf[20];
|
||||||
char *ep;
|
char *ep;
|
||||||
time_t now;
|
time64_t now;
|
||||||
|
|
||||||
if (*ppos || count > sizeof(tbuf)-1)
|
if (*ppos || count > sizeof(tbuf)-1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -166,7 +166,7 @@ static void ip_map_request(struct cache_detail *cd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr);
|
static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr);
|
||||||
static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time_t expiry);
|
static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time64_t expiry);
|
||||||
|
|
||||||
static int ip_map_parse(struct cache_detail *cd,
|
static int ip_map_parse(struct cache_detail *cd,
|
||||||
char *mesg, int mlen)
|
char *mesg, int mlen)
|
||||||
@ -187,7 +187,7 @@ static int ip_map_parse(struct cache_detail *cd,
|
|||||||
|
|
||||||
struct ip_map *ipmp;
|
struct ip_map *ipmp;
|
||||||
struct auth_domain *dom;
|
struct auth_domain *dom;
|
||||||
time_t expiry;
|
time64_t expiry;
|
||||||
|
|
||||||
if (mesg[mlen-1] != '\n')
|
if (mesg[mlen-1] != '\n')
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -308,7 +308,7 @@ static inline struct ip_map *ip_map_lookup(struct net *net, char *class,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
|
static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
|
||||||
struct unix_domain *udom, time_t expiry)
|
struct unix_domain *udom, time64_t expiry)
|
||||||
{
|
{
|
||||||
struct ip_map ip;
|
struct ip_map ip;
|
||||||
struct cache_head *ch;
|
struct cache_head *ch;
|
||||||
@ -328,7 +328,7 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline int ip_map_update(struct net *net, struct ip_map *ipm,
|
static inline int ip_map_update(struct net *net, struct ip_map *ipm,
|
||||||
struct unix_domain *udom, time_t expiry)
|
struct unix_domain *udom, time64_t expiry)
|
||||||
{
|
{
|
||||||
struct sunrpc_net *sn;
|
struct sunrpc_net *sn;
|
||||||
|
|
||||||
@ -491,7 +491,7 @@ static int unix_gid_parse(struct cache_detail *cd,
|
|||||||
int rv;
|
int rv;
|
||||||
int i;
|
int i;
|
||||||
int err;
|
int err;
|
||||||
time_t expiry;
|
time64_t expiry;
|
||||||
struct unix_gid ug, *ugp;
|
struct unix_gid ug, *ugp;
|
||||||
|
|
||||||
if (mesg[mlen - 1] != '\n')
|
if (mesg[mlen - 1] != '\n')
|
||||||
|
Loading…
Reference in New Issue
Block a user