root/fs/cifs/cifssmb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cifs_mark_open_files_invalid
  2. __cifs_reconnect_tcon
  3. __cifs_reconnect_tcon
  4. cifs_reconnect_tcon
  5. small_smb_init
  6. small_smb_init_no_tc
  7. __smb_init
  8. smb_init
  9. smb_init_no_reconnect
  10. validate_t2
  11. decode_ext_sec_blob
  12. cifs_enable_signing
  13. decode_lanman_negprot_rsp
  14. decode_lanman_negprot_rsp
  15. should_set_ext_sec_flag
  16. CIFSSMBNegotiate
  17. CIFSSMBTDis
  18. cifs_echo_callback
  19. CIFSSMBEcho
  20. CIFSSMBLogoff
  21. CIFSPOSIXDelFile
  22. CIFSSMBDelFile
  23. CIFSSMBRmDir
  24. CIFSSMBMkDir
  25. CIFSPOSIXCreate
  26. convert_disposition
  27. access_flags_to_smbopen_mode
  28. SMBLegacyOpen
  29. CIFS_open
  30. cifs_discard_remaining_data
  31. __cifs_readv_discard
  32. cifs_readv_discard
  33. cifs_readv_receive
  34. cifs_readv_callback
  35. cifs_async_readv
  36. CIFSSMBRead
  37. CIFSSMBWrite
  38. cifs_writedata_release
  39. cifs_writev_requeue
  40. cifs_writev_complete
  41. cifs_writedata_alloc
  42. cifs_writedata_direct_alloc
  43. cifs_writev_callback
  44. cifs_async_writev
  45. CIFSSMBWrite2
  46. cifs_lockv
  47. CIFSSMBLock
  48. CIFSSMBPosixLock
  49. CIFSSMBClose
  50. CIFSSMBFlush
  51. CIFSSMBRename
  52. CIFSSMBRenameOpenFile
  53. CIFSSMBCopy
  54. CIFSUnixCreateSymLink
  55. CIFSUnixCreateHardLink
  56. CIFSCreateHardLink
  57. CIFSSMBUnixQuerySymLink
  58. CIFSSMBQuerySymLink
  59. CIFSSMB_set_compression
  60. cifs_convert_ace
  61. cifs_copy_posix_acl
  62. convert_ace_to_cifs_ace
  63. ACL_to_cifs_posix
  64. CIFSSMBGetPosixACL
  65. CIFSSMBSetPosixACL
  66. CIFSGetExtAttr
  67. smb_init_nttransact
  68. validate_ntransact
  69. CIFSSMBGetCIFSACL
  70. CIFSSMBSetCIFSACL
  71. SMBQueryInformation
  72. CIFSSMBQFileInfo
  73. CIFSSMBQPathInfo
  74. CIFSSMBUnixQFileInfo
  75. CIFSSMBUnixQPathInfo
  76. CIFSFindFirst
  77. CIFSFindNext
  78. CIFSFindClose
  79. CIFSGetSrvInodeNumber
  80. CIFSGetDFSRefer
  81. SMBOldQFSInfo
  82. CIFSSMBQFSInfo
  83. CIFSSMBQFSAttributeInfo
  84. CIFSSMBQFSDeviceInfo
  85. CIFSSMBQFSUnixInfo
  86. CIFSSMBSetFSUnixInfo
  87. CIFSSMBQFSPosixInfo
  88. CIFSSMBSetEOF
  89. CIFSSMBSetFileSize
  90. CIFSSMBSetFileInfo
  91. CIFSSMBSetFileDisposition
  92. CIFSSMBSetPathInfo
  93. CIFSSMBSetAttrLegacy
  94. cifs_fill_unix_set_info
  95. CIFSSMBUnixSetFileInfo
  96. CIFSSMBUnixSetPathInfo
  97. CIFSSMBQAllEAs
  98. CIFSSMBSetEA

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

/* [<][>][^][v][top][bottom][index][help] */