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