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