afs: Don't put afs_call in afs_wait_for_call_to_complete()
authorDavid Howells <dhowells@redhat.com>
Thu, 26 Oct 2023 08:54:07 +0000 (09:54 +0100)
committerDavid Howells <dhowells@redhat.com>
Sun, 24 Dec 2023 15:22:53 +0000 (15:22 +0000)
Don't put the afs_call struct in afs_wait_for_call_to_complete() but rather
have the caller do it.  This will allow the caller to fish stuff out of the
afs_call struct rather than the afs_addr_cursor struct, thereby allowing a
subsequent patch to subsume it.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org

fs/afs/fs_operation.c
fs/afs/fsclient.c
fs/afs/internal.h
fs/afs/rxrpc.c
fs/afs/vlclient.c

index bfb9a7634bd99d00c6f4deb86bc2c722593ce334..1c22d6e778460e7a44170f3a0b21d80a4f386ebf 100644 (file)
@@ -191,8 +191,11 @@ void afs_wait_for_operation(struct afs_operation *op)
                else
                        op->ac.error = -ENOTSUPP;
 
-               if (op->call)
-                       op->error = afs_wait_for_call_to_complete(op->call, &op->ac);
+               if (op->call) {
+                       afs_wait_for_call_to_complete(op->call, &op->ac);
+                       op->error = op->ac.error;
+                       afs_put_call(op->call);
+               }
        }
 
        switch (op->error) {
index 6821ce0f9d638e02b3c9442cf51dea9a850c0b8c..020073387111734602165f3f323c682455cb9c5e 100644 (file)
@@ -1612,6 +1612,7 @@ int afs_fs_give_up_all_callbacks(struct afs_net *net,
 {
        struct afs_call *call;
        __be32 *bp;
+       int ret;
 
        _enter("");
 
@@ -1627,7 +1628,9 @@ int afs_fs_give_up_all_callbacks(struct afs_net *net,
 
        call->server = afs_use_server(server, afs_server_trace_give_up_cb);
        afs_make_call(ac, call, GFP_NOFS);
-       return afs_wait_for_call_to_complete(call, ac);
+       afs_wait_for_call_to_complete(call, ac);
+       afs_put_call(call);
+       return ret;
 }
 
 /*
index 5c2d93023d17cc0bc782b7d27aaa3adde355432f..1bc69a115223f375515a518ecd0465a4e3ab0a48 100644 (file)
@@ -1291,7 +1291,7 @@ extern void __net_exit afs_close_socket(struct afs_net *);
 extern void afs_charge_preallocation(struct work_struct *);
 extern void afs_put_call(struct afs_call *);
 extern void afs_make_call(struct afs_addr_cursor *, struct afs_call *, gfp_t);
-extern long afs_wait_for_call_to_complete(struct afs_call *, struct afs_addr_cursor *);
+void afs_wait_for_call_to_complete(struct afs_call *call, struct afs_addr_cursor *ac);
 extern struct afs_call *afs_alloc_flat_call(struct afs_net *,
                                            const struct afs_call_type *,
                                            size_t, size_t);
index 2603db03b7ff8c9b70d581bc8fbe8a2e9e33013f..dad8efadbc441aa47a17ab061d2868d2b0517860 100644 (file)
@@ -575,48 +575,44 @@ call_complete:
 /*
  * Wait synchronously for a call to complete and clean up the call struct.
  */
-long afs_wait_for_call_to_complete(struct afs_call *call,
-                                  struct afs_addr_cursor *ac)
+void afs_wait_for_call_to_complete(struct afs_call *call, struct afs_addr_cursor *ac)
 {
-       long ret;
        bool rxrpc_complete = false;
 
-       DECLARE_WAITQUEUE(myself, current);
-
        _enter("");
 
-       ret = call->error;
-       if (ret < 0)
-               goto out;
+       if (!afs_check_call_state(call, AFS_CALL_COMPLETE)) {
+               DECLARE_WAITQUEUE(myself, current);
+
+               add_wait_queue(&call->waitq, &myself);
+               for (;;) {
+                       set_current_state(TASK_UNINTERRUPTIBLE);
+
+                       /* deliver any messages that are in the queue */
+                       if (!afs_check_call_state(call, AFS_CALL_COMPLETE) &&
+                           call->need_attention) {
+                               call->need_attention = false;
+                               __set_current_state(TASK_RUNNING);
+                               afs_deliver_to_call(call);
+                               continue;
+                       }
 
-       add_wait_queue(&call->waitq, &myself);
-       for (;;) {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-
-               /* deliver any messages that are in the queue */
-               if (!afs_check_call_state(call, AFS_CALL_COMPLETE) &&
-                   call->need_attention) {
-                       call->need_attention = false;
-                       __set_current_state(TASK_RUNNING);
-                       afs_deliver_to_call(call);
-                       continue;
-               }
+                       if (afs_check_call_state(call, AFS_CALL_COMPLETE))
+                               break;
 
-               if (afs_check_call_state(call, AFS_CALL_COMPLETE))
-                       break;
+                       if (!rxrpc_kernel_check_life(call->net->socket, call->rxcall)) {
+                               /* rxrpc terminated the call. */
+                               rxrpc_complete = true;
+                               break;
+                       }
 
-               if (!rxrpc_kernel_check_life(call->net->socket, call->rxcall)) {
-                       /* rxrpc terminated the call. */
-                       rxrpc_complete = true;
-                       break;
+                       schedule();
                }
 
-               schedule();
+               remove_wait_queue(&call->waitq, &myself);
+               __set_current_state(TASK_RUNNING);
        }
 
-       remove_wait_queue(&call->waitq, &myself);
-       __set_current_state(TASK_RUNNING);
-
        if (!afs_check_call_state(call, AFS_CALL_COMPLETE)) {
                if (rxrpc_complete) {
                        afs_set_call_complete(call, call->error, call->abort_code);
@@ -635,23 +631,8 @@ long afs_wait_for_call_to_complete(struct afs_call *call,
        ac->error = call->error;
        spin_unlock_bh(&call->state_lock);
 
-       ret = ac->error;
-       switch (ret) {
-       case 0:
-               ret = call->ret0;
-               call->ret0 = 0;
-
-               fallthrough;
-       case -ECONNABORTED:
+       if (call->error == 0 || call->error == -ECONNABORTED)
                ac->responded = true;
-               break;
-       }
-
-out:
-       _debug("call complete");
-       afs_put_call(call);
-       _leave(" = %p", (void *)ret);
-       return ret;
 }
 
 /*
index 41e7932d75c6f7006d682a9898203b304c4bc665..650534892a20250b07427b9e0b1e785cd5a8bf06 100644 (file)
@@ -106,12 +106,6 @@ static int afs_deliver_vl_get_entry_by_name_u(struct afs_call *call)
        return 0;
 }
 
-static void afs_destroy_vl_get_entry_by_name_u(struct afs_call *call)
-{
-       kfree(call->ret_vldb);
-       afs_flat_call_destructor(call);
-}
-
 /*
  * VL.GetEntryByNameU operation type.
  */
@@ -119,7 +113,7 @@ static const struct afs_call_type afs_RXVLGetEntryByNameU = {
        .name           = "VL.GetEntryByNameU",
        .op             = afs_VL_GetEntryByNameU,
        .deliver        = afs_deliver_vl_get_entry_by_name_u,
-       .destructor     = afs_destroy_vl_get_entry_by_name_u,
+       .destructor     = afs_flat_call_destructor,
 };
 
 /*
@@ -166,7 +160,13 @@ struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *vc,
 
        trace_afs_make_vl_call(call);
        afs_make_call(&vc->ac, call, GFP_KERNEL);
-       return (struct afs_vldb_entry *)afs_wait_for_call_to_complete(call, &vc->ac);
+       afs_wait_for_call_to_complete(call, &vc->ac);
+       afs_put_call(call);
+       if (vc->ac.error) {
+               kfree(entry);
+               return ERR_PTR(vc->ac.error);
+       }
+       return entry;
 }
 
 /*
@@ -249,12 +249,6 @@ static int afs_deliver_vl_get_addrs_u(struct afs_call *call)
        return 0;
 }
 
-static void afs_vl_get_addrs_u_destructor(struct afs_call *call)
-{
-       afs_put_addrlist(call->ret_alist);
-       return afs_flat_call_destructor(call);
-}
-
 /*
  * VL.GetAddrsU operation type.
  */
@@ -262,7 +256,7 @@ static const struct afs_call_type afs_RXVLGetAddrsU = {
        .name           = "VL.GetAddrsU",
        .op             = afs_VL_GetAddrsU,
        .deliver        = afs_deliver_vl_get_addrs_u,
-       .destructor     = afs_vl_get_addrs_u_destructor,
+       .destructor     = afs_flat_call_destructor,
 };
 
 /*
@@ -273,6 +267,7 @@ struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *vc,
                                         const uuid_t *uuid)
 {
        struct afs_ListAddrByAttributes__xdr *r;
+       struct afs_addr_list *alist;
        const struct afs_uuid *u = (const struct afs_uuid *)uuid;
        struct afs_call *call;
        struct afs_net *net = vc->cell->net;
@@ -309,7 +304,14 @@ struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *vc,
 
        trace_afs_make_vl_call(call);
        afs_make_call(&vc->ac, call, GFP_KERNEL);
-       return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac);
+       afs_wait_for_call_to_complete(call, &vc->ac);
+       alist = call->ret_alist;
+       afs_put_call(call);
+       if (vc->ac.error) {
+               afs_put_addrlist(alist);
+               return ERR_PTR(vc->ac.error);
+       }
+       return alist;
 }
 
 /*
@@ -618,7 +620,7 @@ static const struct afs_call_type afs_YFSVLGetEndpoints = {
        .name           = "YFSVL.GetEndpoints",
        .op             = afs_YFSVL_GetEndpoints,
        .deliver        = afs_deliver_yfsvl_get_endpoints,
-       .destructor     = afs_vl_get_addrs_u_destructor,
+       .destructor     = afs_flat_call_destructor,
 };
 
 /*
@@ -628,6 +630,7 @@ static const struct afs_call_type afs_YFSVLGetEndpoints = {
 struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc,
                                              const uuid_t *uuid)
 {
+       struct afs_addr_list *alist;
        struct afs_call *call;
        struct afs_net *net = vc->cell->net;
        __be32 *bp;
@@ -652,7 +655,14 @@ struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc,
 
        trace_afs_make_vl_call(call);
        afs_make_call(&vc->ac, call, GFP_KERNEL);
-       return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac);
+       afs_wait_for_call_to_complete(call, &vc->ac);
+       alist = call->ret_alist;
+       afs_put_call(call);
+       if (vc->ac.error) {
+               afs_put_addrlist(alist);
+               return ERR_PTR(vc->ac.error);
+       }
+       return alist;
 }
 
 /*
@@ -717,12 +727,6 @@ static int afs_deliver_yfsvl_get_cell_name(struct afs_call *call)
        return 0;
 }
 
-static void afs_destroy_yfsvl_get_cell_name(struct afs_call *call)
-{
-       kfree(call->ret_str);
-       afs_flat_call_destructor(call);
-}
-
 /*
  * VL.GetCapabilities operation type
  */
@@ -730,7 +734,7 @@ static const struct afs_call_type afs_YFSVLGetCellName = {
        .name           = "YFSVL.GetCellName",
        .op             = afs_YFSVL_GetCellName,
        .deliver        = afs_deliver_yfsvl_get_cell_name,
-       .destructor     = afs_destroy_yfsvl_get_cell_name,
+       .destructor     = afs_flat_call_destructor,
 };
 
 /*
@@ -745,6 +749,7 @@ char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *vc)
        struct afs_call *call;
        struct afs_net *net = vc->cell->net;
        __be32 *bp;
+       char *cellname;
 
        _enter("");
 
@@ -763,5 +768,12 @@ char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *vc)
        /* Can't take a ref on server */
        trace_afs_make_vl_call(call);
        afs_make_call(&vc->ac, call, GFP_KERNEL);
-       return (char *)afs_wait_for_call_to_complete(call, &vc->ac);
+       afs_wait_for_call_to_complete(call, &vc->ac);
+       cellname = call->ret_str;
+       afs_put_call(call);
+       if (vc->ac.error) {
+               kfree(cellname);
+               return ERR_PTR(vc->ac.error);
+       }
+       return cellname;
 }