Re: [PATCH] cifs : handle ERRBaduid for SMB1

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

 



Reviewed-by: Ronnie Sahlberg <lsahlber@xxxxxxxxxx>

On Fri, Jul 3, 2020 at 7:30 PM Roberto Bergantinos Corpas
<rbergant@xxxxxxxxxx> wrote:
>
> If server returns ERRBaduid but does not reset transport connection,
> we'll keep sending command with a non-valid UID for the server as long
> as transport is healthy, without actually recovering. This have been
> observed on the field.
>
> This patch adds ERRBaduid handling so that we set CifsNeedReconnect.
>
> map_and_check_smb_error() can be modified to extend use cases.
>
> Signed-off-by: Roberto Bergantinos Corpas <rbergant@xxxxxxxxxx>
> ---
>  fs/cifs/cifsproto.h |  1 +
>  fs/cifs/netmisc.c   | 27 +++++++++++++++++++++++++++
>  fs/cifs/transport.c |  2 +-
>  3 files changed, 29 insertions(+), 1 deletion(-)
>
> diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
> index 948bf3474db1..d72cf20ab048 100644
> --- a/fs/cifs/cifsproto.h
> +++ b/fs/cifs/cifsproto.h
> @@ -149,6 +149,7 @@ extern int decode_negTokenInit(unsigned char *security_blob, int length,
>  extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
>  extern void cifs_set_port(struct sockaddr *addr, const unsigned short int port);
>  extern int map_smb_to_linux_error(char *buf, bool logErr);
> +extern int map_and_check_smb_error(struct mid_q_entry *mid, bool logErr);
>  extern void header_assemble(struct smb_hdr *, char /* command */ ,
>                             const struct cifs_tcon *, int /* length of
>                             fixed section (word count) in two byte units */);
> diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
> index 9b41436fb8db..ae9679a27181 100644
> --- a/fs/cifs/netmisc.c
> +++ b/fs/cifs/netmisc.c
> @@ -881,6 +881,33 @@ map_smb_to_linux_error(char *buf, bool logErr)
>         return rc;
>  }
>
> +int
> +map_and_check_smb_error(struct mid_q_entry *mid, bool logErr)
> +{
> +       int rc;
> +       struct smb_hdr *smb = (struct smb_hdr *)mid->resp_buf;
> +
> +       rc = map_smb_to_linux_error((char *)smb, logErr);
> +       if (rc == -EACCES && !(smb->Flags2 & SMBFLG2_ERR_STATUS)) {
> +               /* possible ERRBaduid */
> +               __u8 class = smb->Status.DosError.ErrorClass;
> +               __u16 code = le16_to_cpu(smb->Status.DosError.Error);
> +
> +               /* switch can be used to handle different errors */
> +               if (class == ERRSRV && code == ERRbaduid) {
> +                       cifs_dbg(FYI, "Server returned 0x%x, reconnecting session...\n",
> +                               code);
> +                       spin_lock(&GlobalMid_Lock);
> +                       if (mid->server->tcpStatus != CifsExiting)
> +                               mid->server->tcpStatus = CifsNeedReconnect;
> +                       spin_unlock(&GlobalMid_Lock);
> +               }
> +       }
> +
> +       return rc;
> +}
> +
> +
>  /*
>   * calculate the size of the SMB message based on the fixed header
>   * portion, the number of word parameters and the data portion of the message
> diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
> index cb3ee916f527..e8dbd6b55559 100644
> --- a/fs/cifs/transport.c
> +++ b/fs/cifs/transport.c
> @@ -935,7 +935,7 @@ cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
>         }
>
>         /* BB special case reconnect tid and uid here? */
> -       return map_smb_to_linux_error(mid->resp_buf, log_error);
> +       return map_and_check_smb_error(mid, log_error);
>  }
>
>  struct mid_q_entry *
> --
> 2.21.0
>



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

  Powered by Linux