]> err.no Git - linux-2.6/blobdiff - fs/cifs/connect.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6
[linux-2.6] / fs / cifs / connect.c
index 01608bb4d673d9033ab10adac4bcfd9a38055aab..c78762051da4e5b15da45fa06b46b66d85e55d82 100644 (file)
@@ -89,6 +89,7 @@ struct smb_vol {
        unsigned int wsize;
        unsigned int sockopt;
        unsigned short int port;
+       char * prepath;
 };
 
 static int ipv4_connect(struct sockaddr_in *psin_server, 
@@ -182,6 +183,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
 
        while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood))
        {
+               try_to_freeze();
                if(server->protocolType == IPV6) {
                        rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket);
                } else {
@@ -612,6 +614,10 @@ multi_t2_fnd:
 #ifdef CONFIG_CIFS_STATS2
                                mid_entry->when_received = jiffies;
 #endif
+                               /* so we do not time out requests to  server
+                               which is still responding (since server could
+                               be busy but not dead) */
+                               server->lstrp = jiffies;
                                break;
                        }
                }
@@ -766,12 +772,12 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
        separator[1] = 0; 
 
        memset(vol->source_rfc1001_name,0x20,15);
-       for(i=0;i < strnlen(system_utsname.nodename,15);i++) {
+       for(i=0;i < strnlen(utsname()->nodename,15);i++) {
                /* does not have to be a perfect mapping since the field is
                informational, only used for servers that do not support
                port 445 and it can be overridden at mount time */
                vol->source_rfc1001_name[i] = 
-                       toupper(system_utsname.nodename[i]);
+                       toupper(utsname()->nodename[i]);
        }
        vol->source_rfc1001_name[15] = 0;
        /* null target name indicates to use *SMBSERVR default called name
@@ -915,32 +921,32 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
                                cERROR(1,("no security value specified"));
                                 continue;
                         } else if (strnicmp(value, "krb5i", 5) == 0) {
-                               vol->secFlg = CIFSSEC_MAY_KRB5 | 
+                               vol->secFlg |= CIFSSEC_MAY_KRB5 | 
                                        CIFSSEC_MUST_SIGN;
                        } else if (strnicmp(value, "krb5p", 5) == 0) {
-                               /* vol->secFlg = CIFSSEC_MUST_SEAL | 
+                               /* vol->secFlg |= CIFSSEC_MUST_SEAL | 
                                        CIFSSEC_MAY_KRB5; */ 
                                cERROR(1,("Krb5 cifs privacy not supported"));
                                return 1;
                        } else if (strnicmp(value, "krb5", 4) == 0) {
-                               vol->secFlg = CIFSSEC_MAY_KRB5;
+                               vol->secFlg |= CIFSSEC_MAY_KRB5;
                        } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
-                               vol->secFlg = CIFSSEC_MAY_NTLMV2 |
+                               vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
                                        CIFSSEC_MUST_SIGN;
                        } else if (strnicmp(value, "ntlmv2", 6) == 0) {
-                               vol->secFlg = CIFSSEC_MAY_NTLMV2;
+                               vol->secFlg |= CIFSSEC_MAY_NTLMV2;
                        } else if (strnicmp(value, "ntlmi", 5) == 0) {
-                               vol->secFlg = CIFSSEC_MAY_NTLM |
+                               vol->secFlg |= CIFSSEC_MAY_NTLM |
                                        CIFSSEC_MUST_SIGN;
                        } else if (strnicmp(value, "ntlm", 4) == 0) {
                                /* ntlm is default so can be turned off too */
-                               vol->secFlg = CIFSSEC_MAY_NTLM;
+                               vol->secFlg |= CIFSSEC_MAY_NTLM;
                        } else if (strnicmp(value, "nontlm", 6) == 0) {
                                /* BB is there a better way to do this? */
-                               vol->secFlg = CIFSSEC_MAY_NTLMV2;
+                               vol->secFlg |= CIFSSEC_MAY_NTLMV2;
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
                        } else if (strnicmp(value, "lanman", 6) == 0) {
-                                vol->secFlg = CIFSSEC_MAY_LANMAN;
+                                vol->secFlg |= CIFSSEC_MAY_LANMAN;
 #endif
                        } else if (strnicmp(value, "none", 4) == 0) {
                                vol->nullauth = 1;
@@ -988,6 +994,28 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
                                printk(KERN_WARNING "CIFS: domain name too long\n");
                                return 1;
                        }
