Handle mismatched open calls
A signal can interrupt a SendReceive call which result in incoming responses to the call being ignored. This is a problem for calls such as open which results in the successful response being ignored. This results in an open file resource on the server. The patch looks into responses which were cancelled after being sent and in case of successful open closes the open fids. For this patch, the check is only done in SendReceive2() RH-bz: 1403319 Signed-off-by: Sachin Prabhu <sprabhu@redhat.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> Cc: Stable <stable@vger.kernel.org>
This commit is contained in:

committad av
Steve French

förälder
269c930e66
incheckning
38bd49064a
@@ -1400,9 +1400,9 @@ openRetry:
|
||||
* current bigbuf.
|
||||
*/
|
||||
int
|
||||
cifs_discard_remaining_data(struct TCP_Server_Info *server)
|
||||
cifs_discard_remaining_data(struct TCP_Server_Info *server, char *buf)
|
||||
{
|
||||
unsigned int rfclen = get_rfc1002_length(server->smallbuf);
|
||||
unsigned int rfclen = get_rfc1002_length(buf);
|
||||
int remaining = rfclen + 4 - server->total_read;
|
||||
|
||||
while (remaining > 0) {
|
||||
@@ -1426,7 +1426,7 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
||||
int length;
|
||||
struct cifs_readdata *rdata = mid->callback_data;
|
||||
|
||||
length = cifs_discard_remaining_data(server);
|
||||
length = cifs_discard_remaining_data(server, mid->resp_buf);
|
||||
dequeue_mid(mid, rdata->result);
|
||||
return length;
|
||||
}
|
||||
@@ -1459,7 +1459,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
||||
|
||||
if (server->ops->is_status_pending &&
|
||||
server->ops->is_status_pending(buf, server, 0)) {
|
||||
cifs_discard_remaining_data(server);
|
||||
cifs_discard_remaining_data(server, buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1519,6 +1519,9 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
||||
cifs_dbg(FYI, "0: iov_base=%p iov_len=%u\n",
|
||||
rdata->iov[0].iov_base, server->total_read);
|
||||
|
||||
mid->resp_buf = server->smallbuf;
|
||||
server->smallbuf = NULL;
|
||||
|
||||
/* how much data is in the response? */
|
||||
data_len = server->ops->read_data_length(buf);
|
||||
if (data_offset + data_len > buflen) {
|
||||
|
Referens i nytt ärende
Block a user