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 >