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