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