aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-10-19 19:57:57 -0400
committerDavid Howells <dhowells@redhat.com>2018-10-23 19:41:07 -0400
commitded2f4c58ac24083c536aa7d2ff2b73752a88612 (patch)
tree0a62c14ed24f5d0367466ad6c112a15958cede94 /fs/afs
parent0a5143f2f89cc88d8a3eada8e8ccd86c1e988257 (diff)
afs: Fix TTL on VL server and address lists
Currently the TTL on VL server and address lists isn't set in all circumstances and may be set to poor choices in others, since the TTL is derived from the SRV/AFSDB DNS record if and when available. Fix the TTL by limiting the range to a minimum and maximum from the current time. At some point these can be made into sysctl knobs. Further, use the TTL we obtained from the upcall to set the expiry on negative results too; in future a mechanism can be added to force reloading of such data. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs')
-rw-r--r--fs/afs/cell.c26
-rw-r--r--fs/afs/proc.c14
2 files changed, 33 insertions, 7 deletions
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index 963b6fa51fdf..cf445dbd5f2e 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -20,6 +20,8 @@
20#include "internal.h" 20#include "internal.h"
21 21
22static unsigned __read_mostly afs_cell_gc_delay = 10; 22static unsigned __read_mostly afs_cell_gc_delay = 10;
23static unsigned __read_mostly afs_cell_min_ttl = 10 * 60;
24static unsigned __read_mostly afs_cell_max_ttl = 24 * 60 * 60;
23 25
24static void afs_manage_cell(struct work_struct *); 26static void afs_manage_cell(struct work_struct *);
25 27
@@ -171,6 +173,8 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net,
171 173
172 rcu_assign_pointer(cell->vl_servers, vllist); 174 rcu_assign_pointer(cell->vl_servers, vllist);
173 cell->dns_expiry = TIME64_MAX; 175 cell->dns_expiry = TIME64_MAX;
176 } else {
177 cell->dns_expiry = ktime_get_real_seconds();
174 } 178 }
175 179
176 _leave(" = %p", cell); 180 _leave(" = %p", cell);
@@ -358,25 +362,39 @@ int afs_cell_init(struct afs_net *net, const char *rootcell)
358static void afs_update_cell(struct afs_cell *cell) 362static void afs_update_cell(struct afs_cell *cell)
359{ 363{
360 struct afs_vlserver_list *vllist, *old; 364 struct afs_vlserver_list *vllist, *old;
361 time64_t now, expiry; 365 unsigned int min_ttl = READ_ONCE(afs_cell_min_ttl);
366 unsigned int max_ttl = READ_ONCE(afs_cell_max_ttl);
367 time64_t now, expiry = 0;
362 368
363 _enter("%s", cell->name); 369 _enter("%s", cell->name);
364 370
365 vllist = afs_dns_query(cell, &expiry); 371 vllist = afs_dns_query(cell, &expiry);
372
373 now = ktime_get_real_seconds();
374 if (min_ttl > max_ttl)
375 max_ttl = min_ttl;
376 if (expiry < now + min_ttl)
377 expiry = now + min_ttl;
378 else if (expiry > now + max_ttl)
379 expiry = now + max_ttl;
380
366 if (IS_ERR(vllist)) { 381 if (IS_ERR(vllist)) {
367 switch (PTR_ERR(vllist)) { 382 switch (PTR_ERR(vllist)) {
368 case -ENODATA: 383 case -ENODATA:
369 /* The DNS said that the cell does not exist */ 384 case -EDESTADDRREQ:
385 /* The DNS said that the cell does not exist or there
386 * weren't any addresses to be had.
387 */
370 set_bit(AFS_CELL_FL_NOT_FOUND, &cell->flags); 388 set_bit(AFS_CELL_FL_NOT_FOUND, &cell->flags);
371 clear_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags); 389 clear_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags);
372 cell->dns_expiry = ktime_get_real_seconds() + 61; 390 cell->dns_expiry = expiry;
373 break; 391 break;
374 392
375 case -EAGAIN: 393 case -EAGAIN:
376 case -ECONNREFUSED: 394 case -ECONNREFUSED:
377 default: 395 default:
378 set_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags); 396 set_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags);
379 cell->dns_expiry = ktime_get_real_seconds() + 10; 397 cell->dns_expiry = now + 10;
380 break; 398 break;
381 } 399 }
382 400
diff --git a/fs/afs/proc.c b/fs/afs/proc.c
index 6585f4bec0d3..fc36c41641ab 100644
--- a/fs/afs/proc.c
+++ b/fs/afs/proc.c
@@ -37,16 +37,24 @@ static inline struct afs_net *afs_seq2net_single(struct seq_file *m)
37 */ 37 */
38static int afs_proc_cells_show(struct seq_file *m, void *v) 38static int afs_proc_cells_show(struct seq_file *m, void *v)
39{ 39{
40 struct afs_cell *cell = list_entry(v, struct afs_cell, proc_link); 40 struct afs_vlserver_list *vllist;
41 struct afs_cell *cell;
41 42
42 if (v == SEQ_START_TOKEN) { 43 if (v == SEQ_START_TOKEN) {
43 /* display header on line 1 */ 44 /* display header on line 1 */
44 seq_puts(m, "USE NAME\n"); 45 seq_puts(m, "USE TTL SV NAME\n");
45 return 0; 46 return 0;
46 } 47 }
47 48
49 cell = list_entry(v, struct afs_cell, proc_link);
50 vllist = rcu_dereference(cell->vl_servers);
51
48 /* display one cell per line on subsequent lines */ 52 /* display one cell per line on subsequent lines */
49 seq_printf(m, "%3u %s\n", atomic_read(&cell->usage), cell->name); 53 seq_printf(m, "%3u %6lld %2u %s\n",
54 atomic_read(&cell->usage),
55 cell->dns_expiry - ktime_get_real_seconds(),
56 vllist ? vllist->nr_servers : 0,
57 cell->name);
50 return 0; 58 return 0;
51} 59}
52 60