Re: [PATCH 4/8] cifs: update receive_encrypted_standard to handle compounded responses

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2018-07-31 16:26 GMT-07:00 Ronnie Sahlberg <lsahlber@xxxxxxxxxx>:
> Signed-off-by: Ronnie Sahlberg <lsahlber@xxxxxxxxxx>
> ---
>  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@xxxxxxxxxxxxxxx
> 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@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux