]> www.infradead.org Git - users/hch/misc.git/commitdiff
afs: Give an afs_server object a ref on the afs_cell object it points to
authorDavid Howells <dhowells@redhat.com>
Tue, 18 Feb 2025 19:22:48 +0000 (19:22 +0000)
committerJakub Kicinski <kuba@kernel.org>
Fri, 21 Feb 2025 23:06:29 +0000 (15:06 -0800)
Give an afs_server object a ref on the afs_cell object it points to so that
the cell doesn't get deleted before the server record.

Whilst this is circular (cell -> vol -> server_list -> server -> cell), the
ref only pins the memory, not the lifetime as that's controlled by the
activity counter.  When the volume's activity counter reaches 0, it
detaches from the cell and discards its server list; when a cell's activity
counter reaches 0, it discards its root volume.  At that point, the
circularity is cut.

Fixes: d2ddc776a458 ("afs: Overhaul volume and server record caching and fileserver rotation")
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20250218192250.296870-6-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
fs/afs/server.c
include/trace/events/afs.h

index 038f9d0ae3af8ee1df24dc163c972e826c5d62fb..4504e16b458cc1153db19f5a310e10afc6a186c6 100644 (file)
@@ -163,6 +163,8 @@ static struct afs_server *afs_install_server(struct afs_cell *cell,
        rb_insert_color(&server->uuid_rb, &net->fs_servers);
        hlist_add_head_rcu(&server->proc_link, &net->fs_proc);
 
+       afs_get_cell(cell, afs_cell_trace_get_server);
+
 added_dup:
        write_seqlock(&net->fs_addr_lock);
        estate = rcu_dereference_protected(server->endpoint_state,
@@ -442,6 +444,7 @@ static void afs_server_rcu(struct rcu_head *rcu)
                         atomic_read(&server->active), afs_server_trace_free);
        afs_put_endpoint_state(rcu_access_pointer(server->endpoint_state),
                               afs_estate_trace_put_server);
+       afs_put_cell(server->cell, afs_cell_trace_put_server);
        kfree(server);
 }
 
index b0db89058c9118ab81625b8a90f24040836dc7e5..958a2460330c01d314aeb5f20a096b43e94a9b21 100644 (file)
@@ -174,6 +174,7 @@ enum yfs_cm_operation {
        EM(afs_cell_trace_get_queue_dns,        "GET q-dns ") \
        EM(afs_cell_trace_get_queue_manage,     "GET q-mng ") \
        EM(afs_cell_trace_get_queue_new,        "GET q-new ") \
+       EM(afs_cell_trace_get_server,           "GET server") \
        EM(afs_cell_trace_get_vol,              "GET vol   ") \
        EM(afs_cell_trace_insert,               "INSERT    ") \
        EM(afs_cell_trace_manage,               "MANAGE    ") \
@@ -182,6 +183,7 @@ enum yfs_cm_operation {
        EM(afs_cell_trace_put_destroy,          "PUT destry") \
        EM(afs_cell_trace_put_queue_work,       "PUT q-work") \
        EM(afs_cell_trace_put_queue_fail,       "PUT q-fail") \
+       EM(afs_cell_trace_put_server,           "PUT server") \
        EM(afs_cell_trace_put_vol,              "PUT vol   ") \
        EM(afs_cell_trace_see_source,           "SEE source") \
        EM(afs_cell_trace_see_ws,               "SEE ws    ") \