Auto-update from upstream
[platform/kernel/linux-starfive.git] / fs / cifs / cifssmb.c
index c8ae3ef..9312bfc 100644 (file)
@@ -125,6 +125,9 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
                                rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon
                                        , nls_codepage);
                                up(&tcon->ses->sesSem);
+                               /* BB FIXME add code to check if wsize needs
+                                  update due to negotiated smb buffer size
+                                  shrinking */
                                if(rc == 0)
                                        atomic_inc(&tconInfoReconnectCount);
 
@@ -220,6 +223,9 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
                                rc = CIFSTCon(0, tcon->ses, tcon->treeName,
                                              tcon, nls_codepage);
                                up(&tcon->ses->sesSem);
+                               /* BB FIXME add code to check if wsize needs
+                               update due to negotiated smb buffer size
+                               shrinking */
                                if(rc == 0)
                                        atomic_inc(&tconInfoReconnectCount);
 
@@ -766,7 +772,7 @@ OldOpenRetry:
         if(create_options & CREATE_OPTION_SPECIAL)
                 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
         else
-                pSMB->FileAttributes = cpu_to_le16(ATTR_NORMAL);
+                pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* BB FIXME */
 
        /* if ((omode & S_IWUGO) == 0)
                pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
@@ -777,7 +783,9 @@ OldOpenRetry:
        /* BB FIXME BB */
 /*     pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); */
        /* BB FIXME END BB */
-       pSMB->OpenFunction = convert_disposition(openDisposition);
+
+       pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
+       pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
        count += name_len;
        pSMB->hdr.smb_buf_length += count;
 
@@ -806,10 +814,12 @@ OldOpenRetry:
                        pfile_info->LastAccessTime = 0; /* BB fixme */
                        pfile_info->LastWriteTime = 0; /* BB fixme */
                        pfile_info->ChangeTime = 0;  /* BB fixme */
-                       pfile_info->Attributes = pSMBr->FileAttributes; 
+                       pfile_info->Attributes =
+                               cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes)); 
                        /* the file_info buf is endian converted by caller */
-                       pfile_info->AllocationSize = pSMBr->EndOfFile;
-                       pfile_info->EndOfFile = pSMBr->EndOfFile;
+                       pfile_info->AllocationSize =
+                               cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
+                       pfile_info->EndOfFile = pfile_info->AllocationSize;
                        pfile_info->NumberOfLinks = cpu_to_le32(1);
                }
        }
@@ -923,81 +933,6 @@ openRetry:
        return rc;
 }
 
