#define AFS_VLDB_QUERY_ERROR   4               /* - VL server returned error */
 
        uuid_t                  fs_server[AFS_NMAXNSERVERS];
+       u32                     addr_version[AFS_NMAXNSERVERS]; /* Registration change counters */
        u8                      fs_mask[AFS_NMAXNSERVERS];
 #define AFS_VOL_VTM_RW 0x01 /* R/W version of the volume is available (on this server) */
 #define AFS_VOL_VTM_RO 0x02 /* R/O version of the volume is available (on this server) */
        struct hlist_node       proc_link;      /* Link in net->fs_proc */
        struct afs_server       *gc_next;       /* Next server in manager's list */
        time64_t                put_time;       /* Time at which last put */
-       time64_t                update_at;      /* Time at which to next update the record */
        unsigned long           flags;
 #define AFS_SERVER_FL_NOT_READY        1               /* The record is not ready for use */
 #define AFS_SERVER_FL_NOT_FOUND        2               /* VL server says no such server */
 #define AFS_SERVER_FL_IS_YFS   9               /* Server is YFS not AFS */
 #define AFS_SERVER_FL_NO_RM2   10              /* Fileserver doesn't support YFS.RemoveFile2 */
 #define AFS_SERVER_FL_HAVE_EPOCH 11            /* ->epoch is valid */
+#define AFS_SERVER_FL_NEEDS_UPDATE 12          /* Fileserver address list is out of date */
        atomic_t                usage;
        u32                     addr_version;   /* Address list version */
        u32                     cm_epoch;       /* Server RxRPC epoch */
 extern struct afs_server *afs_find_server(struct afs_net *,
                                          const struct sockaddr_rxrpc *);
 extern struct afs_server *afs_find_server_by_uuid(struct afs_net *, const uuid_t *);
-extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *);
+extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *, u32);
 extern struct afs_server *afs_get_server(struct afs_server *, enum afs_server_trace);
 extern void afs_put_server(struct afs_net *, struct afs_server *, enum afs_server_trace);
 extern void afs_manage_servers(struct work_struct *);
 
 #include "protocol_yfs.h"
 
 static unsigned afs_server_gc_delay = 10;      /* Server record timeout in seconds */
-static unsigned afs_server_update_delay = 30;  /* Time till VLDB recheck in secs */
 static atomic_t afs_server_debug_id;
 
 static void afs_inc_servers_outstanding(struct afs_net *net)
        RCU_INIT_POINTER(server->addresses, alist);
        server->addr_version = alist->version;
        server->uuid = *uuid;
-       server->update_at = ktime_get_real_seconds() + afs_server_update_delay;
        rwlock_init(&server->fs_lock);
        INIT_HLIST_HEAD(&server->cb_volumes);
        rwlock_init(&server->cb_break_lock);
  * Get or create a fileserver record.
  */
 struct afs_server *afs_lookup_server(struct afs_cell *cell, struct key *key,
-                                    const uuid_t *uuid)
+                                    const uuid_t *uuid, u32 addr_version)
 {
        struct afs_addr_list *alist;
        struct afs_server *server, *candidate;
        _enter("%p,%pU", cell->net, uuid);
 
        server = afs_find_server_by_uuid(cell->net, uuid);
-       if (server)
+       if (server) {
+               if (server->addr_version != addr_version)
+                       set_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
                return server;
+       }
 
        alist = afs_vl_lookup_addrs(cell, key, uuid);
        if (IS_ERR(alist))
                write_unlock(&server->fs_lock);
        }
 
-       server->update_at = ktime_get_real_seconds() + afs_server_update_delay;
        afs_put_addrlist(discard);
        _leave(" = t");
        return true;
  */
 bool afs_check_server_record(struct afs_fs_cursor *fc, struct afs_server *server)
 {
-       time64_t now = ktime_get_real_seconds();
-       long diff;
        bool success;
        int ret, retries = 0;
 
        ASSERT(server);
 
 retry:
-       diff = READ_ONCE(server->update_at) - now;
-       if (diff > 0) {
-               _leave(" = t [not now %ld]", diff);
-               return true;
-       }
+       if (test_bit(AFS_SERVER_FL_UPDATING, &server->flags))
+               goto wait;
+       if (test_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags))
+               goto update;
+       _leave(" = t [good]");
+       return true;
 
+update:
        if (!test_and_set_bit_lock(AFS_SERVER_FL_UPDATING, &server->flags)) {
+               clear_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
                success = afs_update_server_record(fc, server);
                clear_bit_unlock(AFS_SERVER_FL_UPDATING, &server->flags);
                wake_up_bit(&server->flags, AFS_SERVER_FL_UPDATING);
                return success;
        }
 
+wait:
        ret = wait_on_bit(&server->flags, AFS_SERVER_FL_UPDATING,
                          (fc->flags & AFS_FS_CURSOR_INTR) ?
                          TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);