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