-int
-SMBLegacyRead(const int xid, struct cifsTconInfo *tcon,
-            const int netfid, unsigned int count,
-            const __u64 lseek, unsigned int *nbytes, char **buf)
-{
-       int rc = -EACCES;
-       READX_REQ *pSMB = NULL;
-       READ_RSP *pSMBr = NULL;
-       char *pReadData = NULL;
-       int bytes_returned;
-
-       cFYI(1,("Legacy read %d bytes fid %d",count,netfid));
-
-       /* field is shorter in legacy read, only 16 bits */
-       if(count > 2048)
-               count = 2048;  /* BB FIXME make this configurable */
-
-       if(lseek > 0xFFFFFFFF)
-               return -EIO; /* can not read that far into file on old server */
-
-       *nbytes = 0;
-       rc = smb_init(SMB_COM_READ_ANDX, 10, tcon, (void **) &pSMB,
-                     (void **) &pSMBr);
-       if (rc)
-               return rc;
-
-       /* tcon and ses pointer are checked in smb_init */
-       if (tcon->ses->server == NULL)
-               return -ECONNABORTED;
-
-       pSMB->AndXCommand = 0xFF;       /* none */
-       pSMB->Fid = netfid;
-       pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
-       pSMB->Remaining = 0;
-       pSMB->MaxCount = cpu_to_le16(count);
-       pSMB->Reserved = 0; /* Must Be Zero */
-       pSMB->ByteCount = 0;  /* no need to do le conversion since it is 0 */
-
-       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-                        (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-       cifs_stats_inc(&tcon->num_reads);
-       if (rc) {
-               cERROR(1, ("Send error in legacy read = %d", rc));
-       } else {
-               int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
-               data_length = data_length << 16;
-               data_length += le16_to_cpu(pSMBr->DataLength);
-               *nbytes = data_length;
-
-               /*check that DataLength would not go beyond end of SMB */
-               if ((data_length > CIFSMaxBufSize) || (data_length > count)) {
-                       cFYI(1,("bad length %d for count %d",data_length,count));
-                       rc = -EIO;
-                       *nbytes = 0;
-               } else {
-                       pReadData = (char *) (&pSMBr->hdr.Protocol) +
-                                               le16_to_cpu(pSMBr->DataOffset);
-/*                      if(rc = copy_to_user(buf, pReadData, data_length)) {
-                               cERROR(1,("Faulting on read rc = %d",rc));
-                               rc = -EFAULT;
-                       }*/ /* can not use copy_to_user when using page cache*/
-                       if(*buf)
-                               memcpy(*buf,pReadData,data_length);
-               }
-       }
-       if(*buf)
-               cifs_buf_release(pSMB);
-       else
-               *buf = (char *)pSMB;
-
-       /* Note: On -EAGAIN error only caller can retry on handle based calls
-               since file handle passed in no longer valid */
-       return rc;
-}
-
 /* If no buffer passed in, then caller wants to do the copy
        as in the case of readpages so the SMB buffer must be
        freed by the caller */
@@ -1012,11 +947,16 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
        READ_RSP *pSMBr = NULL;
        char *pReadData = NULL;
        int bytes_returned;
+       int wct;
 
        cFYI(1,("Reading %d bytes on fid %d",count,netfid));
+       if(tcon->ses->capabilities & CAP_LARGE_FILES)
+               wct = 12;
+       else
+               wct = 10; /* old style read */
 
        *nbytes = 0;
-       rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB,
+       rc = smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
        if (rc)
                return rc;
@@ -1028,12 +968,23 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
        pSMB->AndXCommand = 0xFF;       /* none */
        pSMB->Fid = netfid;
        pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
-       pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
+       if(wct == 12)
+               pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
+        else if((lseek >> 32) > 0) /* can not handle this big offset for old */
+                return -EIO;
+
        pSMB->Remaining = 0;
        pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
        pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
-       pSMB->ByteCount = 0;  /* no need to do le conversion since it is 0 */
-
+       if(wct == 12)
+               pSMB->ByteCount = 0;  /* no need to do le conversion since 0 */
+       else {
+               /* old style read */
+               struct smb_com_readx_req * pSMBW = 
+                       (struct smb_com_readx_req *)pSMB;
+               pSMBW->ByteCount = 0;   
+       }
+       
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_reads);
@@ -1082,12 +1033,20 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
        int rc = -EACCES;
        WRITE_REQ *pSMB = NULL;
        WRITE_RSP *pSMBr = NULL;
-       int bytes_returned;
+       int bytes_returned, wct;
        __u32 bytes_sent;
        __u16 byte_count;
 
        /* cFYI(1,("write at %lld %d bytes",offset,count));*/
-       rc = smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB,
+       if(tcon->ses == NULL)
+               return -ECONNABORTED;
+
+       if(tcon->ses->capabilities & CAP_LARGE_FILES)
+               wct = 14;
+       else
+               wct = 12;
+
+       rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
        if (rc)
                return rc;
@@ -1098,7 +1057,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
        pSMB->AndXCommand = 0xFF;       /* none */
        pSMB->Fid = netfid;
        pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
-       pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
+       if(wct == 14) 
+               pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
+       else if((offset >> 32) > 0) /* can not handle this big offset for old */
+               return -EIO;
+       
        pSMB->Reserved = 0xFFFFFFFF;
        pSMB->WriteMode = 0;
        pSMB->Remaining = 0;
@@ -1117,7 +1080,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
        if (bytes_sent > count)
                bytes_sent = count;
        pSMB->DataOffset =
-           cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
+               cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
        if(buf)
            memcpy(pSMB->Data,buf,bytes_sent);
        else if(ubuf) {
@@ -1125,17 +1088,27 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
                        cifs_buf_release(pSMB);
                        return -EFAULT;
                }
-       } else {
+       } else if (count != 0) {
                /* No buffer */
                cifs_buf_release(pSMB);
                return -EINVAL;
+       } /* else setting file size with write of zero bytes */
+       if(wct == 14)
+               byte_count = bytes_sent + 1; /* pad */
+       else /* wct == 12 */ {
+               byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
        }
-
-       byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */
        pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
        pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
