diff options
-rw-r--r-- | fs/nfs/dns_resolve.c | 6 | ||||
-rw-r--r-- | fs/nfsd/nfs4idmap.c | 2 | ||||
-rw-r--r-- | include/linux/sunrpc/cache.h | 28 | ||||
-rw-r--r-- | net/sunrpc/cache.c | 36 |
4 files changed, 48 insertions, 24 deletions
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c index dba50a5625db..a6e711ad130f 100644 --- a/fs/nfs/dns_resolve.c +++ b/fs/nfs/dns_resolve.c | |||
@@ -167,7 +167,7 @@ static int nfs_dns_show(struct seq_file *m, struct cache_detail *cd, | |||
167 | return 0; | 167 | return 0; |
168 | } | 168 | } |
169 | item = container_of(h, struct nfs_dns_ent, h); | 169 | item = container_of(h, struct nfs_dns_ent, h); |
170 | ttl = (long)item->h.expiry_time - (long)get_seconds(); | 170 | ttl = item->h.expiry_time - seconds_since_boot(); |
171 | if (ttl < 0) | 171 | if (ttl < 0) |
172 | ttl = 0; | 172 | ttl = 0; |
173 | 173 | ||
@@ -239,7 +239,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) | |||
239 | ttl = get_expiry(&buf); | 239 | ttl = get_expiry(&buf); |
240 | if (ttl == 0) | 240 | if (ttl == 0) |
241 | goto out; | 241 | goto out; |
242 | key.h.expiry_time = ttl + get_seconds(); | 242 | key.h.expiry_time = ttl + seconds_since_boot(); |
243 | 243 | ||
244 | ret = -ENOMEM; | 244 | ret = -ENOMEM; |
245 | item = nfs_dns_lookup(cd, &key); | 245 | item = nfs_dns_lookup(cd, &key); |
@@ -301,7 +301,7 @@ static int do_cache_lookup_nowait(struct cache_detail *cd, | |||
301 | goto out_err; | 301 | goto out_err; |
302 | ret = -ETIMEDOUT; | 302 | ret = -ETIMEDOUT; |
303 | if (!test_bit(CACHE_VALID, &(*item)->h.flags) | 303 | if (!test_bit(CACHE_VALID, &(*item)->h.flags) |
304 | || (*item)->h.expiry_time < get_seconds() | 304 | || (*item)->h.expiry_time < seconds_since_boot() |
305 | || cd->flush_time > (*item)->h.last_refresh) | 305 | || cd->flush_time > (*item)->h.last_refresh) |
306 | goto out_put; | 306 | goto out_put; |
307 | ret = -ENOENT; | 307 | ret = -ENOENT; |
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index c78dbf493424..808b33a4a090 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c | |||
@@ -550,7 +550,7 @@ do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *), | |||
550 | goto out_err; | 550 | goto out_err; |
551 | ret = -ETIMEDOUT; | 551 | ret = -ETIMEDOUT; |
552 | if (!test_bit(CACHE_VALID, &(*item)->h.flags) | 552 | if (!test_bit(CACHE_VALID, &(*item)->h.flags) |
553 | || (*item)->h.expiry_time < get_seconds() | 553 | || (*item)->h.expiry_time < seconds_since_boot() |
554 | || detail->flush_time > (*item)->h.last_refresh) | 554 | || detail->flush_time > (*item)->h.last_refresh) |
555 | goto out_put; | 555 | goto out_put; |
556 | ret = -ENOENT; | 556 | ret = -ENOENT; |
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h index 0e1febf4e5bc..ece432b7f87f 100644 --- a/include/linux/sunrpc/cache.h +++ b/include/linux/sunrpc/cache.h | |||
@@ -218,20 +218,42 @@ static inline int get_int(char **bpp, int *anint) | |||
218 | return 0; | 218 | return 0; |
219 | } | 219 | } |
220 | 220 | ||
221 | /* | ||
222 | * timestamps kept in the cache are expressed in seconds | ||
223 | * since boot. This is the best for measuring differences in | ||
224 | * real time. | ||
225 | */ | ||
226 | static inline time_t seconds_since_boot(void) | ||
227 | { | ||
228 | struct timespec boot; | ||
229 | getboottime(&boot); | ||
230 | return get_seconds() - boot.tv_sec; | ||
231 | } | ||
232 | |||
233 | static inline time_t convert_to_wallclock(time_t sinceboot) | ||
234 | { | ||
235 | struct timespec boot; | ||
236 | getboottime(&boot); | ||
237 | return boot.tv_sec + sinceboot; | ||
238 | } | ||
239 | |||
221 | static inline time_t get_expiry(char **bpp) | 240 | static inline time_t get_expiry(char **bpp) |
222 | { | 241 | { |
223 | int rv; | 242 | int rv; |
243 | struct timespec boot; | ||
244 | |||
224 | if (get_int(bpp, &rv)) | 245 | if (get_int(bpp, &rv)) |
225 | return 0; | 246 | return 0; |
226 | if (rv < 0) | 247 | if (rv < 0) |
227 | return 0; | 248 | return 0; |
228 | return rv; | 249 | getboottime(&boot); |
250 | return rv - boot.tv_sec; | ||
229 | } | 251 | } |
230 | 252 | ||
231 | static inline void sunrpc_invalidate(struct cache_head *h, | 253 | static inline void sunrpc_invalidate(struct cache_head *h, |
232 | struct cache_detail *detail) | 254 | struct cache_detail *detail) |
233 | { | 255 | { |
234 | h->expiry_time = get_seconds() - 1; | 256 | h->expiry_time = seconds_since_boot() - 1; |
235 | detail->nextcheck = get_seconds(); | 257 | detail->nextcheck = seconds_since_boot(); |
236 | } | 258 | } |
237 | #endif /* _LINUX_SUNRPC_CACHE_H_ */ | 259 | #endif /* _LINUX_SUNRPC_CACHE_H_ */ |
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 2b06410e584e..8dc121955fdc 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c | |||
@@ -42,7 +42,7 @@ static void cache_revisit_request(struct cache_head *item); | |||
42 | 42 | ||
43 | static void cache_init(struct cache_head *h) | 43 | static void cache_init(struct cache_head *h) |
44 | { | 44 | { |
45 | time_t now = get_seconds(); | 45 | time_t now = seconds_since_boot(); |
46 | h->next = NULL; | 46 | h->next = NULL; |
47 | h->flags = 0; | 47 | h->flags = 0; |
48 | kref_init(&h->ref); | 48 | kref_init(&h->ref); |
@@ -52,7 +52,7 @@ static void cache_init(struct cache_head *h) | |||
52 | 52 | ||
53 | static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h) | 53 | static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h) |
54 | { | 54 | { |
55 | return (h->expiry_time < get_seconds()) || | 55 | return (h->expiry_time < seconds_since_boot()) || |
56 | (detail->flush_time > h->last_refresh); | 56 | (detail->flush_time > h->last_refresh); |
57 | } | 57 | } |
58 | 58 | ||
@@ -127,7 +127,7 @@ static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch); | |||
127 | static void cache_fresh_locked(struct cache_head *head, time_t expiry) | 127 | static void cache_fresh_locked(struct cache_head *head, time_t expiry) |
128 | { | 128 | { |
129 | head->expiry_time = expiry; | 129 | head->expiry_time = expiry; |
130 | head->last_refresh = get_seconds(); | 130 | head->last_refresh = seconds_since_boot(); |
131 | set_bit(CACHE_VALID, &head->flags); | 131 | set_bit(CACHE_VALID, &head->flags); |
132 | } | 132 | } |
133 | 133 | ||
@@ -238,7 +238,7 @@ int cache_check(struct cache_detail *detail, | |||
238 | 238 | ||
239 | /* now see if we want to start an upcall */ | 239 | /* now see if we want to start an upcall */ |
240 | refresh_age = (h->expiry_time - h->last_refresh); | 240 | refresh_age = (h->expiry_time - h->last_refresh); |
241 | age = get_seconds() - h->last_refresh; | 241 | age = seconds_since_boot() - h->last_refresh; |
242 | 242 | ||
243 | if (rqstp == NULL) { | 243 | if (rqstp == NULL) { |
244 | if (rv == -EAGAIN) | 244 | if (rv == -EAGAIN) |
@@ -253,7 +253,7 @@ int cache_check(struct cache_detail *detail, | |||
253 | cache_revisit_request(h); | 253 | cache_revisit_request(h); |
254 | if (rv == -EAGAIN) { | 254 | if (rv == -EAGAIN) { |
255 | set_bit(CACHE_NEGATIVE, &h->flags); | 255 | set_bit(CACHE_NEGATIVE, &h->flags); |
256 | cache_fresh_locked(h, get_seconds()+CACHE_NEW_EXPIRY); | 256 | cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY); |
257 | cache_fresh_unlocked(h, detail); | 257 | cache_fresh_unlocked(h, detail); |
258 | rv = -ENOENT; | 258 | rv = -ENOENT; |
259 | } | 259 | } |
@@ -388,11 +388,11 @@ static int cache_clean(void) | |||
388 | return -1; | 388 | return -1; |
389 | } | 389 | } |
390 | current_detail = list_entry(next, struct cache_detail, others); | 390 | current_detail = list_entry(next, struct cache_detail, others); |
391 | if (current_detail->nextcheck > get_seconds()) | 391 | if (current_detail->nextcheck > seconds_since_boot()) |
392 | current_index = current_detail->hash_size; | 392 | current_index = current_detail->hash_size; |
393 | else { | 393 | else { |
394 | current_index = 0; | 394 | current_index = 0; |
395 | current_detail->nextcheck = get_seconds()+30*60; | 395 | current_detail->nextcheck = seconds_since_boot()+30*60; |
396 | } | 396 | } |
397 | } | 397 | } |
398 | 398 | ||
@@ -477,7 +477,7 @@ EXPORT_SYMBOL_GPL(cache_flush); | |||
477 | void cache_purge(struct cache_detail *detail) | 477 | void cache_purge(struct cache_detail *detail) |
478 | { | 478 | { |
479 | detail->flush_time = LONG_MAX; | 479 | detail->flush_time = LONG_MAX; |
480 | detail->nextcheck = get_seconds(); | 480 | detail->nextcheck = seconds_since_boot(); |
481 | cache_flush(); | 481 | cache_flush(); |
482 | detail->flush_time = 1; | 482 | detail->flush_time = 1; |
483 | } | 483 | } |
@@ -902,7 +902,7 @@ static int cache_release(struct inode *inode, struct file *filp, | |||
902 | filp->private_data = NULL; | 902 | filp->private_data = NULL; |
903 | kfree(rp); | 903 | kfree(rp); |
904 | 904 | ||
905 | cd->last_close = get_seconds(); | 905 | cd->last_close = seconds_since_boot(); |
906 | atomic_dec(&cd->readers); | 906 | atomic_dec(&cd->readers); |
907 | } | 907 | } |
908 | module_put(cd->owner); | 908 | module_put(cd->owner); |
@@ -1034,7 +1034,7 @@ int sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h, | |||
1034 | int len; | 1034 | int len; |
1035 | 1035 | ||
1036 | if (atomic_read(&detail->readers) == 0 && | 1036 | if (atomic_read(&detail->readers) == 0 && |
1037 | detail->last_close < get_seconds() - 30) { | 1037 | detail->last_close < seconds_since_boot() - 30) { |
1038 | warn_no_listener(detail); | 1038 | warn_no_listener(detail); |
1039 | return -EINVAL; | 1039 | return -EINVAL; |
1040 | } | 1040 | } |
@@ -1219,7 +1219,8 @@ static int c_show(struct seq_file *m, void *p) | |||
1219 | 1219 | ||
1220 | ifdebug(CACHE) | 1220 | ifdebug(CACHE) |
1221 | seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n", | 1221 | seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n", |
1222 | cp->expiry_time, atomic_read(&cp->ref.refcount), cp->flags); | 1222 | convert_to_wallclock(cp->expiry_time), |
1223 | atomic_read(&cp->ref.refcount), cp->flags); | ||
1223 | cache_get(cp); | 1224 | cache_get(cp); |
1224 | if (cache_check(cd, cp, NULL)) | 1225 | if (cache_check(cd, cp, NULL)) |
1225 | /* cache_check does a cache_put on failure */ | 1226 | /* cache_check does a cache_put on failure */ |
@@ -1285,7 +1286,7 @@ static ssize_t read_flush(struct file *file, char __user *buf, | |||
1285 | unsigned long p = *ppos; | 1286 | unsigned long p = *ppos; |
1286 | size_t len; | 1287 | size_t len; |
1287 | 1288 | ||
1288 | sprintf(tbuf, "%lu\n", cd->flush_time); | 1289 | sprintf(tbuf, "%lu\n", convert_to_wallclock(cd->flush_time)); |
1289 | len = strlen(tbuf); | 1290 | len = strlen(tbuf); |
1290 | if (p >= len) | 1291 | if (p >= len) |
1291 | return 0; | 1292 | return 0; |
@@ -1303,19 +1304,20 @@ static ssize_t write_flush(struct file *file, const char __user *buf, | |||
1303 | struct cache_detail *cd) | 1304 | struct cache_detail *cd) |
1304 | { | 1305 | { |
1305 | char tbuf[20]; | 1306 | char tbuf[20]; |
1306 | char *ep; | 1307 | char *bp, *ep; |
1307 | long flushtime; | 1308 | |
1308 | if (*ppos || count > sizeof(tbuf)-1) | 1309 | if (*ppos || count > sizeof(tbuf)-1) |
1309 | return -EINVAL; | 1310 | return -EINVAL; |
1310 | if (copy_from_user(tbuf, buf, count)) | 1311 | if (copy_from_user(tbuf, buf, count)) |
1311 | return -EFAULT; | 1312 | return -EFAULT; |
1312 | tbuf[count] = 0; | 1313 | tbuf[count] = 0; |
1313 | flushtime = simple_strtoul(tbuf, &ep, 0); | 1314 | simple_strtoul(tbuf, &ep, 0); |
1314 | if (*ep && *ep != '\n') | 1315 | if (*ep && *ep != '\n') |
1315 | return -EINVAL; | 1316 | return -EINVAL; |
1316 | 1317 | ||
1317 | cd->flush_time = flushtime; | 1318 | bp = tbuf; |
1318 | cd->nextcheck = get_seconds(); | 1319 | cd->flush_time = get_expiry(&bp); |
1320 | cd->nextcheck = seconds_since_boot(); | ||
1319 | cache_flush(); | 1321 | cache_flush(); |
1320 | 1322 | ||
1321 | *ppos += count; | 1323 | *ppos += count; |