+                } else if (strnicmp(data, "prefixpath", 10) == 0) {
+                        if (!value || !*value) {
+                                printk(KERN_WARNING
+                                       "CIFS: invalid path prefix\n");
+                                return 1;       /* needs_arg; */
+                        }
+                        if ((temp_len = strnlen(value, 1024)) < 1024) {
+                               if(value[0] != '/')
+                                       temp_len++;  /* missing leading slash */
+                                vol->prepath = kmalloc(temp_len+1,GFP_KERNEL);
+                                if(vol->prepath == NULL)
+                                        return 1;
+                               if(value[0] != '/') {
+                                       vol->prepath[0] = '/';
+                                       strcpy(vol->prepath+1,value);
+                               } else
+                                       strcpy(vol->prepath,value);
+                               cFYI(1,("prefix path %s",vol->prepath));
+                        } else {
+                                printk(KERN_WARNING "CIFS: prefix too long\n");
+                                return 1;
+                        }
                } else if (strnicmp(data, "iocharset", 9) == 0) {
                        if (!value || !*value) {
                                printk(KERN_WARNING "CIFS: invalid iocharset specified\n");
@@ -1173,6 +1201,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
                        vol->no_psx_acl = 0;
                } else if (strnicmp(data, "noacl",5) == 0) {
                        vol->no_psx_acl = 1;
+               } else if (strnicmp(data, "sign",4) == 0) {
+                       vol->secFlg |= CIFSSEC_MUST_SIGN;
+/*             } else if (strnicmp(data, "seal",4) == 0) {
+                       vol->secFlg |= CIFSSEC_MUST_SEAL; */
                } else if (strnicmp(data, "direct",6) == 0) {
                        vol->direct_io = 1;
                } else if (strnicmp(data, "forcedirectio",13) == 0) {
@@ -1262,33 +1294,35 @@ find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
 
        read_lock(&GlobalSMBSeslock);
        list_for_each(tmp, &GlobalTreeConnectionList) {
-               cFYI(1, ("Next tcon - "));
+               cFYI(1, ("Next tcon"));
                tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
                if (tcon->ses) {
                        if (tcon->ses->server) {
                                cFYI(1,
-                                    (" old ip addr: %x == new ip %x ?",
+                                    ("old ip addr: %x == new ip %x ?",
                                      tcon->ses->server->addr.sockAddr.sin_addr.
                                      s_addr, new_target_ip_addr));
                                if (tcon->ses->server->addr.sockAddr.sin_addr.
                                    s_addr == new_target_ip_addr) {
-       /* BB lock tcon and server and tcp session and increment use count here? */
+       /* BB lock tcon, server and tcp session and increment use count here? */
                                        /* found a match on the TCP session */
                                        /* BB check if reconnection needed */
-                                       cFYI(1,("Matched ip, old UNC: %s == new: %s ?",
+                                       cFYI(1,("IP match, old UNC: %s new: %s",
                                              tcon->treeName, uncName));
                                        if (strncmp
                                            (tcon->treeName, uncName,
                                             MAX_TREE_SIZE) == 0) {
                                                cFYI(1,
-                                                    ("Matched UNC, old user: %s == new: %s ?",
+                                                    ("and old usr: %s new: %s",
                                                      tcon->treeName, uncName));
                                                if (strncmp
                                                    (tcon->ses->userName,
                                                     userName,
                                                     MAX_USERNAME_SIZE) == 0) {
                                                        read_unlock(&GlobalSMBSeslock);
-                                                       return tcon;/* also matched user (smb session)*/
+                                                       /* matched smb session
+                                                       (user name */
+                                                       return tcon;
                                                }
                                        }
                                }
@@ -1594,6 +1628,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
        if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
                kfree(volume_info.UNC);
                kfree(volume_info.password);
+               kfree(volume_info.prepath);
                FreeXid(xid);
                return -EINVAL;
        }
@@ -1608,6 +1643,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
            locations such as env variables and files on disk */
                kfree(volume_info.UNC);
                kfree(volume_info.password);
+               kfree(volume_info.prepath);
                FreeXid(xid);
                return -EINVAL;
        }
@@ -1628,6 +1664,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        /* we failed translating address */
                        kfree(volume_info.UNC);
                        kfree(volume_info.password);
+                       kfree(volume_info.prepath);
                        FreeXid(xid);
                        return -EINVAL;
                }
@@ -1640,6 +1677,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                cERROR(1,("Connecting to DFS root not implemented yet"));
                kfree(volume_info.UNC);
                kfree(volume_info.password);
+               kfree(volume_info.prepath);
                FreeXid(xid);
                return -EINVAL;
        } else /* which servers DFS root would we conect to */ {
@@ -1647,6 +1685,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                       ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified"));
                kfree(volume_info.UNC);
                kfree(volume_info.password);
+               kfree(volume_info.prepath);
                FreeXid(xid);
                return -EINVAL;
        }
@@ -1661,6 +1700,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));
                        kfree(volume_info.UNC);
                        kfree(volume_info.password);
+                       kfree(volume_info.prepath);
                        FreeXid(xid);
                        return -ELIBACC;
                }
@@ -1677,6 +1717,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
        else {
                kfree(volume_info.UNC);
                kfree(volume_info.password);
+               kfree(volume_info.prepath);
                FreeXid(xid);
                return -EINVAL;
        }
@@ -1699,6 +1740,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                                sock_release(csocket);
                        kfree(volume_info.UNC);
                        kfree(volume_info.password);
+                       kfree(volume_info.prepath);
                        FreeXid(xid);
                        return rc;
                }
@@ -1709,6 +1751,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        sock_release(csocket);
                        kfree(volume_info.UNC);
                        kfree(volume_info.password);
+                       kfree(volume_info.prepath);
                        FreeXid(xid);
                        return rc;
                } else {
@@ -1733,6 +1776,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                                sock_release(csocket);
                                kfree(volume_info.UNC);
                                kfree(volume_info.password);
+                               kfree(volume_info.prepath);
                                FreeXid(xid);
                                return rc;
                        }
