/* It shouldn't matter if the number of backchannel session slots * doesn't match the number of RPC/RDMA credits. That just means * one or the other will have extra slots that aren't used. */ static struct rpc_xprt * xprt_setup_rdma_bc(struct xprt_create *args) { struct rpc_xprt *xprt; struct rpcrdma_xprt *new_xprt; if (args->addrlen > sizeof(xprt->addr)) { dprintk("RPC: %s: address too large\n", __func__); return ERR_PTR(-EBADF); } xprt = xprt_alloc(args->net, sizeof(*new_xprt), RPCRDMA_MAX_BC_REQUESTS, RPCRDMA_MAX_BC_REQUESTS); if (!xprt) { dprintk("RPC: %s: couldn't allocate rpc_xprt\n", __func__); return ERR_PTR(-ENOMEM); } xprt->timeout = &xprt_rdma_bc_timeout; xprt_set_bound(xprt); xprt_set_connected(xprt); xprt->bind_timeout = RPCRDMA_BIND_TO; xprt->reestablish_timeout = RPCRDMA_INIT_REEST_TO; xprt->idle_timeout = RPCRDMA_IDLE_DISC_TO; xprt->prot = XPRT_TRANSPORT_BC_RDMA; xprt->tsh_size = RPCRDMA_HDRLEN_MIN / sizeof(__be32); xprt->ops = &xprt_rdma_bc_procs; memcpy(&xprt->addr, args->dstaddr, args->addrlen); xprt->addrlen = args->addrlen; xprt_rdma_format_addresses(xprt, (struct sockaddr *)&xprt->addr); xprt->resvport = 0; xprt->max_payload = xprt_rdma_max_inline_read; new_xprt = rpcx_to_rdmax(xprt); new_xprt->rx_buf.rb_bc_max_requests = xprt->max_reqs; xprt_get(xprt); args->bc_xprt->xpt_bc_xprt = xprt; xprt->bc_xprt = args->bc_xprt; if (!try_module_get(THIS_MODULE)) goto out_fail; /* Final put for backchannel xprt is in __svc_rdma_free */ xprt_get(xprt); return xprt; out_fail: xprt_rdma_free_addresses(xprt); args->bc_xprt->xpt_bc_xprt = NULL; args->bc_xprt->xpt_bc_xps = NULL; xprt_put(xprt); xprt_free(xprt); return ERR_PTR(-EINVAL); }
/** * xs_udp_connect_worker - set up a UDP socket * @args: RPC transport to connect * * Invoked by a work queue tasklet. */ static void xs_udp_connect_worker(void *args) { struct rpc_xprt *xprt = (struct rpc_xprt *) args; struct socket *sock = xprt->sock; int err, status = -EIO; if (xprt->shutdown || xprt->addr.sin_port == 0) goto out; dprintk("RPC: xs_udp_connect_worker for xprt %p\n", xprt); /* Start by resetting any existing state */ xs_close(xprt); if ((err = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) { dprintk("RPC: can't create UDP transport socket (%d).\n", -err); goto out; } xs_reclassify_socket(sock); if (xs_bind(xprt, sock)) { sock_release(sock); goto out; } if (!xprt->inet) { struct sock *sk = sock->sk; write_lock_bh(&sk->sk_callback_lock); sk->sk_user_data = xprt; xprt->old_data_ready = sk->sk_data_ready; xprt->old_state_change = sk->sk_state_change; xprt->old_write_space = sk->sk_write_space; sk->sk_data_ready = xs_udp_data_ready; sk->sk_write_space = xs_udp_write_space; sk->sk_no_check = UDP_CSUM_NORCV; sk->sk_allocation = GFP_ATOMIC; xprt_set_connected(xprt); /* Reset to new socket */ xprt->sock = sock; xprt->inet = sk; write_unlock_bh(&sk->sk_callback_lock); } xs_udp_do_set_buffer_size(xprt); status = 0; out: xprt_wake_pending_tasks(xprt, status); xprt_clear_connecting(xprt); }