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