aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c159
1 files changed, 117 insertions, 42 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index d06260251c30..1866bc2927d4 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -524,8 +524,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
524 int val, seconds, remain, result; 524 int val, seconds, remain, result;
525 struct timespec ts, utc; 525 struct timespec ts, utc;
526 utc = CURRENT_TIME; 526 utc = CURRENT_TIME;
527 ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date), 527 ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
528 le16_to_cpu(rsp->SrvTime.Time)); 528 rsp->SrvTime.Time, 0);
529 cFYI(1, ("SrvTime %d sec since 1970 (utc: %d) diff: %d", 529 cFYI(1, ("SrvTime %d sec since 1970 (utc: %d) diff: %d",
530 (int)ts.tv_sec, (int)utc.tv_sec, 530 (int)ts.tv_sec, (int)utc.tv_sec,
531 (int)(utc.tv_sec - ts.tv_sec))); 531 (int)(utc.tv_sec - ts.tv_sec)));
@@ -594,7 +594,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
594 else if (secFlags & CIFSSEC_MAY_KRB5) 594 else if (secFlags & CIFSSEC_MAY_KRB5)
595 server->secType = Kerberos; 595 server->secType = Kerberos;
596 else if (secFlags & CIFSSEC_MAY_NTLMSSP) 596 else if (secFlags & CIFSSEC_MAY_NTLMSSP)
597 server->secType = NTLMSSP; 597 server->secType = RawNTLMSSP;
598 else if (secFlags & CIFSSEC_MAY_LANMAN) 598 else if (secFlags & CIFSSEC_MAY_LANMAN)
599 server->secType = LANMAN; 599 server->secType = LANMAN;
600/* #ifdef CONFIG_CIFS_EXPERIMENTAL 600/* #ifdef CONFIG_CIFS_EXPERIMENTAL
@@ -729,7 +729,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
729 * the tcon is no longer on the list, so no need to take lock before 729 * the tcon is no longer on the list, so no need to take lock before
730 * checking this. 730 * checking this.
731 */ 731 */
732 if (tcon->need_reconnect) 732 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
733 return 0; 733 return 0;
734 734
735 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, 735 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
@@ -1113,7 +1113,10 @@ PsxCreat:
1113psx_create_err: 1113psx_create_err:
1114 cifs_buf_release(pSMB); 1114 cifs_buf_release(pSMB);
1115 1115
1116 cifs_stats_inc(&tcon->num_mkdirs); 1116 if (posix_flags & SMB_O_DIRECTORY)
1117 cifs_stats_inc(&tcon->num_posixmkdirs);
1118 else
1119 cifs_stats_inc(&tcon->num_posixopens);
1117 1120
1118 if (rc == -EAGAIN) 1121 if (rc == -EAGAIN)
1119 goto PsxCreat; 1122 goto PsxCreat;
@@ -2427,8 +2430,7 @@ querySymLinkRetry:
2427 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 2430 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
2428 pSMB->TotalDataCount = 0; 2431 pSMB->TotalDataCount = 0;
2429 pSMB->MaxParameterCount = cpu_to_le16(2); 2432 pSMB->MaxParameterCount = cpu_to_le16(2);
2430 /* BB find exact max data count below from sess structure BB */ 2433 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2431 pSMB->MaxDataCount = cpu_to_le16(4000);
2432 pSMB->MaxSetupCount = 0; 2434 pSMB->MaxSetupCount = 0;
2433 pSMB->Reserved = 0; 2435 pSMB->Reserved = 0;
2434 pSMB->Flags = 0; 2436 pSMB->Flags = 0;
@@ -5075,10 +5077,114 @@ SetAttrLgcyRetry:
5075} 5077}
5076#endif /* temporarily unneeded SetAttr legacy function */ 5078#endif /* temporarily unneeded SetAttr legacy function */
5077 5079
5080static void
5081cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5082 const struct cifs_unix_set_info_args *args)
5083{
5084 u64 mode = args->mode;
5085
5086 /*
5087 * Samba server ignores set of file size to zero due to bugs in some
5088 * older clients, but we should be precise - we use SetFileSize to
5089 * set file size and do not want to truncate file size to zero
5090 * accidently as happened on one Samba server beta by putting
5091 * zero instead of -1 here
5092 */
5093 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5094 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5095 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5096 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5097 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5098 data_offset->Uid = cpu_to_le64(args->uid);
5099 data_offset->Gid = cpu_to_le64(args->gid);
5100 /* better to leave device as zero when it is */
5101 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5102 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5103 data_offset->Permissions = cpu_to_le64(mode);
5104
5105 if (S_ISREG(mode))
5106 data_offset->Type = cpu_to_le32(UNIX_FILE);
5107 else if (S_ISDIR(mode))
5108 data_offset->Type = cpu_to_le32(UNIX_DIR);
5109 else if (S_ISLNK(mode))
5110 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5111 else if (S_ISCHR(mode))
5112 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5113 else if (S_ISBLK(mode))
5114 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5115 else if (S_ISFIFO(mode))
5116 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5117 else if (S_ISSOCK(mode))
5118 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5119}
5120
5078int 5121int
5079CIFSSMBUnixSetInfo(const int xid, struct cifsTconInfo *tcon, char *fileName, 5122CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
5080 const struct cifs_unix_set_info_args *args, 5123 const struct cifs_unix_set_info_args *args,
5081 const struct nls_table *nls_codepage, int remap) 5124 u16 fid, u32 pid_of_opener)
5125{
5126 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5127 FILE_UNIX_BASIC_INFO *data_offset;
5128 int rc = 0;
5129 u16 params, param_offset, offset, byte_count, count;
5130
5131 cFYI(1, ("Set Unix Info (via SetFileInfo)"));
5132 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5133
5134 if (rc)
5135 return rc;
5136
5137 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5138 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5139
5140 params = 6;
5141 pSMB->MaxSetupCount = 0;
5142 pSMB->Reserved = 0;
5143 pSMB->Flags = 0;
5144 pSMB->Timeout = 0;
5145 pSMB->Reserved2 = 0;
5146 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5147 offset = param_offset + params;
5148
5149 data_offset = (FILE_UNIX_BASIC_INFO *)
5150 ((char *)(&pSMB->hdr.Protocol) + offset);
5151 count = sizeof(FILE_UNIX_BASIC_INFO);
5152
5153 pSMB->MaxParameterCount = cpu_to_le16(2);
5154 /* BB find max SMB PDU from sess */
5155 pSMB->MaxDataCount = cpu_to_le16(1000);
5156 pSMB->SetupCount = 1;
5157 pSMB->Reserved3 = 0;
5158 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5159 byte_count = 3 /* pad */ + params + count;
5160 pSMB->DataCount = cpu_to_le16(count);
5161 pSMB->ParameterCount = cpu_to_le16(params);
5162 pSMB->TotalDataCount = pSMB->DataCount;
5163 pSMB->TotalParameterCount = pSMB->ParameterCount;
5164 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5165 pSMB->DataOffset = cpu_to_le16(offset);
5166 pSMB->Fid = fid;
5167 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5168 pSMB->Reserved4 = 0;
5169 pSMB->hdr.smb_buf_length += byte_count;
5170 pSMB->ByteCount = cpu_to_le16(byte_count);
5171
5172 cifs_fill_unix_set_info(data_offset, args);
5173
5174 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5175 if (rc)
5176 cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc));
5177
5178 /* Note: On -EAGAIN error only caller can retry on handle based calls
5179 since file handle passed in no longer valid */
5180
5181 return rc;
5182}
5183
5184int
5185CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName,
5186 const struct cifs_unix_set_info_args *args,
5187 const struct nls_table *nls_codepage, int remap)
5082{ 5188{
5083 TRANSACTION2_SPI_REQ *pSMB = NULL; 5189 TRANSACTION2_SPI_REQ *pSMB = NULL;
5084 TRANSACTION2_SPI_RSP *pSMBr = NULL; 5190 TRANSACTION2_SPI_RSP *pSMBr = NULL;
@@ -5087,7 +5193,6 @@ CIFSSMBUnixSetInfo(const int xid, struct cifsTconInfo *tcon, char *fileName,
5087 int bytes_returned = 0; 5193 int bytes_returned = 0;
5088 FILE_UNIX_BASIC_INFO *data_offset; 5194 FILE_UNIX_BASIC_INFO *data_offset;
5089 __u16 params, param_offset, offset, count, byte_count; 5195 __u16 params, param_offset, offset, count, byte_count;
5090 __u64 mode = args->mode;
5091 5196
5092 cFYI(1, ("In SetUID/GID/Mode")); 5197 cFYI(1, ("In SetUID/GID/Mode"));
5093setPermsRetry: 5198setPermsRetry:
@@ -5138,38 +5243,8 @@ setPermsRetry:
5138 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5243 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5139 pSMB->Reserved4 = 0; 5244 pSMB->Reserved4 = 0;
5140 pSMB->hdr.smb_buf_length += byte_count; 5245 pSMB->hdr.smb_buf_length += byte_count;
5141 /* Samba server ignores set of file size to zero due to bugs in some
5142 older clients, but we should be precise - we use SetFileSize to
5143 set file size and do not want to truncate file size to zero
5144 accidently as happened on one Samba server beta by putting
5145 zero instead of -1 here */
5146 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5147 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5148 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5149 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5150 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5151 data_offset->Uid = cpu_to_le64(args->uid);
5152 data_offset->Gid = cpu_to_le64(args->gid);
5153 /* better to leave device as zero when it is */
5154 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5155 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5156 data_offset->Permissions = cpu_to_le64(mode);
5157
5158 if (S_ISREG(mode))
5159 data_offset->Type = cpu_to_le32(UNIX_FILE);
5160 else if (S_ISDIR(mode))
5161 data_offset->Type = cpu_to_le32(UNIX_DIR);
5162 else if (S_ISLNK(mode))
5163 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5164 else if (S_ISCHR(mode))
5165 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5166 else if (S_ISBLK(mode))
5167 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5168 else if (S_ISFIFO(mode))
5169 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5170 else if (S_ISSOCK(mode))
5171 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5172 5246
5247 cifs_fill_unix_set_info(data_offset, args);
5173 5248
5174 pSMB->ByteCount = cpu_to_le16(byte_count); 5249 pSMB->ByteCount = cpu_to_le16(byte_count);
5175 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5250 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,