OSDN Git Service

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