X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fcifs%2Fcifssmb.c;h=6a26f8c419fb62aaad15d0c414b028e6666d6a41;hb=eb643825dab24bf61fe40ea800c5be013315220d;hp=b4da800a53ddc1b55d155fdb29aefa8be9b3e962;hpb=86090fcac5e27b630656fe3d963a6b80e26dac44;p=linux-2.6.git diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index b4da800a5..6a26f8c41 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -37,13 +37,24 @@ #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)