Skip to content

Commit

Permalink
CIFS: Avoid returning EBUSY to upper layer VFS
Browse files Browse the repository at this point in the history
EBUSY is not handled by VFS, and will be passed to user-mode. This is not
correct as we need to wait for more credits.

This patch also fixes a bug where rsize or wsize is used uninitialized when
the call to server->ops->wait_mtu_credits() fails.

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Long Li <longli@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
  • Loading branch information
Long Li authored and Steve French committed Dec 7, 2018
1 parent c988de2 commit 6ac7929
Showing 1 changed file with 6 additions and 25 deletions.
31 changes: 6 additions & 25 deletions fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2541,34 +2541,27 @@ static int
cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
struct cifs_aio_ctx *ctx)
{
int wait_retry = 0;
unsigned int wsize, credits;
int rc;
struct TCP_Server_Info *server =
tlink_tcon(wdata->cfile->tlink)->ses->server;

/*
* Try to resend this wdata, waiting for credits up to 3 seconds.
* Wait for credits to resend this wdata.
* Note: we are attempting to resend the whole wdata not in segments
*/
do {
rc = server->ops->wait_mtu_credits(
server, wdata->bytes, &wsize, &credits);

if (rc)
break;
goto out;

if (wsize < wdata->bytes) {
add_credits_and_wake_if(server, credits, 0);
msleep(1000);
wait_retry++;
}
} while (wsize < wdata->bytes && wait_retry < 3);

if (wsize < wdata->bytes) {
rc = -EBUSY;
goto out;
}
} while (wsize < wdata->bytes);

rc = -EAGAIN;
while (rc == -EAGAIN) {
Expand Down Expand Up @@ -3234,39 +3227,27 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
struct list_head *rdata_list,
struct cifs_aio_ctx *ctx)
{
int wait_retry = 0;
unsigned int rsize, credits;
int rc;
struct TCP_Server_Info *server =
tlink_tcon(rdata->cfile->tlink)->ses->server;

/*
* Try to resend this rdata, waiting for credits up to 3 seconds.
* Wait for credits to resend this rdata.
* Note: we are attempting to resend the whole rdata not in segments
*/
do {
rc = server->ops->wait_mtu_credits(server, rdata->bytes,
&rsize, &credits);

if (rc)
break;
goto out;

if (rsize < rdata->bytes) {
add_credits_and_wake_if(server, credits, 0);
msleep(1000);
wait_retry++;
}
} while (rsize < rdata->bytes && wait_retry < 3);

/*
* If we can't find enough credits to send this rdata
* release the rdata and return failure, this will pass
* whatever I/O amount we have finished to VFS.
*/
if (rsize < rdata->bytes) {
rc = -EBUSY;
goto out;
}
} while (rsize < rdata->bytes);

rc = -EAGAIN;
while (rc == -EAGAIN) {
Expand Down

0 comments on commit 6ac7929

Please sign in to comment.