Skip to content

Commit ded2f4c

Browse files
committed
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 <[email protected]>
1 parent 0a5143f commit ded2f4c

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

fs/afs/cell.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "internal.h"
2121

2222
static unsigned __read_mostly afs_cell_gc_delay = 10;
23+
static unsigned __read_mostly afs_cell_min_ttl = 10 * 60;
24+
static unsigned __read_mostly afs_cell_max_ttl = 24 * 60 * 60;
2325

2426
static void afs_manage_cell(struct work_struct *);
2527

@@ -171,6 +173,8 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net,
171173

172174
rcu_assign_pointer(cell->vl_servers, vllist);
173175
cell->dns_expiry = TIME64_MAX;
176+
} else {
177+
cell->dns_expiry = ktime_get_real_seconds();
174178
}
175179

176180
_leave(" = %p", cell);
@@ -358,25 +362,39 @@ int afs_cell_init(struct afs_net *net, const char *rootcell)
358362
static void afs_update_cell(struct afs_cell *cell)
359363
{
360364
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;
362368

363369
_enter("%s", cell->name);
364370

365371
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+
366381
if (IS_ERR(vllist)) {
367382
switch (PTR_ERR(vllist)) {
368383
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+
*/
370388
set_bit(AFS_CELL_FL_NOT_FOUND, &cell->flags);
371389
clear_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags);
372-
cell->dns_expiry = ktime_get_real_seconds() + 61;
390+
cell->dns_expiry = expiry;
373391
break;
374392

375393
case -EAGAIN:
376394
case -ECONNREFUSED:
377395
default:
378396
set_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags);
379-
cell->dns_expiry = ktime_get_real_seconds() + 10;
397+
cell->dns_expiry = now + 10;
380398
break;
381399
}
382400

fs/afs/proc.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,24 @@ static inline struct afs_net *afs_seq2net_single(struct seq_file *m)
3737
*/
3838
static int afs_proc_cells_show(struct seq_file *m, void *v)
3939
{
40-
struct afs_cell *cell = list_entry(v, struct afs_cell, proc_link);
40+
struct afs_vlserver_list *vllist;
41+
struct afs_cell *cell;
4142

4243
if (v == SEQ_START_TOKEN) {
4344
/* display header on line 1 */
44-
seq_puts(m, "USE NAME\n");
45+
seq_puts(m, "USE TTL SV NAME\n");
4546
return 0;
4647
}
4748

49+
cell = list_entry(v, struct afs_cell, proc_link);
50+
vllist = rcu_dereference(cell->vl_servers);
51+
4852
/* 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);
5058
return 0;
5159
}
5260

0 commit comments

Comments
 (0)