mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
afs: Don't put afs_call in afs_wait_for_call_to_complete()
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
This commit is contained in:
parent
2de5599f63
commit
6f2ff7e89b
@ -191,8 +191,11 @@ void afs_wait_for_operation(struct afs_operation *op)
|
|||||||
else
|
else
|
||||||
op->ac.error = -ENOTSUPP;
|
op->ac.error = -ENOTSUPP;
|
||||||
|
|
||||||
if (op->call)
|
if (op->call) {
|
||||||
op->error = afs_wait_for_call_to_complete(op->call, &op->ac);
|
afs_wait_for_call_to_complete(op->call, &op->ac);
|
||||||
|
op->error = op->ac.error;
|
||||||
|
afs_put_call(op->call);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (op->error) {
|
switch (op->error) {
|
||||||
|
@ -1612,6 +1612,7 @@ int afs_fs_give_up_all_callbacks(struct afs_net *net,
|
|||||||
{
|
{
|
||||||
struct afs_call *call;
|
struct afs_call *call;
|
||||||
__be32 *bp;
|
__be32 *bp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
_enter("");
|
_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);
|
call->server = afs_use_server(server, afs_server_trace_give_up_cb);
|
||||||
afs_make_call(ac, call, GFP_NOFS);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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_charge_preallocation(struct work_struct *);
|
||||||
extern void afs_put_call(struct afs_call *);
|
extern void afs_put_call(struct afs_call *);
|
||||||
extern void afs_make_call(struct afs_addr_cursor *, struct afs_call *, gfp_t);
|
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 *,
|
extern struct afs_call *afs_alloc_flat_call(struct afs_net *,
|
||||||
const struct afs_call_type *,
|
const struct afs_call_type *,
|
||||||
size_t, size_t);
|
size_t, size_t);
|
||||||
|
@ -575,48 +575,44 @@ call_complete:
|
|||||||
/*
|
/*
|
||||||
* Wait synchronously for a call to complete and clean up the call struct.
|
* Wait synchronously for a call to complete and clean up the call struct.
|
||||||
*/
|
*/
|
||||||
long afs_wait_for_call_to_complete(struct afs_call *call,
|
void afs_wait_for_call_to_complete(struct afs_call *call, struct afs_addr_cursor *ac)
|
||||||
struct afs_addr_cursor *ac)
|
|
||||||
{
|
{
|
||||||
long ret;
|
|
||||||
bool rxrpc_complete = false;
|
bool rxrpc_complete = false;
|
||||||
|
|
||||||
DECLARE_WAITQUEUE(myself, current);
|
|
||||||
|
|
||||||
_enter("");
|
_enter("");
|
||||||
|
|
||||||
ret = call->error;
|
if (!afs_check_call_state(call, AFS_CALL_COMPLETE)) {
|
||||||
if (ret < 0)
|
DECLARE_WAITQUEUE(myself, current);
|
||||||
goto out;
|
|
||||||
|
|
||||||
add_wait_queue(&call->waitq, &myself);
|
add_wait_queue(&call->waitq, &myself);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||||
|
|
||||||
/* deliver any messages that are in the queue */
|
/* deliver any messages that are in the queue */
|
||||||
if (!afs_check_call_state(call, AFS_CALL_COMPLETE) &&
|
if (!afs_check_call_state(call, AFS_CALL_COMPLETE) &&
|
||||||
call->need_attention) {
|
call->need_attention) {
|
||||||
call->need_attention = false;
|
call->need_attention = false;
|
||||||
__set_current_state(TASK_RUNNING);
|
__set_current_state(TASK_RUNNING);
|
||||||
afs_deliver_to_call(call);
|
afs_deliver_to_call(call);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afs_check_call_state(call, AFS_CALL_COMPLETE))
|
remove_wait_queue(&call->waitq, &myself);
|
||||||
break;
|
__set_current_state(TASK_RUNNING);
|
||||||
|
|
||||||
if (!rxrpc_kernel_check_life(call->net->socket, call->rxcall)) {
|
|
||||||
/* rxrpc terminated the call. */
|
|
||||||
rxrpc_complete = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
schedule();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_wait_queue(&call->waitq, &myself);
|
|
||||||
__set_current_state(TASK_RUNNING);
|
|
||||||
|
|
||||||
if (!afs_check_call_state(call, AFS_CALL_COMPLETE)) {
|
if (!afs_check_call_state(call, AFS_CALL_COMPLETE)) {
|
||||||
if (rxrpc_complete) {
|
if (rxrpc_complete) {
|
||||||
afs_set_call_complete(call, call->error, call->abort_code);
|
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;
|
ac->error = call->error;
|
||||||
spin_unlock_bh(&call->state_lock);
|
spin_unlock_bh(&call->state_lock);
|
||||||
|
|
||||||
ret = ac->error;
|
if (call->error == 0 || call->error == -ECONNABORTED)
|
||||||
switch (ret) {
|
|
||||||
case 0:
|
|
||||||
ret = call->ret0;
|
|
||||||
call->ret0 = 0;
|
|
||||||
|
|
||||||
fallthrough;
|
|
||||||
case -ECONNABORTED:
|
|
||||||
ac->responded = true;
|
ac->responded = true;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
_debug("call complete");
|
|
||||||
afs_put_call(call);
|
|
||||||
_leave(" = %p", (void *)ret);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -106,12 +106,6 @@ static int afs_deliver_vl_get_entry_by_name_u(struct afs_call *call)
|
|||||||
return 0;
|
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.
|
* VL.GetEntryByNameU operation type.
|
||||||
*/
|
*/
|
||||||
@ -119,7 +113,7 @@ static const struct afs_call_type afs_RXVLGetEntryByNameU = {
|
|||||||
.name = "VL.GetEntryByNameU",
|
.name = "VL.GetEntryByNameU",
|
||||||
.op = afs_VL_GetEntryByNameU,
|
.op = afs_VL_GetEntryByNameU,
|
||||||
.deliver = afs_deliver_vl_get_entry_by_name_u,
|
.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);
|
trace_afs_make_vl_call(call);
|
||||||
afs_make_call(&vc->ac, call, GFP_KERNEL);
|
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;
|
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.
|
* VL.GetAddrsU operation type.
|
||||||
*/
|
*/
|
||||||
@ -262,7 +256,7 @@ static const struct afs_call_type afs_RXVLGetAddrsU = {
|
|||||||
.name = "VL.GetAddrsU",
|
.name = "VL.GetAddrsU",
|
||||||
.op = afs_VL_GetAddrsU,
|
.op = afs_VL_GetAddrsU,
|
||||||
.deliver = afs_deliver_vl_get_addrs_u,
|
.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)
|
const uuid_t *uuid)
|
||||||
{
|
{
|
||||||
struct afs_ListAddrByAttributes__xdr *r;
|
struct afs_ListAddrByAttributes__xdr *r;
|
||||||
|
struct afs_addr_list *alist;
|
||||||
const struct afs_uuid *u = (const struct afs_uuid *)uuid;
|
const struct afs_uuid *u = (const struct afs_uuid *)uuid;
|
||||||
struct afs_call *call;
|
struct afs_call *call;
|
||||||
struct afs_net *net = vc->cell->net;
|
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);
|
trace_afs_make_vl_call(call);
|
||||||
afs_make_call(&vc->ac, call, GFP_KERNEL);
|
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",
|
.name = "YFSVL.GetEndpoints",
|
||||||
.op = afs_YFSVL_GetEndpoints,
|
.op = afs_YFSVL_GetEndpoints,
|
||||||
.deliver = afs_deliver_yfsvl_get_endpoints,
|
.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,
|
struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc,
|
||||||
const uuid_t *uuid)
|
const uuid_t *uuid)
|
||||||
{
|
{
|
||||||
|
struct afs_addr_list *alist;
|
||||||
struct afs_call *call;
|
struct afs_call *call;
|
||||||
struct afs_net *net = vc->cell->net;
|
struct afs_net *net = vc->cell->net;
|
||||||
__be32 *bp;
|
__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);
|
trace_afs_make_vl_call(call);
|
||||||
afs_make_call(&vc->ac, call, GFP_KERNEL);
|
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;
|
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
|
* VL.GetCapabilities operation type
|
||||||
*/
|
*/
|
||||||
@ -730,7 +734,7 @@ static const struct afs_call_type afs_YFSVLGetCellName = {
|
|||||||
.name = "YFSVL.GetCellName",
|
.name = "YFSVL.GetCellName",
|
||||||
.op = afs_YFSVL_GetCellName,
|
.op = afs_YFSVL_GetCellName,
|
||||||
.deliver = afs_deliver_yfsvl_get_cell_name,
|
.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_call *call;
|
||||||
struct afs_net *net = vc->cell->net;
|
struct afs_net *net = vc->cell->net;
|
||||||
__be32 *bp;
|
__be32 *bp;
|
||||||
|
char *cellname;
|
||||||
|
|
||||||
_enter("");
|
_enter("");
|
||||||
|
|
||||||
@ -763,5 +768,12 @@ char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *vc)
|
|||||||
/* Can't take a ref on server */
|
/* Can't take a ref on server */
|
||||||
trace_afs_make_vl_call(call);
|
trace_afs_make_vl_call(call);
|
||||||
afs_make_call(&vc->ac, call, GFP_KERNEL);
|
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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user