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