1 // SPDX-License-Identifier: LGPL-2.1 2 /* 3 * 4 * Copyright (C) International Business Machines Corp., 2002,2010 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 * 7 * Contains the routines for constructing the SMB PDUs themselves 8 * 9 */ 10 11 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */ 12 /* These are mostly routines that operate on a pathname, or on a tree id */ 13 /* (mounted volume), but there are eight handle based routines which must be */ 14 /* treated slightly differently for reconnection purposes since we never */ 15 /* want to reuse a stale file handle and only the caller knows the file info */ 16 17 #include <linux/fs.h> 18 #include <linux/filelock.h> 19 #include <linux/kernel.h> 20 #include <linux/vfs.h> 21 #include <linux/slab.h> 22 #include <linux/posix_acl_xattr.h> 23 #include <linux/pagemap.h> 24 #include <linux/swap.h> 25 #include <linux/task_io_accounting_ops.h> 26 #include <linux/uaccess.h> 27 #include <linux/netfs.h> 28 #include <trace/events/netfs.h> 29 #include "cifsglob.h" 30 #include "cifsproto.h" 31 #include "smb1proto.h" 32 #include "../common/smbfsctl.h" 33 #include "cifsfs.h" 34 #include "cifsacl.h" 35 #include "cifs_unicode.h" 36 #include "cifs_debug.h" 37 #include "fscache.h" 38 #include "smbdirect.h" 39 #ifdef CONFIG_CIFS_DFS_UPCALL 40 #include "dfs_cache.h" 41 #endif 42 43 #ifdef CONFIG_CIFS_POSIX 44 static struct { 45 int index; 46 char *name; 47 } protocols[] = { 48 {CIFS_PROT, "\2NT LM 0.12"}, 49 {POSIX_PROT, "\2POSIX 2"}, 50 {BAD_PROT, "\2"} 51 }; 52 #else 53 static struct { 54 int index; 55 char *name; 56 } protocols[] = { 57 {CIFS_PROT, "\2NT LM 0.12"}, 58 {BAD_PROT, "\2"} 59 }; 60 #endif 61 62 /* define the number of elements in the cifs dialect array */ 63 #ifdef CONFIG_CIFS_POSIX 64 #define CIFS_NUM_PROT 2 65 #else /* not posix */ 66 #define CIFS_NUM_PROT 1 67 #endif /* CIFS_POSIX */ 68 69 70 /* reconnect the socket, tcon, and smb session if needed */ 71 static int 72 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) 73 { 74 struct TCP_Server_Info *server; 75 struct cifs_ses *ses; 76 int rc; 77 78 /* 79 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for 80 * tcp and smb session status done differently for those three - in the 81 * calling routine 82 */ 83 if (!tcon) 84 return 0; 85 86 ses = tcon->ses; 87 server = ses->server; 88 89 /* 90 * only tree disconnect, open, and write, (and ulogoff which does not 91 * have tcon) are allowed as we start umount 92 */ 93 spin_lock(&tcon->tc_lock); 94 if (tcon->status == TID_EXITING) { 95 if (smb_command != SMB_COM_TREE_DISCONNECT) { 96 spin_unlock(&tcon->tc_lock); 97 cifs_dbg(FYI, "can not send cmd %d while umounting\n", 98 smb_command); 99 return -ENODEV; 100 } 101 } 102 spin_unlock(&tcon->tc_lock); 103 104 again: 105 rc = cifs_wait_for_server_reconnect(server, tcon->retry); 106 if (rc) 107 return rc; 108 109 spin_lock(&ses->chan_lock); 110 if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) { 111 spin_unlock(&ses->chan_lock); 112 return 0; 113 } 114 spin_unlock(&ses->chan_lock); 115 116 mutex_lock(&ses->session_mutex); 117 /* 118 * Handle the case where a concurrent thread failed to negotiate or 119 * killed a channel. 120 */ 121 spin_lock(&server->srv_lock); 122 switch (server->tcpStatus) { 123 case CifsExiting: 124 spin_unlock(&server->srv_lock); 125 mutex_unlock(&ses->session_mutex); 126 return -EHOSTDOWN; 127 case CifsNeedReconnect: 128 spin_unlock(&server->srv_lock); 129 mutex_unlock(&ses->session_mutex); 130 if (!tcon->retry) 131 return -EHOSTDOWN; 132 goto again; 133 default: 134 break; 135 } 136 spin_unlock(&server->srv_lock); 137 138 /* 139 * need to prevent multiple threads trying to simultaneously 140 * reconnect the same SMB session 141 */ 142 spin_lock(&ses->ses_lock); 143 spin_lock(&ses->chan_lock); 144 if (!cifs_chan_needs_reconnect(ses, server) && 145 ses->ses_status == SES_GOOD) { 146 spin_unlock(&ses->chan_lock); 147 spin_unlock(&ses->ses_lock); 148 149 /* this means that we only need to tree connect */ 150 if (tcon->need_reconnect) 151 goto skip_sess_setup; 152 153 mutex_unlock(&ses->session_mutex); 154 goto out; 155 } 156 spin_unlock(&ses->chan_lock); 157 spin_unlock(&ses->ses_lock); 158 159 rc = cifs_negotiate_protocol(0, ses, server); 160 if (rc) { 161 mutex_unlock(&ses->session_mutex); 162 if (!tcon->retry) 163 return -EHOSTDOWN; 164 goto again; 165 } 166 rc = cifs_setup_session(0, ses, server); 167 if ((rc == -EACCES) || (rc == -EHOSTDOWN) || (rc == -EKEYREVOKED)) { 168 /* 169 * Try alternate password for next reconnect if an alternate 170 * password is available. 171 */ 172 if (ses->password2) 173 swap(ses->password2, ses->password); 174 } 175 176 /* do we need to reconnect tcon? */ 177 if (rc || !tcon->need_reconnect) { 178 mutex_unlock(&ses->session_mutex); 179 goto out; 180 } 181 182 skip_sess_setup: 183 cifs_mark_open_files_invalid(tcon); 184 rc = cifs_tree_connect(0, tcon); 185 mutex_unlock(&ses->session_mutex); 186 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc); 187 188 if (rc) { 189 pr_warn_once("reconnect tcon failed rc = %d\n", rc); 190 goto out; 191 } 192 193 atomic_inc(&tconInfoReconnectCount); 194 195 /* tell server Unix caps we support */ 196 if (cap_unix(ses)) 197 reset_cifs_unix_caps(0, tcon, NULL, NULL); 198 199 /* 200 * Removed call to reopen open files here. It is safer (and faster) to 201 * reopen files one at a time as needed in read and write. 202 * 203 * FIXME: what about file locks? don't we need to reclaim them ASAP? 204 */ 205 206 out: 207 /* 208 * Check if handle based operation so we know whether we can continue 209 * or not without returning to caller to reset file handle 210 */ 211 switch (smb_command) { 212 case SMB_COM_READ_ANDX: 213 case SMB_COM_WRITE_ANDX: 214 case SMB_COM_CLOSE: 215 case SMB_COM_FIND_CLOSE2: 216 case SMB_COM_LOCKING_ANDX: 217 rc = -EAGAIN; 218 } 219 220 return rc; 221 } 222 223 /* Allocate and return pointer to an SMB request buffer, and set basic 224 SMB information in the SMB header. If the return code is zero, this 225 function must have filled in request_buf pointer */ 226 static int 227 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon, 228 void **request_buf) 229 { 230 unsigned int in_len; 231 int rc; 232 233 rc = cifs_reconnect_tcon(tcon, smb_command); 234 if (rc) 235 return rc; 236 237 *request_buf = cifs_small_buf_get(); 238 if (*request_buf == NULL) { 239 /* BB should we add a retry in here if not a writepage? */ 240 return -ENOMEM; 241 } 242 243 in_len = header_assemble((struct smb_hdr *) *request_buf, smb_command, 244 tcon, wct); 245 246 if (tcon != NULL) 247 cifs_stats_inc(&tcon->num_smbs_sent); 248 249 return in_len; 250 } 251 252 int 253 small_smb_init_no_tc(const int smb_command, const int wct, 254 struct cifs_ses *ses, void **request_buf) 255 { 256 int rc; 257 struct smb_hdr *buffer; 258 259 rc = small_smb_init(smb_command, wct, NULL, request_buf); 260 if (rc < 0) 261 return rc; 262 263 buffer = (struct smb_hdr *)*request_buf; 264 buffer->Mid = get_next_mid(ses->server); 265 if (ses->capabilities & CAP_UNICODE) 266 buffer->Flags2 |= SMBFLG2_UNICODE; 267 if (ses->capabilities & CAP_STATUS32) 268 buffer->Flags2 |= SMBFLG2_ERR_STATUS; 269 270 /* uid, tid can stay at zero as set in header assemble */ 271 272 /* BB add support for turning on the signing when 273 this function is used after 1st of session setup requests */ 274 275 return rc; 276 } 277 278 /* If the return code is zero, this function must fill in request_buf pointer */ 279 static int 280 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon, 281 void **request_buf, void **response_buf) 282 { 283 unsigned int in_len; 284 285 *request_buf = cifs_buf_get(); 286 if (*request_buf == NULL) { 287 /* BB should we add a retry in here if not a writepage? */ 288 return -ENOMEM; 289 } 290 /* Although the original thought was we needed the response buf for */ 291 /* potential retries of smb operations it turns out we can determine */ 292 /* from the mid flags when the request buffer can be resent without */ 293 /* having to use a second distinct buffer for the response */ 294 if (response_buf) 295 *response_buf = *request_buf; 296 297 in_len = header_assemble((struct smb_hdr *)*request_buf, smb_command, tcon, 298 wct); 299 300 if (tcon != NULL) 301 cifs_stats_inc(&tcon->num_smbs_sent); 302 303 return in_len; 304 } 305 306 /* If the return code is zero, this function must fill in request_buf pointer */ 307 static int 308 smb_init(int smb_command, int wct, struct cifs_tcon *tcon, 309 void **request_buf, void **response_buf) 310 { 311 int rc; 312 313 rc = cifs_reconnect_tcon(tcon, smb_command); 314 if (rc) 315 return rc; 316 317 return __smb_init(smb_command, wct, tcon, request_buf, response_buf); 318 } 319 320 static int 321 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon, 322 void **request_buf, void **response_buf) 323 { 324 spin_lock(&tcon->ses->chan_lock); 325 if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) || 326 tcon->need_reconnect) { 327 spin_unlock(&tcon->ses->chan_lock); 328 return -EHOSTDOWN; 329 } 330 spin_unlock(&tcon->ses->chan_lock); 331 332 return __smb_init(smb_command, wct, tcon, request_buf, response_buf); 333 } 334 335 static int validate_t2(struct smb_t2_rsp *pSMB) 336 { 337 unsigned int total_size; 338 339 /* check for plausible wct */ 340 if (pSMB->hdr.WordCount < 10) 341 goto vt2_err; 342 343 /* check for parm and data offset going beyond end of smb */ 344 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 || 345 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024) 346 goto vt2_err; 347 348 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount); 349 if (total_size >= 512) 350 goto vt2_err; 351 352 /* check that bcc is at least as big as parms + data, and that it is 353 * less than negotiated smb buffer 354 */ 355 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount); 356 if (total_size > get_bcc(&pSMB->hdr) || 357 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) 358 goto vt2_err; 359 360 return 0; 361 vt2_err: 362 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB, 363 sizeof(struct smb_t2_rsp) + 16); 364 return -EINVAL; 365 } 366 367 static int 368 decode_ext_sec_blob(struct cifs_ses *ses, SMB_NEGOTIATE_RSP *pSMBr) 369 { 370 int rc = 0; 371 u16 count; 372 char *guid = pSMBr->u.extended_response.GUID; 373 struct TCP_Server_Info *server = ses->server; 374 375 count = get_bcc(&pSMBr->hdr); 376 if (count < SMB1_CLIENT_GUID_SIZE) 377 return smb_EIO2(smb_eio_trace_neg_sec_blob_too_small, 378 count, SMB1_CLIENT_GUID_SIZE); 379 380 spin_lock(&cifs_tcp_ses_lock); 381 if (server->srv_count > 1) { 382 spin_unlock(&cifs_tcp_ses_lock); 383 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) { 384 cifs_dbg(FYI, "server UID changed\n"); 385 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE); 386 } 387 } else { 388 spin_unlock(&cifs_tcp_ses_lock); 389 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE); 390 } 391 392 if (count == SMB1_CLIENT_GUID_SIZE) { 393 server->sec_ntlmssp = true; 394 } else { 395 count -= SMB1_CLIENT_GUID_SIZE; 396 rc = decode_negTokenInit( 397 pSMBr->u.extended_response.SecurityBlob, count, server); 398 if (rc != 1) 399 return -EINVAL; 400 } 401 402 return 0; 403 } 404 405 static bool 406 should_set_ext_sec_flag(enum securityEnum sectype) 407 { 408 switch (sectype) { 409 case RawNTLMSSP: 410 case Kerberos: 411 return true; 412 case Unspecified: 413 if (global_secflags & 414 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)) 415 return true; 416 fallthrough; 417 default: 418 return false; 419 } 420 } 421 422 int 423 CIFSSMBNegotiate(const unsigned int xid, 424 struct cifs_ses *ses, 425 struct TCP_Server_Info *server) 426 { 427 SMB_NEGOTIATE_REQ *pSMB; 428 SMB_NEGOTIATE_RSP *pSMBr; 429 unsigned int in_len; 430 int rc = 0; 431 int bytes_returned; 432 int i; 433 u16 count; 434 435 if (!server) { 436 WARN(1, "%s: server is NULL!\n", __func__); 437 return smb_EIO(smb_eio_trace_null_pointers); 438 } 439 440 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ , 441 (void **) &pSMB, (void **) &pSMBr); 442 if (rc < 0) 443 return rc; 444 in_len = rc; 445 446 pSMB->hdr.Mid = get_next_mid(server); 447 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS; 448 449 if (ses->unicode != 0) 450 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 451 452 if (should_set_ext_sec_flag(ses->sectype)) { 453 cifs_dbg(FYI, "Requesting extended security\n"); 454 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 455 } 456 457 count = 0; 458 /* 459 * We know that all the name entries in the protocols array 460 * are short (< 16 bytes anyway) and are NUL terminated. 461 */ 462 for (i = 0; i < CIFS_NUM_PROT; i++) { 463 size_t len = strlen(protocols[i].name) + 1; 464 465 memcpy(&pSMB->DialectsArray[count], protocols[i].name, len); 466 count += len; 467 } 468 in_len += count; 469 pSMB->ByteCount = cpu_to_le16(count); 470 471 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, in_len, 472 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 473 if (rc != 0) 474 goto neg_err_exit; 475 476 server->dialect = le16_to_cpu(pSMBr->DialectIndex); 477 cifs_dbg(FYI, "Dialect: %d\n", server->dialect); 478 /* Check wct = 1 error case */ 479 if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) { 480 /* core returns wct = 1, but we do not ask for core - otherwise 481 small wct just comes when dialect index is -1 indicating we 482 could not negotiate a common dialect */ 483 rc = -EOPNOTSUPP; 484 goto neg_err_exit; 485 } else if (pSMBr->hdr.WordCount != 17) { 486 /* unknown wct */ 487 rc = -EOPNOTSUPP; 488 goto neg_err_exit; 489 } 490 /* else wct == 17, NTLM or better */ 491 492 server->sec_mode = pSMBr->SecurityMode; 493 if ((server->sec_mode & SECMODE_USER) == 0) 494 cifs_dbg(FYI, "share mode security\n"); 495 496 /* one byte, so no need to convert this or EncryptionKeyLen from 497 little endian */ 498 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount), 499 cifs_max_pending); 500 set_credits(server, server->maxReq); 501 /* probably no need to store and check maxvcs */ 502 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize); 503 /* set up max_read for readahead check */ 504 server->max_read = server->maxBuf; 505 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf); 506 server->capabilities = le32_to_cpu(pSMBr->Capabilities); 507 server->session_key_id = pSMBr->SessionKey; 508 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); 509 server->timeAdj *= 60; 510 511 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { 512 server->negflavor = CIFS_NEGFLAVOR_UNENCAP; 513 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey, 514 CIFS_CRYPTO_KEY_SIZE); 515 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC || 516 server->capabilities & CAP_EXTENDED_SECURITY) { 517 server->negflavor = CIFS_NEGFLAVOR_EXTENDED; 518 rc = decode_ext_sec_blob(ses, pSMBr); 519 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) { 520 /* no crypt key only if plain text pwd */ 521 rc = smb_EIO(smb_eio_trace_neg_no_crypt_key); 522 } else { 523 server->negflavor = CIFS_NEGFLAVOR_UNENCAP; 524 server->capabilities &= ~CAP_EXTENDED_SECURITY; 525 } 526 527 if (!rc) 528 rc = cifs_enable_signing(server, ses->sign); 529 neg_err_exit: 530 cifs_buf_release(pSMB); 531 532 cifs_dbg(FYI, "negprot rc %d\n", rc); 533 return rc; 534 } 535 536 /* 537 * Issue a TREE_CONNECT request. 538 */ 539 int CIFSTCon(const unsigned int xid, struct cifs_ses *ses, const char *tree, 540 struct cifs_tcon *tcon) 541 { 542 struct smb_hdr *smb_buffer; 543 struct smb_hdr *smb_buffer_response; 544 TCONX_REQ *pSMB; 545 TCONX_RSP *pSMBr; 546 unsigned char *bcc_ptr; 547 int rc = 0; 548 int length, in_len; 549 __u16 bytes_left, count; 550 551 if (ses == NULL) 552 return smb_EIO(smb_eio_trace_null_pointers); 553 554 smb_buffer = cifs_buf_get(); 555 if (smb_buffer == NULL) 556 return -ENOMEM; 557 558 smb_buffer_response = smb_buffer; 559 560 in_len = header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, 561 NULL /*no tid */, 4 /*wct */); 562 563 smb_buffer->Mid = get_next_mid(ses->server); 564 smb_buffer->Uid = ses->Suid; 565 pSMB = (TCONX_REQ *) smb_buffer; 566 pSMBr = (TCONX_RSP *) smb_buffer_response; 567 568 pSMB->AndXCommand = 0xFF; 569 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); 570 bcc_ptr = &pSMB->Password[0]; 571 572 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ 573 *bcc_ptr = 0; /* password is null byte */ 574 bcc_ptr++; /* skip password */ 575 /* already aligned so no need to do it below */ 576 577 if (ses->server->sign) 578 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 579 580 if (ses->capabilities & CAP_STATUS32) 581 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS; 582 583 if (ses->capabilities & CAP_DFS) 584 smb_buffer->Flags2 |= SMBFLG2_DFS; 585 586 if (ses->capabilities & CAP_UNICODE) { 587 smb_buffer->Flags2 |= SMBFLG2_UNICODE; 588 length = 589 cifs_strtoUTF16((__le16 *) bcc_ptr, tree, 590 6 /* max utf8 char length in bytes */ * 591 (/* server len*/ + 256 /* share len */), 592 ses->local_nls); 593 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */ 594 bcc_ptr += 2; /* skip trailing null */ 595 } else { /* ASCII */ 596 strcpy(bcc_ptr, tree); 597 bcc_ptr += strlen(tree) + 1; 598 } 599 strcpy(bcc_ptr, "?????"); 600 bcc_ptr += strlen("?????"); 601 bcc_ptr += 1; 602 count = bcc_ptr - &pSMB->Password[0]; 603 in_len += count; 604 pSMB->ByteCount = cpu_to_le16(count); 605 606 rc = SendReceive(xid, ses, smb_buffer, in_len, smb_buffer_response, 607 &length, 0); 608 609 /* above now done in SendReceive */ 610 if (rc == 0) { 611 bool is_unicode; 612 613 tcon->tid = smb_buffer_response->Tid; 614 bcc_ptr = pByteArea(smb_buffer_response); 615 bytes_left = get_bcc(smb_buffer_response); 616 if (bytes_left < 2) { 617 rc = smb_EIO2(smb_eio_trace_tcon_bcc_too_small, 618 bytes_left, 2); 619 goto out; 620 } 621 length = strnlen(bcc_ptr, bytes_left - 2); 622 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) 623 is_unicode = true; 624 else 625 is_unicode = false; 626 627 628 /* skip service field (NB: this field is always ASCII) */ 629 if (length == 3) { 630 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') && 631 (bcc_ptr[2] == 'C')) { 632 cifs_dbg(FYI, "IPC connection\n"); 633 tcon->ipc = true; 634 tcon->pipe = true; 635 } 636 } else if (length == 2) { 637 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) { 638 /* the most common case */ 639 cifs_dbg(FYI, "disk share connection\n"); 640 } 641 } 642 bcc_ptr += length + 1; 643 bytes_left -= (length + 1); 644 strscpy(tcon->tree_name, tree, sizeof(tcon->tree_name)); 645 646 /* mostly informational -- no need to fail on error here */ 647 kfree(tcon->nativeFileSystem); 648 tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr, 649 bytes_left, is_unicode, 650 ses->local_nls); 651 652 cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem); 653 654 if ((smb_buffer_response->WordCount == 3) || 655 (smb_buffer_response->WordCount == 7)) 656 /* field is in same location */ 657 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); 658 else 659 tcon->Flags = 0; 660 cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags); 661 662 /* 663 * reset_cifs_unix_caps calls QFSInfo which requires 664 * need_reconnect to be false, but we would not need to call 665 * reset_caps if this were not a reconnect case so must check 666 * need_reconnect flag here. The caller will also clear 667 * need_reconnect when tcon was successful but needed to be 668 * cleared earlier in the case of unix extensions reconnect 669 */ 670 if (tcon->need_reconnect && tcon->unix_ext) { 671 cifs_dbg(FYI, "resetting caps for %s\n", tcon->tree_name); 672 tcon->need_reconnect = false; 673 reset_cifs_unix_caps(xid, tcon, NULL, NULL); 674 } 675 } 676 out: 677 cifs_buf_release(smb_buffer); 678 return rc; 679 } 680 681 int 682 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon) 683 { 684 struct smb_hdr *smb_buffer; 685 unsigned int in_len; 686 int rc = 0; 687 688 cifs_dbg(FYI, "In tree disconnect\n"); 689 690 /* BB: do we need to check this? These should never be NULL. */ 691 if ((tcon->ses == NULL) || (tcon->ses->server == NULL)) 692 return smb_EIO(smb_eio_trace_null_pointers); 693 694 /* 695 * No need to return error on this operation if tid invalidated and 696 * closed on server already e.g. due to tcp session crashing. Also, 697 * the tcon is no longer on the list, so no need to take lock before 698 * checking this. 699 */ 700 spin_lock(&tcon->ses->chan_lock); 701 if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) { 702 spin_unlock(&tcon->ses->chan_lock); 703 return smb_EIO(smb_eio_trace_tdis_in_reconnect); 704 } 705 spin_unlock(&tcon->ses->chan_lock); 706 707 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, 708 (void **)&smb_buffer); 709 if (rc < 0) 710 return rc; 711 in_len = rc; 712 713 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, in_len, 0); 714 cifs_small_buf_release(smb_buffer); 715 if (rc) 716 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc); 717 718 /* No need to return error on this operation if tid invalidated and 719 closed on server already e.g. due to tcp session crashing */ 720 if (rc == -EAGAIN) 721 rc = 0; 722 723 return rc; 724 } 725 726 /* 727 * This is a no-op for now. We're not really interested in the reply, but 728 * rather in the fact that the server sent one and that server->lstrp 729 * gets updated. 730 * 731 * FIXME: maybe we should consider checking that the reply matches request? 732 */ 733 static void 734 cifs_echo_callback(struct TCP_Server_Info *server, struct mid_q_entry *mid) 735 { 736 struct cifs_credits credits = { .value = 1, .instance = 0 }; 737 738 release_mid(server, mid); 739 add_credits(server, &credits, CIFS_ECHO_OP); 740 } 741 742 int 743 CIFSSMBEcho(struct TCP_Server_Info *server) 744 { 745 ECHO_REQ *smb; 746 int rc = 0; 747 struct kvec iov[1]; 748 struct smb_rqst rqst = { 749 .rq_iov = iov, 750 .rq_nvec = ARRAY_SIZE(iov), 751 }; 752 unsigned int in_len; 753 754 cifs_dbg(FYI, "In echo request\n"); 755 756 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb); 757 if (rc < 0) 758 return rc; 759 in_len = rc; 760 761 if (server->capabilities & CAP_UNICODE) 762 smb->hdr.Flags2 |= SMBFLG2_UNICODE; 763 764 /* set up echo request */ 765 smb->hdr.Tid = 0xffff; 766 smb->hdr.WordCount = 1; 767 put_unaligned_le16(1, &smb->EchoCount); 768 put_bcc(1, &smb->hdr); 769 smb->Data[0] = 'a'; 770 in_len += 3; 771 772 iov[0].iov_len = in_len; 773 iov[0].iov_base = smb; 774 775 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL, 776 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL); 777 if (rc) 778 cifs_dbg(FYI, "Echo request failed: %d\n", rc); 779 780 cifs_small_buf_release(smb); 781 782 return rc; 783 } 784 785 int 786 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses) 787 { 788 LOGOFF_ANDX_REQ *pSMB; 789 unsigned int in_len; 790 int rc = 0; 791 792 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n"); 793 794 /* 795 * BB: do we need to check validity of ses and server? They should 796 * always be valid since we have an active reference. If not, that 797 * should probably be a BUG() 798 */ 799 if (!ses || !ses->server) 800 return smb_EIO(smb_eio_trace_null_pointers); 801 802 mutex_lock(&ses->session_mutex); 803 spin_lock(&ses->chan_lock); 804 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) { 805 spin_unlock(&ses->chan_lock); 806 goto session_already_dead; /* no need to send SMBlogoff if uid 807 already closed due to reconnect */ 808 } 809 spin_unlock(&ses->chan_lock); 810 811 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB); 812 if (rc < 0) { 813 mutex_unlock(&ses->session_mutex); 814 return rc; 815 } 816 in_len = rc; 817 818 pSMB->hdr.Mid = get_next_mid(ses->server); 819 820 if (ses->server->sign) 821 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 822 823 pSMB->hdr.Uid = ses->Suid; 824 825 pSMB->AndXCommand = 0xFF; 826 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, in_len, 0); 827 cifs_small_buf_release(pSMB); 828 session_already_dead: 829 mutex_unlock(&ses->session_mutex); 830 831 /* if session dead then we do not need to do ulogoff, 832 since server closed smb session, no sense reporting 833 error */ 834 if (rc == -EAGAIN) 835 rc = 0; 836 return rc; 837 } 838 839 int CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon, 840 const char *fileName, __u16 type, int remap) 841 { 842 TRANSACTION2_SPI_REQ *pSMB = NULL; 843 TRANSACTION2_SPI_RSP *pSMBr = NULL; 844 struct unlink_psx_rq *pRqD; 845 unsigned int in_len; 846 int name_len; 847 int rc = 0; 848 int bytes_returned = 0; 849 __u16 params, param_offset, offset, byte_count; 850 851 cifs_dbg(FYI, "In POSIX delete\n"); 852 PsxDelete: 853 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 854 (void **) &pSMBr); 855 if (rc < 0) 856 return rc; 857 in_len = rc; 858 859 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 860 name_len = 861 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 862 PATH_MAX, tcon->ses->local_nls, remap); 863 name_len++; /* trailing null */ 864 name_len *= 2; 865 } else { 866 name_len = copy_path_name(pSMB->FileName, fileName); 867 } 868 869 params = 6 + name_len; 870 pSMB->MaxParameterCount = cpu_to_le16(2); 871 pSMB->MaxDataCount = 0; /* BB double check this with jra */ 872 pSMB->MaxSetupCount = 0; 873 pSMB->Reserved = 0; 874 pSMB->Flags = 0; 875 pSMB->Timeout = 0; 876 pSMB->Reserved2 = 0; 877 param_offset = offsetof(struct smb_com_transaction2_spi_req, 878 InformationLevel); 879 offset = param_offset + params; 880 881 /* Setup pointer to Request Data (inode type). */ 882 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset); 883 pRqD->type = cpu_to_le16(type); 884 pSMB->ParameterOffset = cpu_to_le16(param_offset); 885 pSMB->DataOffset = cpu_to_le16(offset); 886 pSMB->SetupCount = 1; 887 pSMB->Reserved3 = 0; 888 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 889 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq); 890 891 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq)); 892 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq)); 893 pSMB->ParameterCount = cpu_to_le16(params); 894 pSMB->TotalParameterCount = pSMB->ParameterCount; 895 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK); 896 pSMB->Reserved4 = 0; 897 in_len += byte_count; 898 pSMB->ByteCount = cpu_to_le16(byte_count); 899 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 900 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 901 if (rc) 902 cifs_dbg(FYI, "Posix delete returned %d\n", rc); 903 cifs_buf_release(pSMB); 904 905 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes); 906 907 if (rc == -EAGAIN) 908 goto PsxDelete; 909 910 return rc; 911 } 912 913 int 914 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name, 915 struct cifs_sb_info *cifs_sb, struct dentry *dentry) 916 { 917 DELETE_FILE_REQ *pSMB = NULL; 918 DELETE_FILE_RSP *pSMBr = NULL; 919 unsigned int in_len; 920 int rc = 0; 921 int bytes_returned; 922 int name_len; 923 int remap = cifs_remap(cifs_sb); 924 925 DelFileRetry: 926 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB, 927 (void **) &pSMBr); 928 if (rc < 0) 929 return rc; 930 in_len = rc; 931 932 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 933 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name, 934 PATH_MAX, cifs_sb->local_nls, 935 remap); 936 name_len++; /* trailing null */ 937 name_len *= 2; 938 } else { 939 name_len = copy_path_name(pSMB->fileName, name); 940 } 941 pSMB->SearchAttributes = 942 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM); 943 pSMB->BufferFormat = 0x04; 944 in_len += name_len + 1; 945 pSMB->ByteCount = cpu_to_le16(name_len + 1); 946 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 947 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 948 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes); 949 if (rc) 950 cifs_dbg(FYI, "Error in RMFile = %d\n", rc); 951 952 cifs_buf_release(pSMB); 953 if (rc == -EAGAIN) 954 goto DelFileRetry; 955 956 return rc; 957 } 958 959 int 960 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, 961 struct cifs_sb_info *cifs_sb) 962 { 963 DELETE_DIRECTORY_REQ *pSMB = NULL; 964 DELETE_DIRECTORY_RSP *pSMBr = NULL; 965 unsigned int in_len; 966 int rc = 0; 967 int bytes_returned; 968 int name_len; 969 int remap = cifs_remap(cifs_sb); 970 971 cifs_dbg(FYI, "In CIFSSMBRmDir\n"); 972 RmDirRetry: 973 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB, 974 (void **) &pSMBr); 975 if (rc < 0) 976 return rc; 977 in_len = rc; 978 979 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 980 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, 981 PATH_MAX, cifs_sb->local_nls, 982 remap); 983 name_len++; /* trailing null */ 984 name_len *= 2; 985 } else { 986 name_len = copy_path_name(pSMB->DirName, name); 987 } 988 989 pSMB->BufferFormat = 0x04; 990 in_len += name_len + 1; 991 pSMB->ByteCount = cpu_to_le16(name_len + 1); 992 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 993 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 994 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs); 995 if (rc) 996 cifs_dbg(FYI, "Error in RMDir = %d\n", rc); 997 998 cifs_buf_release(pSMB); 999 if (rc == -EAGAIN) 1000 goto RmDirRetry; 1001 return rc; 1002 } 1003 1004 int 1005 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode, 1006 struct cifs_tcon *tcon, const char *name, 1007 struct cifs_sb_info *cifs_sb) 1008 { 1009 int rc = 0; 1010 CREATE_DIRECTORY_REQ *pSMB = NULL; 1011 CREATE_DIRECTORY_RSP *pSMBr = NULL; 1012 unsigned int in_len; 1013 int bytes_returned; 1014 int name_len; 1015 int remap = cifs_remap(cifs_sb); 1016 1017 cifs_dbg(FYI, "In CIFSSMBMkDir\n"); 1018 MkDirRetry: 1019 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB, 1020 (void **) &pSMBr); 1021 if (rc < 0) 1022 return rc; 1023 in_len = rc; 1024 1025 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1026 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, 1027 PATH_MAX, cifs_sb->local_nls, 1028 remap); 1029 name_len++; /* trailing null */ 1030 name_len *= 2; 1031 } else { 1032 name_len = copy_path_name(pSMB->DirName, name); 1033 } 1034 1035 pSMB->BufferFormat = 0x04; 1036 in_len += name_len + 1; 1037 pSMB->ByteCount = cpu_to_le16(name_len + 1); 1038 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 1039 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1040 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs); 1041 if (rc) 1042 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc); 1043 1044 cifs_buf_release(pSMB); 1045 if (rc == -EAGAIN) 1046 goto MkDirRetry; 1047 return rc; 1048 } 1049 1050 int CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon, 1051 __u32 posix_flags, __u64 mode, __u16 *netfid, 1052 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock, 1053 const char *name, int remap) 1054 { 1055 TRANSACTION2_SPI_REQ *pSMB = NULL; 1056 TRANSACTION2_SPI_RSP *pSMBr = NULL; 1057 unsigned int in_len; 1058 int name_len; 1059 int rc = 0; 1060 int bytes_returned = 0; 1061 __u16 params, param_offset, offset, byte_count, count; 1062 OPEN_PSX_REQ *pdata; 1063 OPEN_PSX_RSP *psx_rsp; 1064 1065 cifs_dbg(FYI, "In POSIX Create\n"); 1066 PsxCreat: 1067 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 1068 (void **) &pSMBr); 1069 if (rc < 0) 1070 return rc; 1071 in_len = rc; 1072 1073 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1074 name_len = 1075 cifsConvertToUTF16((__le16 *) pSMB->FileName, name, 1076 PATH_MAX, tcon->ses->local_nls, remap); 1077 name_len++; /* trailing null */ 1078 name_len *= 2; 1079 } else { 1080 name_len = copy_path_name(pSMB->FileName, name); 1081 } 1082 1083 params = 6 + name_len; 1084 count = sizeof(OPEN_PSX_REQ); 1085 pSMB->MaxParameterCount = cpu_to_le16(2); 1086 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */ 1087 pSMB->MaxSetupCount = 0; 1088 pSMB->Reserved = 0; 1089 pSMB->Flags = 0; 1090 pSMB->Timeout = 0; 1091 pSMB->Reserved2 = 0; 1092 param_offset = offsetof(struct smb_com_transaction2_spi_req, 1093 InformationLevel); 1094 offset = param_offset + params; 1095 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset); 1096 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 1097 pdata->Permissions = cpu_to_le64(mode); 1098 pdata->PosixOpenFlags = cpu_to_le32(posix_flags); 1099 pdata->OpenFlags = cpu_to_le32(*pOplock); 1100 pSMB->ParameterOffset = cpu_to_le16(param_offset); 1101 pSMB->DataOffset = cpu_to_le16(offset); 1102 pSMB->SetupCount = 1; 1103 pSMB->Reserved3 = 0; 1104 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 1105 byte_count = 3 /* pad */ + params + count; 1106 1107 pSMB->DataCount = cpu_to_le16(count); 1108 pSMB->ParameterCount = cpu_to_le16(params); 1109 pSMB->TotalDataCount = pSMB->DataCount; 1110 pSMB->TotalParameterCount = pSMB->ParameterCount; 1111 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN); 1112 pSMB->Reserved4 = 0; 1113 in_len += byte_count; 1114 pSMB->ByteCount = cpu_to_le16(byte_count); 1115 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 1116 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1117 if (rc) { 1118 cifs_dbg(FYI, "Posix create returned %d\n", rc); 1119 goto psx_create_err; 1120 } 1121 1122 cifs_dbg(FYI, "copying inode info\n"); 1123 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 1124 1125 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) { 1126 rc = smb_EIO2(smb_eio_trace_create_rsp_too_small, 1127 get_bcc(&pSMBr->hdr), sizeof(OPEN_PSX_RSP)); 1128 goto psx_create_err; 1129 } 1130 1131 /* copy return information to pRetData */ 1132 psx_rsp = (OPEN_PSX_RSP *) 1133 ((char *)pSMBr + le16_to_cpu(pSMBr->t2.DataOffset)); 1134 1135 *pOplock = le16_to_cpu(psx_rsp->OplockFlags); 1136 if (netfid) 1137 *netfid = psx_rsp->Fid; /* cifs fid stays in le */ 1138 /* Let caller know file was created so we can set the mode. */ 1139 /* Do we care about the CreateAction in any other cases? */ 1140 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction) 1141 *pOplock |= CIFS_CREATE_ACTION; 1142 /* check to make sure response data is there */ 1143 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) { 1144 pRetData->Type = cpu_to_le32(-1); /* unknown */ 1145 cifs_dbg(NOISY, "unknown type\n"); 1146 } else { 1147 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP) 1148 + sizeof(FILE_UNIX_BASIC_INFO)) { 1149 cifs_dbg(VFS, "Open response data too small\n"); 1150 pRetData->Type = cpu_to_le32(-1); 1151 goto psx_create_err; 1152 } 1153 memcpy(pRetData, 1154 (char *)psx_rsp + sizeof(OPEN_PSX_RSP), 1155 sizeof(*pRetData)); 1156 } 1157 1158 psx_create_err: 1159 cifs_buf_release(pSMB); 1160 1161 if (posix_flags & SMB_O_DIRECTORY) 1162 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs); 1163 else 1164 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens); 1165 1166 if (rc == -EAGAIN) 1167 goto PsxCreat; 1168 1169 return rc; 1170 } 1171 1172 static __u16 convert_disposition(int disposition) 1173 { 1174 __u16 ofun = 0; 1175 1176 switch (disposition) { 1177 case FILE_SUPERSEDE: 1178 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC; 1179 break; 1180 case FILE_OPEN: 1181 ofun = SMBOPEN_OAPPEND; 1182 break; 1183 case FILE_CREATE: 1184 ofun = SMBOPEN_OCREATE; 1185 break; 1186 case FILE_OPEN_IF: 1187 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND; 1188 break; 1189 case FILE_OVERWRITE: 1190 ofun = SMBOPEN_OTRUNC; 1191 break; 1192 case FILE_OVERWRITE_IF: 1193 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC; 1194 break; 1195 default: 1196 cifs_dbg(FYI, "unknown disposition %d\n", disposition); 1197 ofun = SMBOPEN_OAPPEND; /* regular open */ 1198 } 1199 return ofun; 1200 } 1201 1202 static int 1203 access_flags_to_smbopen_mode(const int access_flags) 1204 { 1205 /* 1206 * SYSTEM_SECURITY grants both read and write access to SACL, treat is as read/write. 1207 * MAXIMUM_ALLOWED grants as many access as possible, so treat it as read/write too. 1208 * SYNCHRONIZE as is does not grant any specific access, so do not check its mask. 1209 * If only SYNCHRONIZE bit is specified then fallback to read access. 1210 */ 1211 bool with_write_flags = access_flags & (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_EA | 1212 FILE_DELETE_CHILD | FILE_WRITE_ATTRIBUTES | DELETE | 1213 WRITE_DAC | WRITE_OWNER | SYSTEM_SECURITY | 1214 MAXIMUM_ALLOWED | GENERIC_WRITE | GENERIC_ALL); 1215 bool with_read_flags = access_flags & (FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE | 1216 FILE_READ_ATTRIBUTES | READ_CONTROL | 1217 SYSTEM_SECURITY | MAXIMUM_ALLOWED | GENERIC_ALL | 1218 GENERIC_EXECUTE | GENERIC_READ); 1219 bool with_execute_flags = access_flags & (FILE_EXECUTE | MAXIMUM_ALLOWED | GENERIC_ALL | 1220 GENERIC_EXECUTE); 1221 1222 if (with_write_flags && with_read_flags) 1223 return SMBOPEN_READWRITE; 1224 else if (with_write_flags) 1225 return SMBOPEN_WRITE; 1226 else if (with_execute_flags) 1227 return SMBOPEN_EXECUTE; 1228 else 1229 return SMBOPEN_READ; 1230 } 1231 1232 int SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon, 1233 const char *fileName, const int openDisposition, 1234 const int access_flags, const int create_options, 1235 __u16 *netfid, int *pOplock, FILE_ALL_INFO *pfile_info, 1236 int remap) 1237 { 1238 int rc; 1239 OPENX_REQ *pSMB = NULL; 1240 OPENX_RSP *pSMBr = NULL; 1241 unsigned int in_len; 1242 int bytes_returned; 1243 int name_len; 1244 __u16 count; 1245 1246 OldOpenRetry: 1247 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB, 1248 (void **) &pSMBr); 1249 if (rc < 0) 1250 return rc; 1251 in_len = rc; 1252 1253 pSMB->AndXCommand = 0xFF; /* none */ 1254 1255 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1256 count = 1; /* account for one byte pad to word boundary */ 1257 name_len = 1258 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1), 1259 fileName, PATH_MAX, 1260 tcon->ses->local_nls, remap); 1261 name_len++; /* trailing null */ 1262 name_len *= 2; 1263 } else { 1264 count = 0; /* no pad */ 1265 name_len = copy_path_name(pSMB->fileName, fileName); 1266 } 1267 if (*pOplock & REQ_OPLOCK) 1268 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK); 1269 else if (*pOplock & REQ_BATCHOPLOCK) 1270 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK); 1271 1272 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO); 1273 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags)); 1274 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */ 1275 /* set file as system file if special file such as fifo, 1276 * socket, char or block and server expecting SFU style and 1277 no Unix extensions */ 1278 1279 if (create_options & CREATE_OPTION_SPECIAL) 1280 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM); 1281 else /* BB FIXME BB */ 1282 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); 1283 1284 if (create_options & CREATE_OPTION_READONLY) 1285 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY); 1286 1287 /* BB FIXME BB */ 1288 /* pSMB->CreateOptions = cpu_to_le32(create_options & 1289 CREATE_OPTIONS_MASK); */ 1290 /* BB FIXME END BB */ 1291 1292 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY); 1293 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition)); 1294 count += name_len; 1295 in_len += count; 1296 1297 pSMB->ByteCount = cpu_to_le16(count); 1298 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 1299 (struct smb_hdr *)pSMBr, &bytes_returned, 0); 1300 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens); 1301 if (rc) { 1302 cifs_dbg(FYI, "Error in Open = %d\n", rc); 1303 } else { 1304 /* BB verify if wct == 15 */ 1305 *netfid = pSMBr->Fid; /* cifs fid stays in le */ 1306 /* Let caller know file was created so we can set the mode. */ 1307 /* Do we care about the CreateAction in any other cases? */ 1308 /* BB FIXME BB */ 1309 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction) 1310 *pOplock |= CIFS_CREATE_ACTION; */ 1311 /* BB FIXME END */ 1312 1313 if (pfile_info) { 1314 pfile_info->CreationTime = 0; /* BB convert CreateTime*/ 1315 pfile_info->LastAccessTime = 0; /* BB fixme */ 1316 pfile_info->LastWriteTime = 0; /* BB fixme */ 1317 pfile_info->ChangeTime = 0; /* BB fixme */ 1318 pfile_info->Attributes = 1319 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes)); 1320 /* the file_info buf is endian converted by caller */ 1321 pfile_info->AllocationSize = 1322 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile)); 1323 pfile_info->EndOfFile = pfile_info->AllocationSize; 1324 pfile_info->NumberOfLinks = cpu_to_le32(1); 1325 pfile_info->DeletePending = 0; /* successful open = not delete pending */ 1326 } 1327 } 1328 1329 cifs_buf_release(pSMB); 1330 if (rc == -EAGAIN) 1331 goto OldOpenRetry; 1332 return rc; 1333 } 1334 1335 int 1336 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock, 1337 FILE_ALL_INFO *buf) 1338 { 1339 int rc; 1340 OPEN_REQ *req = NULL; 1341 OPEN_RSP *rsp = NULL; 1342 int bytes_returned; 1343 int name_len; 1344 __u16 count; 1345 struct cifs_sb_info *cifs_sb = oparms->cifs_sb; 1346 struct cifs_tcon *tcon = oparms->tcon; 1347 int remap = cifs_remap(cifs_sb); 1348 const struct nls_table *nls = cifs_sb->local_nls; 1349 int create_options = oparms->create_options; 1350 int desired_access = oparms->desired_access; 1351 int disposition = oparms->disposition; 1352 const char *path = oparms->path; 1353 unsigned int in_len; 1354 1355 openRetry: 1356 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req, 1357 (void **)&rsp); 1358 if (rc < 0) 1359 return rc; 1360 in_len = rc; 1361 1362 /* no commands go after this */ 1363 req->AndXCommand = 0xFF; 1364 1365 if (req->hdr.Flags2 & SMBFLG2_UNICODE) { 1366 /* account for one byte pad to word boundary */ 1367 count = 1; 1368 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1), 1369 path, PATH_MAX, nls, remap); 1370 /* trailing null */ 1371 name_len++; 1372 name_len *= 2; 1373 req->NameLength = cpu_to_le16(name_len); 1374 } else { 1375 /* BB improve check for buffer overruns BB */ 1376 /* no pad */ 1377 count = 0; 1378 name_len = copy_path_name(req->fileName, path); 1379 req->NameLength = cpu_to_le16(name_len); 1380 } 1381 1382 if (*oplock & REQ_OPLOCK) 1383 req->OpenFlags = cpu_to_le32(REQ_OPLOCK); 1384 else if (*oplock & REQ_BATCHOPLOCK) 1385 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK); 1386 1387 req->DesiredAccess = cpu_to_le32(desired_access); 1388 req->AllocationSize = 0; 1389 1390 /* 1391 * Set file as system file if special file such as fifo, socket, char 1392 * or block and server expecting SFU style and no Unix extensions. 1393 */ 1394 if (create_options & CREATE_OPTION_SPECIAL) 1395 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM); 1396 else 1397 req->FileAttributes = cpu_to_le32(ATTR_NORMAL); 1398 1399 /* 1400 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case 1401 * sensitive checks for other servers such as Samba. 1402 */ 1403 if (tcon->ses->capabilities & CAP_UNIX) 1404 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS); 1405 1406 if (create_options & CREATE_OPTION_READONLY) 1407 req->FileAttributes |= cpu_to_le32(ATTR_READONLY); 1408 1409 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL); 1410 req->CreateDisposition = cpu_to_le32(disposition); 1411 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); 1412 1413 /* BB Experiment with various impersonation levels and verify */ 1414 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); 1415 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY; 1416 1417 count += name_len; 1418 in_len += count; 1419 1420 req->ByteCount = cpu_to_le16(count); 1421 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req, in_len, 1422 (struct smb_hdr *)rsp, &bytes_returned, 0); 1423 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens); 1424 if (rc) { 1425 cifs_dbg(FYI, "Error in Open = %d\n", rc); 1426 cifs_buf_release(req); 1427 if (rc == -EAGAIN) 1428 goto openRetry; 1429 return rc; 1430 } 1431 1432 /* 1 byte no need to le_to_cpu */ 1433 *oplock = rsp->OplockLevel; 1434 /* cifs fid stays in le */ 1435 oparms->fid->netfid = rsp->Fid; 1436 oparms->fid->access = desired_access; 1437 1438 /* Let caller know file was created so we can set the mode. */ 1439 /* Do we care about the CreateAction in any other cases? */ 1440 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction) 1441 *oplock |= CIFS_CREATE_ACTION; 1442 1443 if (buf) { 1444 /* copy commonly used attributes */ 1445 memcpy(&buf->common_attributes, 1446 &rsp->common_attributes, 1447 sizeof(buf->common_attributes)); 1448 /* the file_info buf is endian converted by caller */ 1449 buf->AllocationSize = rsp->AllocationSize; 1450 buf->EndOfFile = rsp->EndOfFile; 1451 buf->NumberOfLinks = cpu_to_le32(1); 1452 buf->DeletePending = 0; /* successful open = not delete pending */ 1453 } 1454 1455 cifs_buf_release(req); 1456 return rc; 1457 } 1458 1459 static void 1460 cifs_readv_callback(struct TCP_Server_Info *server, struct mid_q_entry *mid) 1461 { 1462 struct cifs_io_subrequest *rdata = mid->callback_data; 1463 struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode); 1464 struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink); 1465 struct inode *inode = &ictx->inode; 1466 struct smb_rqst rqst = { .rq_iov = rdata->iov, 1467 .rq_nvec = 1, 1468 .rq_iter = rdata->subreq.io_iter }; 1469 struct cifs_credits credits = { 1470 .value = 1, 1471 .instance = 0, 1472 .rreq_debug_id = rdata->rreq->debug_id, 1473 .rreq_debug_index = rdata->subreq.debug_index, 1474 }; 1475 unsigned int rreq_debug_id = rdata->rreq->debug_id; 1476 unsigned int subreq_debug_index = rdata->subreq.debug_index; 1477 1478 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n", 1479 __func__, mid->mid, mid->mid_state, rdata->result, 1480 rdata->subreq.len); 1481 1482 switch (mid->mid_state) { 1483 case MID_RESPONSE_RECEIVED: 1484 /* result already set, check signature */ 1485 if (server->sign) { 1486 int rc = 0; 1487 1488 iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes); 1489 rc = cifs_verify_signature(&rqst, server, 1490 mid->sequence_number); 1491 if (rc) 1492 cifs_dbg(VFS, "SMB signature verification returned error = %d\n", 1493 rc); 1494 } 1495 /* FIXME: should this be counted toward the initiating task? */ 1496 task_io_account_read(rdata->got_bytes); 1497 cifs_stats_bytes_read(tcon, rdata->got_bytes); 1498 break; 1499 case MID_REQUEST_SUBMITTED: 1500 trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_req_submitted); 1501 goto do_retry; 1502 case MID_RETRY_NEEDED: 1503 trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_retry_needed); 1504 do_retry: 1505 __set_bit(NETFS_SREQ_NEED_RETRY, &rdata->subreq.flags); 1506 rdata->result = -EAGAIN; 1507 if (server->sign && rdata->got_bytes) 1508 /* reset bytes number since we can not check a sign */ 1509 rdata->got_bytes = 0; 1510 /* FIXME: should this be counted toward the initiating task? */ 1511 task_io_account_read(rdata->got_bytes); 1512 cifs_stats_bytes_read(tcon, rdata->got_bytes); 1513 break; 1514 case MID_RESPONSE_MALFORMED: 1515 trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_malformed); 1516 rdata->result = smb_EIO(smb_eio_trace_read_rsp_malformed); 1517 break; 1518 default: 1519 trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_unknown); 1520 rdata->result = smb_EIO1(smb_eio_trace_read_mid_state_unknown, 1521 mid->mid_state); 1522 break; 1523 } 1524 1525 if (rdata->result == -ENODATA) { 1526 rdata->result = 0; 1527 __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); 1528 trace_smb3_read_err(rdata->rreq->debug_id, 1529 rdata->subreq.debug_index, 1530 rdata->xid, 1531 rdata->req->cfile->fid.persistent_fid, 1532 tcon->tid, tcon->ses->Suid, 1533 rdata->subreq.start + rdata->subreq.transferred, 1534 rdata->subreq.len - rdata->subreq.transferred, 1535 rdata->result); 1536 } else { 1537 size_t trans = rdata->subreq.transferred + rdata->got_bytes; 1538 if (trans < rdata->subreq.len && 1539 rdata->subreq.start + trans >= netfs_read_remote_i_size(inode)) { 1540 rdata->result = 0; 1541 __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); 1542 } else if (rdata->got_bytes > 0) { 1543 __set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags); 1544 } 1545 if (rdata->got_bytes) 1546 __set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags); 1547 trace_smb3_read_done(rdata->rreq->debug_id, 1548 rdata->subreq.debug_index, 1549 rdata->xid, 1550 rdata->req->cfile->fid.persistent_fid, 1551 tcon->tid, tcon->ses->Suid, 1552 rdata->subreq.start + rdata->subreq.transferred, 1553 rdata->got_bytes); 1554 } 1555 1556 trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, rdata->credits.value, 1557 server->credits, server->in_flight, 1558 0, cifs_trace_rw_credits_read_response_clear); 1559 rdata->credits.value = 0; 1560 rdata->subreq.error = rdata->result; 1561 rdata->subreq.transferred += rdata->got_bytes; 1562 trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_progress); 1563 netfs_read_subreq_terminated(&rdata->subreq); 1564 release_mid(server, mid); 1565 add_credits(server, &credits, 0); 1566 trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0, 1567 server->credits, server->in_flight, 1568 credits.value, cifs_trace_rw_credits_read_response_add); 1569 } 1570 1571 /* cifs_async_readv - send an async write, and set up mid to handle result */ 1572 int 1573 cifs_async_readv(struct cifs_io_subrequest *rdata) 1574 { 1575 int rc; 1576 READ_REQ *smb = NULL; 1577 int wct; 1578 struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink); 1579 struct smb_rqst rqst = { .rq_iov = rdata->iov, 1580 .rq_nvec = 1 }; 1581 unsigned int in_len; 1582 1583 cifs_dbg(FYI, "%s: offset=%llu bytes=%zu\n", 1584 __func__, rdata->subreq.start, rdata->subreq.len); 1585 1586 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1587 wct = 12; 1588 else { 1589 wct = 10; /* old style read */ 1590 if ((rdata->subreq.start >> 32) > 0) { 1591 /* can not handle this big offset for old */ 1592 return smb_EIO(smb_eio_trace_read_too_far); 1593 } 1594 } 1595 1596 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb); 1597 if (rc < 0) 1598 return rc; 1599 in_len = rc; 1600 1601 smb->hdr.Pid = cpu_to_le16((__u16)rdata->req->pid); 1602 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->req->pid >> 16)); 1603 1604 smb->AndXCommand = 0xFF; /* none */ 1605 smb->Fid = rdata->req->cfile->fid.netfid; 1606 smb->OffsetLow = cpu_to_le32(rdata->subreq.start & 0xFFFFFFFF); 1607 if (wct == 12) 1608 smb->OffsetHigh = cpu_to_le32(rdata->subreq.start >> 32); 1609 smb->Remaining = 0; 1610 smb->MaxCount = cpu_to_le16(rdata->subreq.len & 0xFFFF); 1611 smb->MaxCountHigh = cpu_to_le32(rdata->subreq.len >> 16); 1612 if (wct == 12) 1613 smb->ByteCount = 0; 1614 else { 1615 /* old style read */ 1616 struct smb_com_readx_req *smbr = 1617 (struct smb_com_readx_req *)smb; 1618 smbr->ByteCount = 0; 1619 } 1620 1621 /* 4 for RFC1001 length + 1 for BCC */ 1622 rdata->iov[0].iov_base = smb; 1623 rdata->iov[0].iov_len = in_len; 1624 1625 trace_smb3_read_enter(rdata->rreq->debug_id, 1626 rdata->subreq.debug_index, 1627 rdata->xid, 1628 rdata->req->cfile->fid.netfid, 1629 tcon->tid, tcon->ses->Suid, 1630 rdata->subreq.start, rdata->subreq.len); 1631 1632 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive, 1633 cifs_readv_callback, NULL, rdata, 0, NULL); 1634 1635 if (rc == 0) 1636 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads); 1637 cifs_small_buf_release(smb); 1638 return rc; 1639 } 1640 1641 int 1642 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms, 1643 unsigned int *nbytes, char **buf, int *pbuf_type) 1644 { 1645 int rc = -EACCES; 1646 READ_REQ *pSMB = NULL; 1647 READ_RSP *pSMBr = NULL; 1648 char *pReadData = NULL; 1649 int wct; 1650 int resp_buf_type = 0; 1651 struct kvec iov[1]; 1652 struct kvec rsp_iov; 1653 __u32 pid = io_parms->pid; 1654 __u16 netfid = io_parms->netfid; 1655 __u64 offset = io_parms->offset; 1656 struct cifs_tcon *tcon = io_parms->tcon; 1657 unsigned int in_len; 1658 unsigned int count = io_parms->length; 1659 1660 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid); 1661 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1662 wct = 12; 1663 else { 1664 wct = 10; /* old style read */ 1665 if ((offset >> 32) > 0) { 1666 /* can not handle this big offset for old */ 1667 return smb_EIO(smb_eio_trace_read_too_far); 1668 } 1669 } 1670 1671 *nbytes = 0; 1672 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB); 1673 if (rc < 0) 1674 return rc; 1675 in_len = rc; 1676 1677 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 1678 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 1679 1680 /* tcon and ses pointer are checked in smb_init */ 1681 if (!tcon->ses->server) { 1682 cifs_small_buf_release(pSMB); 1683 return -ECONNABORTED; 1684 } 1685 1686 pSMB->AndXCommand = 0xFF; /* none */ 1687 pSMB->Fid = netfid; 1688 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1689 if (wct == 12) 1690 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1691 1692 pSMB->Remaining = 0; 1693 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); 1694 pSMB->MaxCountHigh = cpu_to_le32(count >> 16); 1695 if (wct == 12) 1696 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */ 1697 else { 1698 /* old style read */ 1699 struct smb_com_readx_req *pSMBW = 1700 (struct smb_com_readx_req *)pSMB; 1701 pSMBW->ByteCount = 0; 1702 } 1703 1704 iov[0].iov_base = (char *)pSMB; 1705 iov[0].iov_len = in_len; 1706 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type, 1707 CIFS_LOG_ERROR, &rsp_iov); 1708 cifs_small_buf_release(pSMB); 1709 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads); 1710 pSMBr = (READ_RSP *)rsp_iov.iov_base; 1711 if (rc) { 1712 cifs_dbg(VFS, "Send error in read = %d\n", rc); 1713 } else if (rsp_iov.iov_len < tcon->ses->server->vals->read_rsp_size) { 1714 /* check that the received response can hold a whole READ_RSP */ 1715 cifs_dbg(FYI, "%s: server returned short header. got=%zu expected=%zu\n", 1716 __func__, rsp_iov.iov_len, 1717 tcon->ses->server->vals->read_rsp_size); 1718 rc = smb_EIO2(smb_eio_trace_read_rsp_short, 1719 rsp_iov.iov_len, tcon->ses->server->vals->read_rsp_size); 1720 *nbytes = 0; 1721 } else { 1722 unsigned int data_length = le16_to_cpu(pSMBr->DataLengthHigh); 1723 __u16 data_offset = le16_to_cpu(pSMBr->DataOffset); 1724 data_length = data_length << 16; 1725 data_length += le16_to_cpu(pSMBr->DataLength); 1726 *nbytes = data_length; 1727 1728 /*check that DataLength would not go beyond end of SMB */ 1729 if ((data_length > CIFSMaxBufSize) 1730 || (data_length > count)) { 1731 cifs_dbg(FYI, "%s: bad length %u for count %u\n", 1732 __func__, data_length, count); 1733 rc = smb_EIO2(smb_eio_trace_read_overlarge, 1734 data_length, count); 1735 *nbytes = 0; 1736 } else if (data_offset < sizeof(*pSMBr) || 1737 (size_t)data_offset + data_length > rsp_iov.iov_len) { 1738 /* check that the data lies within the received response */ 1739 cifs_dbg(FYI, "%s: bad data offset %u length %u for response of %zu\n", 1740 __func__, data_offset, data_length, rsp_iov.iov_len); 1741 rc = smb_EIO2(smb_eio_trace_read_bad_offset, 1742 data_offset, data_length); 1743 *nbytes = 0; 1744 } else { 1745 pReadData = (char *) (&pSMBr->hdr.Protocol) + data_offset; 1746 /* if (rc = copy_to_user(buf, pReadData, data_length)) { 1747 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc); 1748 rc = -EFAULT; 1749 }*/ /* can not use copy_to_user when using page cache*/ 1750 if (*buf) 1751 memcpy(*buf, pReadData, data_length); 1752 } 1753 } 1754 1755 if (*buf) { 1756 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 1757 } else if (resp_buf_type != CIFS_NO_BUFFER) { 1758 /* return buffer to caller to free */ 1759 *buf = rsp_iov.iov_base; 1760 if (resp_buf_type == CIFS_SMALL_BUFFER) 1761 *pbuf_type = CIFS_SMALL_BUFFER; 1762 else if (resp_buf_type == CIFS_LARGE_BUFFER) 1763 *pbuf_type = CIFS_LARGE_BUFFER; 1764 } /* else no valid buffer on return - leave as null */ 1765 1766 /* Note: On -EAGAIN error only caller can retry on handle based calls 1767 since file handle passed in no longer valid */ 1768 return rc; 1769 } 1770 1771 1772 int 1773 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms, 1774 unsigned int *nbytes, const char *buf) 1775 { 1776 int rc = -EACCES; 1777 WRITE_REQ *pSMB = NULL; 1778 WRITE_RSP *pSMBr = NULL; 1779 int bytes_returned, wct; 1780 __u32 bytes_sent; 1781 __u16 byte_count; 1782 __u32 pid = io_parms->pid; 1783 __u16 netfid = io_parms->netfid; 1784 __u64 offset = io_parms->offset; 1785 struct cifs_tcon *tcon = io_parms->tcon; 1786 unsigned int count = io_parms->length, in_len; 1787 1788 *nbytes = 0; 1789 1790 if (tcon->ses == NULL) 1791 return -ECONNABORTED; 1792 1793 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1794 wct = 14; 1795 else { 1796 wct = 12; 1797 if ((offset >> 32) > 0) { 1798 /* can not handle big offset for old srv */ 1799 return smb_EIO(smb_eio_trace_write_too_far); 1800 } 1801 } 1802 1803 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB, 1804 (void **) &pSMBr); 1805 if (rc < 0) 1806 return rc; 1807 in_len = rc; 1808 1809 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 1810 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 1811 1812 /* tcon and ses pointer are checked in smb_init */ 1813 if (!tcon->ses->server) { 1814 cifs_buf_release(pSMB); 1815 return -ECONNABORTED; 1816 } 1817 1818 pSMB->AndXCommand = 0xFF; /* none */ 1819 pSMB->Fid = netfid; 1820 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1821 if (wct == 14) 1822 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1823 1824 pSMB->Reserved = 0xFFFFFFFF; 1825 pSMB->WriteMode = 0; 1826 pSMB->Remaining = 0; 1827 1828 /* Can increase buffer size if buffer is big enough in some cases ie we 1829 can send more if LARGE_WRITE_X capability returned by the server and if 1830 our buffer is big enough or if we convert to iovecs on socket writes 1831 and eliminate the copy to the CIFS buffer */ 1832 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) { 1833 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count); 1834 } else { 1835 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) 1836 & ~0xFF; 1837 } 1838 1839 if (bytes_sent > count) 1840 bytes_sent = count; 1841 pSMB->DataOffset = 1842 cpu_to_le16(offsetof(struct smb_com_write_req, Data)); 1843 if (buf) 1844 memcpy(pSMB->Data, buf, bytes_sent); 1845 else if (count != 0) { 1846 /* No buffer */ 1847 cifs_buf_release(pSMB); 1848 return -EINVAL; 1849 } /* else setting file size with write of zero bytes */ 1850 if (wct == 14) 1851 byte_count = bytes_sent + 1; /* pad */ 1852 else /* wct == 12 */ 1853 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */ 1854 1855 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); 1856 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); 1857 in_len += byte_count; 1858 1859 if (wct == 14) 1860 pSMB->ByteCount = cpu_to_le16(byte_count); 1861 else { /* old style write has byte count 4 bytes earlier 1862 so 4 bytes pad */ 1863 struct smb_com_writex_req *pSMBW = 1864 (struct smb_com_writex_req *)pSMB; 1865 pSMBW->ByteCount = cpu_to_le16(byte_count); 1866 } 1867 1868 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 1869 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1870 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 1871 if (rc) { 1872 cifs_dbg(FYI, "Send error in write = %d\n", rc); 1873 } else { 1874 *nbytes = le16_to_cpu(pSMBr->CountHigh); 1875 *nbytes = (*nbytes) << 16; 1876 *nbytes += le16_to_cpu(pSMBr->Count); 1877 1878 /* 1879 * Mask off high 16 bits when bytes written as returned by the 1880 * server is greater than bytes requested by the client. Some 1881 * OS/2 servers are known to set incorrect CountHigh values. 1882 */ 1883 if (*nbytes > count) 1884 *nbytes &= 0xFFFF; 1885 } 1886 1887 cifs_buf_release(pSMB); 1888 1889 /* Note: On -EAGAIN error only caller can retry on handle based calls 1890 since file handle passed in no longer valid */ 1891 1892 return rc; 1893 } 1894 1895 /* 1896 * Check the mid_state and signature on received buffer (if any), and queue the 1897 * workqueue completion task. 1898 */ 1899 static void 1900 cifs_writev_callback(struct TCP_Server_Info *server, struct mid_q_entry *mid) 1901 { 1902 struct cifs_io_subrequest *wdata = mid->callback_data; 1903 struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink); 1904 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf; 1905 struct cifs_credits credits = { 1906 .value = 1, 1907 .instance = 0, 1908 .rreq_debug_id = wdata->rreq->debug_id, 1909 .rreq_debug_index = wdata->subreq.debug_index, 1910 }; 1911 ssize_t result; 1912 size_t written; 1913 1914 switch (mid->mid_state) { 1915 case MID_RESPONSE_RECEIVED: 1916 result = cifs_check_receive(mid, tcon->ses->server, 0); 1917 if (result != 0) 1918 break; 1919 1920 written = le16_to_cpu(smb->CountHigh); 1921 written <<= 16; 1922 written += le16_to_cpu(smb->Count); 1923 /* 1924 * Mask off high 16 bits when bytes written as returned 1925 * by the server is greater than bytes requested by the 1926 * client. OS/2 servers are known to set incorrect 1927 * CountHigh values. 1928 */ 1929 if (written > wdata->subreq.len) 1930 written &= 0xFFFF; 1931 1932 if (written < wdata->subreq.len) { 1933 result = -ENOSPC; 1934 } else { 1935 result = written; 1936 if (written > 0) 1937 __set_bit(NETFS_SREQ_MADE_PROGRESS, &wdata->subreq.flags); 1938 } 1939 break; 1940 case MID_REQUEST_SUBMITTED: 1941 trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_req_submitted); 1942 __set_bit(NETFS_SREQ_NEED_RETRY, &wdata->subreq.flags); 1943 result = -EAGAIN; 1944 break; 1945 case MID_RETRY_NEEDED: 1946 trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_retry_needed); 1947 __set_bit(NETFS_SREQ_NEED_RETRY, &wdata->subreq.flags); 1948 result = -EAGAIN; 1949 break; 1950 case MID_RESPONSE_MALFORMED: 1951 trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_malformed); 1952 result = smb_EIO(smb_eio_trace_write_rsp_malformed); 1953 break; 1954 default: 1955 trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_unknown); 1956 result = smb_EIO1(smb_eio_trace_write_mid_state_unknown, 1957 mid->mid_state); 1958 break; 1959 } 1960 1961 trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 1962 wdata->credits.value, 1963 server->credits, server->in_flight, 1964 0, cifs_trace_rw_credits_write_response_clear); 1965 wdata->credits.value = 0; 1966 cifs_write_subrequest_terminated(wdata, result); 1967 release_mid(server, mid); 1968 trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0, 1969 server->credits, server->in_flight, 1970 credits.value, cifs_trace_rw_credits_write_response_add); 1971 add_credits(tcon->ses->server, &credits, 0); 1972 } 1973 1974 /* cifs_async_writev - send an async write, and set up mid to handle result */ 1975 void 1976 cifs_async_writev(struct cifs_io_subrequest *wdata) 1977 { 1978 int rc = -EACCES; 1979 WRITE_REQ *req = NULL; 1980 int wct; 1981 struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink); 1982 struct kvec iov[1]; 1983 struct smb_rqst rqst = { }; 1984 unsigned int in_len; 1985 1986 if (tcon->ses->capabilities & CAP_LARGE_FILES) { 1987 wct = 14; 1988 } else { 1989 wct = 12; 1990 if (wdata->subreq.start >> 32 > 0) { 1991 /* can not handle big offset for old srv */ 1992 rc = smb_EIO(smb_eio_trace_write_too_far); 1993 goto out; 1994 } 1995 } 1996 1997 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&req); 1998 if (rc < 0) 1999 goto async_writev_out; 2000 in_len = rc; 2001 2002 req->hdr.Pid = cpu_to_le16((__u16)wdata->req->pid); 2003 req->hdr.PidHigh = cpu_to_le16((__u16)(wdata->req->pid >> 16)); 2004 2005 req->AndXCommand = 0xFF; /* none */ 2006 req->Fid = wdata->req->cfile->fid.netfid; 2007 req->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF); 2008 if (wct == 14) 2009 req->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32); 2010 req->Reserved = 0xFFFFFFFF; 2011 req->WriteMode = 0; 2012 req->Remaining = 0; 2013 2014 req->DataOffset = 2015 cpu_to_le16(offsetof(struct smb_com_write_req, Data)); 2016 2017 iov[0].iov_base = req; 2018 iov[0].iov_len = in_len + 1; /* +1 for BCC */ 2019 2020 rqst.rq_iov = iov; 2021 rqst.rq_nvec = 1; 2022 rqst.rq_iter = wdata->subreq.io_iter; 2023 2024 cifs_dbg(FYI, "async write at %llu %zu bytes\n", 2025 wdata->subreq.start, wdata->subreq.len); 2026 2027 req->DataLengthLow = cpu_to_le16(wdata->subreq.len & 0xFFFF); 2028 req->DataLengthHigh = cpu_to_le16(wdata->subreq.len >> 16); 2029 2030 if (wct == 14) { 2031 in_len += wdata->subreq.len + 1; 2032 put_bcc(wdata->subreq.len + 1, &req->hdr); 2033 } else { 2034 /* wct == 12 */ 2035 struct smb_com_writex_req *reqw = 2036 (struct smb_com_writex_req *)req; 2037 in_len += wdata->subreq.len + 5; 2038 put_bcc(wdata->subreq.len + 5, &reqw->hdr); 2039 iov[0].iov_len += 4; /* pad bigger by four bytes */ 2040 } 2041 2042 rc = cifs_call_async(tcon->ses->server, &rqst, NULL, 2043 cifs_writev_callback, NULL, wdata, 0, NULL); 2044 /* Can't touch wdata if rc == 0 */ 2045 if (rc == 0) 2046 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 2047 2048 async_writev_out: 2049 cifs_small_buf_release(req); 2050 out: 2051 if (rc) { 2052 add_credits_and_wake_if(wdata->server, &wdata->credits, 0); 2053 cifs_write_subrequest_terminated(wdata, rc); 2054 } 2055 } 2056 2057 int 2058 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms, 2059 unsigned int *nbytes, struct kvec *iov, int n_vec) 2060 { 2061 int rc; 2062 WRITE_REQ *pSMB = NULL; 2063 int wct; 2064 int smb_hdr_len; 2065 int resp_buf_type = 0; 2066 __u32 pid = io_parms->pid; 2067 __u16 netfid = io_parms->netfid; 2068 __u64 offset = io_parms->offset; 2069 struct cifs_tcon *tcon = io_parms->tcon; 2070 unsigned int count = io_parms->length; 2071 struct kvec rsp_iov; 2072 unsigned int in_len; 2073 2074 *nbytes = 0; 2075 2076 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count); 2077 2078 if (tcon->ses->capabilities & CAP_LARGE_FILES) { 2079 wct = 14; 2080 } else { 2081 wct = 12; 2082 if ((offset >> 32) > 0) { 2083 /* can not handle big offset for old srv */ 2084 return smb_EIO(smb_eio_trace_write_too_far); 2085 } 2086 } 2087 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB); 2088 if (rc < 0) 2089 return rc; 2090 in_len = rc; 2091 2092 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 2093 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 2094 2095 /* tcon and ses pointer are checked in smb_init */ 2096 if (!tcon->ses->server) { 2097 cifs_small_buf_release(pSMB); 2098 return -ECONNABORTED; 2099 } 2100 2101 pSMB->AndXCommand = 0xFF; /* none */ 2102 pSMB->Fid = netfid; 2103 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 2104 if (wct == 14) 2105 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 2106 pSMB->Reserved = 0xFFFFFFFF; 2107 pSMB->WriteMode = 0; 2108 pSMB->Remaining = 0; 2109 2110 pSMB->DataOffset = 2111 cpu_to_le16(offsetof(struct smb_com_write_req, Data)); 2112 2113 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF); 2114 pSMB->DataLengthHigh = cpu_to_le16(count >> 16); 2115 /* header + 1 byte pad */ 2116 smb_hdr_len = in_len + 1; 2117 if (wct == 14) 2118 in_len += count + 1; 2119 else /* wct == 12 */ 2120 in_len += count + 5; /* smb data starts later */ 2121 if (wct == 14) 2122 pSMB->ByteCount = cpu_to_le16(count + 1); 2123 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ { 2124 struct smb_com_writex_req *pSMBW = 2125 (struct smb_com_writex_req *)pSMB; 2126 pSMBW->ByteCount = cpu_to_le16(count + 5); 2127 } 2128 iov[0].iov_base = pSMB; 2129 if (wct == 14) 2130 iov[0].iov_len = smb_hdr_len + 4; 2131 else /* wct == 12 pad bigger by four bytes */ 2132 iov[0].iov_len = smb_hdr_len + 8; 2133 2134 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0, 2135 &rsp_iov); 2136 cifs_small_buf_release(pSMB); 2137 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 2138 if (rc) { 2139 cifs_dbg(FYI, "Send error Write2 = %d\n", rc); 2140 } else if (resp_buf_type == 0) { 2141 /* presumably this can not happen, but best to be safe */ 2142 rc = smb_EIO1(smb_eio_trace_write_bad_buf_type, resp_buf_type); 2143 } else { 2144 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base; 2145 *nbytes = le16_to_cpu(pSMBr->CountHigh); 2146 *nbytes = (*nbytes) << 16; 2147 *nbytes += le16_to_cpu(pSMBr->Count); 2148 2149 /* 2150 * Mask off high 16 bits when bytes written as returned by the 2151 * server is greater than bytes requested by the client. OS/2 2152 * servers are known to set incorrect CountHigh values. 2153 */ 2154 if (*nbytes > count) 2155 *nbytes &= 0xFFFF; 2156 } 2157 2158 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 2159 2160 /* Note: On -EAGAIN error only caller can retry on handle based calls 2161 since file handle passed in no longer valid */ 2162 2163 return rc; 2164 } 2165 2166 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon, 2167 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock, 2168 const __u32 num_lock, LOCKING_ANDX_RANGE *buf) 2169 { 2170 int rc = 0; 2171 LOCK_REQ *pSMB = NULL; 2172 struct kvec iov[2]; 2173 struct kvec rsp_iov; 2174 unsigned int in_len; 2175 int resp_buf_type; 2176 __u16 count; 2177 2178 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n", 2179 num_lock, num_unlock); 2180 2181 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 2182 if (rc < 0) 2183 return rc; 2184 in_len = rc; 2185 2186 pSMB->Timeout = 0; 2187 pSMB->NumberOfLocks = cpu_to_le16(num_lock); 2188 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock); 2189 pSMB->LockType = lock_type; 2190 pSMB->AndXCommand = 0xFF; /* none */ 2191 pSMB->Fid = netfid; /* netfid stays le */ 2192 2193 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 2194 in_len += count; 2195 pSMB->ByteCount = cpu_to_le16(count); 2196 2197 iov[0].iov_base = (char *)pSMB; 2198 iov[0].iov_len = in_len - 2199 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 2200 iov[1].iov_base = (char *)buf; 2201 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 2202 2203 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks); 2204 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, 2205 CIFS_NO_RSP_BUF, &rsp_iov); 2206 cifs_small_buf_release(pSMB); 2207 if (rc) 2208 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc); 2209 2210 return rc; 2211 } 2212 2213 int 2214 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon, 2215 const __u16 smb_file_id, const __u32 netpid, const __u64 len, 2216 const __u64 offset, const __u32 numUnlock, 2217 const __u32 numLock, const __u8 lockType, 2218 const bool waitFlag, const __u8 oplock_level) 2219 { 2220 int rc = 0; 2221 LOCK_REQ *pSMB = NULL; 2222 unsigned int in_len; 2223 int bytes_returned; 2224 int flags = CIFS_WINDOWS_LOCK | CIFS_INTERRUPTIBLE_WAIT; 2225 __u16 count; 2226 2227 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n", 2228 (int)waitFlag, numLock); 2229 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 2230 2231 if (rc < 0) 2232 return rc; 2233 in_len = rc; 2234 2235 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { 2236 /* no response expected */ 2237 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP; 2238 pSMB->Timeout = 0; 2239 } else if (waitFlag) { 2240 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ 2241 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */ 2242 } else { 2243 pSMB->Timeout = 0; 2244 } 2245 2246 pSMB->NumberOfLocks = cpu_to_le16(numLock); 2247 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock); 2248 pSMB->LockType = lockType; 2249 pSMB->OplockLevel = oplock_level; 2250 pSMB->AndXCommand = 0xFF; /* none */ 2251 pSMB->Fid = smb_file_id; /* netfid stays le */ 2252 2253 if ((numLock != 0) || (numUnlock != 0)) { 2254 pSMB->Locks[0].Pid = cpu_to_le16(netpid); 2255 /* BB where to store pid high? */ 2256 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len); 2257 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32)); 2258 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset); 2259 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32)); 2260 count = sizeof(LOCKING_ANDX_RANGE); 2261 } else { 2262 /* oplock break */ 2263 count = 0; 2264 } 2265 in_len += count; 2266 pSMB->ByteCount = cpu_to_le16(count); 2267 2268 if (waitFlag) 2269 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 2270 (struct smb_hdr *) pSMB, &bytes_returned, 2271 flags); 2272 else 2273 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, in_len, flags); 2274 cifs_small_buf_release(pSMB); 2275 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks); 2276 if (rc) 2277 cifs_dbg(FYI, "Send error in Lock = %d\n", rc); 2278 2279 /* Note: On -EAGAIN error only caller can retry on handle based calls 2280 since file handle passed in no longer valid */ 2281 return rc; 2282 } 2283 2284 int 2285 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon, 2286 const __u16 smb_file_id, const __u32 netpid, 2287 const loff_t start_offset, const __u64 len, 2288 struct file_lock *pLockData, const __u16 lock_type, 2289 const bool waitFlag) 2290 { 2291 struct smb_com_transaction2_sfi_req *pSMB = NULL; 2292 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 2293 struct cifs_posix_lock *parm_data; 2294 unsigned int in_len; 2295 int rc = 0; 2296 int sr_flags = CIFS_INTERRUPTIBLE_WAIT; 2297 int bytes_returned = 0; 2298 int resp_buf_type = 0; 2299 __u16 params, param_offset, offset, byte_count, count; 2300 struct kvec iov[1]; 2301 struct kvec rsp_iov; 2302 2303 cifs_dbg(FYI, "Posix Lock\n"); 2304 2305 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 2306 if (rc < 0) 2307 return rc; 2308 in_len = rc; 2309 2310 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB; 2311 2312 params = 6; 2313 pSMB->MaxSetupCount = 0; 2314 pSMB->Reserved = 0; 2315 pSMB->Flags = 0; 2316 pSMB->Reserved2 = 0; 2317 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid); 2318 offset = param_offset + params; 2319 2320 count = sizeof(struct cifs_posix_lock); 2321 pSMB->MaxParameterCount = cpu_to_le16(2); 2322 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ 2323 pSMB->SetupCount = 1; 2324 pSMB->Reserved3 = 0; 2325 if (pLockData) 2326 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 2327 else 2328 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 2329 byte_count = 3 /* pad */ + params + count; 2330 pSMB->DataCount = cpu_to_le16(count); 2331 pSMB->ParameterCount = cpu_to_le16(params); 2332 pSMB->TotalDataCount = pSMB->DataCount; 2333 pSMB->TotalParameterCount = pSMB->ParameterCount; 2334 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2335 parm_data = (struct cifs_posix_lock *)(((char *)pSMB) + offset); 2336 2337 parm_data->lock_type = cpu_to_le16(lock_type); 2338 if (waitFlag) { 2339 sr_flags |= CIFS_BLOCKING_OP; /* blocking operation, no timeout */ 2340 parm_data->lock_flags = cpu_to_le16(1); 2341 pSMB->Timeout = cpu_to_le32(-1); 2342 } else 2343 pSMB->Timeout = 0; 2344 2345 parm_data->pid = cpu_to_le32(netpid); 2346 parm_data->start = cpu_to_le64(start_offset); 2347 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */ 2348 2349 pSMB->DataOffset = cpu_to_le16(offset); 2350 pSMB->Fid = smb_file_id; 2351 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK); 2352 pSMB->Reserved4 = 0; 2353 in_len += byte_count; 2354 pSMB->ByteCount = cpu_to_le16(byte_count); 2355 if (waitFlag) { 2356 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 2357 (struct smb_hdr *) pSMBr, &bytes_returned, 2358 sr_flags); 2359 } else { 2360 iov[0].iov_base = (char *)pSMB; 2361 iov[0].iov_len = in_len; 2362 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, 2363 &resp_buf_type, sr_flags, &rsp_iov); 2364 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base; 2365 } 2366 cifs_small_buf_release(pSMB); 2367 2368 if (rc) { 2369 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc); 2370 } else if (pLockData) { 2371 /* lock structure can be returned on get */ 2372 unsigned int rsp_len; 2373 __u16 data_offset; 2374 __u16 data_count; 2375 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2376 2377 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) { 2378 rc = smb_EIO2(smb_eio_trace_lock_bcc_too_small, 2379 get_bcc(&pSMBr->hdr), sizeof(*parm_data)); 2380 goto plk_err_exit; 2381 } 2382 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 2383 data_count = le16_to_cpu(pSMBr->t2.DataCount); 2384 rsp_len = smbCalcSize(&pSMBr->hdr); 2385 if (data_count < sizeof(struct cifs_posix_lock)) { 2386 rc = smb_EIO2(smb_eio_trace_lock_data_too_small, 2387 data_count, sizeof(struct cifs_posix_lock)); 2388 goto plk_err_exit; 2389 } 2390 if (data_offset > rsp_len || 2391 data_count > rsp_len - data_offset) { 2392 rc = smb_EIO2(smb_eio_trace_lock_data_area, 2393 data_offset, data_count); 2394 goto plk_err_exit; 2395 } 2396 parm_data = (struct cifs_posix_lock *) 2397 ((char *)&pSMBr->hdr.Protocol + data_offset); 2398 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK)) 2399 pLockData->c.flc_type = F_UNLCK; 2400 else { 2401 if (parm_data->lock_type == 2402 cpu_to_le16(CIFS_RDLCK)) 2403 pLockData->c.flc_type = F_RDLCK; 2404 else if (parm_data->lock_type == 2405 cpu_to_le16(CIFS_WRLCK)) 2406 pLockData->c.flc_type = F_WRLCK; 2407 2408 pLockData->fl_start = le64_to_cpu(parm_data->start); 2409 pLockData->fl_end = pLockData->fl_start + 2410 (le64_to_cpu(parm_data->length) ? 2411 le64_to_cpu(parm_data->length) - 1 : 0); 2412 pLockData->c.flc_pid = -le32_to_cpu(parm_data->pid); 2413 } 2414 } 2415 2416 plk_err_exit: 2417 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 2418 2419 /* Note: On -EAGAIN error only caller can retry on handle based calls 2420 since file handle passed in no longer valid */ 2421 2422 return rc; 2423 } 2424 2425 2426 int 2427 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id) 2428 { 2429 int rc = 0; 2430 CLOSE_REQ *pSMB = NULL; 2431 unsigned int in_len; 2432 2433 cifs_dbg(FYI, "In CIFSSMBClose\n"); 2434 2435 /* do not retry on dead session on close */ 2436 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB); 2437 if (rc == -EAGAIN) 2438 return 0; 2439 if (rc < 0) 2440 return rc; 2441 in_len = rc; 2442 2443 pSMB->FileID = (__u16) smb_file_id; 2444 pSMB->LastWriteTime = 0xFFFFFFFF; 2445 pSMB->ByteCount = 0; 2446 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); 2447 cifs_small_buf_release(pSMB); 2448 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes); 2449 if (rc) { 2450 if (rc != -EINTR) { 2451 /* EINTR is expected when user ctl-c to kill app */ 2452 cifs_dbg(VFS, "Send error in Close = %d\n", rc); 2453 } 2454 } 2455 2456 /* Since session is dead, file will be closed on server already */ 2457 if (rc == -EAGAIN) 2458 rc = 0; 2459 2460 return rc; 2461 } 2462 2463 int 2464 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id) 2465 { 2466 int rc = 0; 2467 FLUSH_REQ *pSMB = NULL; 2468 unsigned int in_len; 2469 2470 cifs_dbg(FYI, "In CIFSSMBFlush\n"); 2471 2472 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB); 2473 if (rc < 0) 2474 return rc; 2475 in_len = rc; 2476 2477 pSMB->FileID = (__u16) smb_file_id; 2478 pSMB->ByteCount = 0; 2479 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); 2480 cifs_small_buf_release(pSMB); 2481 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes); 2482 if (rc) 2483 cifs_dbg(VFS, "Send error in Flush = %d\n", rc); 2484 2485 return rc; 2486 } 2487 2488 int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon, 2489 struct dentry *source_dentry, 2490 const char *from_name, const char *to_name, 2491 struct cifs_sb_info *cifs_sb) 2492 { 2493 int rc = 0; 2494 RENAME_REQ *pSMB = NULL; 2495 RENAME_RSP *pSMBr = NULL; 2496 unsigned int in_len; 2497 int bytes_returned; 2498 int name_len, name_len2; 2499 __u16 count; 2500 int remap = cifs_remap(cifs_sb); 2501 2502 cifs_dbg(FYI, "In CIFSSMBRename\n"); 2503 renameRetry: 2504 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB, 2505 (void **) &pSMBr); 2506 if (rc < 0) 2507 return rc; 2508 in_len = rc; 2509 2510 pSMB->BufferFormat = 0x04; 2511 pSMB->SearchAttributes = 2512 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 2513 ATTR_DIRECTORY); 2514 2515 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2516 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName, 2517 from_name, PATH_MAX, 2518 cifs_sb->local_nls, remap); 2519 name_len++; /* trailing null */ 2520 name_len *= 2; 2521 pSMB->OldFileName[name_len] = 0x04; /* pad */ 2522 /* protocol requires ASCII signature byte on Unicode string */ 2523 pSMB->OldFileName[name_len + 1] = 0x00; 2524 name_len2 = 2525 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], 2526 to_name, PATH_MAX, cifs_sb->local_nls, 2527 remap); 2528 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2529 name_len2 *= 2; /* convert to bytes */ 2530 } else { 2531 name_len = copy_path_name(pSMB->OldFileName, from_name); 2532 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name); 2533 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ 2534 name_len2++; /* signature byte */ 2535 } 2536 2537 count = 1 /* 1st signature byte */ + name_len + name_len2; 2538 in_len += count; 2539 pSMB->ByteCount = cpu_to_le16(count); 2540 2541 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 2542 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2543 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames); 2544 if (rc) 2545 cifs_dbg(FYI, "Send error in rename = %d\n", rc); 2546 2547 cifs_buf_release(pSMB); 2548 2549 if (rc == -EAGAIN) 2550 goto renameRetry; 2551 2552 return rc; 2553 } 2554 2555 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon, 2556 int netfid, const char *target_name, int remap) 2557 { 2558 struct smb_com_transaction2_sfi_req *pSMB = NULL; 2559 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 2560 struct set_file_rename *rename_info; 2561 unsigned int in_len; 2562 char *data_offset; 2563 char dummy_string[30]; 2564 int rc = 0; 2565 int bytes_returned = 0; 2566 int len_of_str; 2567 __u16 params, param_offset, offset, count, byte_count; 2568 2569 cifs_dbg(FYI, "Rename to File by handle\n"); 2570 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB, 2571 (void **) &pSMBr); 2572 if (rc < 0) 2573 return rc; 2574 in_len = rc; 2575 2576 params = 6; 2577 pSMB->MaxSetupCount = 0; 2578 pSMB->Reserved = 0; 2579 pSMB->Flags = 0; 2580 pSMB->Timeout = 0; 2581 pSMB->Reserved2 = 0; 2582 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid); 2583 offset = param_offset + params; 2584 2585 data_offset = (char *)(pSMB) + offset; 2586 rename_info = (struct set_file_rename *) data_offset; 2587 pSMB->MaxParameterCount = cpu_to_le16(2); 2588 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ 2589 pSMB->SetupCount = 1; 2590 pSMB->Reserved3 = 0; 2591 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 2592 byte_count = 3 /* pad */ + params; 2593 pSMB->ParameterCount = cpu_to_le16(params); 2594 pSMB->TotalParameterCount = pSMB->ParameterCount; 2595 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2596 pSMB->DataOffset = cpu_to_le16(offset); 2597 /* construct random name ".cifs_tmp<inodenum><mid>" */ 2598 rename_info->overwrite = cpu_to_le32(1); 2599 rename_info->root_fid = 0; 2600 /* unicode only call */ 2601 if (target_name == NULL) { 2602 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid); 2603 len_of_str = 2604 cifsConvertToUTF16((__le16 *)rename_info->target_name, 2605 dummy_string, 24, 2606 pTcon->ses->local_nls, remap); 2607 } else { 2608 len_of_str = 2609 cifsConvertToUTF16((__le16 *)rename_info->target_name, 2610 target_name, PATH_MAX, 2611 pTcon->ses->local_nls, remap); 2612 } 2613 rename_info->target_name_len = cpu_to_le32(2 * len_of_str); 2614 count = sizeof(struct set_file_rename) + (2 * len_of_str); 2615 byte_count += count; 2616 pSMB->DataCount = cpu_to_le16(count); 2617 pSMB->TotalDataCount = pSMB->DataCount; 2618 pSMB->Fid = netfid; 2619 pSMB->InformationLevel = 2620 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION); 2621 pSMB->Reserved4 = 0; 2622 in_len += byte_count; 2623 pSMB->ByteCount = cpu_to_le16(byte_count); 2624 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, in_len, 2625 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2626 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames); 2627 if (rc) 2628 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n", 2629 rc); 2630 2631 cifs_buf_release(pSMB); 2632 2633 /* Note: On -EAGAIN error only caller can retry on handle based calls 2634 since file handle passed in no longer valid */ 2635 2636 return rc; 2637 } 2638 2639 int 2640 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon, 2641 const char *fromName, const char *toName, 2642 const struct nls_table *nls_codepage, int remap) 2643 { 2644 TRANSACTION2_SPI_REQ *pSMB = NULL; 2645 TRANSACTION2_SPI_RSP *pSMBr = NULL; 2646 unsigned int in_len; 2647 char *data_offset; 2648 int name_len; 2649 int name_len_target; 2650 int rc = 0; 2651 int bytes_returned = 0; 2652 __u16 params, param_offset, offset, byte_count; 2653 2654 cifs_dbg(FYI, "In Symlink Unix style\n"); 2655 createSymLinkRetry: 2656 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2657 (void **) &pSMBr); 2658 if (rc < 0) 2659 return rc; 2660 in_len = rc; 2661 2662 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2663 name_len = 2664 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName, 2665 /* find define for this maxpathcomponent */ 2666 PATH_MAX, nls_codepage, remap); 2667 name_len++; /* trailing null */ 2668 name_len *= 2; 2669 2670 } else { 2671 name_len = copy_path_name(pSMB->FileName, fromName); 2672 } 2673 params = 6 + name_len; 2674 pSMB->MaxSetupCount = 0; 2675 pSMB->Reserved = 0; 2676 pSMB->Flags = 0; 2677 pSMB->Timeout = 0; 2678 pSMB->Reserved2 = 0; 2679 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2680 InformationLevel); 2681 offset = param_offset + params; 2682 2683 data_offset = (char *)pSMB + offset; 2684 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2685 name_len_target = 2686 cifsConvertToUTF16((__le16 *) data_offset, toName, 2687 /* find define for this maxpathcomponent */ 2688 PATH_MAX, nls_codepage, remap); 2689 name_len_target++; /* trailing null */ 2690 name_len_target *= 2; 2691 } else { 2692 name_len_target = copy_path_name(data_offset, toName); 2693 } 2694 2695 pSMB->MaxParameterCount = cpu_to_le16(2); 2696 /* BB find exact max on data count below from sess */ 2697 pSMB->MaxDataCount = cpu_to_le16(1000); 2698 pSMB->SetupCount = 1; 2699 pSMB->Reserved3 = 0; 2700 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 2701 byte_count = 3 /* pad */ + params + name_len_target; 2702 pSMB->DataCount = cpu_to_le16(name_len_target); 2703 pSMB->ParameterCount = cpu_to_le16(params); 2704 pSMB->TotalDataCount = pSMB->DataCount; 2705 pSMB->TotalParameterCount = pSMB->ParameterCount; 2706 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2707 pSMB->DataOffset = cpu_to_le16(offset); 2708 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK); 2709 pSMB->Reserved4 = 0; 2710 in_len += byte_count; 2711 pSMB->ByteCount = cpu_to_le16(byte_count); 2712 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 2713 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2714 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks); 2715 if (rc) 2716 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n", 2717 rc); 2718 2719 cifs_buf_release(pSMB); 2720 2721 if (rc == -EAGAIN) 2722 goto createSymLinkRetry; 2723 2724 return rc; 2725 } 2726 2727 int 2728 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, 2729 const char *fromName, const char *toName, 2730 const struct nls_table *nls_codepage, int remap) 2731 { 2732 TRANSACTION2_SPI_REQ *pSMB = NULL; 2733 TRANSACTION2_SPI_RSP *pSMBr = NULL; 2734 unsigned int in_len; 2735 char *data_offset; 2736 int name_len; 2737 int name_len_target; 2738 int rc = 0; 2739 int bytes_returned = 0; 2740 __u16 params, param_offset, offset, byte_count; 2741 2742 cifs_dbg(FYI, "In Create Hard link Unix style\n"); 2743 createHardLinkRetry: 2744 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2745 (void **) &pSMBr); 2746 if (rc < 0) 2747 return rc; 2748 in_len = rc; 2749 2750 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2751 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName, 2752 PATH_MAX, nls_codepage, remap); 2753 name_len++; /* trailing null */ 2754 name_len *= 2; 2755 2756 } else { 2757 name_len = copy_path_name(pSMB->FileName, toName); 2758 } 2759 params = 6 + name_len; 2760 pSMB->MaxSetupCount = 0; 2761 pSMB->Reserved = 0; 2762 pSMB->Flags = 0; 2763 pSMB->Timeout = 0; 2764 pSMB->Reserved2 = 0; 2765 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2766 InformationLevel); 2767 offset = param_offset + params; 2768 2769 data_offset = (char *)pSMB + offset; 2770 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2771 name_len_target = 2772 cifsConvertToUTF16((__le16 *) data_offset, fromName, 2773 PATH_MAX, nls_codepage, remap); 2774 name_len_target++; /* trailing null */ 2775 name_len_target *= 2; 2776 } else { 2777 name_len_target = copy_path_name(data_offset, fromName); 2778 } 2779 2780 pSMB->MaxParameterCount = cpu_to_le16(2); 2781 /* BB find exact max on data count below from sess*/ 2782 pSMB->MaxDataCount = cpu_to_le16(1000); 2783 pSMB->SetupCount = 1; 2784 pSMB->Reserved3 = 0; 2785 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 2786 byte_count = 3 /* pad */ + params + name_len_target; 2787 pSMB->ParameterCount = cpu_to_le16(params); 2788 pSMB->TotalParameterCount = pSMB->ParameterCount; 2789 pSMB->DataCount = cpu_to_le16(name_len_target); 2790 pSMB->TotalDataCount = pSMB->DataCount; 2791 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2792 pSMB->DataOffset = cpu_to_le16(offset); 2793 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK); 2794 pSMB->Reserved4 = 0; 2795 in_len += byte_count; 2796 pSMB->ByteCount = cpu_to_le16(byte_count); 2797 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 2798 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2799 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks); 2800 if (rc) 2801 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n", 2802 rc); 2803 2804 cifs_buf_release(pSMB); 2805 if (rc == -EAGAIN) 2806 goto createHardLinkRetry; 2807 2808 return rc; 2809 } 2810 2811 int CIFSCreateHardLink(const unsigned int xid, 2812 struct cifs_tcon *tcon, 2813 struct dentry *source_dentry, 2814 const char *from_name, const char *to_name, 2815 struct cifs_sb_info *cifs_sb) 2816 { 2817 int rc = 0; 2818 NT_RENAME_REQ *pSMB = NULL; 2819 RENAME_RSP *pSMBr = NULL; 2820 unsigned int in_len; 2821 int bytes_returned; 2822 int name_len, name_len2; 2823 __u16 count; 2824 int remap = cifs_remap(cifs_sb); 2825 2826 cifs_dbg(FYI, "In CIFSCreateHardLink\n"); 2827 winCreateHardLinkRetry: 2828 2829 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB, 2830 (void **) &pSMBr); 2831 if (rc < 0) 2832 return rc; 2833 in_len = rc; 2834 2835 pSMB->SearchAttributes = 2836 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 2837 ATTR_DIRECTORY); 2838 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK); 2839 pSMB->ClusterCount = 0; 2840 2841 pSMB->BufferFormat = 0x04; 2842 2843 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2844 name_len = 2845 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name, 2846 PATH_MAX, cifs_sb->local_nls, remap); 2847 name_len++; /* trailing null */ 2848 name_len *= 2; 2849 2850 /* protocol specifies ASCII buffer format (0x04) for unicode */ 2851 pSMB->OldFileName[name_len] = 0x04; 2852 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */ 2853 name_len2 = 2854 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], 2855 to_name, PATH_MAX, cifs_sb->local_nls, 2856 remap); 2857 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2858 name_len2 *= 2; /* convert to bytes */ 2859 } else { 2860 name_len = copy_path_name(pSMB->OldFileName, from_name); 2861 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ 2862 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name); 2863 name_len2++; /* signature byte */ 2864 } 2865 2866 count = 1 /* string type byte */ + name_len + name_len2; 2867 in_len += count; 2868 pSMB->ByteCount = cpu_to_le16(count); 2869 2870 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 2871 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2872 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks); 2873 if (rc) 2874 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc); 2875 2876 cifs_buf_release(pSMB); 2877 if (rc == -EAGAIN) 2878 goto winCreateHardLinkRetry; 2879 2880 return rc; 2881 } 2882 2883 int 2884 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, 2885 const unsigned char *searchName, char **symlinkinfo, 2886 const struct nls_table *nls_codepage, int remap) 2887 { 2888 /* SMB_QUERY_FILE_UNIX_LINK */ 2889 TRANSACTION2_QPI_REQ *pSMB = NULL; 2890 TRANSACTION2_QPI_RSP *pSMBr = NULL; 2891 unsigned int in_len; 2892 int rc = 0; 2893 int bytes_returned; 2894 int name_len; 2895 __u16 params, byte_count; 2896 char *data_start; 2897 2898 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName); 2899 2900 querySymLinkRetry: 2901 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2902 (void **) &pSMBr); 2903 if (rc < 0) 2904 return rc; 2905 in_len = rc; 2906 2907 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2908 name_len = 2909 cifsConvertToUTF16((__le16 *) pSMB->FileName, 2910 searchName, PATH_MAX, nls_codepage, 2911 remap); 2912 name_len++; /* trailing null */ 2913 name_len *= 2; 2914 } else { 2915 name_len = copy_path_name(pSMB->FileName, searchName); 2916 } 2917 2918 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 2919 pSMB->TotalDataCount = 0; 2920 pSMB->MaxParameterCount = cpu_to_le16(2); 2921 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 2922 pSMB->MaxSetupCount = 0; 2923 pSMB->Reserved = 0; 2924 pSMB->Flags = 0; 2925 pSMB->Timeout = 0; 2926 pSMB->Reserved2 = 0; 2927 pSMB->ParameterOffset = cpu_to_le16(offsetof( 2928 struct smb_com_transaction2_qpi_req, InformationLevel)); 2929 pSMB->DataCount = 0; 2930 pSMB->DataOffset = 0; 2931 pSMB->SetupCount = 1; 2932 pSMB->Reserved3 = 0; 2933 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 2934 byte_count = params + 1 /* pad */ ; 2935 pSMB->TotalParameterCount = cpu_to_le16(params); 2936 pSMB->ParameterCount = pSMB->TotalParameterCount; 2937 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK); 2938 pSMB->Reserved4 = 0; 2939 in_len += byte_count; 2940 pSMB->ByteCount = cpu_to_le16(byte_count); 2941 2942 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 2943 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2944 if (rc) { 2945 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc); 2946 } else { 2947 /* decode response */ 2948 2949 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2950 /* BB also check enough total bytes returned */ 2951 if (rc || get_bcc(&pSMBr->hdr) < 2) 2952 rc = smb_EIO2(smb_eio_trace_qsym_bcc_too_small, 2953 get_bcc(&pSMBr->hdr), 2); 2954 else { 2955 bool is_unicode; 2956 u16 count = le16_to_cpu(pSMBr->t2.DataCount); 2957 2958 data_start = ((char *) &pSMBr->hdr.Protocol) + 2959 le16_to_cpu(pSMBr->t2.DataOffset); 2960 2961 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 2962 is_unicode = true; 2963 else 2964 is_unicode = false; 2965 2966 /* BB FIXME investigate remapping reserved chars here */ 2967 *symlinkinfo = cifs_strndup_from_utf16(data_start, 2968 count, is_unicode, nls_codepage); 2969 if (!*symlinkinfo) 2970 rc = -ENOMEM; 2971 } 2972 } 2973 cifs_buf_release(pSMB); 2974 if (rc == -EAGAIN) 2975 goto querySymLinkRetry; 2976 return rc; 2977 } 2978 2979 int cifs_query_reparse_point(const unsigned int xid, 2980 struct cifs_tcon *tcon, 2981 struct cifs_sb_info *cifs_sb, 2982 const char *full_path, 2983 u32 *tag, struct kvec *rsp, 2984 int *rsp_buftype) 2985 { 2986 struct reparse_data_buffer *buf; 2987 struct cifs_open_parms oparms; 2988 TRANSACT_IOCTL_REQ *io_req = NULL; 2989 TRANSACT_IOCTL_RSP *io_rsp = NULL; 2990 struct cifs_fid fid; 2991 unsigned int in_len; 2992 __u32 data_offset, data_count, len; 2993 __u8 *start, *end; 2994 int io_rsp_len; 2995 int oplock = 0; 2996 int rc; 2997 2998 cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path); 2999 3000 if (cap_unix(tcon->ses)) 3001 return -EOPNOTSUPP; 3002 3003 if (!CIFS_REPARSE_SUPPORT(tcon)) 3004 return -EOPNOTSUPP; 3005 3006 oparms = (struct cifs_open_parms) { 3007 .tcon = tcon, 3008 .cifs_sb = cifs_sb, 3009 .desired_access = FILE_READ_ATTRIBUTES, 3010 .create_options = cifs_create_options(cifs_sb, 3011 OPEN_REPARSE_POINT), 3012 .disposition = FILE_OPEN, 3013 .path = full_path, 3014 .fid = &fid, 3015 }; 3016 3017 rc = CIFS_open(xid, &oparms, &oplock, NULL); 3018 if (rc) 3019 return rc; 3020 3021 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, 3022 (void **)&io_req, (void **)&io_rsp); 3023 if (rc < 0) 3024 goto error; 3025 in_len = rc; 3026 3027 io_req->TotalParameterCount = 0; 3028 io_req->TotalDataCount = 0; 3029 io_req->MaxParameterCount = cpu_to_le32(0); 3030 /* BB find exact data count max from sess structure BB */ 3031 io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00); 3032 io_req->MaxSetupCount = 1; 3033 io_req->Reserved = 0; 3034 io_req->ParameterOffset = 0; 3035 io_req->DataCount = 0; 3036 io_req->DataOffset = 0; 3037 io_req->SetupCount = 4; 3038 io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL); 3039 io_req->ParameterCount = io_req->TotalParameterCount; 3040 io_req->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT); 3041 io_req->IsFsctl = 1; 3042 io_req->IsRootFlag = 0; 3043 io_req->Fid = fid.netfid; 3044 io_req->ByteCount = 0; 3045 3046 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req, in_len, 3047 (struct smb_hdr *)io_rsp, &io_rsp_len, 0); 3048 if (rc) 3049 goto error; 3050 3051 data_offset = le32_to_cpu(io_rsp->DataOffset); 3052 data_count = le32_to_cpu(io_rsp->DataCount); 3053 if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 || 3054 !data_count || data_count > 2048) { 3055 rc = smb_EIO2(smb_eio_trace_qreparse_sizes_wrong, 3056 get_bcc(&io_rsp->hdr), data_count); 3057 goto error; 3058 } 3059 3060 /* SetupCount must be 1, otherwise offset to ByteCount is incorrect. */ 3061 if (io_rsp->SetupCount != 1) { 3062 rc = smb_EIO2(smb_eio_trace_qreparse_setup_count, 3063 io_rsp->SetupCount, 1); 3064 goto error; 3065 } 3066 3067 /* 3068 * ReturnedDataLen is output length of executed IOCTL. 3069 * DataCount is output length transferred over network. 3070 * Check that we have full FSCTL_GET_REPARSE_POINT buffer. 3071 */ 3072 if (data_count != le16_to_cpu(io_rsp->ReturnedDataLen)) { 3073 rc = smb_EIO2(smb_eio_trace_qreparse_ret_datalen, 3074 data_count, le16_to_cpu(io_rsp->ReturnedDataLen)); 3075 goto error; 3076 } 3077 3078 end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount; 3079 start = (__u8 *)&io_rsp->hdr.Protocol + data_offset; 3080 if (start >= end || (size_t)(end - start) < sizeof(*buf)) { 3081 rc = smb_EIO2(smb_eio_trace_qreparse_data_area, 3082 (unsigned long)start - (unsigned long)io_rsp, 3083 (unsigned long)end - (unsigned long)io_rsp); 3084 goto error; 3085 } 3086 3087 data_count = le16_to_cpu(io_rsp->ByteCount); 3088 buf = (struct reparse_data_buffer *)start; 3089 len = sizeof(*buf); 3090 if (data_count < len || 3091 data_count < le16_to_cpu(buf->ReparseDataLength) + len) { 3092 rc = smb_EIO2(smb_eio_trace_qreparse_rep_datalen, 3093 data_count, le16_to_cpu(buf->ReparseDataLength) + len); 3094 goto error; 3095 } 3096 3097 *tag = le32_to_cpu(buf->ReparseTag); 3098 rsp->iov_base = io_rsp; 3099 rsp->iov_len = io_rsp_len; 3100 *rsp_buftype = CIFS_LARGE_BUFFER; 3101 CIFSSMBClose(xid, tcon, fid.netfid); 3102 return 0; 3103 3104 error: 3105 cifs_buf_release(io_req); 3106 CIFSSMBClose(xid, tcon, fid.netfid); 3107 return rc; 3108 } 3109 3110 struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data, 3111 struct super_block *sb, 3112 const unsigned int xid, 3113 struct cifs_tcon *tcon, 3114 const char *full_path, 3115 bool directory, 3116 struct kvec *reparse_iov, 3117 struct kvec *xattr_iov) 3118 { 3119 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 3120 struct cifs_open_parms oparms; 3121 TRANSACT_IOCTL_REQ *io_req; 3122 struct inode *new = NULL; 3123 struct kvec in_iov[2]; 3124 struct kvec out_iov; 3125 struct cifs_fid fid; 3126 unsigned int in_len; 3127 int oplock = 0; 3128 int buf_type = 0; 3129 int rc; 3130 3131 cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path); 3132 3133 /* 3134 * If server filesystem does not support reparse points then do not 3135 * attempt to create reparse point. This will prevent creating unusable 3136 * empty object on the server. 3137 */ 3138 if (!CIFS_REPARSE_SUPPORT(tcon)) 3139 return ERR_PTR(-EOPNOTSUPP); 3140 3141 #ifndef CONFIG_CIFS_XATTR 3142 if (xattr_iov) 3143 return ERR_PTR(-EOPNOTSUPP); 3144 #endif 3145 3146 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, 3147 FILE_READ_ATTRIBUTES | FILE_WRITE_DATA | FILE_WRITE_EA, 3148 FILE_CREATE, 3149 (directory ? CREATE_NOT_FILE : CREATE_NOT_DIR) | OPEN_REPARSE_POINT, 3150 ACL_NO_MODE); 3151 oparms.fid = &fid; 3152 3153 rc = CIFS_open(xid, &oparms, &oplock, NULL); 3154 if (rc) 3155 return ERR_PTR(rc); 3156 3157 #ifdef CONFIG_CIFS_XATTR 3158 if (xattr_iov) { 3159 struct smb2_file_full_ea_info *ea; 3160 3161 ea = &((struct smb2_create_ea_ctx *)xattr_iov->iov_base)->ea; 3162 while (1) { 3163 rc = CIFSSMBSetEA(xid, 3164 tcon, 3165 full_path, 3166 &ea->ea_data[0], 3167 &ea->ea_data[ea->ea_name_length+1], 3168 le16_to_cpu(ea->ea_value_length), 3169 cifs_sb); 3170 if (rc) 3171 goto out_close; 3172 if (le32_to_cpu(ea->next_entry_offset) == 0) 3173 break; 3174 ea = (struct smb2_file_full_ea_info *)((u8 *)ea + 3175 le32_to_cpu(ea->next_entry_offset)); 3176 } 3177 } 3178 #endif 3179 3180 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **)&io_req, NULL); 3181 if (rc < 0) 3182 goto out_close; 3183 in_len = rc; 3184 in_len += sizeof(io_req->Pad); 3185 3186 /* NT IOCTL response contains one-word long output setup buffer with size of output data. */ 3187 io_req->MaxSetupCount = 1; 3188 /* NT IOCTL response does not contain output parameters. */ 3189 io_req->MaxParameterCount = cpu_to_le32(0); 3190 /* FSCTL_SET_REPARSE_POINT response contains empty output data. */ 3191 io_req->MaxDataCount = cpu_to_le32(0); 3192 3193 io_req->TotalParameterCount = cpu_to_le32(0); 3194 io_req->TotalDataCount = cpu_to_le32(reparse_iov->iov_len); 3195 io_req->ParameterCount = io_req->TotalParameterCount; 3196 io_req->ParameterOffset = cpu_to_le32(0); 3197 io_req->DataCount = io_req->TotalDataCount; 3198 io_req->DataOffset = cpu_to_le32(offsetof(typeof(*io_req), Data)); 3199 io_req->SetupCount = 4; 3200 io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL); 3201 io_req->FunctionCode = cpu_to_le32(FSCTL_SET_REPARSE_POINT); 3202 io_req->Fid = fid.netfid; 3203 io_req->IsFsctl = 1; 3204 io_req->IsRootFlag = 0; 3205 io_req->ByteCount = cpu_to_le16(le32_to_cpu(io_req->DataCount) + sizeof(io_req->Pad)); 3206 3207 in_iov[0].iov_base = (char *)io_req; 3208 in_iov[0].iov_len = in_len; 3209 in_iov[1] = *reparse_iov; 3210 rc = SendReceive2(xid, tcon->ses, in_iov, ARRAY_SIZE(in_iov), &buf_type, 3211 CIFS_NO_RSP_BUF, &out_iov); 3212 3213 cifs_buf_release(io_req); 3214 3215 if (!rc) 3216 rc = cifs_get_inode_info(&new, full_path, data, sb, xid, NULL); 3217 3218 out_close: 3219 CIFSSMBClose(xid, tcon, fid.netfid); 3220 3221 /* 3222 * If CREATE was successful but FSCTL_SET_REPARSE_POINT failed then 3223 * remove the intermediate object created by CREATE. Otherwise 3224 * empty object stay on the server when reparse call failed. 3225 */ 3226 if (rc) 3227 CIFSSMBDelFile(xid, tcon, full_path, cifs_sb, NULL); 3228 3229 return rc ? ERR_PTR(rc) : new; 3230 } 3231 3232 int 3233 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon, 3234 __u16 fid, __u16 compression_state) 3235 { 3236 int rc = 0; 3237 int bytes_returned; 3238 struct smb_com_transaction_compr_ioctl_req *pSMB; 3239 struct smb_com_transaction_ioctl_rsp *pSMBr; 3240 unsigned int in_len; 3241 3242 cifs_dbg(FYI, "Set compression for %u\n", fid); 3243 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, 3244 (void **) &pSMBr); 3245 if (rc < 0) 3246 return rc; 3247 in_len = rc; 3248 3249 pSMB->compression_state = cpu_to_le16(compression_state); 3250 3251 pSMB->TotalParameterCount = 0; 3252 pSMB->TotalDataCount = cpu_to_le32(2); 3253 pSMB->MaxParameterCount = 0; 3254 pSMB->MaxDataCount = 0; 3255 pSMB->MaxSetupCount = 4; 3256 pSMB->Reserved = 0; 3257 pSMB->ParameterOffset = 0; 3258 pSMB->DataCount = cpu_to_le32(2); 3259 pSMB->DataOffset = 3260 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req, 3261 compression_state)); /* 84 */ 3262 pSMB->SetupCount = 4; 3263 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL); 3264 pSMB->ParameterCount = 0; 3265 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION); 3266 pSMB->IsFsctl = 1; /* FSCTL */ 3267 pSMB->IsRootFlag = 0; 3268 pSMB->Fid = fid; /* file handle always le */ 3269 /* 3 byte pad, followed by 2 byte compress state */ 3270 pSMB->ByteCount = cpu_to_le16(5); 3271 in_len += 5; 3272 3273 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 3274 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3275 if (rc) 3276 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc); 3277 3278 cifs_buf_release(pSMB); 3279 3280 /* 3281 * Note: On -EAGAIN error only caller can retry on handle based calls 3282 * since file handle passed in no longer valid. 3283 */ 3284 return rc; 3285 } 3286 3287 3288 #ifdef CONFIG_CIFS_POSIX 3289 3290 #ifdef CONFIG_FS_POSIX_ACL 3291 /** 3292 * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format 3293 * @ace: POSIX ACL entry to store converted ACL into 3294 * @cifs_ace: ACL in cifs format 3295 * 3296 * Convert an Access Control Entry from wire format to local POSIX xattr 3297 * format. 3298 * 3299 * Note that the @cifs_uid member is used to store both {g,u}id_t. 3300 */ 3301 static void cifs_init_posix_acl(struct posix_acl_entry *ace, 3302 struct cifs_posix_ace *cifs_ace) 3303 { 3304 /* u8 cifs fields do not need le conversion */ 3305 ace->e_perm = cifs_ace->cifs_e_perm; 3306 ace->e_tag = cifs_ace->cifs_e_tag; 3307 3308 switch (ace->e_tag) { 3309 case ACL_USER: 3310 ace->e_uid = make_kuid(&init_user_ns, 3311 le64_to_cpu(cifs_ace->cifs_uid)); 3312 break; 3313 case ACL_GROUP: 3314 ace->e_gid = make_kgid(&init_user_ns, 3315 le64_to_cpu(cifs_ace->cifs_uid)); 3316 break; 3317 } 3318 return; 3319 } 3320 3321 /** 3322 * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format 3323 * @acl: ACLs returned in POSIX ACL format 3324 * @src: ACLs in cifs format 3325 * @acl_type: type of POSIX ACL requested 3326 * @size_of_data_area: size of SMB we got 3327 * 3328 * This function converts ACLs from cifs format to POSIX ACL format. 3329 * If @acl is NULL then the size of the buffer required to store POSIX ACLs in 3330 * their uapi format is returned. 3331 */ 3332 static int cifs_to_posix_acl(struct posix_acl **acl, char *src, 3333 const int acl_type, const int size_of_data_area) 3334 { 3335 int size = 0; 3336 __u16 count; 3337 struct cifs_posix_ace *pACE; 3338 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src; 3339 struct posix_acl *kacl = NULL; 3340 struct posix_acl_entry *pa, *pe; 3341 3342 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION) 3343 return -EOPNOTSUPP; 3344 3345 if (acl_type == ACL_TYPE_ACCESS) { 3346 count = le16_to_cpu(cifs_acl->access_entry_count); 3347 pACE = &cifs_acl->ace_array[0]; 3348 size = sizeof(struct cifs_posix_acl); 3349 size += sizeof(struct cifs_posix_ace) * count; 3350 /* check if we would go beyond end of SMB */ 3351 if (size_of_data_area < size) { 3352 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n", 3353 size_of_data_area, size); 3354 return -EINVAL; 3355 } 3356 } else if (acl_type == ACL_TYPE_DEFAULT) { 3357 count = le16_to_cpu(cifs_acl->access_entry_count); 3358 size = sizeof(struct cifs_posix_acl); 3359 size += sizeof(struct cifs_posix_ace) * count; 3360 /* skip past access ACEs to get to default ACEs */ 3361 pACE = &cifs_acl->ace_array[count]; 3362 count = le16_to_cpu(cifs_acl->default_entry_count); 3363 size += sizeof(struct cifs_posix_ace) * count; 3364 /* check if we would go beyond end of SMB */ 3365 if (size_of_data_area < size) 3366 return -EINVAL; 3367 } else { 3368 /* illegal type */ 3369 return -EINVAL; 3370 } 3371 3372 /* Allocate number of POSIX ACLs to store in VFS format. */ 3373 kacl = posix_acl_alloc(count, GFP_NOFS); 3374 if (!kacl) 3375 return -ENOMEM; 3376 3377 FOREACH_ACL_ENTRY(pa, kacl, pe) { 3378 cifs_init_posix_acl(pa, pACE); 3379 pACE++; 3380 } 3381 3382 *acl = kacl; 3383 return 0; 3384 } 3385 3386 /** 3387 * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format 3388 * @cifs_ace: the cifs ACL entry to store into 3389 * @local_ace: the POSIX ACL entry to convert 3390 */ 3391 static void cifs_init_ace(struct cifs_posix_ace *cifs_ace, 3392 const struct posix_acl_entry *local_ace) 3393 { 3394 cifs_ace->cifs_e_perm = local_ace->e_perm; 3395 cifs_ace->cifs_e_tag = local_ace->e_tag; 3396 3397 switch (local_ace->e_tag) { 3398 case ACL_USER: 3399 cifs_ace->cifs_uid = 3400 cpu_to_le64(from_kuid(&init_user_ns, local_ace->e_uid)); 3401 break; 3402 case ACL_GROUP: 3403 cifs_ace->cifs_uid = 3404 cpu_to_le64(from_kgid(&init_user_ns, local_ace->e_gid)); 3405 break; 3406 default: 3407 cifs_ace->cifs_uid = cpu_to_le64(-1); 3408 } 3409 } 3410 3411 /** 3412 * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format 3413 * @parm_data: ACLs in cifs format to convert to 3414 * @acl: ACLs in POSIX ACL format to convert from 3415 * @acl_type: the type of POSIX ACLs stored in @acl 3416 * 3417 * Return: the number cifs ACL entries after conversion 3418 */ 3419 static __u16 posix_acl_to_cifs(char *parm_data, const struct posix_acl *acl, 3420 const int acl_type) 3421 { 3422 __u16 rc = 0; 3423 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data; 3424 const struct posix_acl_entry *pa, *pe; 3425 int count; 3426 int i = 0; 3427 3428 if ((acl == NULL) || (cifs_acl == NULL)) 3429 return 0; 3430 3431 count = acl->a_count; 3432 cifs_dbg(FYI, "setting acl with %d entries\n", count); 3433 3434 /* 3435 * Note that the uapi POSIX ACL version is verified by the VFS and is 3436 * independent of the cifs ACL version. Changing the POSIX ACL version 3437 * is a uapi change and if it's changed we will pass down the POSIX ACL 3438 * version in struct posix_acl from the VFS. For now there's really 3439 * only one that all filesystems know how to deal with. 3440 */ 3441 cifs_acl->version = cpu_to_le16(1); 3442 if (acl_type == ACL_TYPE_ACCESS) { 3443 cifs_acl->access_entry_count = cpu_to_le16(count); 3444 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF); 3445 } else if (acl_type == ACL_TYPE_DEFAULT) { 3446 cifs_acl->default_entry_count = cpu_to_le16(count); 3447 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF); 3448 } else { 3449 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type); 3450 return 0; 3451 } 3452 FOREACH_ACL_ENTRY(pa, acl, pe) { 3453 cifs_init_ace(&cifs_acl->ace_array[i++], pa); 3454 } 3455 if (rc == 0) { 3456 rc = (__u16)(count * sizeof(struct cifs_posix_ace)); 3457 rc += sizeof(struct cifs_posix_acl); 3458 /* BB add check to make sure ACL does not overflow SMB */ 3459 } 3460 return rc; 3461 } 3462 3463 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon, 3464 const unsigned char *searchName, struct posix_acl **acl, 3465 const int acl_type, const struct nls_table *nls_codepage, 3466 int remap) 3467 { 3468 /* SMB_QUERY_POSIX_ACL */ 3469 TRANSACTION2_QPI_REQ *pSMB = NULL; 3470 TRANSACTION2_QPI_RSP *pSMBr = NULL; 3471 unsigned int in_len; 3472 int rc = 0; 3473 int bytes_returned; 3474 int name_len; 3475 __u16 params, byte_count; 3476 3477 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName); 3478 3479 queryAclRetry: 3480 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3481 (void **) &pSMBr); 3482 if (rc < 0) 3483 return rc; 3484 in_len = rc; 3485 3486 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3487 name_len = 3488 cifsConvertToUTF16((__le16 *) pSMB->FileName, 3489 searchName, PATH_MAX, nls_codepage, 3490 remap); 3491 name_len++; /* trailing null */ 3492 name_len *= 2; 3493 pSMB->FileName[name_len] = 0; 3494 pSMB->FileName[name_len+1] = 0; 3495 } else { 3496 name_len = copy_path_name(pSMB->FileName, searchName); 3497 } 3498 3499 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 3500 pSMB->TotalDataCount = 0; 3501 pSMB->MaxParameterCount = cpu_to_le16(2); 3502 /* BB find exact max data count below from sess structure BB */ 3503 pSMB->MaxDataCount = cpu_to_le16(4000); 3504 pSMB->MaxSetupCount = 0; 3505 pSMB->Reserved = 0; 3506 pSMB->Flags = 0; 3507 pSMB->Timeout = 0; 3508 pSMB->Reserved2 = 0; 3509 pSMB->ParameterOffset = cpu_to_le16( 3510 offsetof(struct smb_com_transaction2_qpi_req, 3511 InformationLevel)); 3512 pSMB->DataCount = 0; 3513 pSMB->DataOffset = 0; 3514 pSMB->SetupCount = 1; 3515 pSMB->Reserved3 = 0; 3516 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 3517 byte_count = params + 1 /* pad */ ; 3518 pSMB->TotalParameterCount = cpu_to_le16(params); 3519 pSMB->ParameterCount = pSMB->TotalParameterCount; 3520 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL); 3521 pSMB->Reserved4 = 0; 3522 in_len += byte_count; 3523 pSMB->ByteCount = cpu_to_le16(byte_count); 3524 3525 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 3526 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3527 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get); 3528 if (rc) { 3529 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc); 3530 } else { 3531 /* decode response */ 3532 3533 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3534 /* BB also check enough total bytes returned */ 3535 if (rc || get_bcc(&pSMBr->hdr) < 2) 3536 rc = smb_EIO2(smb_eio_trace_getacl_bcc_too_small, 3537 get_bcc(&pSMBr->hdr), 2); 3538 else { 3539 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3540 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3541 rc = cifs_to_posix_acl(acl, 3542 (char *)&pSMBr->hdr.Protocol+data_offset, 3543 acl_type, count); 3544 } 3545 } 3546 cifs_buf_release(pSMB); 3547 /* 3548 * The else branch after SendReceive() doesn't return EAGAIN so if we 3549 * allocated @acl in cifs_to_posix_acl() we are guaranteed to return 3550 * here and don't leak POSIX ACLs. 3551 */ 3552 if (rc == -EAGAIN) 3553 goto queryAclRetry; 3554 return rc; 3555 } 3556 3557 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon, 3558 const unsigned char *fileName, const struct posix_acl *acl, 3559 const int acl_type, const struct nls_table *nls_codepage, 3560 int remap) 3561 { 3562 struct smb_com_transaction2_spi_req *pSMB = NULL; 3563 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 3564 unsigned int in_len; 3565 char *parm_data; 3566 int name_len; 3567 int rc = 0; 3568 int bytes_returned = 0; 3569 __u16 params, byte_count, data_count, param_offset, offset; 3570 size_t cifs_acl_size, bytes_available; 3571 3572 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName); 3573 setAclRetry: 3574 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3575 (void **) &pSMBr); 3576 if (rc < 0) 3577 return rc; 3578 in_len = rc; 3579 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3580 name_len = 3581 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 3582 PATH_MAX, nls_codepage, remap); 3583 name_len++; /* trailing null */ 3584 name_len *= 2; 3585 } else { 3586 name_len = copy_path_name(pSMB->FileName, fileName); 3587 } 3588 params = 6 + name_len; 3589 pSMB->MaxParameterCount = cpu_to_le16(2); 3590 pSMB->MaxDataCount = cpu_to_le16(min_t(unsigned int, CIFSMaxBufSize, USHRT_MAX)); 3591 pSMB->MaxSetupCount = 0; 3592 pSMB->Reserved = 0; 3593 pSMB->Flags = 0; 3594 pSMB->Timeout = 0; 3595 pSMB->Reserved2 = 0; 3596 param_offset = offsetof(struct smb_com_transaction2_spi_req, 3597 InformationLevel); 3598 offset = param_offset + params; 3599 parm_data = ((char *)pSMB) + offset; 3600 pSMB->ParameterOffset = cpu_to_le16(param_offset); 3601 3602 /* make sure we can fit the larger cifs_posix_aces in the buffer */ 3603 cifs_acl_size = sizeof(struct cifs_posix_acl) + 3604 (acl->a_count * sizeof(struct cifs_posix_ace)); 3605 bytes_available = (CIFSMaxBufSize + MAX_HEADER_SIZE(tcon->ses->server)) - offset; 3606 if (cifs_acl_size > bytes_available || cifs_acl_size > USHRT_MAX) { 3607 rc = -E2BIG; 3608 goto setACLerrorExit; 3609 } 3610 3611 /* convert to on the wire format for POSIX ACL */ 3612 data_count = posix_acl_to_cifs(parm_data, acl, acl_type); 3613 3614 if (data_count == 0) { 3615 rc = -EOPNOTSUPP; 3616 goto setACLerrorExit; 3617 } 3618 pSMB->DataOffset = cpu_to_le16(offset); 3619 pSMB->SetupCount = 1; 3620 pSMB->Reserved3 = 0; 3621 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 3622 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL); 3623 byte_count = 3 /* pad */ + params + data_count; 3624 pSMB->DataCount = cpu_to_le16(data_count); 3625 pSMB->TotalDataCount = pSMB->DataCount; 3626 pSMB->ParameterCount = cpu_to_le16(params); 3627 pSMB->TotalParameterCount = pSMB->ParameterCount; 3628 pSMB->Reserved4 = 0; 3629 in_len += byte_count; 3630 pSMB->ByteCount = cpu_to_le16(byte_count); 3631 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 3632 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3633 if (rc) 3634 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc); 3635 3636 setACLerrorExit: 3637 cifs_buf_release(pSMB); 3638 if (rc == -EAGAIN) 3639 goto setAclRetry; 3640 return rc; 3641 } 3642 #else 3643 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon, 3644 const unsigned char *searchName, struct posix_acl **acl, 3645 const int acl_type, const struct nls_table *nls_codepage, 3646 int remap) 3647 { 3648 return -EOPNOTSUPP; 3649 } 3650 3651 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon, 3652 const unsigned char *fileName, const struct posix_acl *acl, 3653 const int acl_type, const struct nls_table *nls_codepage, 3654 int remap) 3655 { 3656 return -EOPNOTSUPP; 3657 } 3658 #endif /* CONFIG_FS_POSIX_ACL */ 3659 3660 int 3661 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon, 3662 const int netfid, __u64 *pExtAttrBits, __u64 *pMask) 3663 { 3664 int rc = 0; 3665 struct smb_t2_qfi_req *pSMB = NULL; 3666 struct smb_t2_qfi_rsp *pSMBr = NULL; 3667 unsigned int in_len; 3668 int bytes_returned; 3669 __u16 params, byte_count; 3670 3671 cifs_dbg(FYI, "In GetExtAttr\n"); 3672 if (tcon == NULL) 3673 return -ENODEV; 3674 3675 GetExtAttrRetry: 3676 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3677 (void **) &pSMBr); 3678 if (rc < 0) 3679 return rc; 3680 in_len = rc; 3681 3682 params = 2 /* level */ + 2 /* fid */; 3683 pSMB->t2.TotalDataCount = 0; 3684 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 3685 /* BB find exact max data count below from sess structure BB */ 3686 pSMB->t2.MaxDataCount = cpu_to_le16(4000); 3687 pSMB->t2.MaxSetupCount = 0; 3688 pSMB->t2.Reserved = 0; 3689 pSMB->t2.Flags = 0; 3690 pSMB->t2.Timeout = 0; 3691 pSMB->t2.Reserved2 = 0; 3692 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 3693 Fid)); 3694 pSMB->t2.DataCount = 0; 3695 pSMB->t2.DataOffset = 0; 3696 pSMB->t2.SetupCount = 1; 3697 pSMB->t2.Reserved3 = 0; 3698 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 3699 byte_count = params + 1 /* pad */ ; 3700 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3701 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3702 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS); 3703 pSMB->Pad = 0; 3704 pSMB->Fid = netfid; 3705 in_len += byte_count; 3706 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 3707 3708 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 3709 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3710 if (rc) { 3711 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc); 3712 } else { 3713 /* decode response */ 3714 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3715 /* BB also check enough total bytes returned */ 3716 if (rc || get_bcc(&pSMBr->hdr) < 2) 3717 /* If rc should we check for EOPNOSUPP and 3718 disable the srvino flag? or in caller? */ 3719 rc = smb_EIO2(smb_eio_trace_getextattr_bcc_too_small, 3720 get_bcc(&pSMBr->hdr), 2); 3721 else { 3722 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3723 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3724 struct file_chattr_info *pfinfo; 3725 3726 if (count != 16) { 3727 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n"); 3728 rc = smb_EIO2(smb_eio_trace_getextattr_inv_size, 3729 count, 16); 3730 goto GetExtAttrOut; 3731 } 3732 pfinfo = (struct file_chattr_info *) 3733 (data_offset + (char *) &pSMBr->hdr.Protocol); 3734 *pExtAttrBits = le64_to_cpu(pfinfo->mode); 3735 *pMask = le64_to_cpu(pfinfo->mask); 3736 } 3737 } 3738 GetExtAttrOut: 3739 cifs_buf_release(pSMB); 3740 if (rc == -EAGAIN) 3741 goto GetExtAttrRetry; 3742 return rc; 3743 } 3744 3745 #endif /* CONFIG_POSIX */ 3746 3747 /* 3748 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that 3749 * all NT TRANSACTS that we init here have total parm and data under about 400 3750 * bytes (to fit in small cifs buffer size), which is the case so far, it 3751 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of 3752 * returned setup area) and MaxParameterCount (returned parms size) must be set 3753 * by caller 3754 */ 3755 static int 3756 smb_init_nttransact(const __u16 sub_command, const int setup_count, 3757 const int parm_len, struct cifs_tcon *tcon, 3758 void **ret_buf) 3759 { 3760 int rc; 3761 __u32 temp_offset; 3762 struct smb_com_ntransact_req *pSMB; 3763 unsigned int in_len; 3764 3765 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, 3766 (void **)&pSMB); 3767 if (rc < 0) 3768 return rc; 3769 in_len = rc; 3770 *ret_buf = (void *)pSMB; 3771 pSMB->Reserved = 0; 3772 pSMB->TotalParameterCount = cpu_to_le32(parm_len); 3773 pSMB->TotalDataCount = 0; 3774 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00); 3775 pSMB->ParameterCount = pSMB->TotalParameterCount; 3776 pSMB->DataCount = pSMB->TotalDataCount; 3777 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) + 3778 (setup_count * 2); 3779 pSMB->ParameterOffset = cpu_to_le32(temp_offset); 3780 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len); 3781 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */ 3782 pSMB->SubCommand = cpu_to_le16(sub_command); 3783 return in_len; 3784 } 3785 3786 static int 3787 validate_ntransact(char *buf, char **ppparm, char **ppdata, 3788 __u32 *pparmlen, __u32 *pdatalen) 3789 { 3790 __u32 data_count, data_offset, parm_count, parm_offset; 3791 struct smb_com_ntransact_rsp *pSMBr; 3792 size_t buflen; 3793 char *end_buf; 3794 u16 bcc; 3795 3796 *pdatalen = 0; 3797 *pparmlen = 0; 3798 3799 if (buf == NULL) 3800 return -EINVAL; 3801 3802 pSMBr = (struct smb_com_ntransact_rsp *)buf; 3803 3804 if (pSMBr->hdr.WordCount != 18) { 3805 cifs_dbg(FYI, "invalid NT transaction WordCount %u\n", 3806 pSMBr->hdr.WordCount); 3807 return -EINVAL; 3808 } 3809 3810 bcc = get_bcc(&pSMBr->hdr); 3811 end_buf = 2 /* sizeof byte count */ + bcc + (char *)&pSMBr->ByteCount; 3812 buflen = end_buf - buf; 3813 3814 data_offset = le32_to_cpu(pSMBr->DataOffset); 3815 data_count = le32_to_cpu(pSMBr->DataCount); 3816 parm_offset = le32_to_cpu(pSMBr->ParameterOffset); 3817 parm_count = le32_to_cpu(pSMBr->ParameterCount); 3818 3819 /* should we also check that parm and data areas do not overlap? */ 3820 if (parm_offset > buflen) { 3821 cifs_dbg(FYI, "parms start after end of smb\n"); 3822 return -EINVAL; 3823 } else if (parm_count > buflen - parm_offset) { 3824 cifs_dbg(FYI, "parm end after end of smb\n"); 3825 return -EINVAL; 3826 } else if (data_offset > buflen) { 3827 cifs_dbg(FYI, "data starts after end of smb\n"); 3828 return -EINVAL; 3829 } else if (data_count > buflen - data_offset) { 3830 cifs_dbg(FYI, "data offset %u + count %u past smb length %zu\n", 3831 data_offset, data_count, buflen); 3832 return -EINVAL; 3833 } else if (parm_count + data_count > bcc) { 3834 cifs_dbg(FYI, "parm count and data count larger than SMB\n"); 3835 return -EINVAL; 3836 } 3837 3838 *ppparm = buf + parm_offset; 3839 *ppdata = buf + data_offset; 3840 *pdatalen = data_count; 3841 *pparmlen = parm_count; 3842 return 0; 3843 } 3844 3845 /* Get Security Descriptor (by handle) from remote server for a file or dir */ 3846 int 3847 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, 3848 struct smb_ntsd **acl_inf, __u32 *pbuflen, __u32 info) 3849 { 3850 int rc = 0; 3851 int buf_type = 0; 3852 QUERY_SEC_DESC_REQ *pSMB; 3853 struct kvec iov[1]; 3854 struct kvec rsp_iov; 3855 unsigned int in_len; 3856 3857 cifs_dbg(FYI, "GetCifsACL\n"); 3858 3859 *pbuflen = 0; 3860 *acl_inf = NULL; 3861 3862 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, 3863 8 /* parm len */, tcon, (void **) &pSMB); 3864 if (rc < 0) 3865 return rc; 3866 in_len = rc; 3867 3868 pSMB->MaxParameterCount = cpu_to_le32(4); 3869 /* BB TEST with big acls that might need to be e.g. larger than 16K */ 3870 pSMB->MaxSetupCount = 0; 3871 pSMB->Fid = fid; /* file handle always le */ 3872 pSMB->AclFlags = cpu_to_le32(info); 3873 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */ 3874 in_len += 11; 3875 iov[0].iov_base = (char *)pSMB; 3876 iov[0].iov_len = in_len; 3877 3878 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 3879 0, &rsp_iov); 3880 cifs_small_buf_release(pSMB); 3881 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get); 3882 if (rc) { 3883 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc); 3884 } else { /* decode response */ 3885 __le32 *parm; 3886 __u32 parm_len; 3887 __u32 acl_len; 3888 struct smb_com_ntransact_rsp *pSMBr; 3889 char *pdata; 3890 3891 /* validate_nttransact */ 3892 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm, 3893 &pdata, &parm_len, pbuflen); 3894 if (rc) 3895 goto qsec_out; 3896 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base; 3897 3898 cifs_dbg(FYI, "smb %p parm %p data %p\n", 3899 pSMBr, parm, *acl_inf); 3900 3901 if (le32_to_cpu(pSMBr->ParameterCount) != 4) { 3902 rc = smb_EIO2(smb_eio_trace_getcifsacl_param_count, 3903 le32_to_cpu(pSMBr->ParameterCount), 4); 3904 *pbuflen = 0; 3905 goto qsec_out; 3906 } 3907 3908 /* BB check that data area is minimum length and as big as acl_len */ 3909 3910 acl_len = le32_to_cpu(*parm); 3911 if (acl_len != *pbuflen) { 3912 cifs_dbg(VFS, "acl length %d does not match %d\n", 3913 acl_len, *pbuflen); 3914 if (*pbuflen > acl_len) 3915 *pbuflen = acl_len; 3916 } 3917 3918 /* check if buffer is big enough for the acl 3919 header followed by the smallest SID */ 3920 if ((*pbuflen < sizeof(struct smb_ntsd) + 8) || 3921 (*pbuflen >= 64 * 1024)) { 3922 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen); 3923 rc = -EINVAL; 3924 *pbuflen = 0; 3925 } else { 3926 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL); 3927 if (*acl_inf == NULL) { 3928 *pbuflen = 0; 3929 rc = -ENOMEM; 3930 } 3931 } 3932 } 3933 qsec_out: 3934 free_rsp_buf(buf_type, rsp_iov.iov_base); 3935 return rc; 3936 } 3937 3938 int 3939 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, 3940 struct smb_ntsd *pntsd, __u32 acllen, int aclflag) 3941 { 3942 __u16 byte_count, param_count, data_count, param_offset, data_offset; 3943 int rc = 0; 3944 int bytes_returned = 0; 3945 SET_SEC_DESC_REQ *pSMB = NULL; 3946 unsigned int in_len; 3947 void *pSMBr; 3948 3949 setCifsAclRetry: 3950 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr); 3951 if (rc < 0) 3952 return rc; 3953 in_len = rc; 3954 3955 pSMB->MaxSetupCount = 0; 3956 pSMB->Reserved = 0; 3957 3958 param_count = 8; 3959 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid); 3960 data_count = acllen; 3961 data_offset = param_offset + param_count; 3962 byte_count = 3 /* pad */ + param_count; 3963 3964 pSMB->DataCount = cpu_to_le32(data_count); 3965 pSMB->TotalDataCount = pSMB->DataCount; 3966 pSMB->MaxParameterCount = cpu_to_le32(4); 3967 pSMB->MaxDataCount = cpu_to_le32(16384); 3968 pSMB->ParameterCount = cpu_to_le32(param_count); 3969 pSMB->ParameterOffset = cpu_to_le32(param_offset); 3970 pSMB->TotalParameterCount = pSMB->ParameterCount; 3971 pSMB->DataOffset = cpu_to_le32(data_offset); 3972 pSMB->SetupCount = 0; 3973 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC); 3974 pSMB->ByteCount = cpu_to_le16(byte_count+data_count); 3975 3976 pSMB->Fid = fid; /* file handle always le */ 3977 pSMB->Reserved2 = 0; 3978 pSMB->AclFlags = cpu_to_le32(aclflag); 3979 3980 if (pntsd && acllen) { 3981 memcpy((char *)pSMBr + data_offset, pntsd, acllen); 3982 in_len += byte_count + data_count; 3983 } else 3984 in_len += byte_count; 3985 3986 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 3987 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3988 3989 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n", 3990 bytes_returned, rc); 3991 if (rc) 3992 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc); 3993 cifs_buf_release(pSMB); 3994 3995 if (rc == -EAGAIN) 3996 goto setCifsAclRetry; 3997 3998 return (rc); 3999 } 4000 4001 4002 /* Legacy Query Path Information call for lookup to old servers such 4003 as Win9x/WinME */ 4004 int 4005 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, 4006 const char *search_name, FILE_ALL_INFO *data, 4007 const struct nls_table *nls_codepage, int remap) 4008 { 4009 QUERY_INFORMATION_REQ *pSMB; 4010 QUERY_INFORMATION_RSP *pSMBr; 4011 unsigned int in_len; 4012 int rc = 0; 4013 int bytes_returned; 4014 int name_len; 4015 4016 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name); 4017 QInfRetry: 4018 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB, 4019 (void **) &pSMBr); 4020 if (rc < 0) 4021 return rc; 4022 in_len = rc; 4023 4024 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4025 name_len = 4026 cifsConvertToUTF16((__le16 *) pSMB->FileName, 4027 search_name, PATH_MAX, nls_codepage, 4028 remap); 4029 name_len++; /* trailing null */ 4030 name_len *= 2; 4031 } else { 4032 name_len = copy_path_name(pSMB->FileName, search_name); 4033 } 4034 pSMB->BufferFormat = 0x04; 4035 name_len++; /* account for buffer type byte */ 4036 in_len += name_len; 4037 pSMB->ByteCount = cpu_to_le16(name_len); 4038 4039 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 4040 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4041 if (rc) { 4042 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc); 4043 } else if (data) { 4044 struct timespec64 ts; 4045 __u32 time = le32_to_cpu(pSMBr->last_write_time); 4046 4047 /* decode response */ 4048 /* BB FIXME - add time zone adjustment BB */ 4049 memset(data, 0, sizeof(FILE_ALL_INFO)); 4050 ts.tv_nsec = 0; 4051 ts.tv_sec = time; 4052 /* decode time fields */ 4053 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts)); 4054 data->LastWriteTime = data->ChangeTime; 4055 data->LastAccessTime = 0; 4056 data->AllocationSize = 4057 cpu_to_le64(le32_to_cpu(pSMBr->size)); 4058 data->EndOfFile = data->AllocationSize; 4059 data->Attributes = 4060 cpu_to_le32(le16_to_cpu(pSMBr->attr)); 4061 } else { 4062 /* bad buffer passed in */ 4063 rc = smb_EIO(smb_eio_trace_null_pointers); 4064 } 4065 4066 cifs_buf_release(pSMB); 4067 4068 if (rc == -EAGAIN) 4069 goto QInfRetry; 4070 4071 return rc; 4072 } 4073 4074 int 4075 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 4076 u16 netfid, FILE_ALL_INFO *pFindData) 4077 { 4078 struct smb_t2_qfi_req *pSMB = NULL; 4079 struct smb_t2_qfi_rsp *pSMBr = NULL; 4080 unsigned int in_len; 4081 int rc = 0; 4082 int bytes_returned; 4083 __u16 params, byte_count; 4084 4085 QFileInfoRetry: 4086 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4087 (void **) &pSMBr); 4088 if (rc < 0) 4089 return rc; 4090 in_len = rc; 4091 4092 params = 2 /* level */ + 2 /* fid */; 4093 pSMB->t2.TotalDataCount = 0; 4094 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 4095 /* BB find exact max data count below from sess structure BB */ 4096 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 4097 pSMB->t2.MaxSetupCount = 0; 4098 pSMB->t2.Reserved = 0; 4099 pSMB->t2.Flags = 0; 4100 pSMB->t2.Timeout = 0; 4101 pSMB->t2.Reserved2 = 0; 4102 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 4103 Fid)); 4104 pSMB->t2.DataCount = 0; 4105 pSMB->t2.DataOffset = 0; 4106 pSMB->t2.SetupCount = 1; 4107 pSMB->t2.Reserved3 = 0; 4108 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 4109 byte_count = params + 1 /* pad */ ; 4110 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 4111 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 4112 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 4113 pSMB->Pad = 0; 4114 pSMB->Fid = netfid; 4115 in_len += byte_count; 4116 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 4117 4118 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 4119 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4120 if (rc) { 4121 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc); 4122 } else { /* decode response */ 4123 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4124 4125 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 4126 rc = smb_EIO2(smb_eio_trace_qfileinfo_invalid, 4127 get_bcc(&pSMBr->hdr), 40); 4128 else if (get_bcc(&pSMBr->hdr) < 40) 4129 rc = smb_EIO2(smb_eio_trace_qfileinfo_bcc_too_small, 4130 get_bcc(&pSMBr->hdr), 40); 4131 else if (pFindData) { 4132 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4133 memcpy((char *) pFindData, 4134 (char *) &pSMBr->hdr.Protocol + 4135 data_offset, sizeof(FILE_ALL_INFO)); 4136 } else 4137 rc = -ENOMEM; 4138 } 4139 cifs_buf_release(pSMB); 4140 if (rc == -EAGAIN) 4141 goto QFileInfoRetry; 4142 4143 return rc; 4144 } 4145 4146 int 4147 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 4148 const char *search_name, FILE_ALL_INFO *data, 4149 int legacy /* old style infolevel */, 4150 const struct nls_table *nls_codepage, int remap) 4151 { 4152 /* level 263 SMB_QUERY_FILE_ALL_INFO */ 4153 TRANSACTION2_QPI_REQ *pSMB = NULL; 4154 TRANSACTION2_QPI_RSP *pSMBr = NULL; 4155 unsigned int in_len; 4156 int rc = 0; 4157 int bytes_returned; 4158 int name_len; 4159 __u16 params, byte_count; 4160 4161 QPathInfoRetry: 4162 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4163 (void **) &pSMBr); 4164 if (rc < 0) 4165 return rc; 4166 in_len = rc; 4167 4168 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4169 name_len = 4170 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name, 4171 PATH_MAX, nls_codepage, remap); 4172 name_len++; /* trailing null */ 4173 name_len *= 2; 4174 } else { 4175 name_len = copy_path_name(pSMB->FileName, search_name); 4176 } 4177 4178 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 4179 pSMB->TotalDataCount = 0; 4180 pSMB->MaxParameterCount = cpu_to_le16(2); 4181 /* BB find exact max SMB PDU from sess structure BB */ 4182 pSMB->MaxDataCount = cpu_to_le16(4000); 4183 pSMB->MaxSetupCount = 0; 4184 pSMB->Reserved = 0; 4185 pSMB->Flags = 0; 4186 pSMB->Timeout = 0; 4187 pSMB->Reserved2 = 0; 4188 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4189 struct smb_com_transaction2_qpi_req, InformationLevel)); 4190 pSMB->DataCount = 0; 4191 pSMB->DataOffset = 0; 4192 pSMB->SetupCount = 1; 4193 pSMB->Reserved3 = 0; 4194 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 4195 byte_count = params + 1 /* pad */ ; 4196 pSMB->TotalParameterCount = cpu_to_le16(params); 4197 pSMB->ParameterCount = pSMB->TotalParameterCount; 4198 if (legacy) 4199 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD); 4200 else 4201 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 4202 pSMB->Reserved4 = 0; 4203 in_len += byte_count; 4204 pSMB->ByteCount = cpu_to_le16(byte_count); 4205 4206 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 4207 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4208 if (rc) { 4209 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc); 4210 } else { /* decode response */ 4211 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4212 4213 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 4214 rc = smb_EIO2(smb_eio_trace_qpathinfo_invalid, 4215 get_bcc(&pSMBr->hdr), 40); 4216 else if (!legacy && get_bcc(&pSMBr->hdr) < 40) 4217 rc = smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small, 4218 get_bcc(&pSMBr->hdr), 40); 4219 else if (legacy && get_bcc(&pSMBr->hdr) < 24) 4220 /* 24 or 26 expected but we do not read last field */ 4221 rc = smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small, 4222 get_bcc(&pSMBr->hdr), 24); 4223 else if (data) { 4224 int size; 4225 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4226 4227 /* 4228 * On legacy responses we do not read the last field, 4229 * EAsize, fortunately since it varies by subdialect and 4230 * also note it differs on Set vs Get, ie two bytes or 4 4231 * bytes depending but we don't care here. 4232 */ 4233 if (legacy) 4234 size = sizeof(FILE_INFO_STANDARD); 4235 else 4236 size = sizeof(FILE_ALL_INFO); 4237 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol + 4238 data_offset, size); 4239 } else 4240 rc = -ENOMEM; 4241 } 4242 cifs_buf_release(pSMB); 4243 if (rc == -EAGAIN) 4244 goto QPathInfoRetry; 4245 4246 return rc; 4247 } 4248 4249 int 4250 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 4251 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData) 4252 { 4253 struct smb_t2_qfi_req *pSMB = NULL; 4254 struct smb_t2_qfi_rsp *pSMBr = NULL; 4255 unsigned int in_len; 4256 int rc = 0; 4257 int bytes_returned; 4258 __u16 params, byte_count; 4259 4260 UnixQFileInfoRetry: 4261 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4262 (void **) &pSMBr); 4263 if (rc < 0) 4264 return rc; 4265 in_len = rc; 4266 4267 params = 2 /* level */ + 2 /* fid */; 4268 pSMB->t2.TotalDataCount = 0; 4269 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 4270 /* BB find exact max data count below from sess structure BB */ 4271 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 4272 pSMB->t2.MaxSetupCount = 0; 4273 pSMB->t2.Reserved = 0; 4274 pSMB->t2.Flags = 0; 4275 pSMB->t2.Timeout = 0; 4276 pSMB->t2.Reserved2 = 0; 4277 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 4278 Fid)); 4279 pSMB->t2.DataCount = 0; 4280 pSMB->t2.DataOffset = 0; 4281 pSMB->t2.SetupCount = 1; 4282 pSMB->t2.Reserved3 = 0; 4283 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 4284 byte_count = params + 1 /* pad */ ; 4285 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 4286 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 4287 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 4288 pSMB->Pad = 0; 4289 pSMB->Fid = netfid; 4290 in_len += byte_count; 4291 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 4292 4293 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 4294 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4295 if (rc) { 4296 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc); 4297 } else { /* decode response */ 4298 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4299 4300 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) { 4301 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n"); 4302 rc = smb_EIO2(smb_eio_trace_unixqfileinfo_bcc_too_small, 4303 get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO)); 4304 } else { 4305 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4306 memcpy((char *) pFindData, 4307 (char *) &pSMBr->hdr.Protocol + 4308 data_offset, 4309 sizeof(FILE_UNIX_BASIC_INFO)); 4310 } 4311 } 4312 4313 cifs_buf_release(pSMB); 4314 if (rc == -EAGAIN) 4315 goto UnixQFileInfoRetry; 4316 4317 return rc; 4318 } 4319 4320 int 4321 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 4322 const unsigned char *searchName, 4323 FILE_UNIX_BASIC_INFO *pFindData, 4324 const struct nls_table *nls_codepage, int remap) 4325 { 4326 /* SMB_QUERY_FILE_UNIX_BASIC */ 4327 TRANSACTION2_QPI_REQ *pSMB = NULL; 4328 TRANSACTION2_QPI_RSP *pSMBr = NULL; 4329 unsigned int in_len; 4330 int rc = 0; 4331 int bytes_returned = 0; 4332 int name_len; 4333 __u16 params, byte_count; 4334 4335 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName); 4336 UnixQPathInfoRetry: 4337 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4338 (void **) &pSMBr); 4339 if (rc < 0) 4340 return rc; 4341 in_len = rc; 4342 4343 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4344 name_len = 4345 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 4346 PATH_MAX, nls_codepage, remap); 4347 name_len++; /* trailing null */ 4348 name_len *= 2; 4349 } else { 4350 name_len = copy_path_name(pSMB->FileName, searchName); 4351 } 4352 4353 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 4354 pSMB->TotalDataCount = 0; 4355 pSMB->MaxParameterCount = cpu_to_le16(2); 4356 /* BB find exact max SMB PDU from sess structure BB */ 4357 pSMB->MaxDataCount = cpu_to_le16(4000); 4358 pSMB->MaxSetupCount = 0; 4359 pSMB->Reserved = 0; 4360 pSMB->Flags = 0; 4361 pSMB->Timeout = 0; 4362 pSMB->Reserved2 = 0; 4363 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4364 struct smb_com_transaction2_qpi_req, InformationLevel)); 4365 pSMB->DataCount = 0; 4366 pSMB->DataOffset = 0; 4367 pSMB->SetupCount = 1; 4368 pSMB->Reserved3 = 0; 4369 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 4370 byte_count = params + 1 /* pad */ ; 4371 pSMB->TotalParameterCount = cpu_to_le16(params); 4372 pSMB->ParameterCount = pSMB->TotalParameterCount; 4373 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 4374 pSMB->Reserved4 = 0; 4375 in_len += byte_count; 4376 pSMB->ByteCount = cpu_to_le16(byte_count); 4377 4378 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 4379 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4380 if (rc) { 4381 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc); 4382 } else { /* decode response */ 4383 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4384 4385 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) { 4386 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n"); 4387 rc = smb_EIO2(smb_eio_trace_unixqpathinfo_bcc_too_small, 4388 get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO)); 4389 } else { 4390 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4391 memcpy((char *) pFindData, 4392 (char *) &pSMBr->hdr.Protocol + 4393 data_offset, 4394 sizeof(FILE_UNIX_BASIC_INFO)); 4395 } 4396 } 4397 cifs_buf_release(pSMB); 4398 if (rc == -EAGAIN) 4399 goto UnixQPathInfoRetry; 4400 4401 return rc; 4402 } 4403 4404 /* xid, tcon, searchName and codepage are input parms, rest are returned */ 4405 int 4406 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon, 4407 const char *searchName, struct cifs_sb_info *cifs_sb, 4408 __u16 *pnetfid, __u16 search_flags, 4409 struct cifs_search_info *psrch_inf, bool msearch) 4410 { 4411 /* level 257 SMB_ */ 4412 unsigned int parm_off, parm_count, data_off, data_count; 4413 TRANSACTION2_FFIRST_REQ *pSMB = NULL; 4414 TRANSACTION2_FFIRST_RSP *pSMBr = NULL; 4415 struct nls_table *nls_codepage; 4416 T2_FFIRST_RSP_PARMS *parms; 4417 unsigned int in_len, lnoff; 4418 __u16 params, byte_count; 4419 int bytes_returned = 0; 4420 int name_len, remap; 4421 int rc = 0; 4422 4423 cifs_dbg(FYI, "In FindFirst for %s\n", searchName); 4424 4425 findFirstRetry: 4426 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4427 (void **) &pSMBr); 4428 if (rc < 0) 4429 return rc; 4430 in_len = rc; 4431 4432 nls_codepage = cifs_sb->local_nls; 4433 remap = cifs_remap(cifs_sb); 4434 4435 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4436 name_len = 4437 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 4438 PATH_MAX, nls_codepage, remap); 4439 /* We can not add the asterisk earlier in case 4440 it got remapped to 0xF03A as if it were part of the 4441 directory name instead of a wildcard */ 4442 name_len *= 2; 4443 if (msearch) { 4444 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb); 4445 pSMB->FileName[name_len+1] = 0; 4446 pSMB->FileName[name_len+2] = '*'; 4447 pSMB->FileName[name_len+3] = 0; 4448 name_len += 4; /* now the trailing null */ 4449 /* null terminate just in case */ 4450 pSMB->FileName[name_len] = 0; 4451 pSMB->FileName[name_len+1] = 0; 4452 name_len += 2; 4453 } else if (!searchName[0]) { 4454 pSMB->FileName[0] = CIFS_DIR_SEP(cifs_sb); 4455 pSMB->FileName[1] = 0; 4456 pSMB->FileName[2] = 0; 4457 pSMB->FileName[3] = 0; 4458 name_len = 4; 4459 } 4460 } else { 4461 name_len = copy_path_name(pSMB->FileName, searchName); 4462 if (msearch) { 4463 if (WARN_ON_ONCE(name_len > PATH_MAX-2)) 4464 name_len = PATH_MAX-2; 4465 /* overwrite nul byte */ 4466 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb); 4467 pSMB->FileName[name_len] = '*'; 4468 pSMB->FileName[name_len+1] = 0; 4469 name_len += 2; 4470 } else if (!searchName[0]) { 4471 pSMB->FileName[0] = CIFS_DIR_SEP(cifs_sb); 4472 pSMB->FileName[1] = 0; 4473 name_len = 2; 4474 } 4475 } 4476 4477 params = 12 + name_len /* includes null */ ; 4478 pSMB->TotalDataCount = 0; /* no EAs */ 4479 pSMB->MaxParameterCount = cpu_to_le16(10); 4480 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00); 4481 pSMB->MaxSetupCount = 0; 4482 pSMB->Reserved = 0; 4483 pSMB->Flags = 0; 4484 pSMB->Timeout = 0; 4485 pSMB->Reserved2 = 0; 4486 byte_count = params + 1 /* pad */ ; 4487 pSMB->TotalParameterCount = cpu_to_le16(params); 4488 pSMB->ParameterCount = pSMB->TotalParameterCount; 4489 pSMB->ParameterOffset = cpu_to_le16( 4490 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)); 4491 pSMB->DataCount = 0; 4492 pSMB->DataOffset = 0; 4493 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */ 4494 pSMB->Reserved3 = 0; 4495 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST); 4496 pSMB->SearchAttributes = 4497 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 4498 ATTR_DIRECTORY); 4499 pSMB->SearchCount = cpu_to_le16(msearch ? CIFSMaxBufSize/sizeof(FILE_UNIX_INFO) : 1); 4500 pSMB->SearchFlags = cpu_to_le16(search_flags); 4501 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 4502 4503 /* BB what should we set StorageType to? Does it matter? BB */ 4504 pSMB->SearchStorageType = 0; 4505 in_len += byte_count; 4506 pSMB->ByteCount = cpu_to_le16(byte_count); 4507 4508 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 4509 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4510 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst); 4511 4512 if (rc) { 4513 /* 4514 * BB: add logic to retry regular search if Unix search rejected 4515 * unexpectedly by server. 4516 */ 4517 /* BB: add code to handle unsupported level rc */ 4518 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc); 4519 cifs_buf_release(pSMB); 4520 /* 4521 * BB: eventually could optimize out free and realloc of buf for 4522 * this case. 4523 */ 4524 if (rc == -EAGAIN) 4525 goto findFirstRetry; 4526 return rc; 4527 } 4528 /* decode response */ 4529 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4530 if (rc) { 4531 cifs_buf_release(pSMB); 4532 return rc; 4533 } 4534 4535 parm_off = le16_to_cpu(pSMBr->t2.ParameterOffset); 4536 parm_count = le16_to_cpu(pSMBr->t2.ParameterCount); 4537 if (parm_count < sizeof(*parms) || 4538 parm_off + parm_count > (unsigned int)bytes_returned) { 4539 cifs_dbg(FYI, "%s: bad parameter area offset %u count %u for response of %d\n", 4540 __func__, parm_off, parm_count, bytes_returned); 4541 rc = smb_EIO2(smb_eio_trace_ffirst_param_area, 4542 parm_off, parm_count); 4543 cifs_buf_release(pSMB); 4544 return rc; 4545 } 4546 4547 data_off = le16_to_cpu(pSMBr->t2.DataOffset); 4548 data_count = le16_to_cpu(pSMBr->t2.DataCount); 4549 if (data_off + data_count > (unsigned int)bytes_returned) { 4550 cifs_dbg(VFS, "%s: data area offset %u count %u past response length %d\n", 4551 __func__, data_off, data_count, bytes_returned); 4552 cifs_buf_release(pSMB); 4553 return -EINVAL; 4554 } 4555 4556 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE); 4557 psrch_inf->ntwrk_buf_start = (char *)pSMBr; 4558 psrch_inf->smallBuf = false; 4559 psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol + data_off; 4560 4561 parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol + parm_off); 4562 psrch_inf->endOfSearch = !!parms->EndofSearch; 4563 4564 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 4565 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ + 4566 psrch_inf->entries_in_buffer; 4567 psrch_inf->presume_name = NULL; 4568 psrch_inf->resume_name_len = 0; 4569 psrch_inf->resume_key = 0; 4570 if (pnetfid) 4571 *pnetfid = parms->SearchHandle; 4572 lnoff = le16_to_cpu(parms->LastNameOffset); 4573 if (!psrch_inf->entries_in_buffer) { 4574 psrch_inf->last_entry = NULL; 4575 } else if (psrch_inf->srch_entries_start + lnoff >= 4576 psrch_inf->ntwrk_buf_start + bytes_returned) { 4577 cifs_dbg(VFS, "ignoring corrupt resume name\n"); 4578 psrch_inf->last_entry = NULL; 4579 } else { 4580 psrch_inf->last_entry = psrch_inf->srch_entries_start + lnoff; 4581 } 4582 return 0; 4583 } 4584 4585 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon, 4586 __u16 searchHandle, __u16 search_flags, 4587 struct cifs_search_info *psrch_inf) 4588 { 4589 unsigned int parm_off, parm_count, data_off, data_count; 4590 TRANSACTION2_FNEXT_REQ *pSMB = NULL; 4591 TRANSACTION2_FNEXT_RSP *pSMBr = NULL; 4592 unsigned int name_len, in_len; 4593 T2_FNEXT_RSP_PARMS *parms; 4594 unsigned int lnoff; 4595 __u16 params, byte_count; 4596 char *response_data; 4597 int bytes_returned; 4598 int rc = 0; 4599 4600 cifs_dbg(FYI, "In FindNext\n"); 4601 4602 if (psrch_inf->endOfSearch) 4603 return -ENOENT; 4604 4605 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4606 (void **) &pSMBr); 4607 if (rc < 0) 4608 return rc; 4609 in_len = rc; 4610 4611 params = 14; /* includes 2 bytes of null string, converted to LE below*/ 4612 byte_count = 0; 4613 pSMB->TotalDataCount = 0; /* no EAs */ 4614 pSMB->MaxParameterCount = cpu_to_le16(8); 4615 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00); 4616 pSMB->MaxSetupCount = 0; 4617 pSMB->Reserved = 0; 4618 pSMB->Flags = 0; 4619 pSMB->Timeout = 0; 4620 pSMB->Reserved2 = 0; 4621 pSMB->ParameterOffset = cpu_to_le16( 4622 offsetof(struct smb_com_transaction2_fnext_req, SearchHandle)); 4623 pSMB->DataCount = 0; 4624 pSMB->DataOffset = 0; 4625 pSMB->SetupCount = 1; 4626 pSMB->Reserved3 = 0; 4627 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT); 4628 pSMB->SearchHandle = searchHandle; /* always kept as le */ 4629 pSMB->SearchCount = 4630 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO)); 4631 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 4632 pSMB->ResumeKey = psrch_inf->resume_key; 4633 pSMB->SearchFlags = cpu_to_le16(search_flags); 4634 4635 name_len = psrch_inf->resume_name_len; 4636 params += name_len; 4637 if (name_len < PATH_MAX) { 4638 if (name_len) { 4639 memcpy(pSMB->ResumeFileName, 4640 psrch_inf->presume_name, name_len); 4641 } 4642 byte_count += name_len; 4643 /* 14 byte parm len above enough for 2 byte null terminator */ 4644 pSMB->ResumeFileName[name_len] = 0; 4645 pSMB->ResumeFileName[name_len+1] = 0; 4646 } else { 4647 cifs_buf_release(pSMB); 4648 return -EINVAL; 4649 } 4650 byte_count = params + 1 /* pad */ ; 4651 pSMB->TotalParameterCount = cpu_to_le16(params); 4652 pSMB->ParameterCount = pSMB->TotalParameterCount; 4653 in_len += byte_count; 4654 pSMB->ByteCount = cpu_to_le16(byte_count); 4655 4656 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 4657 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4658 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext); 4659 4660 if (rc) { 4661 cifs_buf_release(pSMB); 4662 if (rc == -EBADF) { 4663 psrch_inf->endOfSearch = true; 4664 rc = 0; /* search probably was closed at end of search*/ 4665 } else { 4666 cifs_dbg(FYI, "FindNext returned = %d\n", rc); 4667 } 4668 return rc; 4669 } 4670 4671 /* decode response */ 4672 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4673 if (rc) { 4674 cifs_buf_release(pSMB); 4675 return rc; 4676 } 4677 4678 parm_off = le16_to_cpu(pSMBr->t2.ParameterOffset); 4679 parm_count = le16_to_cpu(pSMBr->t2.ParameterCount); 4680 if (parm_count < sizeof(*parms) || 4681 parm_off + parm_count > (unsigned int)bytes_returned) { 4682 cifs_dbg(FYI, "%s: bad parameter area offset %u count %u for response of %d\n", 4683 __func__, parm_off, parm_count, bytes_returned); 4684 rc = smb_EIO2(smb_eio_trace_fnext_param_area, 4685 parm_off, parm_count); 4686 cifs_buf_release(pSMB); 4687 return rc; 4688 } 4689 4690 data_off = le16_to_cpu(pSMBr->t2.DataOffset); 4691 data_count = le16_to_cpu(pSMBr->t2.DataCount); 4692 if (data_off + data_count > (unsigned int)bytes_returned) { 4693 cifs_dbg(VFS, "%s: data area offset %u count %u past response length %d\n", 4694 __func__, data_off, data_count, bytes_returned); 4695 cifs_buf_release(pSMB); 4696 return -EINVAL; 4697 } 4698 4699 /* BB fixme add lock for file (srch_info) struct here */ 4700 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE); 4701 response_data = (char *)&pSMBr->hdr.Protocol + parm_off; 4702 parms = (T2_FNEXT_RSP_PARMS *)response_data; 4703 response_data = (char *)&pSMBr->hdr.Protocol + data_off; 4704 4705 if (psrch_inf->smallBuf) 4706 cifs_small_buf_release(psrch_inf->ntwrk_buf_start); 4707 else 4708 cifs_buf_release(psrch_inf->ntwrk_buf_start); 4709 4710 psrch_inf->srch_entries_start = response_data; 4711 psrch_inf->ntwrk_buf_start = (char *)pSMB; 4712 psrch_inf->smallBuf = false; 4713 psrch_inf->endOfSearch = !!parms->EndofSearch; 4714 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 4715 psrch_inf->index_of_last_entry += psrch_inf->entries_in_buffer; 4716 psrch_inf->presume_name = NULL; 4717 psrch_inf->resume_name_len = 0; 4718 psrch_inf->resume_key = 0; 4719 lnoff = le16_to_cpu(parms->LastNameOffset); 4720 if (!psrch_inf->entries_in_buffer) { 4721 psrch_inf->last_entry = NULL; 4722 } else if (psrch_inf->srch_entries_start + lnoff >= 4723 psrch_inf->ntwrk_buf_start + bytes_returned) { 4724 cifs_dbg(VFS, "ignoring corrupt resume name\n"); 4725 psrch_inf->last_entry = NULL; 4726 } else { 4727 psrch_inf->last_entry = 4728 psrch_inf->srch_entries_start + lnoff; 4729 } 4730 /* BB fixme add unlock here */ 4731 4732 /* 4733 * BB: On error, should we leave previous search buf 4734 * (and count and last entry fields) intact or free the previous one? 4735 * 4736 * Note: On -EAGAIN error only caller can retry on handle based calls 4737 * since file handle passed in no longer valid. 4738 */ 4739 return 0; 4740 } 4741 4742 int 4743 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon, 4744 const __u16 searchHandle) 4745 { 4746 int rc = 0; 4747 FINDCLOSE_REQ *pSMB = NULL; 4748 unsigned int in_len; 4749 4750 cifs_dbg(FYI, "In CIFSSMBFindClose\n"); 4751 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB); 4752 4753 /* no sense returning error if session restarted 4754 as file handle has been closed */ 4755 if (rc == -EAGAIN) 4756 return 0; 4757 if (rc < 0) 4758 return rc; 4759 in_len = rc; 4760 4761 pSMB->FileID = searchHandle; 4762 pSMB->ByteCount = 0; 4763 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); 4764 cifs_small_buf_release(pSMB); 4765 if (rc) 4766 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc); 4767 4768 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose); 4769 4770 /* Since session is dead, search handle closed on server already */ 4771 if (rc == -EAGAIN) 4772 rc = 0; 4773 4774 return rc; 4775 } 4776 4777 int 4778 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon, 4779 const char *search_name, __u64 *inode_number, 4780 const struct nls_table *nls_codepage, int remap) 4781 { 4782 int rc = 0; 4783 TRANSACTION2_QPI_REQ *pSMB = NULL; 4784 TRANSACTION2_QPI_RSP *pSMBr = NULL; 4785 unsigned int in_len; 4786 int name_len, bytes_returned; 4787 __u16 params, byte_count; 4788 4789 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name); 4790 if (tcon == NULL) 4791 return -ENODEV; 4792 4793 GetInodeNumberRetry: 4794 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4795 (void **) &pSMBr); 4796 if (rc < 0) 4797 return rc; 4798 in_len = rc; 4799 4800 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4801 name_len = 4802 cifsConvertToUTF16((__le16 *) pSMB->FileName, 4803 search_name, PATH_MAX, nls_codepage, 4804 remap); 4805 name_len++; /* trailing null */ 4806 name_len *= 2; 4807 } else { 4808 name_len = copy_path_name(pSMB->FileName, search_name); 4809 } 4810 4811 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 4812 pSMB->TotalDataCount = 0; 4813 pSMB->MaxParameterCount = cpu_to_le16(2); 4814 /* BB find exact max data count below from sess structure BB */ 4815 pSMB->MaxDataCount = cpu_to_le16(4000); 4816 pSMB->MaxSetupCount = 0; 4817 pSMB->Reserved = 0; 4818 pSMB->Flags = 0; 4819 pSMB->Timeout = 0; 4820 pSMB->Reserved2 = 0; 4821 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4822 struct smb_com_transaction2_qpi_req, InformationLevel)); 4823 pSMB->DataCount = 0; 4824 pSMB->DataOffset = 0; 4825 pSMB->SetupCount = 1; 4826 pSMB->Reserved3 = 0; 4827 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 4828 byte_count = params + 1 /* pad */ ; 4829 pSMB->TotalParameterCount = cpu_to_le16(params); 4830 pSMB->ParameterCount = pSMB->TotalParameterCount; 4831 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO); 4832 pSMB->Reserved4 = 0; 4833 in_len += byte_count; 4834 pSMB->ByteCount = cpu_to_le16(byte_count); 4835 4836 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 4837 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4838 if (rc) { 4839 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc); 4840 } else { 4841 /* decode response */ 4842 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4843 /* BB also check enough total bytes returned */ 4844 if (rc || get_bcc(&pSMBr->hdr) < 2) 4845 /* If rc should we check for EOPNOSUPP and 4846 disable the srvino flag? or in caller? */ 4847 rc = smb_EIO2(smb_eio_trace_getsrvinonum_bcc_too_small, 4848 get_bcc(&pSMBr->hdr), 2); 4849 else { 4850 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4851 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 4852 struct file_internal_info *pfinfo; 4853 /* BB Do we need a cast or hash here ? */ 4854 if (count < 8) { 4855 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n"); 4856 rc = smb_EIO2(smb_eio_trace_getsrvinonum_size, 4857 count, 8); 4858 goto GetInodeNumOut; 4859 } 4860 pfinfo = (struct file_internal_info *) 4861 (data_offset + (char *) &pSMBr->hdr.Protocol); 4862 *inode_number = le64_to_cpu(pfinfo->UniqueId); 4863 } 4864 } 4865 GetInodeNumOut: 4866 cifs_buf_release(pSMB); 4867 if (rc == -EAGAIN) 4868 goto GetInodeNumberRetry; 4869 return rc; 4870 } 4871 4872 int 4873 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses, 4874 const char *search_name, struct dfs_info3_param **target_nodes, 4875 unsigned int *num_of_nodes, 4876 const struct nls_table *nls_codepage, int remap) 4877 { 4878 /* TRANS2_GET_DFS_REFERRAL */ 4879 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL; 4880 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL; 4881 unsigned int in_len; 4882 int rc = 0; 4883 int bytes_returned; 4884 int name_len; 4885 __u16 params, byte_count; 4886 *num_of_nodes = 0; 4887 *target_nodes = NULL; 4888 4889 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name); 4890 if (ses == NULL || ses->tcon_ipc == NULL) 4891 return -ENODEV; 4892 4893 getDFSRetry: 4894 /* 4895 * Use smb_init_no_reconnect() instead of smb_init() as 4896 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus 4897 * causing an infinite recursion. 4898 */ 4899 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, 4900 (void **)&pSMB, (void **)&pSMBr); 4901 if (rc < 0) 4902 return rc; 4903 in_len = rc; 4904 4905 /* server pointer checked in called function, 4906 but should never be null here anyway */ 4907 pSMB->hdr.Mid = get_next_mid(ses->server); 4908 pSMB->hdr.Tid = ses->tcon_ipc->tid; 4909 pSMB->hdr.Uid = ses->Suid; 4910 if (ses->capabilities & CAP_STATUS32) 4911 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS; 4912 if (ses->capabilities & CAP_DFS) 4913 pSMB->hdr.Flags2 |= SMBFLG2_DFS; 4914 4915 if (ses->capabilities & CAP_UNICODE) { 4916 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 4917 name_len = 4918 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName, 4919 search_name, PATH_MAX, nls_codepage, 4920 remap); 4921 name_len++; /* trailing null */ 4922 name_len *= 2; 4923 } else { /* BB improve the check for buffer overruns BB */ 4924 name_len = copy_path_name(pSMB->RequestFileName, search_name); 4925 } 4926 4927 if (ses->server->sign) 4928 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 4929 4930 pSMB->hdr.Uid = ses->Suid; 4931 4932 params = 2 /* level */ + name_len /*includes null */ ; 4933 pSMB->TotalDataCount = 0; 4934 pSMB->DataCount = 0; 4935 pSMB->DataOffset = 0; 4936 pSMB->MaxParameterCount = 0; 4937 /* BB find exact max SMB PDU from sess structure BB */ 4938 pSMB->MaxDataCount = cpu_to_le16(4000); 4939 pSMB->MaxSetupCount = 0; 4940 pSMB->Reserved = 0; 4941 pSMB->Flags = 0; 4942 pSMB->Timeout = 0; 4943 pSMB->Reserved2 = 0; 4944 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4945 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel)); 4946 pSMB->SetupCount = 1; 4947 pSMB->Reserved3 = 0; 4948 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL); 4949 byte_count = params + 3 /* pad */ ; 4950 pSMB->ParameterCount = cpu_to_le16(params); 4951 pSMB->TotalParameterCount = pSMB->ParameterCount; 4952 pSMB->MaxReferralLevel = cpu_to_le16(3); 4953 in_len += byte_count; 4954 pSMB->ByteCount = cpu_to_le16(byte_count); 4955 4956 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, in_len, 4957 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4958 if (rc) { 4959 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc); 4960 goto GetDFSRefExit; 4961 } 4962 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4963 4964 /* BB Also check if enough total bytes returned? */ 4965 if (rc || get_bcc(&pSMBr->hdr) < 17) { 4966 rc = smb_EIO2(smb_eio_trace_getdfsrefer_bcc_too_small, 4967 get_bcc(&pSMBr->hdr), 17); 4968 goto GetDFSRefExit; 4969 } 4970 4971 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n", 4972 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset)); 4973 4974 /* parse returned result into more usable form */ 4975 rc = parse_dfs_referrals(&pSMBr->dfs_data, 4976 le16_to_cpu(pSMBr->t2.DataCount), 4977 num_of_nodes, target_nodes, nls_codepage, 4978 remap, search_name, 4979 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0); 4980 4981 GetDFSRefExit: 4982 cifs_buf_release(pSMB); 4983 4984 if (rc == -EAGAIN) 4985 goto getDFSRetry; 4986 4987 return rc; 4988 } 4989 4990 /* Query File System Info such as free space to old servers such as Win 9x */ 4991 int 4992 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, 4993 struct kstatfs *FSData) 4994 { 4995 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */ 4996 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4997 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4998 FILE_SYSTEM_ALLOC_INFO *response_data; 4999 unsigned int in_len; 5000 int rc = 0; 5001 int bytes_returned = 0; 5002 __u16 params, byte_count; 5003 5004 cifs_dbg(FYI, "OldQFSInfo\n"); 5005 oldQFSInfoRetry: 5006 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5007 (void **) &pSMBr); 5008 if (rc < 0) 5009 return rc; 5010 in_len = rc; 5011 5012 params = 2; /* level */ 5013 pSMB->TotalDataCount = 0; 5014 pSMB->MaxParameterCount = cpu_to_le16(2); 5015 pSMB->MaxDataCount = cpu_to_le16(1000); 5016 pSMB->MaxSetupCount = 0; 5017 pSMB->Reserved = 0; 5018 pSMB->Flags = 0; 5019 pSMB->Timeout = 0; 5020 pSMB->Reserved2 = 0; 5021 byte_count = params + 1 /* pad */ ; 5022 pSMB->TotalParameterCount = cpu_to_le16(params); 5023 pSMB->ParameterCount = pSMB->TotalParameterCount; 5024 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5025 struct smb_com_transaction2_qfsi_req, InformationLevel)); 5026 pSMB->DataCount = 0; 5027 pSMB->DataOffset = 0; 5028 pSMB->SetupCount = 1; 5029 pSMB->Reserved3 = 0; 5030 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5031 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION); 5032 in_len += byte_count; 5033 pSMB->ByteCount = cpu_to_le16(byte_count); 5034 5035 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 5036 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5037 if (rc) { 5038 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc); 5039 } else { /* decode response */ 5040 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5041 5042 if (rc || get_bcc(&pSMBr->hdr) < 18) 5043 rc = smb_EIO2(smb_eio_trace_oldqfsinfo_bcc_too_small, 5044 get_bcc(&pSMBr->hdr), 18); 5045 else { 5046 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5047 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n", 5048 get_bcc(&pSMBr->hdr), data_offset); 5049 5050 response_data = (FILE_SYSTEM_ALLOC_INFO *) 5051 (((char *) &pSMBr->hdr.Protocol) + data_offset); 5052 FSData->f_bsize = 5053 le16_to_cpu(response_data->BytesPerSector) * 5054 le32_to_cpu(response_data-> 5055 SectorsPerAllocationUnit); 5056 /* 5057 * much prefer larger but if server doesn't report 5058 * a valid size than 4K is a reasonable minimum 5059 */ 5060 if (FSData->f_bsize < 512) 5061 FSData->f_bsize = 4096; 5062 5063 FSData->f_blocks = 5064 le32_to_cpu(response_data->TotalAllocationUnits); 5065 FSData->f_bfree = FSData->f_bavail = 5066 le32_to_cpu(response_data->FreeAllocationUnits); 5067 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n", 5068 (unsigned long long)FSData->f_blocks, 5069 (unsigned long long)FSData->f_bfree, 5070 FSData->f_bsize); 5071 } 5072 } 5073 cifs_buf_release(pSMB); 5074 5075 if (rc == -EAGAIN) 5076 goto oldQFSInfoRetry; 5077 5078 return rc; 5079 } 5080 5081 int 5082 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, 5083 struct kstatfs *FSData) 5084 { 5085 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */ 5086 TRANSACTION2_QFSI_REQ *pSMB = NULL; 5087 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 5088 FILE_SYSTEM_SIZE_INFO *response_data; 5089 unsigned int in_len; 5090 int rc = 0; 5091 int bytes_returned = 0; 5092 __u16 params, byte_count; 5093 5094 cifs_dbg(FYI, "In QFSInfo\n"); 5095 QFSInfoRetry: 5096 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5097 (void **) &pSMBr); 5098 if (rc < 0) 5099 return rc; 5100 in_len = rc; 5101 5102 params = 2; /* level */ 5103 pSMB->TotalDataCount = 0; 5104 pSMB->MaxParameterCount = cpu_to_le16(2); 5105 pSMB->MaxDataCount = cpu_to_le16(1000); 5106 pSMB->MaxSetupCount = 0; 5107 pSMB->Reserved = 0; 5108 pSMB->Flags = 0; 5109 pSMB->Timeout = 0; 5110 pSMB->Reserved2 = 0; 5111 byte_count = params + 1 /* pad */ ; 5112 pSMB->TotalParameterCount = cpu_to_le16(params); 5113 pSMB->ParameterCount = pSMB->TotalParameterCount; 5114 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5115 struct smb_com_transaction2_qfsi_req, InformationLevel)); 5116 pSMB->DataCount = 0; 5117 pSMB->DataOffset = 0; 5118 pSMB->SetupCount = 1; 5119 pSMB->Reserved3 = 0; 5120 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5121 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO); 5122 in_len += byte_count; 5123 pSMB->ByteCount = cpu_to_le16(byte_count); 5124 5125 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 5126 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5127 if (rc) { 5128 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc); 5129 } else { /* decode response */ 5130 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5131 5132 if (rc || get_bcc(&pSMBr->hdr) < 24) 5133 rc = smb_EIO2(smb_eio_trace_qfsinfo_bcc_too_small, 5134 get_bcc(&pSMBr->hdr), 24); 5135 else { 5136 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5137 5138 response_data = 5139 (FILE_SYSTEM_SIZE_INFO 5140 *) (((char *) &pSMBr->hdr.Protocol) + 5141 data_offset); 5142 FSData->f_bsize = 5143 le32_to_cpu(response_data->BytesPerSector) * 5144 le32_to_cpu(response_data-> 5145 SectorsPerAllocationUnit); 5146 /* 5147 * much prefer larger but if server doesn't report 5148 * a valid size than 4K is a reasonable minimum 5149 */ 5150 if (FSData->f_bsize < 512) 5151 FSData->f_bsize = 4096; 5152 5153 FSData->f_blocks = 5154 le64_to_cpu(response_data->TotalAllocationUnits); 5155 FSData->f_bfree = FSData->f_bavail = 5156 le64_to_cpu(response_data->AvailableAllocationUnits); 5157 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n", 5158 (unsigned long long)FSData->f_blocks, 5159 (unsigned long long)FSData->f_bfree, 5160 FSData->f_bsize); 5161 } 5162 } 5163 cifs_buf_release(pSMB); 5164 5165 if (rc == -EAGAIN) 5166 goto QFSInfoRetry; 5167 5168 return rc; 5169 } 5170 5171 int 5172 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon) 5173 { 5174 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */ 5175 TRANSACTION2_QFSI_REQ *pSMB = NULL; 5176 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 5177 FILE_SYSTEM_ATTRIBUTE_INFO *response_data; 5178 unsigned int in_len; 5179 int rc = 0; 5180 int bytes_returned = 0; 5181 __u16 params, byte_count; 5182 5183 cifs_dbg(FYI, "In QFSAttributeInfo\n"); 5184 QFSAttributeRetry: 5185 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5186 (void **) &pSMBr); 5187 if (rc < 0) 5188 return rc; 5189 in_len = rc; 5190 5191 params = 2; /* level */ 5192 pSMB->TotalDataCount = 0; 5193 pSMB->MaxParameterCount = cpu_to_le16(2); 5194 /* BB find exact max SMB PDU from sess structure BB */ 5195 pSMB->MaxDataCount = cpu_to_le16(1000); 5196 pSMB->MaxSetupCount = 0; 5197 pSMB->Reserved = 0; 5198 pSMB->Flags = 0; 5199 pSMB->Timeout = 0; 5200 pSMB->Reserved2 = 0; 5201 byte_count = params + 1 /* pad */ ; 5202 pSMB->TotalParameterCount = cpu_to_le16(params); 5203 pSMB->ParameterCount = pSMB->TotalParameterCount; 5204 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5205 struct smb_com_transaction2_qfsi_req, InformationLevel)); 5206 pSMB->DataCount = 0; 5207 pSMB->DataOffset = 0; 5208 pSMB->SetupCount = 1; 5209 pSMB->Reserved3 = 0; 5210 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5211 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO); 5212 in_len += byte_count; 5213 pSMB->ByteCount = cpu_to_le16(byte_count); 5214 5215 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 5216 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5217 if (rc) { 5218 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc); 5219 } else { /* decode response */ 5220 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5221 5222 if (rc || get_bcc(&pSMBr->hdr) < 13) { 5223 /* BB also check if enough bytes returned */ 5224 rc = smb_EIO2(smb_eio_trace_qfsattrinfo_bcc_too_small, 5225 get_bcc(&pSMBr->hdr), 13); 5226 } else { 5227 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5228 response_data = 5229 (FILE_SYSTEM_ATTRIBUTE_INFO 5230 *) (((char *) &pSMBr->hdr.Protocol) + 5231 data_offset); 5232 memcpy(&tcon->fsAttrInfo, response_data, 5233 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO)); 5234 } 5235 } 5236 cifs_buf_release(pSMB); 5237 5238 if (rc == -EAGAIN) 5239 goto QFSAttributeRetry; 5240 5241 return rc; 5242 } 5243 5244 int 5245 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon) 5246 { 5247 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */ 5248 TRANSACTION2_QFSI_REQ *pSMB = NULL; 5249 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 5250 FILE_SYSTEM_DEVICE_INFO *response_data; 5251 unsigned int in_len; 5252 int rc = 0; 5253 int bytes_returned = 0; 5254 __u16 params, byte_count; 5255 5256 cifs_dbg(FYI, "In QFSDeviceInfo\n"); 5257 QFSDeviceRetry: 5258 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5259 (void **) &pSMBr); 5260 if (rc < 0) 5261 return rc; 5262 in_len = rc; 5263 5264 params = 2; /* level */ 5265 pSMB->TotalDataCount = 0; 5266 pSMB->MaxParameterCount = cpu_to_le16(2); 5267 /* BB find exact max SMB PDU from sess structure BB */ 5268 pSMB->MaxDataCount = cpu_to_le16(1000); 5269 pSMB->MaxSetupCount = 0; 5270 pSMB->Reserved = 0; 5271 pSMB->Flags = 0; 5272 pSMB->Timeout = 0; 5273 pSMB->Reserved2 = 0; 5274 byte_count = params + 1 /* pad */ ; 5275 pSMB->TotalParameterCount = cpu_to_le16(params); 5276 pSMB->ParameterCount = pSMB->TotalParameterCount; 5277 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5278 struct smb_com_transaction2_qfsi_req, InformationLevel)); 5279 5280 pSMB->DataCount = 0; 5281 pSMB->DataOffset = 0; 5282 pSMB->SetupCount = 1; 5283 pSMB->Reserved3 = 0; 5284 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5285 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO); 5286 in_len += byte_count; 5287 pSMB->ByteCount = cpu_to_le16(byte_count); 5288 5289 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 5290 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5291 if (rc) { 5292 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc); 5293 } else { /* decode response */ 5294 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5295 5296 if (rc || get_bcc(&pSMBr->hdr) < 5297 sizeof(FILE_SYSTEM_DEVICE_INFO)) 5298 rc = smb_EIO2(smb_eio_trace_qfsdevinfo_bcc_too_small, 5299 get_bcc(&pSMBr->hdr), 5300 sizeof(FILE_SYSTEM_DEVICE_INFO)); 5301 else { 5302 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5303 response_data = 5304 (FILE_SYSTEM_DEVICE_INFO *) 5305 (((char *) &pSMBr->hdr.Protocol) + 5306 data_offset); 5307 memcpy(&tcon->fsDevInfo, response_data, 5308 sizeof(FILE_SYSTEM_DEVICE_INFO)); 5309 } 5310 } 5311 cifs_buf_release(pSMB); 5312 5313 if (rc == -EAGAIN) 5314 goto QFSDeviceRetry; 5315 5316 return rc; 5317 } 5318 5319 int 5320 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon) 5321 { 5322 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */ 5323 TRANSACTION2_QFSI_REQ *pSMB = NULL; 5324 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 5325 FILE_SYSTEM_UNIX_INFO *response_data; 5326 unsigned int in_len; 5327 int rc = 0; 5328 int bytes_returned = 0; 5329 __u16 params, byte_count; 5330 5331 cifs_dbg(FYI, "In QFSUnixInfo\n"); 5332 QFSUnixRetry: 5333 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, 5334 (void **) &pSMB, (void **) &pSMBr); 5335 if (rc < 0) 5336 return rc; 5337 in_len = rc; 5338 5339 params = 2; /* level */ 5340 pSMB->TotalDataCount = 0; 5341 pSMB->DataCount = 0; 5342 pSMB->DataOffset = 0; 5343 pSMB->MaxParameterCount = cpu_to_le16(2); 5344 /* BB find exact max SMB PDU from sess structure BB */ 5345 pSMB->MaxDataCount = cpu_to_le16(100); 5346 pSMB->MaxSetupCount = 0; 5347 pSMB->Reserved = 0; 5348 pSMB->Flags = 0; 5349 pSMB->Timeout = 0; 5350 pSMB->Reserved2 = 0; 5351 byte_count = params + 1 /* pad */ ; 5352 pSMB->ParameterCount = cpu_to_le16(params); 5353 pSMB->TotalParameterCount = pSMB->ParameterCount; 5354 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 5355 smb_com_transaction2_qfsi_req, InformationLevel)); 5356 pSMB->SetupCount = 1; 5357 pSMB->Reserved3 = 0; 5358 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5359 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO); 5360 in_len += byte_count; 5361 pSMB->ByteCount = cpu_to_le16(byte_count); 5362 5363 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 5364 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5365 if (rc) { 5366 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc); 5367 } else { /* decode response */ 5368 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5369 5370 if (rc || get_bcc(&pSMBr->hdr) < 13) { 5371 rc = smb_EIO2(smb_eio_trace_qfsunixinfo_bcc_too_small, 5372 get_bcc(&pSMBr->hdr), 13); 5373 } else { 5374 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5375 response_data = 5376 (FILE_SYSTEM_UNIX_INFO 5377 *) (((char *) &pSMBr->hdr.Protocol) + 5378 data_offset); 5379 memcpy(&tcon->fsUnixInfo, response_data, 5380 sizeof(FILE_SYSTEM_UNIX_INFO)); 5381 } 5382 } 5383 cifs_buf_release(pSMB); 5384 5385 if (rc == -EAGAIN) 5386 goto QFSUnixRetry; 5387 5388 5389 return rc; 5390 } 5391 5392 int 5393 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap) 5394 { 5395 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */ 5396 TRANSACTION2_SETFSI_REQ *pSMB = NULL; 5397 TRANSACTION2_SETFSI_RSP *pSMBr = NULL; 5398 unsigned int in_len; 5399 int rc = 0; 5400 int bytes_returned = 0; 5401 __u16 params, param_offset, offset, byte_count; 5402 5403 cifs_dbg(FYI, "In SETFSUnixInfo\n"); 5404 SETFSUnixRetry: 5405 /* BB switch to small buf init to save memory */ 5406 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, 5407 (void **) &pSMB, (void **) &pSMBr); 5408 if (rc < 0) 5409 return rc; 5410 in_len = rc; 5411 5412 params = 4; /* 2 bytes zero followed by info level. */ 5413 pSMB->MaxSetupCount = 0; 5414 pSMB->Reserved = 0; 5415 pSMB->Flags = 0; 5416 pSMB->Timeout = 0; 5417 pSMB->Reserved2 = 0; 5418 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum); 5419 offset = param_offset + params; 5420 5421 pSMB->MaxParameterCount = cpu_to_le16(4); 5422 /* BB find exact max SMB PDU from sess structure BB */ 5423 pSMB->MaxDataCount = cpu_to_le16(100); 5424 pSMB->SetupCount = 1; 5425 pSMB->Reserved3 = 0; 5426 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION); 5427 byte_count = 1 /* pad */ + params + 12; 5428 5429 pSMB->DataCount = cpu_to_le16(12); 5430 pSMB->ParameterCount = cpu_to_le16(params); 5431 pSMB->TotalDataCount = pSMB->DataCount; 5432 pSMB->TotalParameterCount = pSMB->ParameterCount; 5433 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5434 pSMB->DataOffset = cpu_to_le16(offset); 5435 5436 /* Params. */ 5437 pSMB->FileNum = 0; 5438 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO); 5439 5440 /* Data. */ 5441 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION); 5442 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION); 5443 pSMB->ClientUnixCap = cpu_to_le64(cap); 5444 5445 in_len += byte_count; 5446 pSMB->ByteCount = cpu_to_le16(byte_count); 5447 5448 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 5449 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5450 if (rc) { 5451 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc); 5452 } else { /* decode response */ 5453 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5454 if (rc) 5455 rc = -EIO; /* bad smb */ 5456 } 5457 cifs_buf_release(pSMB); 5458 5459 if (rc == -EAGAIN) 5460 goto SETFSUnixRetry; 5461 5462 return rc; 5463 } 5464 5465 5466 5467 int 5468 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon, 5469 struct kstatfs *FSData) 5470 { 5471 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */ 5472 TRANSACTION2_QFSI_REQ *pSMB = NULL; 5473 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 5474 FILE_SYSTEM_POSIX_INFO *response_data; 5475 unsigned int in_len; 5476 int rc = 0; 5477 int bytes_returned = 0; 5478 __u16 params, byte_count; 5479 5480 cifs_dbg(FYI, "In QFSPosixInfo\n"); 5481 QFSPosixRetry: 5482 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5483 (void **) &pSMBr); 5484 if (rc < 0) 5485 return rc; 5486 in_len = rc; 5487 5488 params = 2; /* level */ 5489 pSMB->TotalDataCount = 0; 5490 pSMB->DataCount = 0; 5491 pSMB->DataOffset = 0; 5492 pSMB->MaxParameterCount = cpu_to_le16(2); 5493 /* BB find exact max SMB PDU from sess structure BB */ 5494 pSMB->MaxDataCount = cpu_to_le16(100); 5495 pSMB->MaxSetupCount = 0; 5496 pSMB->Reserved = 0; 5497 pSMB->Flags = 0; 5498 pSMB->Timeout = 0; 5499 pSMB->Reserved2 = 0; 5500 byte_count = params + 1 /* pad */ ; 5501 pSMB->ParameterCount = cpu_to_le16(params); 5502 pSMB->TotalParameterCount = pSMB->ParameterCount; 5503 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 5504 smb_com_transaction2_qfsi_req, InformationLevel)); 5505 pSMB->SetupCount = 1; 5506 pSMB->Reserved3 = 0; 5507 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5508 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO); 5509 in_len += byte_count; 5510 pSMB->ByteCount = cpu_to_le16(byte_count); 5511 5512 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 5513 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5514 if (rc) { 5515 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc); 5516 } else { /* decode response */ 5517 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5518 5519 if (rc || get_bcc(&pSMBr->hdr) < 13) { 5520 rc = smb_EIO2(smb_eio_trace_qfsposixinfo_bcc_too_small, 5521 get_bcc(&pSMBr->hdr), 13); 5522 } else { 5523 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5524 response_data = 5525 (FILE_SYSTEM_POSIX_INFO 5526 *) (((char *) &pSMBr->hdr.Protocol) + 5527 data_offset); 5528 FSData->f_bsize = 5529 le32_to_cpu(response_data->BlockSize); 5530 /* 5531 * much prefer larger but if server doesn't report 5532 * a valid size than 4K is a reasonable minimum 5533 */ 5534 if (FSData->f_bsize < 512) 5535 FSData->f_bsize = 4096; 5536 5537 FSData->f_blocks = 5538 le64_to_cpu(response_data->TotalBlocks); 5539 FSData->f_bfree = 5540 le64_to_cpu(response_data->BlocksAvail); 5541 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) { 5542 FSData->f_bavail = FSData->f_bfree; 5543 } else { 5544 FSData->f_bavail = 5545 le64_to_cpu(response_data->UserBlocksAvail); 5546 } 5547 if (response_data->TotalFileNodes != cpu_to_le64(-1)) 5548 FSData->f_files = 5549 le64_to_cpu(response_data->TotalFileNodes); 5550 if (response_data->FreeFileNodes != cpu_to_le64(-1)) 5551 FSData->f_ffree = 5552 le64_to_cpu(response_data->FreeFileNodes); 5553 } 5554 } 5555 cifs_buf_release(pSMB); 5556 5557 if (rc == -EAGAIN) 5558 goto QFSPosixRetry; 5559 5560 return rc; 5561 } 5562 5563 5564 /* 5565 * We can not use write of zero bytes trick to set file size due to need for 5566 * large file support. Also note that this SetPathInfo is preferred to 5567 * SetFileInfo based method in next routine which is only needed to work around 5568 * a sharing violation bugin Samba which this routine can run into. 5569 */ 5570 int 5571 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon, 5572 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb, 5573 bool set_allocation, struct dentry *dentry) 5574 { 5575 struct smb_com_transaction2_spi_req *pSMB = NULL; 5576 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 5577 struct file_end_of_file_info *parm_data; 5578 unsigned int in_len; 5579 int name_len; 5580 int rc = 0; 5581 int bytes_returned = 0; 5582 int remap = cifs_remap(cifs_sb); 5583 5584 __u16 params, byte_count, data_count, param_offset, offset; 5585 5586 cifs_dbg(FYI, "In SetEOF\n"); 5587 SetEOFRetry: 5588 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5589 (void **) &pSMBr); 5590 if (rc < 0) 5591 return rc; 5592 in_len = rc; 5593 5594 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5595 name_len = 5596 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name, 5597 PATH_MAX, cifs_sb->local_nls, remap); 5598 name_len++; /* trailing null */ 5599 name_len *= 2; 5600 } else { 5601 name_len = copy_path_name(pSMB->FileName, file_name); 5602 } 5603 params = 6 + name_len; 5604 data_count = sizeof(struct file_end_of_file_info); 5605 pSMB->MaxParameterCount = cpu_to_le16(2); 5606 pSMB->MaxDataCount = cpu_to_le16(4100); 5607 pSMB->MaxSetupCount = 0; 5608 pSMB->Reserved = 0; 5609 pSMB->Flags = 0; 5610 pSMB->Timeout = 0; 5611 pSMB->Reserved2 = 0; 5612 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5613 InformationLevel); 5614 offset = param_offset + params; 5615 if (set_allocation) { 5616 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5617 pSMB->InformationLevel = 5618 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5619 else 5620 pSMB->InformationLevel = 5621 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 5622 } else /* Set File Size */ { 5623 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5624 pSMB->InformationLevel = 5625 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 5626 else 5627 pSMB->InformationLevel = 5628 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 5629 } 5630 5631 parm_data = 5632 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) + 5633 offset); 5634 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5635 pSMB->DataOffset = cpu_to_le16(offset); 5636 pSMB->SetupCount = 1; 5637 pSMB->Reserved3 = 0; 5638 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5639 byte_count = 3 /* pad */ + params + data_count; 5640 pSMB->DataCount = cpu_to_le16(data_count); 5641 pSMB->TotalDataCount = pSMB->DataCount; 5642 pSMB->ParameterCount = cpu_to_le16(params); 5643 pSMB->TotalParameterCount = pSMB->ParameterCount; 5644 pSMB->Reserved4 = 0; 5645 in_len += byte_count; 5646 parm_data->FileSize = cpu_to_le64(size); 5647 pSMB->ByteCount = cpu_to_le16(byte_count); 5648 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 5649 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5650 if (rc) 5651 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc); 5652 5653 cifs_buf_release(pSMB); 5654 5655 if (rc == -EAGAIN) 5656 goto SetEOFRetry; 5657 5658 return rc; 5659 } 5660 5661 int 5662 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, 5663 struct cifsFileInfo *cfile, __u64 size, bool set_allocation) 5664 { 5665 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5666 struct file_end_of_file_info *parm_data; 5667 unsigned int in_len; 5668 int rc = 0; 5669 __u16 params, param_offset, offset, byte_count, count; 5670 5671 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n", 5672 (long long)size); 5673 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5674 if (rc < 0) 5675 return rc; 5676 in_len = rc; 5677 5678 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid); 5679 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16)); 5680 5681 params = 6; 5682 pSMB->MaxSetupCount = 0; 5683 pSMB->Reserved = 0; 5684 pSMB->Flags = 0; 5685 pSMB->Timeout = 0; 5686 pSMB->Reserved2 = 0; 5687 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid); 5688 offset = param_offset + params; 5689 5690 count = sizeof(struct file_end_of_file_info); 5691 pSMB->MaxParameterCount = cpu_to_le16(2); 5692 /* BB find exact max SMB PDU from sess structure BB */ 5693 pSMB->MaxDataCount = cpu_to_le16(1000); 5694 pSMB->SetupCount = 1; 5695 pSMB->Reserved3 = 0; 5696 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5697 byte_count = 3 /* pad */ + params + count; 5698 pSMB->DataCount = cpu_to_le16(count); 5699 pSMB->ParameterCount = cpu_to_le16(params); 5700 pSMB->TotalDataCount = pSMB->DataCount; 5701 pSMB->TotalParameterCount = pSMB->ParameterCount; 5702 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5703 parm_data = 5704 (struct file_end_of_file_info *)(((char *)pSMB) + offset); 5705 pSMB->DataOffset = cpu_to_le16(offset); 5706 parm_data->FileSize = cpu_to_le64(size); 5707 pSMB->Fid = cfile->fid.netfid; 5708 if (set_allocation) { 5709 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5710 pSMB->InformationLevel = 5711 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5712 else 5713 pSMB->InformationLevel = 5714 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 5715 } else /* Set File Size */ { 5716 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5717 pSMB->InformationLevel = 5718 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 5719 else 5720 pSMB->InformationLevel = 5721 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 5722 } 5723 pSMB->Reserved4 = 0; 5724 in_len += byte_count; 5725 pSMB->ByteCount = cpu_to_le16(byte_count); 5726 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); 5727 cifs_small_buf_release(pSMB); 5728 if (rc) { 5729 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n", 5730 rc); 5731 } 5732 5733 /* Note: On -EAGAIN error only caller can retry on handle based calls 5734 since file handle passed in no longer valid */ 5735 5736 return rc; 5737 } 5738 5739 int SMBSetInformation(const unsigned int xid, struct cifs_tcon *tcon, 5740 const char *fileName, __le32 attributes, 5741 __le64 write_time, struct cifs_sb_info *cifs_sb) 5742 { 5743 SETATTR_REQ *pSMB; 5744 SETATTR_RSP *pSMBr; 5745 struct timespec64 ts; 5746 unsigned int in_len; 5747 int bytes_returned; 5748 int name_len; 5749 int rc; 5750 5751 cifs_dbg(FYI, "In %s path %s\n", __func__, fileName); 5752 5753 retry: 5754 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB, 5755 (void **) &pSMBr); 5756 if (rc < 0) 5757 return rc; 5758 in_len = rc; 5759 5760 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5761 name_len = 5762 cifsConvertToUTF16((__le16 *) pSMB->fileName, 5763 fileName, PATH_MAX, 5764 tcon->ses->local_nls, 5765 cifs_remap(cifs_sb)); 5766 name_len++; /* trailing null */ 5767 name_len *= 2; 5768 } else { 5769 name_len = copy_path_name(pSMB->fileName, fileName); 5770 } 5771 /* Only few attributes can be set by this command, others are not accepted by Win9x. */ 5772 pSMB->attr = cpu_to_le16(le32_to_cpu(attributes) & 5773 (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE)); 5774 /* Zero write time value (in both NT and SETATTR formats) means to not change it. */ 5775 if (le64_to_cpu(write_time) != 0) { 5776 ts = cifs_NTtimeToUnix(write_time); 5777 pSMB->last_write_time = cpu_to_le32(ts.tv_sec); 5778 } 5779 pSMB->BufferFormat = 0x04; 5780 name_len++; /* account for buffer type byte */ 5781 in_len += name_len; 5782 pSMB->ByteCount = cpu_to_le16(name_len); 5783 5784 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 5785 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5786 if (rc) 5787 cifs_dbg(FYI, "Send error in %s = %d\n", __func__, rc); 5788 5789 cifs_buf_release(pSMB); 5790 5791 if (rc == -EAGAIN) 5792 goto retry; 5793 5794 return rc; 5795 } 5796 5797 /* Some legacy servers such as NT4 require that the file times be set on 5798 an open handle, rather than by pathname - this is awkward due to 5799 potential access conflicts on the open, but it is unavoidable for these 5800 old servers since the only other choice is to go from 100 nanosecond DCE 5801 time and resort to the original setpathinfo level which takes the ancient 5802 DOS time format with 2 second granularity */ 5803 int 5804 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 5805 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener) 5806 { 5807 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5808 unsigned int in_len; 5809 char *data_offset; 5810 int rc = 0; 5811 __u16 params, param_offset, offset, byte_count, count; 5812 5813 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n"); 5814 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5815 if (rc < 0) 5816 return rc; 5817 in_len = rc; 5818 5819 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5820 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5821 5822 params = 6; 5823 pSMB->MaxSetupCount = 0; 5824 pSMB->Reserved = 0; 5825 pSMB->Flags = 0; 5826 pSMB->Timeout = 0; 5827 pSMB->Reserved2 = 0; 5828 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid); 5829 offset = param_offset + params; 5830 5831 data_offset = (char *)pSMB + offset; 5832 5833 count = sizeof(FILE_BASIC_INFO); 5834 pSMB->MaxParameterCount = cpu_to_le16(2); 5835 /* BB find max SMB PDU from sess */ 5836 pSMB->MaxDataCount = cpu_to_le16(1000); 5837 pSMB->SetupCount = 1; 5838 pSMB->Reserved3 = 0; 5839 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5840 byte_count = 3 /* pad */ + params + count; 5841 pSMB->DataCount = cpu_to_le16(count); 5842 pSMB->ParameterCount = cpu_to_le16(params); 5843 pSMB->TotalDataCount = pSMB->DataCount; 5844 pSMB->TotalParameterCount = pSMB->ParameterCount; 5845 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5846 pSMB->DataOffset = cpu_to_le16(offset); 5847 pSMB->Fid = fid; 5848 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5849 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2); 5850 else 5851 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5852 pSMB->Reserved4 = 0; 5853 in_len += byte_count; 5854 pSMB->ByteCount = cpu_to_le16(byte_count); 5855 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5856 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); 5857 cifs_small_buf_release(pSMB); 5858 if (rc) 5859 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n", 5860 rc); 5861 5862 /* Note: On -EAGAIN error only caller can retry on handle based calls 5863 since file handle passed in no longer valid */ 5864 5865 return rc; 5866 } 5867 5868 int 5869 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon, 5870 bool delete_file, __u16 fid, __u32 pid_of_opener) 5871 { 5872 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5873 unsigned int in_len; 5874 char *data_offset; 5875 int rc = 0; 5876 __u16 params, param_offset, offset, byte_count, count; 5877 5878 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n"); 5879 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5880 if (rc < 0) 5881 return rc; 5882 in_len = rc; 5883 5884 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5885 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5886 5887 params = 6; 5888 pSMB->MaxSetupCount = 0; 5889 pSMB->Reserved = 0; 5890 pSMB->Flags = 0; 5891 pSMB->Timeout = 0; 5892 pSMB->Reserved2 = 0; 5893 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid); 5894 offset = param_offset + params; 5895 data_offset = (char *)(pSMB) + offset; 5896 5897 count = 1; 5898 pSMB->MaxParameterCount = cpu_to_le16(2); 5899 /* BB find max SMB PDU from sess */ 5900 pSMB->MaxDataCount = cpu_to_le16(1000); 5901 pSMB->SetupCount = 1; 5902 pSMB->Reserved3 = 0; 5903 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5904 byte_count = 3 /* pad */ + params + count; 5905 pSMB->DataCount = cpu_to_le16(count); 5906 pSMB->ParameterCount = cpu_to_le16(params); 5907 pSMB->TotalDataCount = pSMB->DataCount; 5908 pSMB->TotalParameterCount = pSMB->ParameterCount; 5909 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5910 pSMB->DataOffset = cpu_to_le16(offset); 5911 pSMB->Fid = fid; 5912 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO); 5913 pSMB->Reserved4 = 0; 5914 in_len += byte_count; 5915 pSMB->ByteCount = cpu_to_le16(byte_count); 5916 *data_offset = delete_file ? 1 : 0; 5917 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); 5918 cifs_small_buf_release(pSMB); 5919 if (rc) 5920 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc); 5921 5922 return rc; 5923 } 5924 5925 int CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 5926 const char *fileName, const FILE_BASIC_INFO *data, 5927 struct cifs_sb_info *cifs_sb) 5928 { 5929 TRANSACTION2_SPI_REQ *pSMB = NULL; 5930 TRANSACTION2_SPI_RSP *pSMBr = NULL; 5931 unsigned int in_len; 5932 int name_len; 5933 int rc = 0; 5934 int bytes_returned = 0; 5935 char *data_offset; 5936 __u16 params, param_offset, offset, byte_count, count; 5937 int remap = cifs_remap(cifs_sb); 5938 5939 cifs_dbg(FYI, "In SetTimes\n"); 5940 5941 SetTimesRetry: 5942 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5943 (void **) &pSMBr); 5944 if (rc < 0) 5945 return rc; 5946 in_len = rc; 5947 5948 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5949 name_len = 5950 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 5951 PATH_MAX, tcon->ses->local_nls, remap); 5952 name_len++; /* trailing null */ 5953 name_len *= 2; 5954 } else { 5955 name_len = copy_path_name(pSMB->FileName, fileName); 5956 } 5957 5958 params = 6 + name_len; 5959 count = sizeof(FILE_BASIC_INFO); 5960 pSMB->MaxParameterCount = cpu_to_le16(2); 5961 /* BB find max SMB PDU from sess structure BB */ 5962 pSMB->MaxDataCount = cpu_to_le16(1000); 5963 pSMB->MaxSetupCount = 0; 5964 pSMB->Reserved = 0; 5965 pSMB->Flags = 0; 5966 pSMB->Timeout = 0; 5967 pSMB->Reserved2 = 0; 5968 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5969 InformationLevel); 5970 offset = param_offset + params; 5971 data_offset = (char *)pSMB + offsetof(typeof(*pSMB), hdr.Protocol) + offset; 5972 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5973 pSMB->DataOffset = cpu_to_le16(offset); 5974 pSMB->SetupCount = 1; 5975 pSMB->Reserved3 = 0; 5976 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5977 byte_count = 3 /* pad */ + params + count; 5978 5979 pSMB->DataCount = cpu_to_le16(count); 5980 pSMB->ParameterCount = cpu_to_le16(params); 5981 pSMB->TotalDataCount = pSMB->DataCount; 5982 pSMB->TotalParameterCount = pSMB->ParameterCount; 5983 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5984 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2); 5985 else 5986 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5987 pSMB->Reserved4 = 0; 5988 in_len += byte_count; 5989 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5990 pSMB->ByteCount = cpu_to_le16(byte_count); 5991 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 5992 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5993 if (rc) 5994 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc); 5995 5996 cifs_buf_release(pSMB); 5997 5998 if (rc == -EAGAIN) 5999 goto SetTimesRetry; 6000 6001 return rc; 6002 } 6003 6004 static void 6005 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, 6006 const struct cifs_unix_set_info_args *args) 6007 { 6008 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64; 6009 u64 mode = args->mode; 6010 6011 if (uid_valid(args->uid)) 6012 uid = from_kuid(&init_user_ns, args->uid); 6013 if (gid_valid(args->gid)) 6014 gid = from_kgid(&init_user_ns, args->gid); 6015 6016 /* 6017 * Samba server ignores set of file size to zero due to bugs in some 6018 * older clients, but we should be precise - we use SetFileSize to 6019 * set file size and do not want to truncate file size to zero 6020 * accidentally as happened on one Samba server beta by putting 6021 * zero instead of -1 here 6022 */ 6023 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64); 6024 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64); 6025 data_offset->LastStatusChange = cpu_to_le64(args->ctime); 6026 data_offset->LastAccessTime = cpu_to_le64(args->atime); 6027 data_offset->LastModificationTime = cpu_to_le64(args->mtime); 6028 data_offset->Uid = cpu_to_le64(uid); 6029 data_offset->Gid = cpu_to_le64(gid); 6030 /* better to leave device as zero when it is */ 6031 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); 6032 data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); 6033 data_offset->Permissions = cpu_to_le64(mode); 6034 6035 if (S_ISREG(mode)) 6036 data_offset->Type = cpu_to_le32(UNIX_FILE); 6037 else if (S_ISDIR(mode)) 6038 data_offset->Type = cpu_to_le32(UNIX_DIR); 6039 else if (S_ISLNK(mode)) 6040 data_offset->Type = cpu_to_le32(UNIX_SYMLINK); 6041 else if (S_ISCHR(mode)) 6042 data_offset->Type = cpu_to_le32(UNIX_CHARDEV); 6043 else if (S_ISBLK(mode)) 6044 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV); 6045 else if (S_ISFIFO(mode)) 6046 data_offset->Type = cpu_to_le32(UNIX_FIFO); 6047 else if (S_ISSOCK(mode)) 6048 data_offset->Type = cpu_to_le32(UNIX_SOCKET); 6049 } 6050 6051 int 6052 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 6053 const struct cifs_unix_set_info_args *args, 6054 u16 fid, u32 pid_of_opener) 6055 { 6056 struct smb_com_transaction2_sfi_req *pSMB = NULL; 6057 unsigned int in_len; 6058 char *data_offset; 6059 int rc = 0; 6060 u16 params, param_offset, offset, byte_count, count; 6061 6062 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n"); 6063 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 6064 if (rc < 0) 6065 return rc; 6066 in_len = rc; 6067 6068 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 6069 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 6070 6071 params = 6; 6072 pSMB->MaxSetupCount = 0; 6073 pSMB->Reserved = 0; 6074 pSMB->Flags = 0; 6075 pSMB->Timeout = 0; 6076 pSMB->Reserved2 = 0; 6077 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid); 6078 offset = param_offset + params; 6079 6080 data_offset = (char *)pSMB + offset; 6081 6082 count = sizeof(FILE_UNIX_BASIC_INFO); 6083 6084 pSMB->MaxParameterCount = cpu_to_le16(2); 6085 /* BB find max SMB PDU from sess */ 6086 pSMB->MaxDataCount = cpu_to_le16(1000); 6087 pSMB->SetupCount = 1; 6088 pSMB->Reserved3 = 0; 6089 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 6090 byte_count = 3 /* pad */ + params + count; 6091 pSMB->DataCount = cpu_to_le16(count); 6092 pSMB->ParameterCount = cpu_to_le16(params); 6093 pSMB->TotalDataCount = pSMB->DataCount; 6094 pSMB->TotalParameterCount = pSMB->ParameterCount; 6095 pSMB->ParameterOffset = cpu_to_le16(param_offset); 6096 pSMB->DataOffset = cpu_to_le16(offset); 6097 pSMB->Fid = fid; 6098 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 6099 pSMB->Reserved4 = 0; 6100 in_len += byte_count; 6101 pSMB->ByteCount = cpu_to_le16(byte_count); 6102 6103 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args); 6104 6105 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); 6106 cifs_small_buf_release(pSMB); 6107 if (rc) 6108 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n", 6109 rc); 6110 6111 /* Note: On -EAGAIN error only caller can retry on handle based calls 6112 since file handle passed in no longer valid */ 6113 6114 return rc; 6115 } 6116 6117 int 6118 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 6119 const char *file_name, 6120 const struct cifs_unix_set_info_args *args, 6121 const struct nls_table *nls_codepage, int remap) 6122 { 6123 TRANSACTION2_SPI_REQ *pSMB = NULL; 6124 TRANSACTION2_SPI_RSP *pSMBr = NULL; 6125 unsigned int in_len; 6126 int name_len; 6127 int rc = 0; 6128 int bytes_returned = 0; 6129 FILE_UNIX_BASIC_INFO *data_offset; 6130 __u16 params, param_offset, offset, count, byte_count; 6131 6132 cifs_dbg(FYI, "In SetUID/GID/Mode\n"); 6133 setPermsRetry: 6134 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 6135 (void **) &pSMBr); 6136 if (rc < 0) 6137 return rc; 6138 in_len = rc; 6139 6140 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 6141 name_len = 6142 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name, 6143 PATH_MAX, nls_codepage, remap); 6144 name_len++; /* trailing null */ 6145 name_len *= 2; 6146 } else { 6147 name_len = copy_path_name(pSMB->FileName, file_name); 6148 } 6149 6150 params = 6 + name_len; 6151 count = sizeof(FILE_UNIX_BASIC_INFO); 6152 pSMB->MaxParameterCount = cpu_to_le16(2); 6153 /* BB find max SMB PDU from sess structure BB */ 6154 pSMB->MaxDataCount = cpu_to_le16(1000); 6155 pSMB->MaxSetupCount = 0; 6156 pSMB->Reserved = 0; 6157 pSMB->Flags = 0; 6158 pSMB->Timeout = 0; 6159 pSMB->Reserved2 = 0; 6160 param_offset = offsetof(struct smb_com_transaction2_spi_req, 6161 InformationLevel); 6162 offset = param_offset + params; 6163 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset); 6164 memset(data_offset, 0, count); 6165 pSMB->DataOffset = cpu_to_le16(offset); 6166 pSMB->ParameterOffset = cpu_to_le16(param_offset); 6167 pSMB->SetupCount = 1; 6168 pSMB->Reserved3 = 0; 6169 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 6170 byte_count = 3 /* pad */ + params + count; 6171 pSMB->ParameterCount = cpu_to_le16(params); 6172 pSMB->DataCount = cpu_to_le16(count); 6173 pSMB->TotalParameterCount = pSMB->ParameterCount; 6174 pSMB->TotalDataCount = pSMB->DataCount; 6175 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 6176 pSMB->Reserved4 = 0; 6177 in_len += byte_count; 6178 6179 cifs_fill_unix_set_info(data_offset, args); 6180 6181 pSMB->ByteCount = cpu_to_le16(byte_count); 6182 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 6183 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 6184 if (rc) 6185 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc); 6186 6187 cifs_buf_release(pSMB); 6188 if (rc == -EAGAIN) 6189 goto setPermsRetry; 6190 return rc; 6191 } 6192 6193 #ifdef CONFIG_CIFS_XATTR 6194 /* 6195 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common 6196 * function used by listxattr and getxattr type calls. When ea_name is set, 6197 * it looks for that attribute name and stuffs that value into the EAData 6198 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the 6199 * buffer. In both cases, the return value is either the length of the 6200 * resulting data or a negative error code. If EAData is a NULL pointer then 6201 * the data isn't copied to it, but the length is returned. 6202 */ 6203 ssize_t 6204 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon, 6205 const unsigned char *searchName, const unsigned char *ea_name, 6206 char *EAData, size_t buf_size, 6207 struct cifs_sb_info *cifs_sb) 6208 { 6209 /* BB assumes one setup word */ 6210 TRANSACTION2_QPI_REQ *pSMB = NULL; 6211 TRANSACTION2_QPI_RSP *pSMBr = NULL; 6212 int remap = cifs_remap(cifs_sb); 6213 struct nls_table *nls_codepage = cifs_sb->local_nls; 6214 unsigned int in_len; 6215 int rc = 0; 6216 int bytes_returned; 6217 int list_len; 6218 u32 ea_list_len; 6219 struct fealist *ea_response_data; 6220 struct fea *temp_fea; 6221 char *temp_ptr; 6222 char *byte_area; 6223 char *end_of_smb; 6224 __u16 params, byte_count, data_offset; 6225 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0; 6226 6227 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName); 6228 QAllEAsRetry: 6229 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 6230 (void **) &pSMBr); 6231 if (rc < 0) 6232 return rc; 6233 in_len = rc; 6234 6235 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 6236 list_len = 6237 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 6238 PATH_MAX, nls_codepage, remap); 6239 list_len++; /* trailing null */ 6240 list_len *= 2; 6241 } else { 6242 list_len = copy_path_name(pSMB->FileName, searchName); 6243 } 6244 6245 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */; 6246 pSMB->TotalDataCount = 0; 6247 pSMB->MaxParameterCount = cpu_to_le16(2); 6248 /* BB find exact max SMB PDU from sess structure BB */ 6249 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 6250 pSMB->MaxSetupCount = 0; 6251 pSMB->Reserved = 0; 6252 pSMB->Flags = 0; 6253 pSMB->Timeout = 0; 6254 pSMB->Reserved2 = 0; 6255 pSMB->ParameterOffset = cpu_to_le16(offsetof( 6256 struct smb_com_transaction2_qpi_req, InformationLevel)); 6257 pSMB->DataCount = 0; 6258 pSMB->DataOffset = 0; 6259 pSMB->SetupCount = 1; 6260 pSMB->Reserved3 = 0; 6261 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 6262 byte_count = params + 1 /* pad */ ; 6263 pSMB->TotalParameterCount = cpu_to_le16(params); 6264 pSMB->ParameterCount = pSMB->TotalParameterCount; 6265 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS); 6266 pSMB->Reserved4 = 0; 6267 in_len += byte_count; 6268 pSMB->ByteCount = cpu_to_le16(byte_count); 6269 6270 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 6271 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 6272 if (rc) { 6273 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc); 6274 goto QAllEAsOut; 6275 } 6276 6277 6278 /* BB also check enough total bytes returned */ 6279 /* BB we need to improve the validity checking 6280 of these trans2 responses */ 6281 6282 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 6283 if (rc || get_bcc(&pSMBr->hdr) < 4) { 6284 rc = smb_EIO2(smb_eio_trace_qalleas_bcc_too_small, 6285 get_bcc(&pSMBr->hdr), 4); 6286 goto QAllEAsOut; 6287 } 6288 6289 /* check that length of list is not more than bcc */ 6290 /* check that each entry does not go beyond length 6291 of list */ 6292 /* check that each element of each entry does not 6293 go beyond end of list */ 6294 /* validate_trans2_offsets() */ 6295 /* BB check if start of smb + data_offset > &bcc+ bcc */ 6296 6297 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 6298 ea_response_data = (struct fealist *) 6299 (((char *) &pSMBr->hdr.Protocol) + data_offset); 6300 6301 byte_area = pByteArea(&pSMBr->hdr); 6302 end_of_smb = byte_area + get_bcc(&pSMBr->hdr); 6303 if ((char *)ea_response_data < byte_area || 6304 (char *)ea_response_data > 6305 end_of_smb - sizeof(ea_response_data->list_len)) { 6306 rc = smb_EIO2(smb_eio_trace_qalleas_overlong, 6307 data_offset, get_bcc(&pSMBr->hdr)); 6308 goto QAllEAsOut; 6309 } 6310 6311 ea_list_len = le32_to_cpu(ea_response_data->list_len); 6312 cifs_dbg(FYI, "%s: ea length: %u\n", __func__, ea_list_len); 6313 if (ea_list_len <= 8) { 6314 cifs_dbg(FYI, "empty EA list returned from server\n"); 6315 /* didn't find the named attribute */ 6316 if (ea_name) 6317 rc = -ENODATA; 6318 goto QAllEAsOut; 6319 } 6320 6321 /* make sure list_len doesn't go past end of SMB */ 6322 if (ea_list_len > end_of_smb - (char *)ea_response_data) { 6323 cifs_dbg(FYI, "EA list appears to go beyond SMB\n"); 6324 rc = smb_EIO2(smb_eio_trace_qalleas_overlong, 6325 ea_list_len, 6326 end_of_smb - (char *)ea_response_data); 6327 goto QAllEAsOut; 6328 } 6329 list_len = ea_list_len; 6330 6331 /* account for ea list len */ 6332 list_len -= 4; 6333 temp_fea = &ea_response_data->list; 6334 temp_ptr = (char *)temp_fea; 6335 while (list_len > 0) { 6336 unsigned int name_len; 6337 __u16 value_len; 6338 6339 list_len -= 4; 6340 temp_ptr += 4; 6341 /* make sure we can read name_len and value_len */ 6342 if (list_len < 0) { 6343 cifs_dbg(FYI, "EA entry goes beyond length of list\n"); 6344 rc = smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len); 6345 goto QAllEAsOut; 6346 } 6347 6348 name_len = temp_fea->name_len; 6349 value_len = le16_to_cpu(temp_fea->value_len); 6350 list_len -= name_len + 1 + value_len; 6351 if (list_len < 0) { 6352 cifs_dbg(FYI, "EA entry goes beyond length of list\n"); 6353 rc = smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len); 6354 goto QAllEAsOut; 6355 } 6356 6357 if (ea_name) { 6358 if (ea_name_len == name_len && 6359 memcmp(ea_name, temp_ptr, name_len) == 0) { 6360 temp_ptr += name_len + 1; 6361 rc = value_len; 6362 if (buf_size == 0) 6363 goto QAllEAsOut; 6364 if ((size_t)value_len > buf_size) { 6365 rc = -ERANGE; 6366 goto QAllEAsOut; 6367 } 6368 memcpy(EAData, temp_ptr, value_len); 6369 goto QAllEAsOut; 6370 } 6371 } else { 6372 /* account for prefix user. and trailing null */ 6373 rc += (5 + 1 + name_len); 6374 if (rc < (int) buf_size) { 6375 memcpy(EAData, "user.", 5); 6376 EAData += 5; 6377 memcpy(EAData, temp_ptr, name_len); 6378 EAData += name_len; 6379 /* null terminate name */ 6380 *EAData = 0; 6381 ++EAData; 6382 } else if (buf_size == 0) { 6383 /* skip copy - calc size only */ 6384 } else { 6385 /* stop before overrun buffer */ 6386 rc = -ERANGE; 6387 break; 6388 } 6389 } 6390 temp_ptr += name_len + 1 + value_len; 6391 temp_fea = (struct fea *)temp_ptr; 6392 } 6393 6394 /* didn't find the named attribute */ 6395 if (ea_name) 6396 rc = -ENODATA; 6397 6398 QAllEAsOut: 6399 cifs_buf_release(pSMB); 6400 if (rc == -EAGAIN) 6401 goto QAllEAsRetry; 6402 6403 return (ssize_t)rc; 6404 } 6405 6406 int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, 6407 const char *fileName, const char *ea_name, 6408 const void *ea_value, const __u16 ea_value_len, 6409 struct cifs_sb_info *cifs_sb) 6410 { 6411 struct smb_com_transaction2_spi_req *pSMB = NULL; 6412 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 6413 struct fealist *parm_data; 6414 unsigned int in_len; 6415 int name_len; 6416 int rc = 0; 6417 int bytes_returned = 0; 6418 __u16 params, param_offset; 6419 unsigned int byte_count, offset, count; 6420 int remap = cifs_remap(cifs_sb); 6421 unsigned int total_len; 6422 6423 cifs_dbg(FYI, "In SetEA\n"); 6424 SetEARetry: 6425 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 6426 (void **) &pSMBr); 6427 if (rc < 0) 6428 return rc; 6429 in_len = rc; 6430 6431 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 6432 name_len = 6433 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 6434 PATH_MAX, tcon->ses->local_nls, remap); 6435 name_len++; /* trailing null */ 6436 name_len *= 2; 6437 } else { 6438 name_len = copy_path_name(pSMB->FileName, fileName); 6439 } 6440 6441 params = 6 + name_len; 6442 6443 /* done calculating parms using name_len of file name, 6444 now use name_len to calculate length of ea name 6445 we are going to create in the inode xattrs */ 6446 if (ea_name == NULL) 6447 name_len = 0; 6448 else 6449 name_len = strnlen(ea_name, 255); 6450 6451 count = sizeof(*parm_data) + 1 + ea_value_len + name_len; 6452 pSMB->MaxParameterCount = cpu_to_le16(2); 6453 /* BB find max SMB PDU from sess */ 6454 pSMB->MaxDataCount = cpu_to_le16(1000); 6455 pSMB->MaxSetupCount = 0; 6456 pSMB->Reserved = 0; 6457 pSMB->Flags = 0; 6458 pSMB->Timeout = 0; 6459 pSMB->Reserved2 = 0; 6460 param_offset = offsetof(struct smb_com_transaction2_spi_req, 6461 InformationLevel); 6462 offset = param_offset + params; 6463 pSMB->InformationLevel = 6464 cpu_to_le16(SMB_SET_FILE_EA); 6465 6466 parm_data = (void *)pSMB + offset; 6467 pSMB->ParameterOffset = cpu_to_le16(param_offset); 6468 pSMB->DataOffset = cpu_to_le16(offset); 6469 pSMB->SetupCount = 1; 6470 pSMB->Reserved3 = 0; 6471 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 6472 byte_count = 3 /* pad */ + params + count; 6473 if (check_add_overflow(in_len, byte_count, &total_len) || 6474 byte_count > U16_MAX || 6475 total_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { 6476 cifs_dbg(VFS, "EA request too large: %u bytes\n", total_len); 6477 cifs_buf_release(pSMB); 6478 return -E2BIG; 6479 } 6480 pSMB->DataCount = cpu_to_le16(count); 6481 parm_data->list_len = cpu_to_le32(count); 6482 parm_data->list.EA_flags = 0; 6483 /* we checked above that name len is less than 255 */ 6484 parm_data->list.name_len = (__u8)name_len; 6485 /* EA names are always ASCII and NUL-terminated */ 6486 strscpy(parm_data->list.name, ea_name ?: "", name_len + 1); 6487 parm_data->list.value_len = cpu_to_le16(ea_value_len); 6488 /* caller ensures that ea_value_len is less than 64K but 6489 we need to ensure that it fits within the smb */ 6490 6491 /*BB add length check to see if it would fit in 6492 negotiated SMB buffer size BB */ 6493 /* if (ea_value_len > buffer_size - 512 (enough for header)) */ 6494 if (ea_value_len) 6495 memcpy(parm_data->list.name + name_len + 1, 6496 ea_value, ea_value_len); 6497 6498 pSMB->TotalDataCount = pSMB->DataCount; 6499 pSMB->ParameterCount = cpu_to_le16(params); 6500 pSMB->TotalParameterCount = pSMB->ParameterCount; 6501 pSMB->Reserved4 = 0; 6502 in_len += byte_count; 6503 pSMB->ByteCount = cpu_to_le16(byte_count); 6504 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, 6505 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 6506 if (rc) 6507 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc); 6508 6509 cifs_buf_release(pSMB); 6510 6511 if (rc == -EAGAIN) 6512 goto SetEARetry; 6513 6514 return rc; 6515 } 6516 #endif 6517