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