Message ID | 20180731232618.23586-5-lsahlber@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | cifs compounding | expand |
2018-07-31 16:26 GMT-07:00 Ronnie Sahlberg <lsahlber@redhat.com>: > Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> > --- > fs/cifs/smb2ops.c | 39 ++++++++++++++++++++++++++++++++++++--- > 1 file changed, 36 insertions(+), 3 deletions(-) > > diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c > index 81ff2bd6ceaa..10b888b954e4 100644 > --- a/fs/cifs/smb2ops.c > +++ b/fs/cifs/smb2ops.c > @@ -2930,11 +2930,14 @@ static int > receive_encrypted_standard(struct TCP_Server_Info *server, > struct mid_q_entry **mid) > { > - int length; > + int ret, length; > char *buf = server->smallbuf; > + struct smb2_sync_hdr *shdr; > unsigned int pdu_length = server->pdu_size; > unsigned int buf_size; > struct mid_q_entry *mid_entry; > + int next_is_large; > + char *next_buffer = NULL; > > /* switch to large buffer if too big for a small one */ > if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE) { > @@ -2955,6 +2958,21 @@ receive_encrypted_standard(struct TCP_Server_Info *server, > if (length) > return length; > > + next_is_large = server->large_buf; > + one_more: > + shdr = (struct smb2_sync_hdr *)buf; > + if (shdr->NextCommand) { > + if (next_is_large) { > + next_buffer = (char *)cifs_buf_get(); > + memcpy(next_buffer, server->bigbuf + shdr->NextCommand, > + pdu_length - shdr->NextCommand); > + } else { > + next_buffer = (char *)cifs_small_buf_get(); > + memcpy(next_buffer, server->smallbuf + shdr->NextCommand, > + pdu_length - shdr->NextCommand); > + } > + } > + > mid_entry = smb2_find_mid(server, buf); > if (mid_entry == NULL) > cifs_dbg(FYI, "mid not found\n"); > @@ -2962,13 +2980,28 @@ receive_encrypted_standard(struct TCP_Server_Info *server, > cifs_dbg(FYI, "mid found\n"); > mid_entry->decrypted = true; > } > + mid_entry->resp_buf_size = server->pdu_size; > > *mid = mid_entry; demultiplex thread calls receive_encrypted_standard() with double pointer to mid to populate, so it can issue mid->callback to wake up a thread waiting for a specific mid. Now in receive_encrypted_standard() we process several mids but save only the last one in the output thus demultiplex thread will only call mid->callback for the last message in a chain. In the same time in compound_send_recv() we call wait_for_response() for every mid in a compounded chain. Doesn't it mean that we will wait forever or am I missing something? > > if (mid_entry && mid_entry->handle) > - return mid_entry->handle(server, mid_entry); > + ret = mid_entry->handle(server, mid_entry); > + else > + ret = cifs_handle_standard(server, mid_entry); > + > + if (ret == 0 && shdr->NextCommand) { > + pdu_length -= shdr->NextCommand; > + server->large_buf = next_is_large; > + if (next_is_large) { > + server->bigbuf = next_buffer; > + } else { > + server->smallbuf = next_buffer; > + } > + buf += shdr->NextCommand; > + goto one_more; > + } > > - return cifs_handle_standard(server, mid_entry); > + return ret; > } > > static int > -- > 2.13.3 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-cifs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 81ff2bd6ceaa..10b888b954e4 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -2930,11 +2930,14 @@ static int receive_encrypted_standard(struct TCP_Server_Info *server, struct mid_q_entry **mid) { - int length; + int ret, length; char *buf = server->smallbuf; + struct smb2_sync_hdr *shdr; unsigned int pdu_length = server->pdu_size; unsigned int buf_size; struct mid_q_entry *mid_entry; + int next_is_large; + char *next_buffer = NULL; /* switch to large buffer if too big for a small one */ if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE) { @@ -2955,6 +2958,21 @@ receive_encrypted_standard(struct TCP_Server_Info *server, if (length) return length; + next_is_large = server->large_buf; + one_more: + shdr = (struct smb2_sync_hdr *)buf; + if (shdr->NextCommand) { + if (next_is_large) { + next_buffer = (char *)cifs_buf_get(); + memcpy(next_buffer, server->bigbuf + shdr->NextCommand, + pdu_length - shdr->NextCommand); + } else { + next_buffer = (char *)cifs_small_buf_get(); + memcpy(next_buffer, server->smallbuf + shdr->NextCommand, + pdu_length - shdr->NextCommand); + } + } + mid_entry = smb2_find_mid(server, buf); if (mid_entry == NULL) cifs_dbg(FYI, "mid not found\n"); @@ -2962,13 +2980,28 @@ receive_encrypted_standard(struct TCP_Server_Info *server, cifs_dbg(FYI, "mid found\n"); mid_entry->decrypted = true; } + mid_entry->resp_buf_size = server->pdu_size; *mid = mid_entry; if (mid_entry && mid_entry->handle) - return mid_entry->handle(server, mid_entry); + ret = mid_entry->handle(server, mid_entry); + else + ret = cifs_handle_standard(server, mid_entry); + + if (ret == 0 && shdr->NextCommand) { + pdu_length -= shdr->NextCommand; + server->large_buf = next_is_large; + if (next_is_large) { + server->bigbuf = next_buffer; + } else { + server->smallbuf = next_buffer; + } + buf += shdr->NextCommand; + goto one_more; + } - return cifs_handle_standard(server, mid_entry); + return ret; } static int
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> --- fs/cifs/smb2ops.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-)