-       pSMB->hdr.smb_buf_length += bytes_sent+1;
-       pSMB->ByteCount = cpu_to_le16(byte_count);
+       pSMB->hdr.smb_buf_length += byte_count;
+
+       if(wct == 14)
+               pSMB->ByteCount = cpu_to_le16(byte_count);
+       else { /* old style write has byte count 4 bytes earlier so 4 bytes pad  */
+               struct smb_com_writex_req * pSMBW = 
+                       (struct smb_com_writex_req *)pSMB;
+               pSMBW->ByteCount = cpu_to_le16(byte_count);
+       }
 
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
@@ -1161,18 +1134,20 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
 int
 CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
             const int netfid, const unsigned int count,
-            const __u64 offset, unsigned int *nbytes, const char *buf,
-            const int long_op)
+            const __u64 offset, unsigned int *nbytes, struct kvec *iov,
+            int n_vec, const int long_op)
 {
        int rc = -EACCES;
        WRITE_REQ *pSMB = NULL;
-       int bytes_returned;
+       int bytes_returned, wct;
        int smb_hdr_len;
-       __u32 bytes_sent;
-       __u16 byte_count;
 
        cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */
-       rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB);
+       if(tcon->ses->capabilities & CAP_LARGE_FILES)
+               wct = 14;
+       else
+               wct = 12;
+       rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
        if (rc)
                return rc;
        /* tcon and ses pointer are checked in smb_init */
@@ -1182,39 +1157,39 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
        pSMB->AndXCommand = 0xFF;       /* none */
        pSMB->Fid = netfid;
        pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
-       pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
+       if(wct == 14)
+               pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
+       else if((offset >> 32) > 0) /* can not handle this big offset for old */
+               return -EIO;
        pSMB->Reserved = 0xFFFFFFFF;
        pSMB->WriteMode = 0;
        pSMB->Remaining = 0;
 
-       /* Can increase buffer size if buffer is big enough in some cases - ie 
-       can send more if LARGE_WRITE_X capability returned by the server and if
-       our buffer is big enough or if we convert to iovecs on socket writes
-       and eliminate the copy to the CIFS buffer */
-       if(tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
-               bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
-       } else {
-               bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
-                        & ~0xFF;
-       }
-
-       if (bytes_sent > count)
-               bytes_sent = count;
        pSMB->DataOffset =
            cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
 
-       byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */
-       pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
-       pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
+       pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
+       pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
        smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
-       pSMB->hdr.smb_buf_length += bytes_sent+1;
-       pSMB->ByteCount = cpu_to_le16(byte_count);
+       if(wct == 14)
+               pSMB->hdr.smb_buf_length += count+1;
+       else /* wct == 12 */
+               pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */ 
+       if(wct == 14)
+               pSMB->ByteCount = cpu_to_le16(count + 1);
+       else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
+               struct smb_com_writex_req * pSMBW =
+                               (struct smb_com_writex_req *)pSMB;
+               pSMBW->ByteCount = cpu_to_le16(count + 5);
+       }
+       iov[0].iov_base = pSMB;
+       iov[0].iov_len = smb_hdr_len + 4;
 
-       rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB, smb_hdr_len,
-                         buf, bytes_sent, &bytes_returned, long_op);
+       rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &bytes_returned,
+                         long_op);
        cifs_stats_inc(&tcon->num_writes);
        if (rc) {
-               cFYI(1, ("Send error in write = %d", rc));
+               cFYI(1, ("Send error Write2 = %d", rc));
                *nbytes = 0;
        } else {
                WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB;
@@ -2425,9 +2400,11 @@ QInfRetry:
                cFYI(1, ("Send error in QueryInfo = %d", rc));
        } else if (pFinfo) {            /* decode response */
                memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
-               pFinfo->AllocationSize = (__le64) pSMBr->size;
-               pFinfo->EndOfFile = (__le64) pSMBr->size;
-               pFinfo->Attributes = (__le32) pSMBr->attr;
+               pFinfo->AllocationSize =
+                       cpu_to_le64(le32_to_cpu(pSMBr->size));
+               pFinfo->EndOfFile = pFinfo->AllocationSize;
+               pFinfo->Attributes =
+                       cpu_to_le32(le16_to_cpu(pSMBr->attr));
        } else
                rc = -EIO; /* bad buffer passed in */
 
