]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/cifs/misc.c
Merge ../linux-2.6
[karo-tx-linux.git] / fs / cifs / misc.c
index eba1de917f2a87c2d9d5a173978c26f4e10e06b2..812c6bb0fe38adff74cc25c8dc7848cbae3315bd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/misc.c
  *
- *   Copyright (C) International Business Machines  Corp., 2002,2004
+ *   Copyright (C) International Business Machines  Corp., 2002,2005
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -98,14 +98,10 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
        atomic_dec(&sesInfoAllocCount);
        list_del(&buf_to_free->cifsSessionList);
        write_unlock(&GlobalSMBSeslock);
-       if (buf_to_free->serverOS)
-               kfree(buf_to_free->serverOS);
-       if (buf_to_free->serverDomain)
-               kfree(buf_to_free->serverDomain);
-       if (buf_to_free->serverNOS)
-               kfree(buf_to_free->serverNOS);
-       if (buf_to_free->password)
-               kfree(buf_to_free->password);
+       kfree(buf_to_free->serverOS);
+       kfree(buf_to_free->serverDomain);
+       kfree(buf_to_free->serverNOS);
+       kfree(buf_to_free->password);
        kfree(buf_to_free);
 }
 
@@ -144,8 +140,7 @@ tconInfoFree(struct cifsTconInfo *buf_to_free)
        atomic_dec(&tconInfoAllocCount);
        list_del(&buf_to_free->cifsConnectionList);
        write_unlock(&GlobalSMBSeslock);
-       if (buf_to_free->nativeFileSystem)
-               kfree(buf_to_free->nativeFileSystem);
+       kfree(buf_to_free->nativeFileSystem);
        kfree(buf_to_free);
 }
 
@@ -166,6 +161,9 @@ cifs_buf_get(void)
        if (ret_buf) {
                memset(ret_buf, 0, sizeof(struct smb_hdr) + 3);
                atomic_inc(&bufAllocCount);
+#ifdef CONFIG_CIFS_STATS2
+               atomic_inc(&totBufAllocCount);
+#endif /* CONFIG_CIFS_STATS2 */
        }
 
        return ret_buf;
@@ -200,6 +198,10 @@ cifs_small_buf_get(void)
        /* No need to clear memory here, cleared in header assemble */
        /*      memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/
                atomic_inc(&smBufAllocCount);
+#ifdef CONFIG_CIFS_STATS2
+               atomic_inc(&totSmBufAllocCount);
+#endif /* CONFIG_CIFS_STATS2 */
+
        }
        return ret_buf;
 }
@@ -297,7 +299,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
        struct cifsSesInfo * ses;
        char *temp = (char *) buffer;
 
-       memset(temp,0,MAX_CIFS_HDR_SIZE);
+       memset(temp,0,256); /* bigger than MAX_CIFS_HDR_SIZE */
 
        buffer->smb_buf_length =
            (2 * word_count) + sizeof (struct smb_hdr) -
@@ -353,12 +355,12 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
                /*  BB Add support for establishing new tCon and SMB Session  */
                /*      with userid/password pairs found on the smb session   */ 
                /*      for other target tcp/ip addresses               BB    */
-                               if(current->uid != treeCon->ses->linux_uid) {
-                                       cFYI(1,("Multiuser mode and UID did not match tcon uid "));
+                               if(current->fsuid != treeCon->ses->linux_uid) {
+                                       cFYI(1,("Multiuser mode and UID did not match tcon uid"));
                                        read_lock(&GlobalSMBSeslock);
                                        list_for_each(temp_item, &GlobalSMBSessionList) {
                                                ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList);
-                                               if(ses->linux_uid == current->uid) {
+                                               if(ses->linux_uid == current->fsuid) {
                                                        if(ses->server == treeCon->ses->server) {
                                                                cFYI(1,("found matching uid substitute right smb_uid"));  
                                                                buffer->Uid = ses->Suid;
@@ -402,12 +404,12 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid)
                        if(smb->Command == SMB_COM_LOCKING_ANDX)
                                return 0;
                        else
-                               cERROR(1, ("Rcvd Request not response "));         
+                               cERROR(1, ("Rcvd Request not response"));         
                }
        } else { /* bad signature or mid */
                if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff))
                        cERROR(1,
-                              ("Bad protocol string signature header %x ",
+                              ("Bad protocol string signature header %x",
                                *(unsigned int *) smb->Protocol));
                if (mid != smb->Mid)
                        cERROR(1, ("Mids do not match"));
@@ -422,7 +424,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
        __u32 len = smb->smb_buf_length;
        __u32 clc_len;  /* calculated length */
        cFYI(0,
-            ("Entering checkSMB with Length: %x, smb_buf_length: %x ",
+            ("Entering checkSMB with Length: %x, smb_buf_length: %x",
              length, len));
        if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) ||
            (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) {
@@ -456,9 +458,16 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
                cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid));
                /* Windows XP can return a few bytes too much, presumably
                an illegal pad, at the end of byte range lock responses 
-               so we allow for up to eight byte pad, as long as actual
+               so we allow for that three byte pad, as long as actual
                received length is as long or longer than calculated length */
-               if((4+len > clc_len) && (len <= clc_len + 3))
+               /* We have now had to extend this more, since there is a 
+               case in which it needs to be bigger still to handle a
+               malformed response to transact2 findfirst from WinXP when
+               access denied is returned and thus bcc and wct are zero
+               but server says length is 0x21 bytes too long as if the server
+               forget to reset the smb rfc1001 length when it reset the
+               wct and bcc to minimum size and drop the t2 parms and data */
+               if((4+len > clc_len) && (len <= clc_len + 512))
                        return 0;
                else
                        return 1;
@@ -683,7 +692,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
        __u16 temp;
 
        if(!mapChars) 
-               return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp);
+               return cifs_strtoUCS(target, source, PATH_MAX, cp);
 
        for(i = 0, j = 0; i < maxlen; j++) {
                src_char = source[i];