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