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