~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/cifs/cifssmb.c

Version: ~ [ linux-5.5-rc7 ] ~ [ linux-5.4.13 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.97 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.166 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.210 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.210 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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