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