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