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