Skip to content

Commit 8100680

Browse files
committed
afs: Use the serverUnique field in the UVLDB record to reduce rpc ops
The U-version VLDB volume record retrieved by the VL.GetEntryByNameU rpc op carries a change counter (the serverUnique field) for each fileserver listed in the record as backing that volume. This is incremented whenever the registration details for a fileserver change (such as its address list). Note that the same value will be seen in all UVLDB records that refer to that fileserver. This should be checked before calling the VL server to re-query the address list for a fileserver. If it's the same, there's no point doing the query. Reported-by: Jeffrey Altman <[email protected]> Signed-off-by: David Howells <[email protected]>
1 parent 13fcc63 commit 8100680

File tree

4 files changed

+20
-15
lines changed

4 files changed

+20
-15
lines changed

fs/afs/internal.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ struct afs_vldb_entry {
471471
#define AFS_VLDB_QUERY_ERROR 4 /* - VL server returned error */
472472

473473
uuid_t fs_server[AFS_NMAXNSERVERS];
474+
u32 addr_version[AFS_NMAXNSERVERS]; /* Registration change counters */
474475
u8 fs_mask[AFS_NMAXNSERVERS];
475476
#define AFS_VOL_VTM_RW 0x01 /* R/W version of the volume is available (on this server) */
476477
#define AFS_VOL_VTM_RO 0x02 /* R/O version of the volume is available (on this server) */
@@ -498,7 +499,6 @@ struct afs_server {
498499
struct hlist_node proc_link; /* Link in net->fs_proc */
499500
struct afs_server *gc_next; /* Next server in manager's list */
500501
time64_t put_time; /* Time at which last put */
501-
time64_t update_at; /* Time at which to next update the record */
502502
unsigned long flags;
503503
#define AFS_SERVER_FL_NOT_READY 1 /* The record is not ready for use */
504504
#define AFS_SERVER_FL_NOT_FOUND 2 /* VL server says no such server */
@@ -511,6 +511,7 @@ struct afs_server {
511511
#define AFS_SERVER_FL_IS_YFS 9 /* Server is YFS not AFS */
512512
#define AFS_SERVER_FL_NO_RM2 10 /* Fileserver doesn't support YFS.RemoveFile2 */
513513
#define AFS_SERVER_FL_HAVE_EPOCH 11 /* ->epoch is valid */
514+
#define AFS_SERVER_FL_NEEDS_UPDATE 12 /* Fileserver address list is out of date */
514515
atomic_t usage;
515516
u32 addr_version; /* Address list version */
516517
u32 cm_epoch; /* Server RxRPC epoch */
@@ -1241,7 +1242,7 @@ extern spinlock_t afs_server_peer_lock;
12411242
extern struct afs_server *afs_find_server(struct afs_net *,
12421243
const struct sockaddr_rxrpc *);
12431244
extern struct afs_server *afs_find_server_by_uuid(struct afs_net *, const uuid_t *);
1244-
extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *);
1245+
extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *, u32);
12451246
extern struct afs_server *afs_get_server(struct afs_server *, enum afs_server_trace);
12461247
extern void afs_put_server(struct afs_net *, struct afs_server *, enum afs_server_trace);
12471248
extern void afs_manage_servers(struct work_struct *);

fs/afs/server.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include "protocol_yfs.h"
1313

1414
static unsigned afs_server_gc_delay = 10; /* Server record timeout in seconds */
15-
static unsigned afs_server_update_delay = 30; /* Time till VLDB recheck in secs */
1615
static atomic_t afs_server_debug_id;
1716

1817
static void afs_inc_servers_outstanding(struct afs_net *net)
@@ -218,7 +217,6 @@ static struct afs_server *afs_alloc_server(struct afs_net *net,
218217
RCU_INIT_POINTER(server->addresses, alist);
219218
server->addr_version = alist->version;
220219
server->uuid = *uuid;
221-
server->update_at = ktime_get_real_seconds() + afs_server_update_delay;
222220
rwlock_init(&server->fs_lock);
223221
INIT_HLIST_HEAD(&server->cb_volumes);
224222
rwlock_init(&server->cb_break_lock);
@@ -264,16 +262,19 @@ static struct afs_addr_list *afs_vl_lookup_addrs(struct afs_cell *cell,
264262
* Get or create a fileserver record.
265263
*/
266264
struct afs_server *afs_lookup_server(struct afs_cell *cell, struct key *key,
267-
const uuid_t *uuid)
265+
const uuid_t *uuid, u32 addr_version)
268266
{
269267
struct afs_addr_list *alist;
270268
struct afs_server *server, *candidate;
271269

272270
_enter("%p,%pU", cell->net, uuid);
273271

274272
server = afs_find_server_by_uuid(cell->net, uuid);
275-
if (server)
273+
if (server) {
274+
if (server->addr_version != addr_version)
275+
set_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
276276
return server;
277+
}
277278

278279
alist = afs_vl_lookup_addrs(cell, key, uuid);
279280
if (IS_ERR(alist))
@@ -558,7 +559,6 @@ static noinline bool afs_update_server_record(struct afs_fs_cursor *fc, struct a
558559
write_unlock(&server->fs_lock);
559560
}
560561

561-
server->update_at = ktime_get_real_seconds() + afs_server_update_delay;
562562
afs_put_addrlist(discard);
563563
_leave(" = t");
564564
return true;
@@ -569,8 +569,6 @@ static noinline bool afs_update_server_record(struct afs_fs_cursor *fc, struct a
569569
*/
570570
bool afs_check_server_record(struct afs_fs_cursor *fc, struct afs_server *server)
571571
{
572-
time64_t now = ktime_get_real_seconds();
573-
long diff;
574572
bool success;
575573
int ret, retries = 0;
576574

@@ -579,20 +577,24 @@ bool afs_check_server_record(struct afs_fs_cursor *fc, struct afs_server *server
579577
ASSERT(server);
580578

581579
retry:
582-
diff = READ_ONCE(server->update_at) - now;
583-
if (diff > 0) {
584-
_leave(" = t [not now %ld]", diff);
585-
return true;
586-
}
580+
if (test_bit(AFS_SERVER_FL_UPDATING, &server->flags))
581+
goto wait;
582+
if (test_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags))
583+
goto update;
584+
_leave(" = t [good]");
585+
return true;
587586

587+
update:
588588
if (!test_and_set_bit_lock(AFS_SERVER_FL_UPDATING, &server->flags)) {
589+
clear_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
589590
success = afs_update_server_record(fc, server);
590591
clear_bit_unlock(AFS_SERVER_FL_UPDATING, &server->flags);
591592
wake_up_bit(&server->flags, AFS_SERVER_FL_UPDATING);
592593
_leave(" = %d", success);
593594
return success;
594595
}
595596

597+
wait:
596598
ret = wait_on_bit(&server->flags, AFS_SERVER_FL_UPDATING,
597599
(fc->flags & AFS_FS_CURSOR_INTR) ?
598600
TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);

fs/afs/server_list.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell,
5151
if (!(vldb->fs_mask[i] & type_mask))
5252
continue;
5353

54-
server = afs_lookup_server(cell, key, &vldb->fs_server[i]);
54+
server = afs_lookup_server(cell, key, &vldb->fs_server[i],
55+
vldb->addr_version[i]);
5556
if (IS_ERR(server)) {
5657
ret = PTR_ERR(server);
5758
if (ret == -ENOENT ||

fs/afs/vlclient.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ static int afs_deliver_vl_get_entry_by_name_u(struct afs_call *call)
8282
for (j = 0; j < 6; j++)
8383
uuid->node[j] = (u8)ntohl(xdr->node[j]);
8484

85+
entry->addr_version[n] = ntohl(uvldb->serverUnique[i]);
8586
entry->nr_servers++;
8687
}
8788

0 commit comments

Comments
 (0)