This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / fs / cifs / cifssmb.c
index b4da800..6a26f8c 100644 (file)
 #include "cifs_unicode.h"
 #include "cifs_debug.h"
 
+#ifdef CONFIG_CIFS_POSIX
 static struct {
        int index;
        char *name;
 } protocols[] = {
        {CIFS_PROT, "\2NT LM 0.12"}, 
+       {CIFS_PROT, "\2POSIX 2"},
        {BAD_PROT, "\2"}
 };
+#else
+static struct {
+       int index;
+       char *name;
+} protocols[] = {
+       {CIFS_PROT, "\2NT LM 0.12"}, 
+       {BAD_PROT, "\2"}
+};
+#endif
 
 
 /* Mark as invalid, all open files on tree connections since they
@@ -143,7 +154,8 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
                return rc;
 
        *request_buf = cifs_buf_get();
-       if (request_buf == 0) {
+       if (*request_buf == 0) {
+               /* BB should we add a retry in here if not a writepage? */
                return -ENOMEM;
        }
     /* Although the original thought was we needed the response buf for  */
@@ -154,6 +166,12 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
 
        header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
                        wct /*wct */ );
+
+#ifdef CONFIG_CIFS_STATS
+        if(tcon != NULL) {
+                atomic_inc(&tcon->num_smbs_sent);
+        }
+#endif
        return rc;
 }
 
@@ -418,7 +436,13 @@ DelFileRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
                cFYI(1, ("Error in RMFile = %d", rc));
-       }
+       } 
+#ifdef CONFIG_CIFS_STATS
+        else {
+               atomic_inc(&tcon->num_deletes);
+        }
+#endif
+
        if (pSMB)
                cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -465,6 +489,12 @@ RmDirRetry:
        if (rc) {
                cFYI(1, ("Error in RMDir = %d", rc));
        }
+#ifdef CONFIG_CIFS_STATS
+        else {
+               atomic_inc(&tcon->num_rmdirs);
+        }
+#endif
+
        if (pSMB)
                cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -510,6 +540,11 @@ MkDirRetry:
        if (rc) {
                cFYI(1, ("Error in Mkdir = %d", rc));
        }
+#ifdef CONFIG_CIFS_STATS
+        else {
+               atomic_inc(&tcon->num_mkdirs);
+        }
+#endif
        if (pSMB)
                cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -606,6 +641,10 @@ openRetry:
                    pfile_info->EndOfFile = pSMBr->EndOfFile;
                    pfile_info->NumberOfLinks = cpu_to_le32(1);
                }
+
+#ifdef CONFIG_CIFS_STATS
+               atomic_inc(&tcon->num_opens);
+#endif
        }
        if (pSMB)
                cifs_buf_release(pSMB);
@@ -728,7 +767,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
        if (rc) {
-               cERROR(1, ("Send error in write = %d", rc));
+               cFYI(1, ("Send error in write = %d", rc));
                *nbytes = 0;
        } else
                *nbytes = le16_to_cpu(pSMBr->Count);
@@ -792,7 +831,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
                         (struct smb_hdr *) pSMBr, &bytes_returned, timeout);
 
        if (rc) {
-               cERROR(1, ("Send error in Lock = %d", rc));
+               cFYI(1, ("Send error in Lock = %d", rc));
        }
        if (pSMB)
                cifs_buf_release(pSMB);
@@ -892,7 +931,6 @@ renameRetry:
        }
 
        pSMB->ByteCount = 1 /* 1st signature byte */  + name_len + name_len2;
-    /* we could also set search attributes but not needed */
        pSMB->hdr.smb_buf_length += pSMB->ByteCount;
        pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
 
@@ -986,6 +1024,76 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
        return rc;
 }
 
