вт, 5 мар. 2019 г. в 21:45, Ronnie Sahlberg <lsahlber@xxxxxxxxxx>: > > A negative timeout is the same as the current behaviour, i.e. no timeout. > > Signed-off-by: Ronnie Sahlberg <lsahlber@xxxxxxxxxx> > --- > fs/cifs/transport.c | 40 ++++++++++++++++++++++++++++++---------- > 1 file changed, 30 insertions(+), 10 deletions(-) > > diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c > index f4ec9635dab2..3263e8b3a57d 100644 > --- a/fs/cifs/transport.c > +++ b/fs/cifs/transport.c > @@ -478,11 +478,18 @@ smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer, > > static int > wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, > - const int flags, unsigned int *instance) > + const int timeout, const int flags, > + unsigned int *instance) > { > int rc; > int *credits; > int optype; > + long int t; > + > + if (timeout < 0) > + t = MAX_JIFFY_OFFSET; > + else > + t = msecs_to_jiffies(timeout); > > optype = flags & CIFS_OP_MASK; > > @@ -507,11 +514,16 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, > if (*credits < num_credits) { > spin_unlock(&server->req_lock); > cifs_num_waiters_inc(server); > - rc = wait_event_killable(server->request_q, > - has_credits(server, credits, num_credits)); > + rc = wait_event_killable_timeout(server->request_q, > + has_credits(server, credits, num_credits), t); > cifs_num_waiters_dec(server); > - if (rc) > - return rc; > + if (!rc) { > + cifs_dbg(VFS, "wait timed out after %d ms\n", > + timeout); > + return -EAGAIN; It would be hard to distinguish different EAGAIN reasons in the upper layers. As of now we use EAGAIN as retryable error indicating the upper layer to retry. This case is different because the retry most likely won't help and the sequential fallback is needed. In compound_send_recv() we return -ENOTSUPP if there is not enough credits to satisfy compounding and the number of requests in flight doesn't promise to get new credits in future. I suggest to return the same error code here (-ENOTSUPP). Probably this particular error code isn't ideal choice and suggestions to change it are welcome. > + } > + if (rc == -ERESTARTSYS) > + return -ERESTARTSYS; > spin_lock(&server->req_lock); > } else { > if (server->tcpStatus == CifsExiting) { > @@ -537,12 +549,19 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, > *credits <= MAX_COMPOUND) { > spin_unlock(&server->req_lock); > cifs_num_waiters_inc(server); > - rc = wait_event_killable(server->request_q, > + rc = wait_event_killable_timeout( > + server->request_q, > has_credits(server, credits, > - MAX_COMPOUND + 1)); > + MAX_COMPOUND + 1), > + t); > cifs_num_waiters_dec(server); > - if (rc) > - return rc; > + if (!rc) { > + cifs_dbg(VFS, "wait timed out after %d ms\n", > + timeout); > + return -EAGAIN; > + } > + if (rc == -ERESTARTSYS) > + return -ERESTARTSYS; > spin_lock(&server->req_lock); > continue; > } > @@ -569,7 +588,8 @@ static int > wait_for_free_request(struct TCP_Server_Info *server, const int flags, > unsigned int *instance) > { > - return wait_for_free_credits(server, 1, flags, instance); > + return wait_for_free_credits(server, 1, -1, flags, > + instance); > } > > int > -- > 2.13.6 > -- Best regards, Pavel Shilovsky