diff options
author | NeilBrown <neilb@suse.de> | 2010-08-12 02:55:22 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2010-09-07 19:21:20 -0400 |
commit | c5b29f885afe890f953f7f23424045cdad31d3e4 (patch) | |
tree | cc2016f256da966974b4ed7a24ff9378a77facb2 /net | |
parent | 17cebf658e088935d4bdebfc7ad9800e9fc4a0b2 (diff) |
sunrpc: use seconds since boot in expiry cache
This protects us from confusion when the wallclock time changes.
We convert to and from wallclock when setting or reading expiry
times.
Also use seconds since boot for last_clost time.
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/cache.c | 36 |
1 files changed, 19 insertions, 17 deletions
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; |