aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/cache.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-08-12 02:55:22 -0400
committerJ. Bruce Fields <bfields@redhat.com>2010-09-07 19:21:20 -0400
commitc5b29f885afe890f953f7f23424045cdad31d3e4 (patch)
treecc2016f256da966974b4ed7a24ff9378a77facb2 /net/sunrpc/cache.c
parent17cebf658e088935d4bdebfc7ad9800e9fc4a0b2 (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/sunrpc/cache.c')
-rw-r--r--net/sunrpc/cache.c36
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
43static void cache_init(struct cache_head *h) 43static 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
53static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h) 53static 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);
127static void cache_fresh_locked(struct cache_head *head, time_t expiry) 127static 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);
477void cache_purge(struct cache_detail *detail) 477void 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;