diff options
Diffstat (limited to 'net/sunrpc/clnt.c')
| -rw-r--r-- | net/sunrpc/clnt.c | 20 | 
1 files changed, 17 insertions, 3 deletions
| diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 8bf2af8546d2..af0174d7ce5a 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1127,6 +1127,8 @@ struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)  	struct rpc_task *task;  	task = rpc_new_task(task_setup_data); +	if (IS_ERR(task)) +		return task;  	if (!RPC_IS_ASYNC(task))  		task->tk_flags |= RPC_TASK_CRED_NOREF; @@ -1227,6 +1229,11 @@ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req)  	 * Create an rpc_task to send the data  	 */  	task = rpc_new_task(&task_setup_data); +	if (IS_ERR(task)) { +		xprt_free_bc_request(req); +		return task; +	} +  	xprt_init_bc_request(req, task);  	task->tk_action = call_bc_encode; @@ -1858,6 +1865,9 @@ call_encode(struct rpc_task *task)  	xprt_request_dequeue_xprt(task);  	/* Encode here so that rpcsec_gss can use correct sequence number. */  	rpc_xdr_encode(task); +	/* Add task to reply queue before transmission to avoid races */ +	if (task->tk_status == 0 && rpc_reply_expected(task)) +		task->tk_status = xprt_request_enqueue_receive(task);  	/* Did the encode result in an error condition? */  	if (task->tk_status != 0) {  		/* Was the error nonfatal? */ @@ -1881,9 +1891,6 @@ call_encode(struct rpc_task *task)  		return;  	} -	/* Add task to reply queue before transmission to avoid races */ -	if (rpc_reply_expected(task)) -		xprt_request_enqueue_receive(task);  	xprt_request_enqueue_transmit(task);  out:  	task->tk_action = call_transmit; @@ -2200,6 +2207,7 @@ call_transmit_status(struct rpc_task *task)  		 * socket just returned a connection error,  		 * then hold onto the transport lock.  		 */ +	case -ENOMEM:  	case -ENOBUFS:  		rpc_delay(task, HZ>>2);  		fallthrough; @@ -2283,6 +2291,7 @@ call_bc_transmit_status(struct rpc_task *task)  	case -ENOTCONN:  	case -EPIPE:  		break; +	case -ENOMEM:  	case -ENOBUFS:  		rpc_delay(task, HZ>>2);  		fallthrough; @@ -2365,6 +2374,11 @@ call_status(struct rpc_task *task)  	case -EPIPE:  	case -EAGAIN:  		break; +	case -ENFILE: +	case -ENOBUFS: +	case -ENOMEM: +		rpc_delay(task, HZ>>2); +		break;  	case -EIO:  		/* shutdown or soft timeout */  		goto out_exit; | 
