Skip to content

Commit fda0ab4

Browse files
androsadamsonamschuma-ntap
authored andcommitted
SUNRPC: rpc_clnt_add_xprt setup function for NFS layer
Use a setup function to call into the NFS layer to test an rpc_xprt for session trunking so as to not leak the rpc_xprt_switch into the nfs layer. Search for the address in the rpc_xprt_switch first so as not to put an unnecessary EXCHANGE_ID on the wire. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent 39e5d2d commit fda0ab4

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

include/linux/sunrpc/clnt.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,13 @@ struct rpc_create_args {
125125
struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */
126126
};
127127

128+
struct rpc_add_xprt_test {
129+
int (*add_xprt_test)(struct rpc_clnt *,
130+
struct rpc_xprt *,
131+
void *calldata);
132+
void *data;
133+
};
134+
128135
/* Values for "flags" field */
129136
#define RPC_CLNT_CREATE_HARDRTRY (1UL << 0)
130137
#define RPC_CLNT_CREATE_AUTOBIND (1UL << 2)
@@ -198,6 +205,11 @@ int rpc_clnt_add_xprt(struct rpc_clnt *, struct xprt_create *,
198205
void rpc_cap_max_reconnect_timeout(struct rpc_clnt *clnt,
199206
unsigned long timeo);
200207

208+
int rpc_clnt_setup_test_and_add_xprt(struct rpc_clnt *,
209+
struct rpc_xprt_switch *,
210+
struct rpc_xprt *,
211+
void *);
212+
201213
const char *rpc_proc_name(const struct rpc_task *task);
202214

203215
void rpc_clnt_xprt_switch_put(struct rpc_clnt *);

net/sunrpc/clnt.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2613,6 +2613,70 @@ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt,
26132613
}
26142614
EXPORT_SYMBOL_GPL(rpc_clnt_test_and_add_xprt);
26152615

2616+
/**
2617+
* rpc_clnt_setup_test_and_add_xprt()
2618+
*
2619+
* This is an rpc_clnt_add_xprt setup() function which returns 1 so:
2620+
* 1) caller of the test function must dereference the rpc_xprt_switch
2621+
* and the rpc_xprt.
2622+
* 2) test function must call rpc_xprt_switch_add_xprt, usually in
2623+
* the rpc_call_done routine.
2624+
*
2625+
* Upon success (return of 1), the test function adds the new
2626+
* transport to the rpc_clnt xprt switch
2627+
*
2628+
* @clnt: struct rpc_clnt to get the new transport
2629+
* @xps: the rpc_xprt_switch to hold the new transport
2630+
* @xprt: the rpc_xprt to test
2631+
* @data: a struct rpc_add_xprt_test pointer that holds the test function
2632+
* and test function call data
2633+
*/
2634+
int rpc_clnt_setup_test_and_add_xprt(struct rpc_clnt *clnt,
2635+
struct rpc_xprt_switch *xps,
2636+
struct rpc_xprt *xprt,
2637+
void *data)
2638+
{
2639+
struct rpc_cred *cred;
2640+
struct rpc_task *task;
2641+
struct rpc_add_xprt_test *xtest = (struct rpc_add_xprt_test *)data;
2642+
int status = -EADDRINUSE;
2643+
2644+
xprt = xprt_get(xprt);
2645+
xprt_switch_get(xps);
2646+
2647+
if (rpc_xprt_switch_has_addr(xps, (struct sockaddr *)&xprt->addr))
2648+
goto out_err;
2649+
2650+
/* Test the connection */
2651+
cred = authnull_ops.lookup_cred(NULL, NULL, 0);
2652+
task = rpc_call_null_helper(clnt, xprt, cred,
2653+
RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
2654+
NULL, NULL);
2655+
put_rpccred(cred);
2656+
if (IS_ERR(task)) {
2657+
status = PTR_ERR(task);
2658+
goto out_err;
2659+
}
2660+
status = task->tk_status;
2661+
rpc_put_task(task);
2662+
2663+
if (status < 0)
2664+
goto out_err;
2665+
2666+
/* rpc_xprt_switch and rpc_xprt are deferrenced by add_xprt_test() */
2667+
xtest->add_xprt_test(clnt, xprt, xtest->data);
2668+
2669+
/* so that rpc_clnt_add_xprt does not call rpc_xprt_switch_add_xprt */
2670+
return 1;
2671+
out_err:
2672+
xprt_put(xprt);
2673+
xprt_switch_put(xps);
2674+
pr_info("RPC: rpc_clnt_test_xprt failed: %d addr %s not added\n",
2675+
status, xprt->address_strings[RPC_DISPLAY_ADDR]);
2676+
return status;
2677+
}
2678+
EXPORT_SYMBOL_GPL(rpc_clnt_setup_test_and_add_xprt);
2679+
26162680
/**
26172681
* rpc_clnt_add_xprt - Add a new transport to a rpc_clnt
26182682
* @clnt: pointer to struct rpc_clnt

0 commit comments

Comments
 (0)