#include "internal.h"
 
 static unsigned __read_mostly afs_cell_gc_delay = 10;
+static unsigned __read_mostly afs_cell_min_ttl = 10 * 60;
+static unsigned __read_mostly afs_cell_max_ttl = 24 * 60 * 60;
 
 static void afs_manage_cell(struct work_struct *);
 
 
                rcu_assign_pointer(cell->vl_servers, vllist);
                cell->dns_expiry = TIME64_MAX;
+       } else {
+               cell->dns_expiry = ktime_get_real_seconds();
        }
 
        _leave(" = %p", cell);
 static void afs_update_cell(struct afs_cell *cell)
 {
        struct afs_vlserver_list *vllist, *old;
-       time64_t now, expiry;
+       unsigned int min_ttl = READ_ONCE(afs_cell_min_ttl);
+       unsigned int max_ttl = READ_ONCE(afs_cell_max_ttl);
+       time64_t now, expiry = 0;
 
        _enter("%s", cell->name);
 
        vllist = afs_dns_query(cell, &expiry);
+
+       now = ktime_get_real_seconds();
+       if (min_ttl > max_ttl)
+               max_ttl = min_ttl;
+       if (expiry < now + min_ttl)
+               expiry = now + min_ttl;
+       else if (expiry > now + max_ttl)
+               expiry = now + max_ttl;
+
        if (IS_ERR(vllist)) {
                switch (PTR_ERR(vllist)) {
                case -ENODATA:
-                       /* The DNS said that the cell does not exist */
+               case -EDESTADDRREQ:
+                       /* The DNS said that the cell does not exist or there
+                        * weren't any addresses to be had.
+                        */
                        set_bit(AFS_CELL_FL_NOT_FOUND, &cell->flags);
                        clear_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags);
-                       cell->dns_expiry = ktime_get_real_seconds() + 61;
+                       cell->dns_expiry = expiry;
                        break;
 
                case -EAGAIN:
                case -ECONNREFUSED:
                default:
                        set_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags);
-                       cell->dns_expiry = ktime_get_real_seconds() + 10;
+                       cell->dns_expiry = now + 10;
                        break;
                }
 
 
  */
 static int afs_proc_cells_show(struct seq_file *m, void *v)
 {
-       struct afs_cell *cell = list_entry(v, struct afs_cell, proc_link);
+       struct afs_vlserver_list *vllist;
+       struct afs_cell *cell;
 
        if (v == SEQ_START_TOKEN) {
                /* display header on line 1 */
-               seq_puts(m, "USE NAME\n");
+               seq_puts(m, "USE    TTL SV NAME\n");
                return 0;
        }
 
+       cell = list_entry(v, struct afs_cell, proc_link);
+       vllist = rcu_dereference(cell->vl_servers);
+
        /* display one cell per line on subsequent lines */
-       seq_printf(m, "%3u %s\n", atomic_read(&cell->usage), cell->name);
+       seq_printf(m, "%3u %6lld %2u %s\n",
+                  atomic_read(&cell->usage),
+                  cell->dns_expiry - ktime_get_real_seconds(),
+                  vllist ? vllist->nr_servers : 0,
+                  cell->name);
        return 0;
 }