@@ -3250,6 +3227,92 @@ GetDFSRefExit:
        return rc;
 }
 
+/* Query File System Info such as free space to old servers such as Win 9x */
+int
+SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
+{
+/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
+       TRANSACTION2_QFSI_REQ *pSMB = NULL;
+       TRANSACTION2_QFSI_RSP *pSMBr = NULL;
+       FILE_SYSTEM_ALLOC_INFO *response_data;
+       int rc = 0;
+       int bytes_returned = 0;
+       __u16 params, byte_count;
+
+       cFYI(1, ("OldQFSInfo"));
+oldQFSInfoRetry:
+       rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+               (void **) &pSMBr);
+       if (rc)
+               return rc;
+       rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+                     (void **) &pSMBr);
+       if (rc)
+               return rc;
+
+       params = 2;     /* level */
+       pSMB->TotalDataCount = 0;
+       pSMB->MaxParameterCount = cpu_to_le16(2);
+       pSMB->MaxDataCount = cpu_to_le16(1000);
+       pSMB->MaxSetupCount = 0;
+       pSMB->Reserved = 0;
+       pSMB->Flags = 0;
+       pSMB->Timeout = 0;
+       pSMB->Reserved2 = 0;
+       byte_count = params + 1 /* pad */ ;
+       pSMB->TotalParameterCount = cpu_to_le16(params);
+       pSMB->ParameterCount = pSMB->TotalParameterCount;
+       pSMB->ParameterOffset = cpu_to_le16(offsetof(
+       struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
+       pSMB->DataCount = 0;
+       pSMB->DataOffset = 0;
+       pSMB->SetupCount = 1;
+       pSMB->Reserved3 = 0;
+       pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
+       pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
+       pSMB->hdr.smb_buf_length += byte_count;
+       pSMB->ByteCount = cpu_to_le16(byte_count);
+
+       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+               (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+       if (rc) {
+               cFYI(1, ("Send error in QFSInfo = %d", rc));
+       } else {                /* decode response */
+               rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+
+               if (rc || (pSMBr->ByteCount < 18))
+                       rc = -EIO;      /* bad smb */
+               else {
+                       __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+                       cFYI(1,("qfsinf resp BCC: %d  Offset %d",
+                                pSMBr->ByteCount, data_offset));
+
+                       response_data =
+                               (FILE_SYSTEM_ALLOC_INFO *) 
+                               (((char *) &pSMBr->hdr.Protocol) + data_offset);
+                       FSData->f_bsize =
+                               le16_to_cpu(response_data->BytesPerSector) *
+                               le32_to_cpu(response_data->
+                                       SectorsPerAllocationUnit);
+                       FSData->f_blocks =
+                               le32_to_cpu(response_data->TotalAllocationUnits);
+                       FSData->f_bfree = FSData->f_bavail =
+                               le32_to_cpu(response_data->FreeAllocationUnits);
+                       cFYI(1,
+                            ("Blocks: %lld  Free: %lld Block size %ld",
+                             (unsigned long long)FSData->f_blocks,
+                             (unsigned long long)FSData->f_bfree,
+                             FSData->f_bsize));
+               }
+       }
+       cifs_buf_release(pSMB);
+
+       if (rc == -EAGAIN)
+               goto oldQFSInfoRetry;
+
+       return rc;
+}
+
 int
 CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
 {
@@ -3271,7 +3334,7 @@ QFSInfoRetry:
        params = 2;     /* level */
        pSMB->TotalDataCount = 0;
        pSMB->MaxParameterCount = cpu_to_le16(2);
-       pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
+       pSMB->MaxDataCount = cpu_to_le16(1000);
        pSMB->MaxSetupCount = 0;
        pSMB->Reserved = 0;
        pSMB->Flags = 0;
@@ -3294,17 +3357,14 @@ QFSInfoRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cERROR(1, ("Send error in QFSInfo = %d", rc));
+               cFYI(1, ("Send error in QFSInfo = %d", rc));
        } else {                /* decode response */
                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
-               if (rc || (pSMBr->ByteCount < 24)) /* BB alsO CHEck enough total bytes returned */
+               if (rc || (pSMBr->ByteCount < 24))
                        rc = -EIO;      /* bad smb */
                else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
-                       cFYI(1,
-                               ("Decoding qfsinfo response.  BCC: %d  Offset %d",
-                               pSMBr->ByteCount, data_offset));
 
                        response_data =
                            (FILE_SYSTEM_INFO
@@ -3674,16 +3734,16 @@ QFSPosixRetry:
                                        le64_to_cpu(response_data->TotalBlocks);
                        FSData->f_bfree =
                            le64_to_cpu(response_data->BlocksAvail);
-                       if(response_data->UserBlocksAvail == -1) {
+                       if(response_data->UserBlocksAvail == cpu_to_le64(-1)) {
                                FSData->f_bavail = FSData->f_bfree;
                        } else {
                                FSData->f_bavail =
                                        le64_to_cpu(response_data->UserBlocksAvail);
                        }
-                       if(response_data->TotalFileNodes != -1)
+                       if(response_data->TotalFileNodes != cpu_to_le64(-1))
                                FSData->f_files =
                                        le64_to_cpu(response_data->TotalFileNodes);
-                       if(response_data->FreeFileNodes != -1)
+                       if(response_data->FreeFileNodes != cpu_to_le64(-1))
                                FSData->f_ffree =
                                        le64_to_cpu(response_data->FreeFileNodes);
                }
@@ -3729,7 +3789,7 @@ SetEOFRetry:
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {                /* BB improve the check for buffer overruns BB */
+       } else {        /* BB improve the check for buffer overruns BB */
                name_len = strnlen(fileName, PATH_MAX);
                name_len++;     /* trailing null */
                strncpy(pSMB->FileName, fileName, name_len);
@@ -3737,7 +3797,7 @@ SetEOFRetry:
        params = 6 + name_len;
        data_count = sizeof (struct file_end_of_file_info);
        pSMB->MaxParameterCount = cpu_to_le16(2);
-       pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */
+       pSMB->MaxDataCount = cpu_to_le16(4100);
        pSMB->MaxSetupCount = 0;
        pSMB->Reserved = 0;
        pSMB->Flags = 0;
@@ -4119,7 +4179,7 @@ setPermsRetry:
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {                /* BB improve the check for buffer overruns BB */
+       } else {        /* BB improve the check for buffer overruns BB */
                name_len = strnlen(fileName, PATH_MAX);
                name_len++;     /* trailing null */
                strncpy(pSMB->FileName, fileName, name_len);
@@ -4234,20 +4294,26 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
                cFYI(1, ("Error in Notify = %d", rc));
        } else {
                /* Add file to outstanding requests */
+               /* BB change to kmem cache alloc */     
                dnotify_req = (struct dir_notify_req *) kmalloc(
-                                               sizeof(struct dir_notify_req), GFP_KERNEL);
-               dnotify_req->Pid = pSMB->hdr.Pid;
-               dnotify_req->PidHigh = pSMB->hdr.PidHigh;
-               dnotify_req->Mid = pSMB->hdr.Mid;
-               dnotify_req->Tid = pSMB->hdr.Tid;
-               dnotify_req->Uid = pSMB->hdr.Uid;
-               dnotify_req->netfid = netfid;
-               dnotify_req->pfile = pfile;
-               dnotify_req->filter = filter;
-               dnotify_req->multishot = multishot;
-               spin_lock(&GlobalMid_Lock);
-               list_add_tail(&dnotify_req->lhead, &GlobalDnotifyReqList);
-               spin_unlock(&GlobalMid_Lock);
+                                               sizeof(struct dir_notify_req),
+                                                GFP_KERNEL);
+               if(dnotify_req) {
+                       dnotify_req->Pid = pSMB->hdr.Pid;
+                       dnotify_req->PidHigh = pSMB->hdr.PidHigh;
+                       dnotify_req->Mid = pSMB->hdr.Mid;
+                       dnotify_req->Tid = pSMB->hdr.Tid;
+                       dnotify_req->Uid = pSMB->hdr.Uid;
+                       dnotify_req->netfid = netfid;
+                       dnotify_req->pfile = pfile;
+                       dnotify_req->filter = filter;
+                       dnotify_req->multishot = multishot;
+                       spin_lock(&GlobalMid_Lock);
+                       list_add_tail(&dnotify_req->lhead, 
+                                       &GlobalDnotifyReqList);
+                       spin_unlock(&GlobalMid_Lock);
+               } else 
+                       rc = -ENOMEM;
        }
        cifs_buf_release(pSMB);
        return rc;