@@ -807,6 +807,13 @@ int rpc_clnt_xprt_iter_init(struct rpc_clnt *clnt, struct rpc_xprt_iter *xpi)
807807 return _rpc_clnt_xprt_iter_init (clnt , xpi , xprt_iter_init_listall );
808808}
809809
810+ static
811+ int rpc_clnt_xprt_iter_offline_init (struct rpc_clnt * clnt ,
812+ struct rpc_xprt_iter * xpi )
813+ {
814+ return _rpc_clnt_xprt_iter_init (clnt , xpi , xprt_iter_init_listoffline );
815+ }
816+
810817/**
811818 * rpc_clnt_iterate_for_each_xprt - Apply a function to all transports
812819 * @clnt: pointer to client
@@ -3018,6 +3025,64 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
30183025}
30193026EXPORT_SYMBOL_GPL (rpc_clnt_add_xprt );
30203027
3028+ static int rpc_xprt_probe_trunked (struct rpc_clnt * clnt ,
3029+ struct rpc_xprt * xprt ,
3030+ struct rpc_add_xprt_test * data )
3031+ {
3032+ struct rpc_xprt_switch * xps ;
3033+ struct rpc_xprt * main_xprt ;
3034+ int status = 0 ;
3035+
3036+ xprt_get (xprt );
3037+
3038+ rcu_read_lock ();
3039+ main_xprt = xprt_get (rcu_dereference (clnt -> cl_xprt ));
3040+ xps = xprt_switch_get (rcu_dereference (clnt -> cl_xpi .xpi_xpswitch ));
3041+ status = rpc_cmp_addr_port ((struct sockaddr * )& xprt -> addr ,
3042+ (struct sockaddr * )& main_xprt -> addr );
3043+ rcu_read_unlock ();
3044+ xprt_put (main_xprt );
3045+ if (status || !test_bit (XPRT_OFFLINE , & xprt -> state ))
3046+ goto out ;
3047+
3048+ status = rpc_clnt_add_xprt_helper (clnt , xprt , data );
3049+ out :
3050+ xprt_put (xprt );
3051+ xprt_switch_put (xps );
3052+ return status ;
3053+ }
3054+
3055+ /* rpc_clnt_probe_trunked_xprt -- probe offlined transport for session trunking
3056+ * @clnt rpc_clnt structure
3057+ *
3058+ * For each offlined transport found in the rpc_clnt structure call
3059+ * the function rpc_xprt_probe_trunked() which will determine if this
3060+ * transport still belongs to the trunking group.
3061+ */
3062+ void rpc_clnt_probe_trunked_xprts (struct rpc_clnt * clnt ,
3063+ struct rpc_add_xprt_test * data )
3064+ {
3065+ struct rpc_xprt_iter xpi ;
3066+ int ret ;
3067+
3068+ ret = rpc_clnt_xprt_iter_offline_init (clnt , & xpi );
3069+ if (ret )
3070+ return ;
3071+ for (;;) {
3072+ struct rpc_xprt * xprt = xprt_iter_get_next (& xpi );
3073+
3074+ if (!xprt )
3075+ break ;
3076+ ret = rpc_xprt_probe_trunked (clnt , xprt , data );
3077+ xprt_put (xprt );
3078+ if (ret < 0 )
3079+ break ;
3080+ xprt_iter_rewind (& xpi );
3081+ }
3082+ xprt_iter_destroy (& xpi );
3083+ }
3084+ EXPORT_SYMBOL_GPL (rpc_clnt_probe_trunked_xprts );
3085+
30213086static int rpc_xprt_offline (struct rpc_clnt * clnt ,
30223087 struct rpc_xprt * xprt ,
30233088 void * data )
0 commit comments