@@ -1776,6 +1820,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                                                volume_info.domainname);
                        }
                        pSesInfo->linux_uid = volume_info.linux_uid;
+                       pSesInfo->overrideSecFlg = volume_info.secFlg;
                        down(&pSesInfo->sesSem);
                        /* BB FIXME need to pass vol->secFlgs BB */
                        rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls);
@@ -1819,6 +1864,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        /* Windows ME may prefer this */
                        cFYI(1,("readsize set to minimum 2048"));
                }
+               /* calculate prepath */
+               cifs_sb->prepath = volume_info.prepath;
+               if(cifs_sb->prepath) {
+                       cifs_sb->prepathlen = strlen(cifs_sb->prepath);
+                       cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
+                       volume_info.prepath = NULL;
+               } else 
+                       cifs_sb->prepathlen = 0;
                cifs_sb->mnt_uid = volume_info.linux_uid;
                cifs_sb->mnt_gid = volume_info.linux_gid;
                cifs_sb->mnt_file_mode = volume_info.file_mode;
@@ -1964,7 +2017,18 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                                }
                                        
                                cFYI(1,("Negotiate caps 0x%x",(int)cap));
-
+#ifdef CONFIG_CIFS_DEBUG2
+                               if(cap & CIFS_UNIX_FCNTL_CAP)
+                                       cFYI(1,("FCNTL cap"));
+                               if(cap & CIFS_UNIX_EXTATTR_CAP)
+                                       cFYI(1,("EXTATTR cap"));
+                               if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
+                                       cFYI(1,("POSIX path cap"));
+                               if(cap & CIFS_UNIX_XATTR_CAP)
+                                       cFYI(1,("XATTR cap"));
+                               if(cap & CIFS_UNIX_POSIX_ACL_CAP)
+                                       cFYI(1,("POSIX ACL cap"));
+#endif /* CIFS_DEBUG2 */
                                if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
                                        cFYI(1,("setting capabilities failed"));
                                }
