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