aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-11 12:31:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-11 12:31:53 -0400
commit86ed5a93b8b56e4e0877b914af0e10883a196384 (patch)
tree761c3db8250c54eb07c6e4a02ca7f93f044928b3 /fs/cifs/cifssmb.c
parent835a1c092432b3293ba6c4dec45ee6869c6f61fd (diff)
parentb77d753c413e02559669df66e543869dad40c847 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: [CIFS] Check that last search entry resume key is valid [CIFS] make sure we have the right resume info before calling CIFSFindNext [CIFS] clean up error handling in cifs_unlink [CIFS] fix some settings of cifsAttrs after calling SetFileInfo and SetPathInfo cifs: explicitly revoke SPNEGO key after session setup cifs: Convert cifs to new aops. [CIFS] update DOS attributes in cifsInode if we successfully changed them cifs: remove NULL termination from rename target in CIFSSMBRenameOpenFIle cifs: work around samba returning -ENOENT on SetFileDisposition call cifs: fix inverted NULL check after kmalloc [CIFS] clean up upcall handling for dns_resolver keys [CIFS] fix busy-file renames and refactor cifs_rename logic cifs: add function to set file disposition [CIFS] add constants for string lengths of keynames in SPNEGO upcall string cifs: move rename and delete-on-close logic into helper function cifs: have find_writeable_file prefer filehandles opened by same task cifs: don't use GFP_KERNEL with GFP_NOFS [CIFS] use common code for turning off ATTR_READONLY in cifs_unlink cifs: clean up variables in cifs_unlink
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c84
1 files changed, 82 insertions, 2 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 994de7c90474..6f4ffe15d68d 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2017,7 +2017,7 @@ renameRetry:
2017} 2017}
2018 2018
2019int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon, 2019int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
2020 int netfid, char *target_name, 2020 int netfid, const char *target_name,
2021 const struct nls_table *nls_codepage, int remap) 2021 const struct nls_table *nls_codepage, int remap)
2022{ 2022{
2023 struct smb_com_transaction2_sfi_req *pSMB = NULL; 2023 struct smb_com_transaction2_sfi_req *pSMB = NULL;
@@ -2071,7 +2071,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
2071 remap); 2071 remap);
2072 } 2072 }
2073 rename_info->target_name_len = cpu_to_le32(2 * len_of_str); 2073 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2074 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str) + 2; 2074 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2075 byte_count += count; 2075 byte_count += count;
2076 pSMB->DataCount = cpu_to_le16(count); 2076 pSMB->DataCount = cpu_to_le16(count);
2077 pSMB->TotalDataCount = pSMB->DataCount; 2077 pSMB->TotalDataCount = pSMB->DataCount;
@@ -3614,6 +3614,8 @@ findFirstRetry:
3614 /* BB remember to free buffer if error BB */ 3614 /* BB remember to free buffer if error BB */
3615 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3615 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3616 if (rc == 0) { 3616 if (rc == 0) {
3617 unsigned int lnoff;
3618
3617 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 3619 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3618 psrch_inf->unicode = true; 3620 psrch_inf->unicode = true;
3619 else 3621 else
@@ -3636,6 +3638,17 @@ findFirstRetry:
3636 le16_to_cpu(parms->SearchCount); 3638 le16_to_cpu(parms->SearchCount);
3637 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ + 3639 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
3638 psrch_inf->entries_in_buffer; 3640 psrch_inf->entries_in_buffer;
3641 lnoff = le16_to_cpu(parms->LastNameOffset);
3642 if (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE <
3643 lnoff) {
3644 cERROR(1, ("ignoring corrupt resume name"));
3645 psrch_inf->last_entry = NULL;
3646 return rc;
3647 }
3648
3649 psrch_inf->last_entry = psrch_inf->srch_entries_start +
3650 lnoff;
3651
3639 *pnetfid = parms->SearchHandle; 3652 *pnetfid = parms->SearchHandle;
3640 } else { 3653 } else {
3641 cifs_buf_release(pSMB); 3654 cifs_buf_release(pSMB);
@@ -3725,6 +3738,8 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3725 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3738 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3726 3739
3727 if (rc == 0) { 3740 if (rc == 0) {
3741 unsigned int lnoff;
3742
3728 /* BB fixme add lock for file (srch_info) struct here */ 3743 /* BB fixme add lock for file (srch_info) struct here */
3729 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 3744 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3730 psrch_inf->unicode = true; 3745 psrch_inf->unicode = true;
@@ -3751,6 +3766,16 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3751 le16_to_cpu(parms->SearchCount); 3766 le16_to_cpu(parms->SearchCount);
3752 psrch_inf->index_of_last_entry += 3767 psrch_inf->index_of_last_entry +=
3753 psrch_inf->entries_in_buffer; 3768 psrch_inf->entries_in_buffer;
3769 lnoff = le16_to_cpu(parms->LastNameOffset);
3770 if (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE <
3771 lnoff) {
3772 cERROR(1, ("ignoring corrupt resume name"));
3773 psrch_inf->last_entry = NULL;
3774 return rc;
3775 } else
3776 psrch_inf->last_entry =
3777 psrch_inf->srch_entries_start + lnoff;
3778
3754/* cFYI(1,("fnxt2 entries in buf %d index_of_last %d", 3779/* cFYI(1,("fnxt2 entries in buf %d index_of_last %d",
3755 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry)); */ 3780 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry)); */
3756 3781
@@ -4876,6 +4901,61 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
4876 return rc; 4901 return rc;
4877} 4902}
4878 4903
4904int
4905CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
4906 bool delete_file, __u16 fid, __u32 pid_of_opener)
4907{
4908 struct smb_com_transaction2_sfi_req *pSMB = NULL;
4909 char *data_offset;
4910 int rc = 0;
4911 __u16 params, param_offset, offset, byte_count, count;
4912
4913 cFYI(1, ("Set File Disposition (via SetFileInfo)"));
4914 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
4915
4916 if (rc)
4917 return rc;
4918
4919 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
4920 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
4921
4922 params = 6;
4923 pSMB->MaxSetupCount = 0;
4924 pSMB->Reserved = 0;
4925 pSMB->Flags = 0;
4926 pSMB->Timeout = 0;
4927 pSMB->Reserved2 = 0;
4928 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
4929 offset = param_offset + params;
4930
4931 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
4932
4933 count = 1;
4934 pSMB->MaxParameterCount = cpu_to_le16(2);
4935 /* BB find max SMB PDU from sess */
4936 pSMB->MaxDataCount = cpu_to_le16(1000);
4937 pSMB->SetupCount = 1;
4938 pSMB->Reserved3 = 0;
4939 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
4940 byte_count = 3 /* pad */ + params + count;
4941 pSMB->DataCount = cpu_to_le16(count);
4942 pSMB->ParameterCount = cpu_to_le16(params);
4943 pSMB->TotalDataCount = pSMB->DataCount;
4944 pSMB->TotalParameterCount = pSMB->ParameterCount;
4945 pSMB->ParameterOffset = cpu_to_le16(param_offset);
4946 pSMB->DataOffset = cpu_to_le16(offset);
4947 pSMB->Fid = fid;
4948 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
4949 pSMB->Reserved4 = 0;
4950 pSMB->hdr.smb_buf_length += byte_count;
4951 pSMB->ByteCount = cpu_to_le16(byte_count);
4952 *data_offset = delete_file ? 1 : 0;
4953 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4954 if (rc)
4955 cFYI(1, ("Send error in SetFileDisposition = %d", rc));
4956
4957 return rc;
4958}
4879 4959
4880int 4960int
4881CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon, 4961CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,