@@ -1985,6 +2049,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
        the password ptr is put in the new session structure (in which case the
        password will be freed at unmount time) */
        kfree(volume_info.UNC);
+       kfree(volume_info.prepath);
        FreeXid(xid);
        return rc;
 }
@@ -2088,7 +2153,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                  32, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bytes_returned =
-                   cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
                                  32, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;
@@ -2115,8 +2180,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                }
                strcpy(bcc_ptr, "Linux version ");
                bcc_ptr += strlen("Linux version ");
-               strcpy(bcc_ptr, system_utsname.release);
-               bcc_ptr += strlen(system_utsname.release) + 1;
+               strcpy(bcc_ptr, utsname()->release);
+               bcc_ptr += strlen(utsname()->release) + 1;
                strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
                bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
        }
@@ -2173,8 +2238,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                if (remaining_words > 0) {
                                        len = UniStrnlen((wchar_t *)bcc_ptr,
                                                         remaining_words-1);
-                                       if(ses->serverNOS)
-                                               kfree(ses->serverNOS);
+                                       kfree(ses->serverNOS);
                                        ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL);
                                        if(ses->serverNOS == NULL)
                                                goto sesssetup_nomem;
@@ -2214,12 +2278,10 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                        /* if these kcallocs fail not much we
                                           can do, but better to not fail the
                                           sesssetup itself */
-                                       if(ses->serverDomain)
-                                               kfree(ses->serverDomain);
+                                       kfree(ses->serverDomain);
                                        ses->serverDomain =
                                            kzalloc(2, GFP_KERNEL);
-                                       if(ses->serverNOS)
-                                               kfree(ses->serverNOS);
+                                       kfree(ses->serverNOS);
                                        ses->serverNOS =
                                            kzalloc(2, GFP_KERNEL);
                                }
@@ -2228,8 +2290,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                if (((long) bcc_ptr + len) - (long)
                                    pByteArea(smb_buffer_response)
                                            <= BCC(smb_buffer_response)) {
-                                       if(ses->serverOS)
-                                               kfree(ses->serverOS);
+                                       kfree(ses->serverOS);
                                        ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
                                        if(ses->serverOS == NULL)
                                                goto sesssetup_nomem;
@@ -2240,8 +2301,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                        bcc_ptr++;
 
                                        len = strnlen(bcc_ptr, 1024);
-                                       if(ses->serverNOS)
-                                               kfree(ses->serverNOS);
+                                       kfree(ses->serverNOS);
                                        ses->serverNOS = kzalloc(len + 1,GFP_KERNEL);
                                        if(ses->serverNOS == NULL)
                                                goto sesssetup_nomem;
@@ -2385,7 +2445,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                  32, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bytes_returned =
-                   cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
                                  nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;   /* null terminate Linux version */
@@ -2402,8 +2462,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
        } else {                /* ASCII */
                strcpy(bcc_ptr, "Linux version ");
                bcc_ptr += strlen("Linux version ");
-               strcpy(bcc_ptr, system_utsname.release);
-               bcc_ptr += strlen(system_utsname.release) + 1;
+               strcpy(bcc_ptr, utsname()->release);
+               bcc_ptr += strlen(utsname()->release) + 1;
                strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
                bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
                bcc_ptr++;      /* empty domain field */
@@ -2508,8 +2568,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                                                 bcc_ptr,
                                                                 remaining_words
                                                                 - 1);
-                                               if(ses->serverNOS)
-                                                       kfree(ses->serverNOS);
+                                               kfree(ses->serverNOS);
                                                ses->serverNOS =
                                                    kzalloc(2 * (len + 1),
                                                            GFP_KERNEL);
