aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2008-07-03 16:24:06 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-07-03 16:24:06 -0400
commite86322f611eef95aafaf726fd3965e5b211f1985 (patch)
tree28547e26df4fc6ae671dc8cc6912a53717e4db08 /fs/cifs/cifssmb.c
parentb001a1b6aa960949a24c2cdc28257dfcc9428d74 (diff)
parent8948896c9e098c6fd31a6a698a598a7cbd7fa40e (diff)
Merge branch 'for-bfields' of git://linux-nfs.org/~tomtucker/xprt-switch-2.6 into for-2.6.27
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c339
1 files changed, 200 insertions, 139 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 95fbba4ea7d4..4511b708f0f3 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -81,6 +81,40 @@ static struct {
81#endif /* CONFIG_CIFS_WEAK_PW_HASH */ 81#endif /* CONFIG_CIFS_WEAK_PW_HASH */
82#endif /* CIFS_POSIX */ 82#endif /* CIFS_POSIX */
83 83
84/* Allocates buffer into dst and copies smb string from src to it.
85 * caller is responsible for freeing dst if function returned 0.
86 * returns:
87 * on success - 0
88 * on failure - errno
89 */
90static int
91cifs_strncpy_to_host(char **dst, const char *src, const int maxlen,
92 const bool is_unicode, const struct nls_table *nls_codepage)
93{
94 int plen;
95
96 if (is_unicode) {
97 plen = UniStrnlen((wchar_t *)src, maxlen);
98 *dst = kmalloc(plen + 2, GFP_KERNEL);
99 if (!*dst)
100 goto cifs_strncpy_to_host_ErrExit;
101 cifs_strfromUCS_le(*dst, (__le16 *)src, plen, nls_codepage);
102 } else {
103 plen = strnlen(src, maxlen);
104 *dst = kmalloc(plen + 2, GFP_KERNEL);
105 if (!*dst)
106 goto cifs_strncpy_to_host_ErrExit;
107 strncpy(*dst, src, plen);
108 }
109 (*dst)[plen] = 0;
110 (*dst)[plen+1] = 0; /* harmless for ASCII case, needed for Unicode */
111 return 0;
112
113cifs_strncpy_to_host_ErrExit:
114 cERROR(1, ("Failed to allocate buffer for string\n"));
115 return -ENOMEM;
116}
117
84 118
85/* Mark as invalid, all open files on tree connections since they 119/* Mark as invalid, all open files on tree connections since they
86 were closed when session to server was lost */ 120 were closed when session to server was lost */
@@ -1166,6 +1200,20 @@ static __u16 convert_disposition(int disposition)
1166 return ofun; 1200 return ofun;
1167} 1201}
1168 1202
1203static int
1204access_flags_to_smbopen_mode(const int access_flags)
1205{
1206 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1207
1208 if (masked_flags == GENERIC_READ)
1209 return SMBOPEN_READ;
1210 else if (masked_flags == GENERIC_WRITE)
1211 return SMBOPEN_WRITE;
1212
1213 /* just go for read/write */
1214 return SMBOPEN_READWRITE;
1215}
1216
1169int 1217int
1170SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, 1218SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
1171 const char *fileName, const int openDisposition, 1219 const char *fileName, const int openDisposition,
@@ -1207,13 +1255,7 @@ OldOpenRetry:
1207 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK); 1255 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1208 1256
1209 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO); 1257 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1210 /* BB fixme add conversion for access_flags to bits 0 - 2 of mode */ 1258 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1211 /* 0 = read
1212 1 = write
1213 2 = rw
1214 3 = execute
1215 */
1216 pSMB->Mode = cpu_to_le16(2);
1217 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */ 1259 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1218 /* set file as system file if special file such 1260 /* set file as system file if special file such
1219 as fifo and server expecting SFU style and 1261 as fifo and server expecting SFU style and
@@ -1247,7 +1289,7 @@ OldOpenRetry:
1247 } else { 1289 } else {
1248 /* BB verify if wct == 15 */ 1290 /* BB verify if wct == 15 */
1249 1291
1250/* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field BB */ 1292/* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1251 1293
1252 *netfid = pSMBr->Fid; /* cifs fid stays in le */ 1294 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1253 /* Let caller know file was created so we can set the mode. */ 1295 /* Let caller know file was created so we can set the mode. */
@@ -1686,7 +1728,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1686{ 1728{
1687 int rc = 0; 1729 int rc = 0;
1688 LOCK_REQ *pSMB = NULL; 1730 LOCK_REQ *pSMB = NULL;
1689 LOCK_RSP *pSMBr = NULL; 1731/* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
1690 int bytes_returned; 1732 int bytes_returned;
1691 int timeout = 0; 1733 int timeout = 0;
1692 __u16 count; 1734 __u16 count;
@@ -1697,8 +1739,6 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1697 if (rc) 1739 if (rc)
1698 return rc; 1740 return rc;
1699 1741
1700 pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */
1701
1702 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { 1742 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1703 timeout = CIFS_ASYNC_OP; /* no response expected */ 1743 timeout = CIFS_ASYNC_OP; /* no response expected */
1704 pSMB->Timeout = 0; 1744 pSMB->Timeout = 0;
@@ -1732,7 +1772,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1732 1772
1733 if (waitFlag) { 1773 if (waitFlag) {
1734 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 1774 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1735 (struct smb_hdr *) pSMBr, &bytes_returned); 1775 (struct smb_hdr *) pSMB, &bytes_returned);
1736 cifs_small_buf_release(pSMB); 1776 cifs_small_buf_release(pSMB);
1737 } else { 1777 } else {
1738 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB, 1778 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
@@ -1767,7 +1807,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1767 cFYI(1, ("Posix Lock")); 1807 cFYI(1, ("Posix Lock"));
1768 1808
1769 if (pLockData == NULL) 1809 if (pLockData == NULL)
1770 return EINVAL; 1810 return -EINVAL;
1771 1811
1772 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 1812 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
1773 1813
@@ -1944,7 +1984,7 @@ renameRetry:
1944 /* protocol requires ASCII signature byte on Unicode string */ 1984 /* protocol requires ASCII signature byte on Unicode string */
1945 pSMB->OldFileName[name_len + 1] = 0x00; 1985 pSMB->OldFileName[name_len + 1] = 0x00;
1946 name_len2 = 1986 name_len2 =
1947 cifsConvertToUCS((__le16 *) &pSMB->OldFileName[name_len + 2], 1987 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
1948 toName, PATH_MAX, nls_codepage, remap); 1988 toName, PATH_MAX, nls_codepage, remap);
1949 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 1989 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
1950 name_len2 *= 2; /* convert to bytes */ 1990 name_len2 *= 2; /* convert to bytes */
@@ -2117,8 +2157,7 @@ copyRetry:
2117 cFYI(1, ("Send error in copy = %d with %d files copied", 2157 cFYI(1, ("Send error in copy = %d with %d files copied",
2118 rc, le16_to_cpu(pSMBr->CopyCount))); 2158 rc, le16_to_cpu(pSMBr->CopyCount)));
2119 } 2159 }
2120 if (pSMB) 2160 cifs_buf_release(pSMB);
2121 cifs_buf_release(pSMB);
2122 2161
2123 if (rc == -EAGAIN) 2162 if (rc == -EAGAIN)
2124 goto copyRetry; 2163 goto copyRetry;
@@ -2207,8 +2246,7 @@ createSymLinkRetry:
2207 if (rc) 2246 if (rc)
2208 cFYI(1, ("Send error in SetPathInfo create symlink = %d", rc)); 2247 cFYI(1, ("Send error in SetPathInfo create symlink = %d", rc));
2209 2248
2210 if (pSMB) 2249 cifs_buf_release(pSMB);
2211 cifs_buf_release(pSMB);
2212 2250
2213 if (rc == -EAGAIN) 2251 if (rc == -EAGAIN)
2214 goto createSymLinkRetry; 2252 goto createSymLinkRetry;
@@ -2925,7 +2963,8 @@ setAclRetry:
2925 } 2963 }
2926 params = 6 + name_len; 2964 params = 6 + name_len;
2927 pSMB->MaxParameterCount = cpu_to_le16(2); 2965 pSMB->MaxParameterCount = cpu_to_le16(2);
2928 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */ 2966 /* BB find max SMB size from sess */
2967 pSMB->MaxDataCount = cpu_to_le16(1000);
2929 pSMB->MaxSetupCount = 0; 2968 pSMB->MaxSetupCount = 0;
2930 pSMB->Reserved = 0; 2969 pSMB->Reserved = 0;
2931 pSMB->Flags = 0; 2970 pSMB->Flags = 0;
@@ -3322,7 +3361,8 @@ QPathInfoRetry:
3322 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 3361 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3323 pSMB->TotalDataCount = 0; 3362 pSMB->TotalDataCount = 0;
3324 pSMB->MaxParameterCount = cpu_to_le16(2); 3363 pSMB->MaxParameterCount = cpu_to_le16(2);
3325 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 3364 /* BB find exact max SMB PDU from sess structure BB */
3365 pSMB->MaxDataCount = cpu_to_le16(4000);
3326 pSMB->MaxSetupCount = 0; 3366 pSMB->MaxSetupCount = 0;
3327 pSMB->Reserved = 0; 3367 pSMB->Reserved = 0;
3328 pSMB->Flags = 0; 3368 pSMB->Flags = 0;
@@ -3388,7 +3428,7 @@ QPathInfoRetry:
3388int 3428int
3389CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, 3429CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
3390 const unsigned char *searchName, 3430 const unsigned char *searchName,
3391 FILE_UNIX_BASIC_INFO * pFindData, 3431 FILE_UNIX_BASIC_INFO *pFindData,
3392 const struct nls_table *nls_codepage, int remap) 3432 const struct nls_table *nls_codepage, int remap)
3393{ 3433{
3394/* SMB_QUERY_FILE_UNIX_BASIC */ 3434/* SMB_QUERY_FILE_UNIX_BASIC */
@@ -3679,6 +3719,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3679 if (rc) { 3719 if (rc) {
3680 if (rc == -EBADF) { 3720 if (rc == -EBADF) {
3681 psrch_inf->endOfSearch = true; 3721 psrch_inf->endOfSearch = true;
3722 cifs_buf_release(pSMB);
3682 rc = 0; /* search probably was closed at end of search*/ 3723 rc = 0; /* search probably was closed at end of search*/
3683 } else 3724 } else
3684 cFYI(1, ("FindNext returned = %d", rc)); 3725 cFYI(1, ("FindNext returned = %d", rc));
@@ -3856,25 +3897,112 @@ GetInodeNumOut:
3856 return rc; 3897 return rc;
3857} 3898}
3858 3899
3900/* parses DFS refferal V3 structure
3901 * caller is responsible for freeing target_nodes
3902 * returns:
3903 * on success - 0
3904 * on failure - errno
3905 */
3906static int
3907parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
3908 unsigned int *num_of_nodes,
3909 struct dfs_info3_param **target_nodes,
3910 const struct nls_table *nls_codepage)
3911{
3912 int i, rc = 0;
3913 char *data_end;
3914 bool is_unicode;
3915 struct dfs_referral_level_3 *ref;
3916
3917 is_unicode = pSMBr->hdr.Flags2 & SMBFLG2_UNICODE;
3918 *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
3919
3920 if (*num_of_nodes < 1) {
3921 cERROR(1, ("num_referrals: must be at least > 0,"
3922 "but we get num_referrals = %d\n", *num_of_nodes));
3923 rc = -EINVAL;
3924 goto parse_DFS_referrals_exit;
3925 }
3926
3927 ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
3928 if (ref->VersionNumber != cpu_to_le16(3)) {
3929 cERROR(1, ("Referrals of V%d version are not supported,"
3930 "should be V3", le16_to_cpu(ref->VersionNumber)));
3931 rc = -EINVAL;
3932 goto parse_DFS_referrals_exit;
3933 }
3934
3935 /* get the upper boundary of the resp buffer */
3936 data_end = (char *)(&(pSMBr->PathConsumed)) +
3937 le16_to_cpu(pSMBr->t2.DataCount);
3938
3939 cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n",
3940 *num_of_nodes,
3941 le16_to_cpu(pSMBr->DFSFlags)));
3942
3943 *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
3944 *num_of_nodes, GFP_KERNEL);
3945 if (*target_nodes == NULL) {
3946 cERROR(1, ("Failed to allocate buffer for target_nodes\n"));
3947 rc = -ENOMEM;
3948 goto parse_DFS_referrals_exit;
3949 }
3950
3951 /* collect neccessary data from referrals */
3952 for (i = 0; i < *num_of_nodes; i++) {
3953 char *temp;
3954 int max_len;
3955 struct dfs_info3_param *node = (*target_nodes)+i;
3956
3957 node->flags = le16_to_cpu(pSMBr->DFSFlags);
3958 node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
3959 node->server_type = le16_to_cpu(ref->ServerType);
3960 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
3961
3962 /* copy DfsPath */
3963 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
3964 max_len = data_end - temp;
3965 rc = cifs_strncpy_to_host(&(node->path_name), temp,
3966 max_len, is_unicode, nls_codepage);
3967 if (rc)
3968 goto parse_DFS_referrals_exit;
3969
3970 /* copy link target UNC */
3971 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
3972 max_len = data_end - temp;
3973 rc = cifs_strncpy_to_host(&(node->node_name), temp,
3974 max_len, is_unicode, nls_codepage);
3975 if (rc)
3976 goto parse_DFS_referrals_exit;
3977
3978 ref += le16_to_cpu(ref->Size);
3979 }
3980
3981parse_DFS_referrals_exit:
3982 if (rc) {
3983 free_dfs_info_array(*target_nodes, *num_of_nodes);
3984 *target_nodes = NULL;
3985 *num_of_nodes = 0;
3986 }
3987 return rc;
3988}
3989
3859int 3990int
3860CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, 3991CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
3861 const unsigned char *searchName, 3992 const unsigned char *searchName,
3862 unsigned char **targetUNCs, 3993 struct dfs_info3_param **target_nodes,
3863 unsigned int *number_of_UNC_in_array, 3994 unsigned int *num_of_nodes,
3864 const struct nls_table *nls_codepage, int remap) 3995 const struct nls_table *nls_codepage, int remap)
3865{ 3996{
3866/* TRANS2_GET_DFS_REFERRAL */ 3997/* TRANS2_GET_DFS_REFERRAL */
3867 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL; 3998 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
3868 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL; 3999 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
3869 struct dfs_referral_level_3 *referrals = NULL;
3870 int rc = 0; 4000 int rc = 0;
3871 int bytes_returned; 4001 int bytes_returned;
3872 int name_len; 4002 int name_len;
3873 unsigned int i;
3874 char *temp;
3875 __u16 params, byte_count; 4003 __u16 params, byte_count;
3876 *number_of_UNC_in_array = 0; 4004 *num_of_nodes = 0;
3877 *targetUNCs = NULL; 4005 *target_nodes = NULL;
3878 4006
3879 cFYI(1, ("In GetDFSRefer the path %s", searchName)); 4007 cFYI(1, ("In GetDFSRefer the path %s", searchName));
3880 if (ses == NULL) 4008 if (ses == NULL)
@@ -3921,7 +4049,8 @@ getDFSRetry:
3921 pSMB->DataCount = 0; 4049 pSMB->DataCount = 0;
3922 pSMB->DataOffset = 0; 4050 pSMB->DataOffset = 0;
3923 pSMB->MaxParameterCount = 0; 4051 pSMB->MaxParameterCount = 0;
3924 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 4052 /* BB find exact max SMB PDU from sess structure BB */
4053 pSMB->MaxDataCount = cpu_to_le16(4000);
3925 pSMB->MaxSetupCount = 0; 4054 pSMB->MaxSetupCount = 0;
3926 pSMB->Reserved = 0; 4055 pSMB->Reserved = 0;
3927 pSMB->Flags = 0; 4056 pSMB->Flags = 0;
@@ -3943,103 +4072,26 @@ getDFSRetry:
3943 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4072 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3944 if (rc) { 4073 if (rc) {
3945 cFYI(1, ("Send error in GetDFSRefer = %d", rc)); 4074 cFYI(1, ("Send error in GetDFSRefer = %d", rc));
3946 } else { /* decode response */ 4075 goto GetDFSRefExit;
3947/* BB Add logic to parse referrals here */ 4076 }
3948 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4077 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3949 4078
3950 /* BB Also check if enough total bytes returned? */ 4079 /* BB Also check if enough total bytes returned? */
3951 if (rc || (pSMBr->ByteCount < 17)) 4080 if (rc || (pSMBr->ByteCount < 17)) {
3952 rc = -EIO; /* bad smb */ 4081 rc = -EIO; /* bad smb */
3953 else { 4082 goto GetDFSRefExit;
3954 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4083 }
3955 __u16 data_count = le16_to_cpu(pSMBr->t2.DataCount);
3956 4084
3957 cFYI(1, 4085 cFYI(1, ("Decoding GetDFSRefer response BCC: %d Offset %d",
3958 ("Decoding GetDFSRefer response BCC: %d Offset %d", 4086 pSMBr->ByteCount,
3959 pSMBr->ByteCount, data_offset)); 4087 le16_to_cpu(pSMBr->t2.DataOffset)));
3960 referrals =
3961 (struct dfs_referral_level_3 *)
3962 (8 /* sizeof start of data block */ +
3963 data_offset +
3964 (char *) &pSMBr->hdr.Protocol);
3965 cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n"
3966 "for referral one refer size: 0x%x srv "
3967 "type: 0x%x refer flags: 0x%x ttl: 0x%x",
3968 le16_to_cpu(pSMBr->NumberOfReferrals),
3969 le16_to_cpu(pSMBr->DFSFlags),
3970 le16_to_cpu(referrals->ReferralSize),
3971 le16_to_cpu(referrals->ServerType),
3972 le16_to_cpu(referrals->ReferralFlags),
3973 le16_to_cpu(referrals->TimeToLive)));
3974 /* BB This field is actually two bytes in from start of
3975 data block so we could do safety check that DataBlock
3976 begins at address of pSMBr->NumberOfReferrals */
3977 *number_of_UNC_in_array =
3978 le16_to_cpu(pSMBr->NumberOfReferrals);
3979
3980 /* BB Fix below so can return more than one referral */
3981 if (*number_of_UNC_in_array > 1)
3982 *number_of_UNC_in_array = 1;
3983
3984 /* get the length of the strings describing refs */
3985 name_len = 0;
3986 for (i = 0; i < *number_of_UNC_in_array; i++) {
3987 /* make sure that DfsPathOffset not past end */
3988 __u16 offset =
3989 le16_to_cpu(referrals->DfsPathOffset);
3990 if (offset > data_count) {
3991 /* if invalid referral, stop here and do
3992 not try to copy any more */
3993 *number_of_UNC_in_array = i;
3994 break;
3995 }
3996 temp = ((char *)referrals) + offset;
3997 4088
3998 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 4089 /* parse returned result into more usable form */
3999 name_len += UniStrnlen((wchar_t *)temp, 4090 rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4000 data_count); 4091 target_nodes, nls_codepage);
4001 } else {
4002 name_len += strnlen(temp, data_count);
4003 }
4004 referrals++;
4005 /* BB add check that referral pointer does
4006 not fall off end PDU */
4007 }
4008 /* BB add check for name_len bigger than bcc */
4009 *targetUNCs =
4010 kmalloc(name_len+1+(*number_of_UNC_in_array),
4011 GFP_KERNEL);
4012 if (*targetUNCs == NULL) {
4013 rc = -ENOMEM;
4014 goto GetDFSRefExit;
4015 }
4016 /* copy the ref strings */
4017 referrals = (struct dfs_referral_level_3 *)
4018 (8 /* sizeof data hdr */ + data_offset +
4019 (char *) &pSMBr->hdr.Protocol);
4020
4021 for (i = 0; i < *number_of_UNC_in_array; i++) {
4022 temp = ((char *)referrals) +
4023 le16_to_cpu(referrals->DfsPathOffset);
4024 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
4025 cifs_strfromUCS_le(*targetUNCs,
4026 (__le16 *) temp,
4027 name_len,
4028 nls_codepage);
4029 } else {
4030 strncpy(*targetUNCs, temp, name_len);
4031 }
4032 /* BB update target_uncs pointers */
4033 referrals++;
4034 }
4035 temp = *targetUNCs;
4036 temp[name_len] = 0;
4037 }
4038 4092
4039 }
4040GetDFSRefExit: 4093GetDFSRefExit:
4041 if (pSMB) 4094 cifs_buf_release(pSMB);
4042 cifs_buf_release(pSMB);
4043 4095
4044 if (rc == -EAGAIN) 4096 if (rc == -EAGAIN)
4045 goto getDFSRetry; 4097 goto getDFSRetry;
@@ -4229,7 +4281,8 @@ QFSAttributeRetry:
4229 params = 2; /* level */ 4281 params = 2; /* level */
4230 pSMB->TotalDataCount = 0; 4282 pSMB->TotalDataCount = 0;
4231 pSMB->MaxParameterCount = cpu_to_le16(2); 4283 pSMB->MaxParameterCount = cpu_to_le16(2);
4232 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ 4284 /* BB find exact max SMB PDU from sess structure BB */
4285 pSMB->MaxDataCount = cpu_to_le16(1000);
4233 pSMB->MaxSetupCount = 0; 4286 pSMB->MaxSetupCount = 0;
4234 pSMB->Reserved = 0; 4287 pSMB->Reserved = 0;
4235 pSMB->Flags = 0; 4288 pSMB->Flags = 0;
@@ -4298,7 +4351,8 @@ QFSDeviceRetry:
4298 params = 2; /* level */ 4351 params = 2; /* level */
4299 pSMB->TotalDataCount = 0; 4352 pSMB->TotalDataCount = 0;
4300 pSMB->MaxParameterCount = cpu_to_le16(2); 4353 pSMB->MaxParameterCount = cpu_to_le16(2);
4301 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ 4354 /* BB find exact max SMB PDU from sess structure BB */
4355 pSMB->MaxDataCount = cpu_to_le16(1000);
4302 pSMB->MaxSetupCount = 0; 4356 pSMB->MaxSetupCount = 0;
4303 pSMB->Reserved = 0; 4357 pSMB->Reserved = 0;
4304 pSMB->Flags = 0; 4358 pSMB->Flags = 0;
@@ -4369,7 +4423,8 @@ QFSUnixRetry:
4369 pSMB->DataCount = 0; 4423 pSMB->DataCount = 0;
4370 pSMB->DataOffset = 0; 4424 pSMB->DataOffset = 0;
4371 pSMB->MaxParameterCount = cpu_to_le16(2); 4425 pSMB->MaxParameterCount = cpu_to_le16(2);
4372 pSMB->MaxDataCount = cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */ 4426 /* BB find exact max SMB PDU from sess structure BB */
4427 pSMB->MaxDataCount = cpu_to_le16(100);
4373 pSMB->MaxSetupCount = 0; 4428 pSMB->MaxSetupCount = 0;
4374 pSMB->Reserved = 0; 4429 pSMB->Reserved = 0;
4375 pSMB->Flags = 0; 4430 pSMB->Flags = 0;
@@ -4444,7 +4499,8 @@ SETFSUnixRetry:
4444 offset = param_offset + params; 4499 offset = param_offset + params;
4445 4500
4446 pSMB->MaxParameterCount = cpu_to_le16(4); 4501 pSMB->MaxParameterCount = cpu_to_le16(4);
4447 pSMB->MaxDataCount = cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */ 4502 /* BB find exact max SMB PDU from sess structure BB */
4503 pSMB->MaxDataCount = cpu_to_le16(100);
4448 pSMB->SetupCount = 1; 4504 pSMB->SetupCount = 1;
4449 pSMB->Reserved3 = 0; 4505 pSMB->Reserved3 = 0;
4450 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION); 4506 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
@@ -4512,7 +4568,8 @@ QFSPosixRetry:
4512 pSMB->DataCount = 0; 4568 pSMB->DataCount = 0;
4513 pSMB->DataOffset = 0; 4569 pSMB->DataOffset = 0;
4514 pSMB->MaxParameterCount = cpu_to_le16(2); 4570 pSMB->MaxParameterCount = cpu_to_le16(2);
4515 pSMB->MaxDataCount = cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */ 4571 /* BB find exact max SMB PDU from sess structure BB */
4572 pSMB->MaxDataCount = cpu_to_le16(100);
4516 pSMB->MaxSetupCount = 0; 4573 pSMB->MaxSetupCount = 0;
4517 pSMB->Reserved = 0; 4574 pSMB->Reserved = 0;
4518 pSMB->Flags = 0; 4575 pSMB->Flags = 0;
@@ -4702,7 +4759,8 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4702 4759
4703 count = sizeof(struct file_end_of_file_info); 4760 count = sizeof(struct file_end_of_file_info);
4704 pSMB->MaxParameterCount = cpu_to_le16(2); 4761 pSMB->MaxParameterCount = cpu_to_le16(2);
4705 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ 4762 /* BB find exact max SMB PDU from sess structure BB */
4763 pSMB->MaxDataCount = cpu_to_le16(1000);
4706 pSMB->SetupCount = 1; 4764 pSMB->SetupCount = 1;
4707 pSMB->Reserved3 = 0; 4765 pSMB->Reserved3 = 0;
4708 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 4766 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
@@ -4789,7 +4847,8 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
4789 4847
4790 count = sizeof(FILE_BASIC_INFO); 4848 count = sizeof(FILE_BASIC_INFO);
4791 pSMB->MaxParameterCount = cpu_to_le16(2); 4849 pSMB->MaxParameterCount = cpu_to_le16(2);
4792 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ 4850 /* BB find max SMB PDU from sess */
4851 pSMB->MaxDataCount = cpu_to_le16(1000);
4793 pSMB->SetupCount = 1; 4852 pSMB->SetupCount = 1;
4794 pSMB->Reserved3 = 0; 4853 pSMB->Reserved3 = 0;
4795 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 4854 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
@@ -4856,7 +4915,8 @@ SetTimesRetry:
4856 params = 6 + name_len; 4915 params = 6 + name_len;
4857 count = sizeof(FILE_BASIC_INFO); 4916 count = sizeof(FILE_BASIC_INFO);
4858 pSMB->MaxParameterCount = cpu_to_le16(2); 4917 pSMB->MaxParameterCount = cpu_to_le16(2);
4859 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ 4918 /* BB find max SMB PDU from sess structure BB */
4919 pSMB->MaxDataCount = cpu_to_le16(1000);
4860 pSMB->MaxSetupCount = 0; 4920 pSMB->MaxSetupCount = 0;
4861 pSMB->Reserved = 0; 4921 pSMB->Reserved = 0;
4862 pSMB->Flags = 0; 4922 pSMB->Flags = 0;
@@ -4986,7 +5046,8 @@ setPermsRetry:
4986 params = 6 + name_len; 5046 params = 6 + name_len;
4987 count = sizeof(FILE_UNIX_BASIC_INFO); 5047 count = sizeof(FILE_UNIX_BASIC_INFO);
4988 pSMB->MaxParameterCount = cpu_to_le16(2); 5048 pSMB->MaxParameterCount = cpu_to_le16(2);
4989 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ 5049 /* BB find max SMB PDU from sess structure BB */
5050 pSMB->MaxDataCount = cpu_to_le16(1000);
4990 pSMB->MaxSetupCount = 0; 5051 pSMB->MaxSetupCount = 0;
4991 pSMB->Reserved = 0; 5052 pSMB->Reserved = 0;
4992 pSMB->Flags = 0; 5053 pSMB->Flags = 0;
@@ -5051,8 +5112,7 @@ setPermsRetry:
5051 if (rc) 5112 if (rc)
5052 cFYI(1, ("SetPathInfo (perms) returned %d", rc)); 5113 cFYI(1, ("SetPathInfo (perms) returned %d", rc));
5053 5114
5054 if (pSMB) 5115 cifs_buf_release(pSMB);
5055 cifs_buf_release(pSMB);
5056 if (rc == -EAGAIN) 5116 if (rc == -EAGAIN)
5057 goto setPermsRetry; 5117 goto setPermsRetry;
5058 return rc; 5118 return rc;
@@ -5169,7 +5229,8 @@ QAllEAsRetry:
5169 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 5229 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
5170 pSMB->TotalDataCount = 0; 5230 pSMB->TotalDataCount = 0;
5171 pSMB->MaxParameterCount = cpu_to_le16(2); 5231 pSMB->MaxParameterCount = cpu_to_le16(2);
5172 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 5232 /* BB find exact max SMB PDU from sess structure BB */
5233 pSMB->MaxDataCount = cpu_to_le16(4000);
5173 pSMB->MaxSetupCount = 0; 5234 pSMB->MaxSetupCount = 0;
5174 pSMB->Reserved = 0; 5235 pSMB->Reserved = 0;
5175 pSMB->Flags = 0; 5236 pSMB->Flags = 0;
@@ -5273,8 +5334,7 @@ QAllEAsRetry:
5273 } 5334 }
5274 } 5335 }
5275 } 5336 }
5276 if (pSMB) 5337 cifs_buf_release(pSMB);
5277 cifs_buf_release(pSMB);
5278 if (rc == -EAGAIN) 5338 if (rc == -EAGAIN)
5279 goto QAllEAsRetry; 5339 goto QAllEAsRetry;
5280 5340
@@ -5317,7 +5377,8 @@ QEARetry:
5317 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 5377 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
5318 pSMB->TotalDataCount = 0; 5378 pSMB->TotalDataCount = 0;
5319 pSMB->MaxParameterCount = cpu_to_le16(2); 5379 pSMB->MaxParameterCount = cpu_to_le16(2);
5320 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 5380 /* BB find exact max SMB PDU from sess structure BB */
5381 pSMB->MaxDataCount = cpu_to_le16(4000);
5321 pSMB->MaxSetupCount = 0; 5382 pSMB->MaxSetupCount = 0;
5322 pSMB->Reserved = 0; 5383 pSMB->Reserved = 0;
5323 pSMB->Flags = 0; 5384 pSMB->Flags = 0;
@@ -5422,8 +5483,7 @@ QEARetry:
5422 } 5483 }
5423 } 5484 }
5424 } 5485 }
5425 if (pSMB) 5486 cifs_buf_release(pSMB);
5426 cifs_buf_release(pSMB);
5427 if (rc == -EAGAIN) 5487 if (rc == -EAGAIN)
5428 goto QEARetry; 5488 goto QEARetry;
5429 5489
@@ -5475,7 +5535,8 @@ SetEARetry:
5475 5535
5476 count = sizeof(*parm_data) + ea_value_len + name_len; 5536 count = sizeof(*parm_data) + ea_value_len + name_len;
5477 pSMB->MaxParameterCount = cpu_to_le16(2); 5537 pSMB->MaxParameterCount = cpu_to_le16(2);
5478 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */ 5538 /* BB find max SMB PDU from sess */
5539 pSMB->MaxDataCount = cpu_to_le16(1000);
5479 pSMB->MaxSetupCount = 0; 5540 pSMB->MaxSetupCount = 0;
5480 pSMB->Reserved = 0; 5541 pSMB->Reserved = 0;
5481 pSMB->Flags = 0; 5542 pSMB->Flags = 0;