[linux-cifs-client] [PATCH 4/6] [CIFS] change cifs_setup_session to take a unc string arg

Steve French smfrench at gmail.com
Wed Nov 7 14:10:22 GMT 2007


Reconnection of tcp session after network failure today assumes that
the IP address stays the same (we reconnect to the same ip address)
but eventually we should be able to handle the case in which the host
has gone down but been mapped to a different ip address.   This also
seems to require saving the host name in the TCP_Server_Info struct.

On Nov 7, 2007 5:31 AM, Q (Igor Mammedov) <qwerty0987654321 at mail.ru> wrote:
> Wouldn't it be better if we saved hostname portion of unc in some field
> of TCP_Server_Info struct? That would result in more reusability of it
> in future and we wouldn't have to change signatures whenever we wish to
> use it.
>
> Jeff Layton wrote:
> > ...then extract the host portion of the UNC string so that we can
>
> > use in SPNEGO.
> >
> > Signed-off-by: Jeff Layton <jlayton at redhat.com>
> > ---
> >  fs/cifs/cifsproto.h |    2 +-
> >  fs/cifs/cifssmb.c   |    6 ++++--
> >  fs/cifs/connect.c   |   46 ++++++++++++++++++++++++++++++++++++++++++++--
> >  3 files changed, 49 insertions(+), 5 deletions(-)
> >
> > diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
> > index dd1d7c2..b256e8a 100644
> > --- a/fs/cifs/cifsproto.h
> > +++ b/fs/cifs/cifsproto.h
> > @@ -107,7 +107,7 @@ void cifs_proc_init(void);
> >  void cifs_proc_clean(void);
> >
> >  extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
> > -                     struct nls_table *nls_info);
> > +                     struct nls_table *nls_info, const char *unc);
> >  extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);
> >
> >  extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
> > diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
> > index 0bb3e43..49ad995 100644
> > --- a/fs/cifs/cifssmb.c
> > +++ b/fs/cifs/cifssmb.c
> > @@ -157,7 +157,8 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
> >                       down(&tcon->ses->sesSem);
> >                       if (tcon->ses->status == CifsNeedReconnect)
> >                               rc = cifs_setup_session(0, tcon->ses,
> > -                                                     nls_codepage);
> > +                                                     nls_codepage,
> > +                                                     tcon->treeName);
> >                       if (!rc && (tcon->tidStatus == CifsNeedReconnect)) {
> >                               mark_open_files_invalid(tcon);
> >                               rc = CIFSTCon(0, tcon->ses, tcon->treeName,
> > @@ -302,7 +303,8 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
> >                       down(&tcon->ses->sesSem);
> >                       if (tcon->ses->status == CifsNeedReconnect)
> >                               rc = cifs_setup_session(0, tcon->ses,
> > -                                                     nls_codepage);
> > +                                                     nls_codepage,
> > +                                                     tcon->treeName);
> >                       if (!rc && (tcon->tidStatus == CifsNeedReconnect)) {
> >                               mark_open_files_invalid(tcon);
> >                               rc = CIFSTCon(0, tcon->ses, tcon->treeName,
> > diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> > index 380ee99..14b564e 100644
> > --- a/fs/cifs/connect.c
> > +++ b/fs/cifs/connect.c
> > @@ -1996,7 +1996,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
> >                       down(&pSesInfo->sesSem);
> >                       /* BB FIXME need to pass vol->secFlgs BB */
> >                       rc = cifs_setup_session(xid, pSesInfo,
> > -                                             cifs_sb->local_nls);
> > +                                             cifs_sb->local_nls,
> > +                                             volume_info.UNC);
> >                       up(&pSesInfo->sesSem);
> >                       if (!rc)
> >                               atomic_inc(&srvTcp->socketUseCount);
> > @@ -3508,13 +3509,51 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
> >       return rc;      /* BB check if we should always return zero here */
> >  }
> >
> > +/* extract the host portion of the UNC string */
> > +static char *
> > +extract_hostname_from_unc(const char *unc)
> > +{
> > +     const char *src;
> > +     char *dst, *delim;
> > +     unsigned int len;
> > +
> > +     /* skip double chars at beginning of string */
> > +     /* BB: check validity of these bytes? */
> > +     src = unc + 2;
> > +
> > +     delim = strchr(src, '/');
> > +     if (!delim) {
> > +             delim = strchr(src, '\\');
> > +             if (!delim)
> > +                     return ERR_PTR(-EINVAL);
> > +     }
> > +
> > +     len = delim - src;
> > +     dst = kmalloc((len + 1), GFP_KERNEL);
> > +     if (dst == NULL)
> > +             return ERR_PTR(-ENOMEM);
> > +
> > +     memcpy(dst, src, len);
> > +     dst[len] = '\0';
> > +
> > +     return dst;
> > +}
> > +
> >  int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
> > -                                        struct nls_table *nls_info)
> > +                     struct nls_table *nls_info, const char *unc)
> >  {
> >       int rc = 0;
> >       char ntlm_session_key[CIFS_SESS_KEY_SIZE];
> >       int ntlmv2_flag = FALSE;
> >       int first_time = 0;
> > +     char *hostname;
> > +
> > +     hostname = extract_hostname_from_unc(unc);
> > +     if (IS_ERR(hostname)) {
> > +             rc = PTR_ERR(hostname);
> > +             hostname = NULL;
> > +             goto ss_err_exit;
> > +     }
> >
> >       /* what if server changes its buffer size after dropping the session? */
> >       if (pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
> > @@ -3627,6 +3666,9 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
> >               }
> >       }
> >  ss_err_exit:
> > +     if (hostname)
> > +             kfree(hostname);
> > +
> >       return rc;
> >  }
> >
>
>
> --
>
> Best regards,
>
> -------------------------
> Igor Mammedov,
> niallain "at" gmail.com
>
>
>
>
>



-- 
Thanks,

Steve


More information about the linux-cifs-client mailing list