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

Jeff Layton jlayton at redhat.com
Wed Nov 7 14:58:05 GMT 2007


On Wed, 7 Nov 2007 08:10:22 -0600
"Steve French" <smfrench at gmail.com> wrote:

> 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.
> 

Sounds reasonable. If we're going to do that though, maybe it makes
sense to do this parsing from cifs_mount (during the phase where
we parse arguments) instead of doing it from the session setup.

> 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


-- 
Jeff Layton <jlayton at redhat.com>


More information about the linux-cifs-client mailing list