@@ -2527,8 +2586,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                                if (remaining_words > 0) {
                                                        len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 
            /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
-                                                       if(ses->serverDomain)
-                                                               kfree(ses->serverDomain);
+                                                       kfree(ses->serverDomain);
                                                        ses->serverDomain =
                                                            kzalloc(2 *
                                                                    (len +
@@ -2547,19 +2605,16 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                                            = 0;
                                                } /* else no more room so create dummy domain string */
                                                else {
-                                                       if(ses->serverDomain)
-                                                               kfree(ses->serverDomain);
+                                                       kfree(ses->serverDomain);
                                                        ses->serverDomain =
                                                            kzalloc(2,
                                                                    GFP_KERNEL);
                                                }
                                        } else {        /* no room so create dummy domain and NOS string */
-                                               if(ses->serverDomain);
-                                                       kfree(ses->serverDomain);
+                                               kfree(ses->serverDomain);
                                                ses->serverDomain =
                                                    kzalloc(2, GFP_KERNEL);
-                                               if(ses->serverNOS)
-                                                       kfree(ses->serverNOS);
+                                               kfree(ses->serverNOS);
                                                ses->serverNOS =
                                                    kzalloc(2, GFP_KERNEL);
                                        }
@@ -2581,8 +2636,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                                bcc_ptr++;
 
                                                len = strnlen(bcc_ptr, 1024);
-                                               if(ses->serverNOS)
-                                                       kfree(ses->serverNOS);
+                                               kfree(ses->serverNOS);
                                                ses->serverNOS =
                                                    kzalloc(len + 1,
                                                            GFP_KERNEL);
@@ -2592,8 +2646,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                                bcc_ptr++;
 
                                                len = strnlen(bcc_ptr, 1024);
-                                               if(ses->serverDomain)
-                                                       kfree(ses->serverDomain);
+                                               kfree(ses->serverDomain);
                                                ses->serverDomain =
                                                    kzalloc(len + 1,
                                                            GFP_KERNEL);
@@ -2783,7 +2836,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                  32, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bytes_returned =
-                   cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
                                  nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;   /* null term version string */
@@ -2835,8 +2888,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
 
                strcpy(bcc_ptr, "Linux version ");
                bcc_ptr += strlen("Linux version ");
-               strcpy(bcc_ptr, system_utsname.release);
-               bcc_ptr += strlen(system_utsname.release) + 1;
+               strcpy(bcc_ptr, utsname()->release);
+               bcc_ptr += strlen(utsname()->release) + 1;
                strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
                bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
                bcc_ptr++;      /* null domain */
@@ -2915,8 +2968,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                                 bcc_ptr,
                                                                 remaining_words
                                                                 - 1);
-                                               if(ses->serverNOS)
-                                                       kfree(ses->serverNOS);
+                                               kfree(ses->serverNOS);
                                                ses->serverNOS =
                                                    kzalloc(2 * (len + 1),
                                                            GFP_KERNEL);
@@ -2969,8 +3021,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                if(ses->serverDomain)
                                                        kfree(ses->serverDomain);
                                                ses->serverDomain = kzalloc(2, GFP_KERNEL);
-                                               if(ses->serverNOS)
-                                                       kfree(ses->serverNOS);
+                                               kfree(ses->serverNOS);
                                                ses->serverNOS = kzalloc(2, GFP_KERNEL);
                                        }
                                } else {        /* ASCII */
@@ -2988,8 +3039,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                bcc_ptr++;
 
                                                len = strnlen(bcc_ptr, 1024);
-                                               if(ses->serverNOS)
-                                                       kfree(ses->serverNOS);
+                                               kfree(ses->serverNOS);
                                                ses->serverNOS = kzalloc(len+1,GFP_KERNEL);
                                                strncpy(ses->serverNOS, bcc_ptr, len);  
                                                bcc_ptr += len;
@@ -3187,6 +3237,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
        int xid;
        struct cifsSesInfo *ses = NULL;
        struct task_struct *cifsd_task;
+       char * tmp;
 
        xid = GetXid();
 
@@ -3220,6 +3271,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
        }
        
        cifs_sb->tcon = NULL;
+       tmp = cifs_sb->prepath;
+       cifs_sb->prepathlen = 0;
+       cifs_sb->prepath = NULL;
+       kfree(tmp);
        if (ses)
                schedule_timeout_interruptible(msecs_to_jiffies(500));
        if (ses)