afs: Reorganise volume and server trees to be rooted on the cell

Reorganise afs_volume objects such that they're in a tree keyed on volume
ID, rooted at on an afs_cell object rather than being in multiple trees,
each of which is rooted on an afs_server object.

afs_server structs become per-cell and acquire a pointer to the cell.

The process of breaking a callback then starts with finding the server by
its network address, following that to the cell and then looking up each
volume ID in the volume tree.

This is simpler than the afs_vol_interest/afs_cb_interest N:M mapping web
and allows those structs and the code for maintaining them to be simplified
or removed.

It does make a couple of things a bit more tricky, though:

 (1) Operations now start with a volume, not a server, so there can be more
     than one answer as to whether or not the server we'll end up using
     supports the FS.InlineBulkStatus RPC.

 (2) CB RPC operations that specify the server UUID.  There's still a tree
     of servers by UUID on the afs_net struct, but the UUIDs in it aren't
     guaranteed unique.

Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
David Howells
2020-04-30 01:03:49 +01:00
parent cca37d45d5
commit 20325960f8
17 changed files with 257 additions and 543 deletions

View File

@@ -132,11 +132,12 @@ struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uu
/*
* Install a server record in the namespace tree
*/
static struct afs_server *afs_install_server(struct afs_net *net,
static struct afs_server *afs_install_server(struct afs_cell *cell,
struct afs_server *candidate)
{
const struct afs_addr_list *alist;
struct afs_server *server;
struct afs_net *net = cell->net;
struct rb_node **pp, *p;
int diff;
@@ -193,11 +194,12 @@ exists:
/*
* Allocate a new server record and mark it active.
*/
static struct afs_server *afs_alloc_server(struct afs_net *net,
static struct afs_server *afs_alloc_server(struct afs_cell *cell,
const uuid_t *uuid,
struct afs_addr_list *alist)
{
struct afs_server *server;
struct afs_net *net = cell->net;
_enter("");
@@ -212,11 +214,10 @@ static struct afs_server *afs_alloc_server(struct afs_net *net,
server->addr_version = alist->version;
server->uuid = *uuid;
rwlock_init(&server->fs_lock);
server->cb_volumes = RB_ROOT;
seqlock_init(&server->cb_break_lock);
init_waitqueue_head(&server->probe_wq);
INIT_LIST_HEAD(&server->probe_link);
spin_lock_init(&server->probe_lock);
server->cell = cell;
afs_inc_servers_outstanding(net);
trace_afs_server(server, 1, 1, afs_server_trace_alloc);
@@ -275,13 +276,13 @@ struct afs_server *afs_lookup_server(struct afs_cell *cell, struct key *key,
if (IS_ERR(alist))
return ERR_CAST(alist);
candidate = afs_alloc_server(cell->net, uuid, alist);
candidate = afs_alloc_server(cell, uuid, alist);
if (!candidate) {
afs_put_addrlist(alist);
return ERR_PTR(-ENOMEM);
}
server = afs_install_server(cell->net, candidate);
server = afs_install_server(cell, candidate);
if (server != candidate) {
afs_put_addrlist(alist);
kfree(candidate);