+int
+CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char * fromName, 
+            const __u16 target_tid, const char *toName, const int flags,
+            const struct nls_table *nls_codepage)
+{
+       int rc = 0;
+       COPY_REQ *pSMB = NULL;
+       COPY_RSP *pSMBr = NULL;
+       int bytes_returned;
+       int name_len, name_len2;
+
+       cFYI(1, ("In CIFSSMBCopy"));
+copyRetry:
+       rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
+                       (void **) &pSMBr);
+       if (rc)
+               return rc;
+
+       pSMB->BufferFormat = 0x04;
+       pSMB->Tid2 = target_tid;
+
+       if(flags & COPY_TREE)
+               pSMB->Flags |= COPY_TREE;
+       pSMB->Flags = cpu_to_le16(pSMB->Flags);
+
+       if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
+               name_len = cifs_strtoUCS((wchar_t *) pSMB->OldFileName, 
+                               fromName, 
+                               530 /* find define for this maxpathcomponent */,
+                               nls_codepage);
+               name_len++;     /* trailing null */
+               name_len *= 2;
+               pSMB->OldFileName[name_len] = 0x04;     /* pad */
+               /* protocol requires ASCII signature byte on Unicode string */
+               pSMB->OldFileName[name_len + 1] = 0x00;
+               name_len2 = cifs_strtoUCS((wchar_t *) & pSMB->
+                               OldFileName[name_len + 2], toName, 530,
+                               nls_codepage);
+               name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
+               name_len2 *= 2; /* convert to bytes */
+       } else {                /* BB improve the check for buffer overruns BB */
+               name_len = strnlen(fromName, 530);
+               name_len++;     /* trailing null */
+               strncpy(pSMB->OldFileName, fromName, name_len);
+               name_len2 = strnlen(toName, 530);
+               name_len2++;    /* trailing null */
+               pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
+               strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
+               name_len2++;    /* trailing null */
+               name_len2++;    /* signature byte */
+       }
+
+       pSMB->ByteCount = 1 /* 1st signature byte */  + name_len + name_len2;
+       pSMB->hdr.smb_buf_length += pSMB->ByteCount;
+       pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
+
+       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+               (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+       if (rc) {
+               cFYI(1, ("Send error in copy = %d with %d files copied",
+                       rc, pSMBr->CopyCount));
+       }
+       if (pSMB)
+               cifs_buf_release(pSMB);
+
+       if (rc == -EAGAIN)
+               goto copyRetry;
+
+       return rc;
+}
 
 int
 CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
@@ -2211,6 +2319,11 @@ QFSAttributeRetry:
                            (FILE_SYSTEM_ATTRIBUTE_INFO
                             *) (((char *) &pSMBr->hdr.Protocol) +
                                 pSMBr->DataOffset);
+                       response_data->Attributes = le32_to_cpu(response_data->Attributes);
+                       response_data->MaxPathNameComponentLength = 
+                               le32_to_cpu(response_data->MaxPathNameComponentLength);
+                       response_data->FileSystemNameLen = 
+                               le32_to_cpu(response_data->FileSystemNameLen);
                        memcpy(&tcon->fsAttrInfo, response_data,
                               sizeof (FILE_SYSTEM_ATTRIBUTE_INFO));
                }
@@ -2280,6 +2393,10 @@ QFSDeviceRetry:
                            (FILE_SYSTEM_DEVICE_INFO
                             *) (((char *) &pSMBr->hdr.Protocol) +
                                 pSMBr->DataOffset);
+                       response_data->DeviceType = 
+                               le32_to_cpu(response_data->DeviceType);
+                       response_data->DeviceCharacteristics = 
+                               le32_to_cpu(response_data->DeviceCharacteristics);
                        memcpy(&tcon->fsDevInfo, response_data,
                               sizeof (FILE_SYSTEM_DEVICE_INFO));
                }
@@ -2290,7 +2407,6 @@ QFSDeviceRetry:
        if (rc == -EAGAIN)
                goto QFSDeviceRetry;
 
-
        return rc;
 }
 
@@ -2348,6 +2464,12 @@ QFSUnixRetry:
                            (FILE_SYSTEM_UNIX_INFO
                             *) (((char *) &pSMBr->hdr.Protocol) +
                                 pSMBr->DataOffset);
+                       response_data->MajorVersionNumber =
+                               le16_to_cpu(response_data->MajorVersionNumber);
+                       response_data->MinorVersionNumber =
+                               le16_to_cpu(response_data->MinorVersionNumber);
+                       response_data->Capability =
+                               le64_to_cpu(response_data->Capability);
                        memcpy(&tcon->fsUnixInfo, response_data,
                               sizeof (FILE_SYSTEM_UNIX_INFO));
                }
@@ -2511,7 +2633,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
                (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
                        pSMB->DataOffset);
        pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset); /* now safe to change to le */
-       parm_data->FileSize = size;
+       parm_data->FileSize = cpu_to_le64(size);
        pSMB->Fid = fid;
        if(SetAllocation) {
                if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)