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