diff options
Diffstat (limited to 'net/9p/client.c')
| -rw-r--r-- | net/9p/client.c | 26 | 
1 files changed, 23 insertions, 3 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 776618cd2be..b23a17c431c 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -740,10 +740,18 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)  			c->status = Disconnected;  		goto reterr;  	} +again:  	/* Wait for the response */  	err = wait_event_interruptible(*req->wq,  				       req->status >= REQ_STATUS_RCVD); +	if ((err == -ERESTARTSYS) && (c->status == Connected) +				  && (type == P9_TFLUSH)) { +		sigpending = 1; +		clear_thread_flag(TIF_SIGPENDING); +		goto again; +	} +  	if (req->status == REQ_STATUS_ERROR) {  		p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);  		err = req->t_err; @@ -1420,6 +1428,7 @@ int p9_client_clunk(struct p9_fid *fid)  	int err;  	struct p9_client *clnt;  	struct p9_req_t *req; +	int retries = 0;  	if (!fid) {  		pr_warn("%s (%d): Trying to clunk with NULL fid\n", @@ -1428,7 +1437,9 @@ int p9_client_clunk(struct p9_fid *fid)  		return 0;  	} -	p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d\n", fid->fid); +again: +	p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n", fid->fid, +								retries);  	err = 0;  	clnt = fid->clnt; @@ -1444,8 +1455,14 @@ int p9_client_clunk(struct p9_fid *fid)  error:  	/*  	 * Fid is not valid even after a failed clunk +	 * If interrupted, retry once then give up and +	 * leak fid until umount.  	 */ -	p9_fid_destroy(fid); +	if (err == -ERESTARTSYS) { +		if (retries++ == 0) +			goto again; +	} else +		p9_fid_destroy(fid);  	return err;  }  EXPORT_SYMBOL(p9_client_clunk); @@ -1470,7 +1487,10 @@ int p9_client_remove(struct p9_fid *fid)  	p9_free_req(clnt, req);  error: -	p9_fid_destroy(fid); +	if (err == -ERESTARTSYS) +		p9_client_clunk(fid); +	else +		p9_fid_destroy(fid);  	return err;  }  EXPORT_SYMBOL(p9_client_remove);  |