Merge branch 'work.drm' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[sfrench/cifs-2.6.git] / fs / cifs / cifssmb.c
1 /*
2  *   fs/cifs/cifssmb.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002,2010
5  *   Author(s): Steve French (sfrench@us.ibm.com)
6  *
7  *   Contains the routines for constructing the SMB PDUs themselves
8  *
9  *   This library is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU Lesser General Public License as published
11  *   by the Free Software Foundation; either version 2.1 of the License, or
12  *   (at your option) any later version.
13  *
14  *   This library is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17  *   the GNU Lesser General Public License for more details.
18  *
19  *   You should have received a copy of the GNU Lesser General Public License
20  *   along with this library; if not, write to the Free Software
21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23
24  /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c   */
25  /* These are mostly routines that operate on a pathname, or on a tree id     */
26  /* (mounted volume), but there are eight handle based routines which must be */
27  /* treated slightly differently for reconnection purposes since we never     */
28  /* want to reuse a stale file handle and only the caller knows the file info */
29
30 #include <linux/fs.h>
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <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;
482                 unsigned long utc = ktime_get_real_seconds();
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,
487                          (int)(utc - ts.tv_sec));
488                 val = (int)(utc - 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         DeleteMidQEntry(mid);
701         add_credits(server, 1, CIFS_ECHO_OP);
702 }
703
704 int
705 CIFSSMBEcho(struct TCP_Server_Info *server)
706 {
707         ECHO_REQ *smb;
708         int rc = 0;
709         struct kvec iov[2];
710         struct smb_rqst rqst = { .rq_iov = iov,
711                                  .rq_nvec = 2 };
712
713         cifs_dbg(FYI, "In echo request\n");
714
715         rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
716         if (rc)
717                 return rc;
718
719         if (server->capabilities & CAP_UNICODE)
720                 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
721
722         /* set up echo request */
723         smb->hdr.Tid = 0xffff;
724         smb->hdr.WordCount = 1;
725         put_unaligned_le16(1, &smb->EchoCount);
726         put_bcc(1, &smb->hdr);
727         smb->Data[0] = 'a';
728         inc_rfc1001_len(smb, 3);
729
730         iov[0].iov_len = 4;
731         iov[0].iov_base = smb;
732         iov[1].iov_len = get_rfc1002_length(smb);
733         iov[1].iov_base = (char *)smb + 4;
734
735         rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
736                              server, CIFS_ASYNC_OP | CIFS_ECHO_OP);
737         if (rc)
738                 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
739
740         cifs_small_buf_release(smb);
741
742         return rc;
743 }
744
745 int
746 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
747 {
748         LOGOFF_ANDX_REQ *pSMB;
749         int rc = 0;
750
751         cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
752
753         /*
754          * BB: do we need to check validity of ses and server? They should
755          * always be valid since we have an active reference. If not, that
756          * should probably be a BUG()
757          */
758         if (!ses || !ses->server)
759                 return -EIO;
760
761         mutex_lock(&ses->session_mutex);
762         if (ses->need_reconnect)
763                 goto session_already_dead; /* no need to send SMBlogoff if uid
764                                               already closed due to reconnect */
765         rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
766         if (rc) {
767                 mutex_unlock(&ses->session_mutex);
768                 return rc;
769         }
770
771         pSMB->hdr.Mid = get_next_mid(ses->server);
772
773         if (ses->server->sign)
774                 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
775
776         pSMB->hdr.Uid = ses->Suid;
777
778         pSMB->AndXCommand = 0xFF;
779         rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
780         cifs_small_buf_release(pSMB);
781 session_already_dead:
782         mutex_unlock(&ses->session_mutex);
783
784         /* if session dead then we do not need to do ulogoff,
785                 since server closed smb session, no sense reporting
786                 error */
787         if (rc == -EAGAIN)
788                 rc = 0;
789         return rc;
790 }
791
792 int
793 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
794                  const char *fileName, __u16 type,
795                  const struct nls_table *nls_codepage, int remap)
796 {
797         TRANSACTION2_SPI_REQ *pSMB = NULL;
798         TRANSACTION2_SPI_RSP *pSMBr = NULL;
799         struct unlink_psx_rq *pRqD;
800         int name_len;
801         int rc = 0;
802         int bytes_returned = 0;
803         __u16 params, param_offset, offset, byte_count;
804
805         cifs_dbg(FYI, "In POSIX delete\n");
806 PsxDelete:
807         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
808                       (void **) &pSMBr);
809         if (rc)
810                 return rc;
811
812         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
813                 name_len =
814                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
815                                        PATH_MAX, nls_codepage, remap);
816                 name_len++;     /* trailing null */
817                 name_len *= 2;
818         } else { /* BB add path length overrun check */
819                 name_len = strnlen(fileName, PATH_MAX);
820                 name_len++;     /* trailing null */
821                 strncpy(pSMB->FileName, fileName, name_len);
822         }
823
824         params = 6 + name_len;
825         pSMB->MaxParameterCount = cpu_to_le16(2);
826         pSMB->MaxDataCount = 0; /* BB double check this with jra */
827         pSMB->MaxSetupCount = 0;
828         pSMB->Reserved = 0;
829         pSMB->Flags = 0;
830         pSMB->Timeout = 0;
831         pSMB->Reserved2 = 0;
832         param_offset = offsetof(struct smb_com_transaction2_spi_req,
833                                 InformationLevel) - 4;
834         offset = param_offset + params;
835
836         /* Setup pointer to Request Data (inode type) */
837         pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
838         pRqD->type = cpu_to_le16(type);
839         pSMB->ParameterOffset = cpu_to_le16(param_offset);
840         pSMB->DataOffset = cpu_to_le16(offset);
841         pSMB->SetupCount = 1;
842         pSMB->Reserved3 = 0;
843         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
844         byte_count = 3 /* pad */  + params + sizeof(struct unlink_psx_rq);
845
846         pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
847         pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
848         pSMB->ParameterCount = cpu_to_le16(params);
849         pSMB->TotalParameterCount = pSMB->ParameterCount;
850         pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
851         pSMB->Reserved4 = 0;
852         inc_rfc1001_len(pSMB, byte_count);
853         pSMB->ByteCount = cpu_to_le16(byte_count);
854         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
855                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
856         if (rc)
857                 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
858         cifs_buf_release(pSMB);
859
860         cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
861
862         if (rc == -EAGAIN)
863                 goto PsxDelete;
864
865         return rc;
866 }
867
868 int
869 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
870                struct cifs_sb_info *cifs_sb)
871 {
872         DELETE_FILE_REQ *pSMB = NULL;
873         DELETE_FILE_RSP *pSMBr = NULL;
874         int rc = 0;
875         int bytes_returned;
876         int name_len;
877         int remap = cifs_remap(cifs_sb);
878
879 DelFileRetry:
880         rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
881                       (void **) &pSMBr);
882         if (rc)
883                 return rc;
884
885         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
886                 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
887                                               PATH_MAX, cifs_sb->local_nls,
888                                               remap);
889                 name_len++;     /* trailing null */
890                 name_len *= 2;
891         } else {                /* BB improve check for buffer overruns BB */
892                 name_len = strnlen(name, PATH_MAX);
893                 name_len++;     /* trailing null */
894                 strncpy(pSMB->fileName, name, name_len);
895         }
896         pSMB->SearchAttributes =
897             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
898         pSMB->BufferFormat = 0x04;
899         inc_rfc1001_len(pSMB, name_len + 1);
900         pSMB->ByteCount = cpu_to_le16(name_len + 1);
901         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
902                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
903         cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
904         if (rc)
905                 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
906
907         cifs_buf_release(pSMB);
908         if (rc == -EAGAIN)
909                 goto DelFileRetry;
910
911         return rc;
912 }
913
914 int
915 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
916              struct cifs_sb_info *cifs_sb)
917 {
918         DELETE_DIRECTORY_REQ *pSMB = NULL;
919         DELETE_DIRECTORY_RSP *pSMBr = NULL;
920         int rc = 0;
921         int bytes_returned;
922         int name_len;
923         int remap = cifs_remap(cifs_sb);
924
925         cifs_dbg(FYI, "In CIFSSMBRmDir\n");
926 RmDirRetry:
927         rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
928                       (void **) &pSMBr);
929         if (rc)
930                 return rc;
931
932         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
933                 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
934                                               PATH_MAX, cifs_sb->local_nls,
935                                               remap);
936                 name_len++;     /* trailing null */
937                 name_len *= 2;
938         } else {                /* BB improve check for buffer overruns BB */
939                 name_len = strnlen(name, PATH_MAX);
940                 name_len++;     /* trailing null */
941                 strncpy(pSMB->DirName, name, name_len);
942         }
943
944         pSMB->BufferFormat = 0x04;
945         inc_rfc1001_len(pSMB, name_len + 1);
946         pSMB->ByteCount = cpu_to_le16(name_len + 1);
947         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
948                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
949         cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
950         if (rc)
951                 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
952
953         cifs_buf_release(pSMB);
954         if (rc == -EAGAIN)
955                 goto RmDirRetry;
956         return rc;
957 }
958
959 int
960 CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
961              struct cifs_sb_info *cifs_sb)
962 {
963         int rc = 0;
964         CREATE_DIRECTORY_REQ *pSMB = NULL;
965         CREATE_DIRECTORY_RSP *pSMBr = NULL;
966         int bytes_returned;
967         int name_len;
968         int remap = cifs_remap(cifs_sb);
969
970         cifs_dbg(FYI, "In CIFSSMBMkDir\n");
971 MkDirRetry:
972         rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
973                       (void **) &pSMBr);
974         if (rc)
975                 return rc;
976
977         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
978                 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
979                                               PATH_MAX, cifs_sb->local_nls,
980                                               remap);
981                 name_len++;     /* trailing null */
982                 name_len *= 2;
983         } else {                /* BB improve check for buffer overruns BB */
984                 name_len = strnlen(name, PATH_MAX);
985                 name_len++;     /* trailing null */
986                 strncpy(pSMB->DirName, name, name_len);
987         }
988
989         pSMB->BufferFormat = 0x04;
990         inc_rfc1001_len(pSMB, name_len + 1);
991         pSMB->ByteCount = cpu_to_le16(name_len + 1);
992         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
993                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
994         cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
995         if (rc)
996                 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
997
998         cifs_buf_release(pSMB);
999         if (rc == -EAGAIN)
1000                 goto MkDirRetry;
1001         return rc;
1002 }
1003
1004 int
1005 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1006                 __u32 posix_flags, __u64 mode, __u16 *netfid,
1007                 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1008                 const char *name, const struct nls_table *nls_codepage,
1009                 int remap)
1010 {
1011         TRANSACTION2_SPI_REQ *pSMB = NULL;
1012         TRANSACTION2_SPI_RSP *pSMBr = NULL;
1013         int name_len;
1014         int rc = 0;
1015         int bytes_returned = 0;
1016         __u16 params, param_offset, offset, byte_count, count;
1017         OPEN_PSX_REQ *pdata;
1018         OPEN_PSX_RSP *psx_rsp;
1019
1020         cifs_dbg(FYI, "In POSIX Create\n");
1021 PsxCreat:
1022         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1023                       (void **) &pSMBr);
1024         if (rc)
1025                 return rc;
1026
1027         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1028                 name_len =
1029                     cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1030                                        PATH_MAX, nls_codepage, remap);
1031                 name_len++;     /* trailing null */
1032                 name_len *= 2;
1033         } else {        /* BB improve the check for buffer overruns BB */
1034                 name_len = strnlen(name, PATH_MAX);
1035                 name_len++;     /* trailing null */
1036                 strncpy(pSMB->FileName, name, name_len);
1037         }
1038
1039         params = 6 + name_len;
1040         count = sizeof(OPEN_PSX_REQ);
1041         pSMB->MaxParameterCount = cpu_to_le16(2);
1042         pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1043         pSMB->MaxSetupCount = 0;
1044         pSMB->Reserved = 0;
1045         pSMB->Flags = 0;
1046         pSMB->Timeout = 0;
1047         pSMB->Reserved2 = 0;
1048         param_offset = offsetof(struct smb_com_transaction2_spi_req,
1049                                 InformationLevel) - 4;
1050         offset = param_offset + params;
1051         pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1052         pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1053         pdata->Permissions = cpu_to_le64(mode);
1054         pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1055         pdata->OpenFlags =  cpu_to_le32(*pOplock);
1056         pSMB->ParameterOffset = cpu_to_le16(param_offset);
1057         pSMB->DataOffset = cpu_to_le16(offset);
1058         pSMB->SetupCount = 1;
1059         pSMB->Reserved3 = 0;
1060         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1061         byte_count = 3 /* pad */  + params + count;
1062
1063         pSMB->DataCount = cpu_to_le16(count);
1064         pSMB->ParameterCount = cpu_to_le16(params);
1065         pSMB->TotalDataCount = pSMB->DataCount;
1066         pSMB->TotalParameterCount = pSMB->ParameterCount;
1067         pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1068         pSMB->Reserved4 = 0;
1069         inc_rfc1001_len(pSMB, byte_count);
1070         pSMB->ByteCount = cpu_to_le16(byte_count);
1071         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1072                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1073         if (rc) {
1074                 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1075                 goto psx_create_err;
1076         }
1077
1078         cifs_dbg(FYI, "copying inode info\n");
1079         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1080
1081         if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1082                 rc = -EIO;      /* bad smb */
1083                 goto psx_create_err;
1084         }
1085
1086         /* copy return information to pRetData */
1087         psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1088                         + le16_to_cpu(pSMBr->t2.DataOffset));
1089
1090         *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1091         if (netfid)
1092                 *netfid = psx_rsp->Fid;   /* cifs fid stays in le */
1093         /* Let caller know file was created so we can set the mode. */
1094         /* Do we care about the CreateAction in any other cases? */
1095         if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1096                 *pOplock |= CIFS_CREATE_ACTION;
1097         /* check to make sure response data is there */
1098         if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1099                 pRetData->Type = cpu_to_le32(-1); /* unknown */
1100                 cifs_dbg(NOISY, "unknown type\n");
1101         } else {
1102                 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1103                                         + sizeof(FILE_UNIX_BASIC_INFO)) {
1104                         cifs_dbg(VFS, "Open response data too small\n");
1105                         pRetData->Type = cpu_to_le32(-1);
1106                         goto psx_create_err;
1107                 }
1108                 memcpy((char *) pRetData,
1109                         (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1110                         sizeof(FILE_UNIX_BASIC_INFO));
1111         }
1112
1113 psx_create_err:
1114         cifs_buf_release(pSMB);
1115
1116         if (posix_flags & SMB_O_DIRECTORY)
1117                 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1118         else
1119                 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1120
1121         if (rc == -EAGAIN)
1122                 goto PsxCreat;
1123
1124         return rc;
1125 }
1126
1127 static __u16 convert_disposition(int disposition)
1128 {
1129         __u16 ofun = 0;
1130
1131         switch (disposition) {
1132                 case FILE_SUPERSEDE:
1133                         ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1134                         break;
1135                 case FILE_OPEN:
1136                         ofun = SMBOPEN_OAPPEND;
1137                         break;
1138                 case FILE_CREATE:
1139                         ofun = SMBOPEN_OCREATE;
1140                         break;
1141                 case FILE_OPEN_IF:
1142                         ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1143                         break;
1144                 case FILE_OVERWRITE:
1145                         ofun = SMBOPEN_OTRUNC;
1146                         break;
1147                 case FILE_OVERWRITE_IF:
1148                         ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1149                         break;
1150                 default:
1151                         cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1152                         ofun =  SMBOPEN_OAPPEND; /* regular open */
1153         }
1154         return ofun;
1155 }
1156
1157 static int
1158 access_flags_to_smbopen_mode(const int access_flags)
1159 {
1160         int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1161
1162         if (masked_flags == GENERIC_READ)
1163                 return SMBOPEN_READ;
1164         else if (masked_flags == GENERIC_WRITE)
1165                 return SMBOPEN_WRITE;
1166
1167         /* just go for read/write */
1168         return SMBOPEN_READWRITE;
1169 }
1170
1171 int
1172 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1173             const char *fileName, const int openDisposition,
1174             const int access_flags, const int create_options, __u16 *netfid,
1175             int *pOplock, FILE_ALL_INFO *pfile_info,
1176             const struct nls_table *nls_codepage, int remap)
1177 {
1178         int rc = -EACCES;
1179         OPENX_REQ *pSMB = NULL;
1180         OPENX_RSP *pSMBr = NULL;
1181         int bytes_returned;
1182         int name_len;
1183         __u16 count;
1184
1185 OldOpenRetry:
1186         rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1187                       (void **) &pSMBr);
1188         if (rc)
1189                 return rc;
1190
1191         pSMB->AndXCommand = 0xFF;       /* none */
1192
1193         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1194                 count = 1;      /* account for one byte pad to word boundary */
1195                 name_len =
1196                    cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1197                                       fileName, PATH_MAX, nls_codepage, remap);
1198                 name_len++;     /* trailing null */
1199                 name_len *= 2;
1200         } else {                /* BB improve check for buffer overruns BB */
1201                 count = 0;      /* no pad */
1202                 name_len = strnlen(fileName, PATH_MAX);
1203                 name_len++;     /* trailing null */
1204                 strncpy(pSMB->fileName, fileName, name_len);
1205         }
1206         if (*pOplock & REQ_OPLOCK)
1207                 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1208         else if (*pOplock & REQ_BATCHOPLOCK)
1209                 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1210
1211         pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1212         pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1213         pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1214         /* set file as system file if special file such
1215            as fifo and server expecting SFU style and
1216            no Unix extensions */
1217
1218         if (create_options & CREATE_OPTION_SPECIAL)
1219                 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1220         else /* BB FIXME BB */
1221                 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1222
1223         if (create_options & CREATE_OPTION_READONLY)
1224                 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1225
1226         /* BB FIXME BB */
1227 /*      pSMB->CreateOptions = cpu_to_le32(create_options &
1228                                                  CREATE_OPTIONS_MASK); */
1229         /* BB FIXME END BB */
1230
1231         pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1232         pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1233         count += name_len;
1234         inc_rfc1001_len(pSMB, count);
1235
1236         pSMB->ByteCount = cpu_to_le16(count);
1237         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1238                         (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1239         cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1240         if (rc) {
1241                 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1242         } else {
1243         /* BB verify if wct == 15 */
1244
1245 /*              *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1246
1247                 *netfid = pSMBr->Fid;   /* cifs fid stays in le */
1248                 /* Let caller know file was created so we can set the mode. */
1249                 /* Do we care about the CreateAction in any other cases? */
1250         /* BB FIXME BB */
1251 /*              if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1252                         *pOplock |= CIFS_CREATE_ACTION; */
1253         /* BB FIXME END */
1254
1255                 if (pfile_info) {
1256                         pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1257                         pfile_info->LastAccessTime = 0; /* BB fixme */
1258                         pfile_info->LastWriteTime = 0; /* BB fixme */
1259                         pfile_info->ChangeTime = 0;  /* BB fixme */
1260                         pfile_info->Attributes =
1261                                 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1262                         /* the file_info buf is endian converted by caller */
1263                         pfile_info->AllocationSize =
1264                                 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1265                         pfile_info->EndOfFile = pfile_info->AllocationSize;
1266                         pfile_info->NumberOfLinks = cpu_to_le32(1);
1267                         pfile_info->DeletePending = 0;
1268                 }
1269         }
1270
1271         cifs_buf_release(pSMB);
1272         if (rc == -EAGAIN)
1273                 goto OldOpenRetry;
1274         return rc;
1275 }
1276
1277 int
1278 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1279           FILE_ALL_INFO *buf)
1280 {
1281         int rc = -EACCES;
1282         OPEN_REQ *req = NULL;
1283         OPEN_RSP *rsp = NULL;
1284         int bytes_returned;
1285         int name_len;
1286         __u16 count;
1287         struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1288         struct cifs_tcon *tcon = oparms->tcon;
1289         int remap = cifs_remap(cifs_sb);
1290         const struct nls_table *nls = cifs_sb->local_nls;
1291         int create_options = oparms->create_options;
1292         int desired_access = oparms->desired_access;
1293         int disposition = oparms->disposition;
1294         const char *path = oparms->path;
1295
1296 openRetry:
1297         rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1298                       (void **)&rsp);
1299         if (rc)
1300                 return rc;
1301
1302         /* no commands go after this */
1303         req->AndXCommand = 0xFF;
1304
1305         if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1306                 /* account for one byte pad to word boundary */
1307                 count = 1;
1308                 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1309                                               path, PATH_MAX, nls, remap);
1310                 /* trailing null */
1311                 name_len++;
1312                 name_len *= 2;
1313                 req->NameLength = cpu_to_le16(name_len);
1314         } else {
1315                 /* BB improve check for buffer overruns BB */
1316                 /* no pad */
1317                 count = 0;
1318                 name_len = strnlen(path, PATH_MAX);
1319                 /* trailing null */
1320                 name_len++;
1321                 req->NameLength = cpu_to_le16(name_len);
1322                 strncpy(req->fileName, path, name_len);
1323         }
1324
1325         if (*oplock & REQ_OPLOCK)
1326                 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1327         else if (*oplock & REQ_BATCHOPLOCK)
1328                 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1329
1330         req->DesiredAccess = cpu_to_le32(desired_access);
1331         req->AllocationSize = 0;
1332
1333         /*
1334          * Set file as system file if special file such as fifo and server
1335          * expecting SFU style and no Unix extensions.
1336          */
1337         if (create_options & CREATE_OPTION_SPECIAL)
1338                 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1339         else
1340                 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1341
1342         /*
1343          * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1344          * sensitive checks for other servers such as Samba.
1345          */
1346         if (tcon->ses->capabilities & CAP_UNIX)
1347                 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1348
1349         if (create_options & CREATE_OPTION_READONLY)
1350                 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1351
1352         req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1353         req->CreateDisposition = cpu_to_le32(disposition);
1354         req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1355
1356         /* BB Expirement with various impersonation levels and verify */
1357         req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1358         req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1359
1360         count += name_len;
1361         inc_rfc1001_len(req, count);
1362
1363         req->ByteCount = cpu_to_le16(count);
1364         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1365                          (struct smb_hdr *)rsp, &bytes_returned, 0);
1366         cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1367         if (rc) {
1368                 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1369                 cifs_buf_release(req);
1370                 if (rc == -EAGAIN)
1371                         goto openRetry;
1372                 return rc;
1373         }
1374
1375         /* 1 byte no need to le_to_cpu */
1376         *oplock = rsp->OplockLevel;
1377         /* cifs fid stays in le */
1378         oparms->fid->netfid = rsp->Fid;
1379
1380         /* Let caller know file was created so we can set the mode. */
1381         /* Do we care about the CreateAction in any other cases? */
1382         if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1383                 *oplock |= CIFS_CREATE_ACTION;
1384
1385         if (buf) {
1386                 /* copy from CreationTime to Attributes */
1387                 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1388                 /* the file_info buf is endian converted by caller */
1389                 buf->AllocationSize = rsp->AllocationSize;
1390                 buf->EndOfFile = rsp->EndOfFile;
1391                 buf->NumberOfLinks = cpu_to_le32(1);
1392                 buf->DeletePending = 0;
1393         }
1394
1395         cifs_buf_release(req);
1396         return rc;
1397 }
1398
1399 /*
1400  * Discard any remaining data in the current SMB. To do this, we borrow the
1401  * current bigbuf.
1402  */
1403 int
1404 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1405 {
1406         unsigned int rfclen = get_rfc1002_length(server->smallbuf);
1407         int remaining = rfclen + 4 - server->total_read;
1408
1409         while (remaining > 0) {
1410                 int length;
1411
1412                 length = cifs_read_from_socket(server, server->bigbuf,
1413                                 min_t(unsigned int, remaining,
1414                                     CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1415                 if (length < 0)
1416                         return length;
1417                 server->total_read += length;
1418                 remaining -= length;
1419         }
1420
1421         return 0;
1422 }
1423
1424 static int
1425 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1426 {
1427         int length;
1428         struct cifs_readdata *rdata = mid->callback_data;
1429
1430         length = cifs_discard_remaining_data(server);
1431         dequeue_mid(mid, rdata->result);
1432         mid->resp_buf = server->smallbuf;
1433         server->smallbuf = NULL;
1434         return length;
1435 }
1436
1437 int
1438 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1439 {
1440         int length, len;
1441         unsigned int data_offset, data_len;
1442         struct cifs_readdata *rdata = mid->callback_data;
1443         char *buf = server->smallbuf;
1444         unsigned int buflen = get_rfc1002_length(buf) + 4;
1445
1446         cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1447                  __func__, mid->mid, rdata->offset, rdata->bytes);
1448
1449         /*
1450          * read the rest of READ_RSP header (sans Data array), or whatever we
1451          * can if there's not enough data. At this point, we've read down to
1452          * the Mid.
1453          */
1454         len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1455                                                         HEADER_SIZE(server) + 1;
1456
1457         length = cifs_read_from_socket(server,
1458                                        buf + HEADER_SIZE(server) - 1, len);
1459         if (length < 0)
1460                 return length;
1461         server->total_read += length;
1462
1463         if (server->ops->is_status_pending &&
1464             server->ops->is_status_pending(buf, server, 0)) {
1465                 cifs_discard_remaining_data(server);
1466                 return -1;
1467         }
1468
1469         /* Was the SMB read successful? */
1470         rdata->result = server->ops->map_error(buf, false);
1471         if (rdata->result != 0) {
1472                 cifs_dbg(FYI, "%s: server returned error %d\n",
1473                          __func__, rdata->result);
1474                 return cifs_readv_discard(server, mid);
1475         }
1476
1477         /* Is there enough to get to the rest of the READ_RSP header? */
1478         if (server->total_read < server->vals->read_rsp_size) {
1479                 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1480                          __func__, server->total_read,
1481                          server->vals->read_rsp_size);
1482                 rdata->result = -EIO;
1483                 return cifs_readv_discard(server, mid);
1484         }
1485
1486         data_offset = server->ops->read_data_offset(buf) + 4;
1487         if (data_offset < server->total_read) {
1488                 /*
1489                  * win2k8 sometimes sends an offset of 0 when the read
1490                  * is beyond the EOF. Treat it as if the data starts just after
1491                  * the header.
1492                  */
1493                 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1494                          __func__, data_offset);
1495                 data_offset = server->total_read;
1496         } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1497                 /* data_offset is beyond the end of smallbuf */
1498                 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1499                          __func__, data_offset);
1500                 rdata->result = -EIO;
1501                 return cifs_readv_discard(server, mid);
1502         }
1503
1504         cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1505                  __func__, server->total_read, data_offset);
1506
1507         len = data_offset - server->total_read;
1508         if (len > 0) {
1509                 /* read any junk before data into the rest of smallbuf */
1510                 length = cifs_read_from_socket(server,
1511                                                buf + server->total_read, len);
1512                 if (length < 0)
1513                         return length;
1514                 server->total_read += length;
1515         }
1516
1517         /* set up first iov for signature check */
1518         rdata->iov[0].iov_base = buf;
1519         rdata->iov[0].iov_len = 4;
1520         rdata->iov[1].iov_base = buf + 4;
1521         rdata->iov[1].iov_len = server->total_read - 4;
1522         cifs_dbg(FYI, "0: iov_base=%p iov_len=%u\n",
1523                  rdata->iov[0].iov_base, server->total_read);
1524
1525         /* how much data is in the response? */
1526         data_len = server->ops->read_data_length(buf);
1527         if (data_offset + data_len > buflen) {
1528                 /* data_len is corrupt -- discard frame */
1529                 rdata->result = -EIO;
1530                 return cifs_readv_discard(server, mid);
1531         }
1532
1533         length = rdata->read_into_pages(server, rdata, data_len);
1534         if (length < 0)
1535                 return length;
1536
1537         server->total_read += length;
1538
1539         cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1540                  server->total_read, buflen, data_len);
1541
1542         /* discard anything left over */
1543         if (server->total_read < buflen)
1544                 return cifs_readv_discard(server, mid);
1545
1546         dequeue_mid(mid, false);
1547         mid->resp_buf = server->smallbuf;
1548         server->smallbuf = NULL;
1549         return length;
1550 }
1551
1552 static void
1553 cifs_readv_callback(struct mid_q_entry *mid)
1554 {
1555         struct cifs_readdata *rdata = mid->callback_data;
1556         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1557         struct TCP_Server_Info *server = tcon->ses->server;
1558         struct smb_rqst rqst = { .rq_iov = rdata->iov,
1559                                  .rq_nvec = 2,
1560                                  .rq_pages = rdata->pages,
1561                                  .rq_npages = rdata->nr_pages,
1562                                  .rq_pagesz = rdata->pagesz,
1563                                  .rq_tailsz = rdata->tailsz };
1564
1565         cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1566                  __func__, mid->mid, mid->mid_state, rdata->result,
1567                  rdata->bytes);
1568
1569         switch (mid->mid_state) {
1570         case MID_RESPONSE_RECEIVED:
1571                 /* result already set, check signature */
1572                 if (server->sign) {
1573                         int rc = 0;
1574
1575                         rc = cifs_verify_signature(&rqst, server,
1576                                                   mid->sequence_number);
1577                         if (rc)
1578                                 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1579                                          rc);
1580                 }
1581                 /* FIXME: should this be counted toward the initiating task? */
1582                 task_io_account_read(rdata->got_bytes);
1583                 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1584                 break;
1585         case MID_REQUEST_SUBMITTED:
1586         case MID_RETRY_NEEDED:
1587                 rdata->result = -EAGAIN;
1588                 if (server->sign && rdata->got_bytes)
1589                         /* reset bytes number since we can not check a sign */
1590                         rdata->got_bytes = 0;
1591                 /* FIXME: should this be counted toward the initiating task? */
1592                 task_io_account_read(rdata->got_bytes);
1593                 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1594                 break;
1595         default:
1596                 rdata->result = -EIO;
1597         }
1598
1599         queue_work(cifsiod_wq, &rdata->work);
1600         DeleteMidQEntry(mid);
1601         add_credits(server, 1, 0);
1602 }
1603
1604 /* cifs_async_readv - send an async write, and set up mid to handle result */
1605 int
1606 cifs_async_readv(struct cifs_readdata *rdata)
1607 {
1608         int rc;
1609         READ_REQ *smb = NULL;
1610         int wct;
1611         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1612         struct smb_rqst rqst = { .rq_iov = rdata->iov,
1613                                  .rq_nvec = 2 };
1614
1615         cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1616                  __func__, rdata->offset, rdata->bytes);
1617
1618         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1619                 wct = 12;
1620         else {
1621                 wct = 10; /* old style read */
1622                 if ((rdata->offset >> 32) > 0)  {
1623                         /* can not handle this big offset for old */
1624                         return -EIO;
1625                 }
1626         }
1627
1628         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1629         if (rc)
1630                 return rc;
1631
1632         smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1633         smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1634
1635         smb->AndXCommand = 0xFF;        /* none */
1636         smb->Fid = rdata->cfile->fid.netfid;
1637         smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1638         if (wct == 12)
1639                 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1640         smb->Remaining = 0;
1641         smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1642         smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1643         if (wct == 12)
1644                 smb->ByteCount = 0;
1645         else {
1646                 /* old style read */
1647                 struct smb_com_readx_req *smbr =
1648                         (struct smb_com_readx_req *)smb;
1649                 smbr->ByteCount = 0;
1650         }
1651
1652         /* 4 for RFC1001 length + 1 for BCC */
1653         rdata->iov[0].iov_base = smb;
1654         rdata->iov[0].iov_len = 4;
1655         rdata->iov[1].iov_base = (char *)smb + 4;
1656         rdata->iov[1].iov_len = get_rfc1002_length(smb);
1657
1658         kref_get(&rdata->refcount);
1659         rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1660                              cifs_readv_callback, NULL, rdata, 0);
1661
1662         if (rc == 0)
1663                 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1664         else
1665                 kref_put(&rdata->refcount, cifs_readdata_release);
1666
1667         cifs_small_buf_release(smb);
1668         return rc;
1669 }
1670
1671 int
1672 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1673             unsigned int *nbytes, char **buf, int *pbuf_type)
1674 {
1675         int rc = -EACCES;
1676         READ_REQ *pSMB = NULL;
1677         READ_RSP *pSMBr = NULL;
1678         char *pReadData = NULL;
1679         int wct;
1680         int resp_buf_type = 0;
1681         struct kvec iov[1];
1682         struct kvec rsp_iov;
1683         __u32 pid = io_parms->pid;
1684         __u16 netfid = io_parms->netfid;
1685         __u64 offset = io_parms->offset;
1686         struct cifs_tcon *tcon = io_parms->tcon;
1687         unsigned int count = io_parms->length;
1688
1689         cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1690         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1691                 wct = 12;
1692         else {
1693                 wct = 10; /* old style read */
1694                 if ((offset >> 32) > 0)  {
1695                         /* can not handle this big offset for old */
1696                         return -EIO;
1697                 }
1698         }
1699
1700         *nbytes = 0;
1701         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1702         if (rc)
1703                 return rc;
1704
1705         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1706         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1707
1708         /* tcon and ses pointer are checked in smb_init */
1709         if (tcon->ses->server == NULL)
1710                 return -ECONNABORTED;
1711
1712         pSMB->AndXCommand = 0xFF;       /* none */
1713         pSMB->Fid = netfid;
1714         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1715         if (wct == 12)
1716                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1717
1718         pSMB->Remaining = 0;
1719         pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1720         pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1721         if (wct == 12)
1722                 pSMB->ByteCount = 0;  /* no need to do le conversion since 0 */
1723         else {
1724                 /* old style read */
1725                 struct smb_com_readx_req *pSMBW =
1726                         (struct smb_com_readx_req *)pSMB;
1727                 pSMBW->ByteCount = 0;
1728         }
1729
1730         iov[0].iov_base = (char *)pSMB;
1731         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1732         rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1733                           CIFS_LOG_ERROR, &rsp_iov);
1734         cifs_small_buf_release(pSMB);
1735         cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1736         pSMBr = (READ_RSP *)rsp_iov.iov_base;
1737         if (rc) {
1738                 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1739         } else {
1740                 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1741                 data_length = data_length << 16;
1742                 data_length += le16_to_cpu(pSMBr->DataLength);
1743                 *nbytes = data_length;
1744
1745                 /*check that DataLength would not go beyond end of SMB */
1746                 if ((data_length > CIFSMaxBufSize)
1747                                 || (data_length > count)) {
1748                         cifs_dbg(FYI, "bad length %d for count %d\n",
1749                                  data_length, count);
1750                         rc = -EIO;
1751                         *nbytes = 0;
1752                 } else {
1753                         pReadData = (char *) (&pSMBr->hdr.Protocol) +
1754                                         le16_to_cpu(pSMBr->DataOffset);
1755 /*                      if (rc = copy_to_user(buf, pReadData, data_length)) {
1756                                 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1757                                 rc = -EFAULT;
1758                         }*/ /* can not use copy_to_user when using page cache*/
1759                         if (*buf)
1760                                 memcpy(*buf, pReadData, data_length);
1761                 }
1762         }
1763
1764         if (*buf) {
1765                 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1766         } else if (resp_buf_type != CIFS_NO_BUFFER) {
1767                 /* return buffer to caller to free */
1768                 *buf = rsp_iov.iov_base;
1769                 if (resp_buf_type == CIFS_SMALL_BUFFER)
1770                         *pbuf_type = CIFS_SMALL_BUFFER;
1771                 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1772                         *pbuf_type = CIFS_LARGE_BUFFER;
1773         } /* else no valid buffer on return - leave as null */
1774
1775         /* Note: On -EAGAIN error only caller can retry on handle based calls
1776                 since file handle passed in no longer valid */
1777         return rc;
1778 }
1779
1780
1781 int
1782 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1783              unsigned int *nbytes, const char *buf)
1784 {
1785         int rc = -EACCES;
1786         WRITE_REQ *pSMB = NULL;
1787         WRITE_RSP *pSMBr = NULL;
1788         int bytes_returned, wct;
1789         __u32 bytes_sent;
1790         __u16 byte_count;
1791         __u32 pid = io_parms->pid;
1792         __u16 netfid = io_parms->netfid;
1793         __u64 offset = io_parms->offset;
1794         struct cifs_tcon *tcon = io_parms->tcon;
1795         unsigned int count = io_parms->length;
1796
1797         *nbytes = 0;
1798
1799         /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1800         if (tcon->ses == NULL)
1801                 return -ECONNABORTED;
1802
1803         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1804                 wct = 14;
1805         else {
1806                 wct = 12;
1807                 if ((offset >> 32) > 0) {
1808                         /* can not handle big offset for old srv */
1809                         return -EIO;
1810                 }
1811         }
1812
1813         rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1814                       (void **) &pSMBr);
1815         if (rc)
1816                 return rc;
1817
1818         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1819         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1820
1821         /* tcon and ses pointer are checked in smb_init */
1822         if (tcon->ses->server == NULL)
1823                 return -ECONNABORTED;
1824
1825         pSMB->AndXCommand = 0xFF;       /* none */
1826         pSMB->Fid = netfid;
1827         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1828         if (wct == 14)
1829                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1830
1831         pSMB->Reserved = 0xFFFFFFFF;
1832         pSMB->WriteMode = 0;
1833         pSMB->Remaining = 0;
1834
1835         /* Can increase buffer size if buffer is big enough in some cases ie we
1836         can send more if LARGE_WRITE_X capability returned by the server and if
1837         our buffer is big enough or if we convert to iovecs on socket writes
1838         and eliminate the copy to the CIFS buffer */
1839         if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1840                 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1841         } else {
1842                 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1843                          & ~0xFF;
1844         }
1845
1846         if (bytes_sent > count)
1847                 bytes_sent = count;
1848         pSMB->DataOffset =
1849                 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1850         if (buf)
1851                 memcpy(pSMB->Data, buf, bytes_sent);
1852         else if (count != 0) {
1853                 /* No buffer */
1854                 cifs_buf_release(pSMB);
1855                 return -EINVAL;
1856         } /* else setting file size with write of zero bytes */
1857         if (wct == 14)
1858                 byte_count = bytes_sent + 1; /* pad */
1859         else /* wct == 12 */
1860                 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1861
1862         pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1863         pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1864         inc_rfc1001_len(pSMB, byte_count);
1865
1866         if (wct == 14)
1867                 pSMB->ByteCount = cpu_to_le16(byte_count);
1868         else { /* old style write has byte count 4 bytes earlier
1869                   so 4 bytes pad  */
1870                 struct smb_com_writex_req *pSMBW =
1871                         (struct smb_com_writex_req *)pSMB;
1872                 pSMBW->ByteCount = cpu_to_le16(byte_count);
1873         }
1874
1875         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1876                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1877         cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1878         if (rc) {
1879                 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1880         } else {
1881                 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1882                 *nbytes = (*nbytes) << 16;
1883                 *nbytes += le16_to_cpu(pSMBr->Count);
1884
1885                 /*
1886                  * Mask off high 16 bits when bytes written as returned by the
1887                  * server is greater than bytes requested by the client. Some
1888                  * OS/2 servers are known to set incorrect CountHigh values.
1889                  */
1890                 if (*nbytes > count)
1891                         *nbytes &= 0xFFFF;
1892         }
1893
1894         cifs_buf_release(pSMB);
1895
1896         /* Note: On -EAGAIN error only caller can retry on handle based calls
1897                 since file handle passed in no longer valid */
1898
1899         return rc;
1900 }
1901
1902 void
1903 cifs_writedata_release(struct kref *refcount)
1904 {
1905         struct cifs_writedata *wdata = container_of(refcount,
1906                                         struct cifs_writedata, refcount);
1907
1908         if (wdata->cfile)
1909                 cifsFileInfo_put(wdata->cfile);
1910
1911         kfree(wdata);
1912 }
1913
1914 /*
1915  * Write failed with a retryable error. Resend the write request. It's also
1916  * possible that the page was redirtied so re-clean the page.
1917  */
1918 static void
1919 cifs_writev_requeue(struct cifs_writedata *wdata)
1920 {
1921         int i, rc = 0;
1922         struct inode *inode = d_inode(wdata->cfile->dentry);
1923         struct TCP_Server_Info *server;
1924         unsigned int rest_len;
1925
1926         server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1927         i = 0;
1928         rest_len = wdata->bytes;
1929         do {
1930                 struct cifs_writedata *wdata2;
1931                 unsigned int j, nr_pages, wsize, tailsz, cur_len;
1932
1933                 wsize = server->ops->wp_retry_size(inode);
1934                 if (wsize < rest_len) {
1935                         nr_pages = wsize / PAGE_SIZE;
1936                         if (!nr_pages) {
1937                                 rc = -ENOTSUPP;
1938                                 break;
1939                         }
1940                         cur_len = nr_pages * PAGE_SIZE;
1941                         tailsz = PAGE_SIZE;
1942                 } else {
1943                         nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
1944                         cur_len = rest_len;
1945                         tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
1946                 }
1947
1948                 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
1949                 if (!wdata2) {
1950                         rc = -ENOMEM;
1951                         break;
1952                 }
1953
1954                 for (j = 0; j < nr_pages; j++) {
1955                         wdata2->pages[j] = wdata->pages[i + j];
1956                         lock_page(wdata2->pages[j]);
1957                         clear_page_dirty_for_io(wdata2->pages[j]);
1958                 }
1959
1960                 wdata2->sync_mode = wdata->sync_mode;
1961                 wdata2->nr_pages = nr_pages;
1962                 wdata2->offset = page_offset(wdata2->pages[0]);
1963                 wdata2->pagesz = PAGE_SIZE;
1964                 wdata2->tailsz = tailsz;
1965                 wdata2->bytes = cur_len;
1966
1967                 wdata2->cfile = find_writable_file(CIFS_I(inode), false);
1968                 if (!wdata2->cfile) {
1969                         cifs_dbg(VFS, "No writable handles for inode\n");
1970                         rc = -EBADF;
1971                         break;
1972                 }
1973                 wdata2->pid = wdata2->cfile->pid;
1974                 rc = server->ops->async_writev(wdata2, cifs_writedata_release);
1975
1976                 for (j = 0; j < nr_pages; j++) {
1977                         unlock_page(wdata2->pages[j]);
1978                         if (rc != 0 && rc != -EAGAIN) {
1979                                 SetPageError(wdata2->pages[j]);
1980                                 end_page_writeback(wdata2->pages[j]);
1981                                 put_page(wdata2->pages[j]);
1982                         }
1983                 }
1984
1985                 if (rc) {
1986                         kref_put(&wdata2->refcount, cifs_writedata_release);
1987                         if (rc == -EAGAIN)
1988                                 continue;
1989                         break;
1990                 }
1991
1992                 rest_len -= cur_len;
1993                 i += nr_pages;
1994         } while (i < wdata->nr_pages);
1995
1996         mapping_set_error(inode->i_mapping, rc);
1997         kref_put(&wdata->refcount, cifs_writedata_release);
1998 }
1999
2000 void
2001 cifs_writev_complete(struct work_struct *work)
2002 {
2003         struct cifs_writedata *wdata = container_of(work,
2004                                                 struct cifs_writedata, work);
2005         struct inode *inode = d_inode(wdata->cfile->dentry);
2006         int i = 0;
2007
2008         if (wdata->result == 0) {
2009                 spin_lock(&inode->i_lock);
2010                 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2011                 spin_unlock(&inode->i_lock);
2012                 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2013                                          wdata->bytes);
2014         } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2015                 return cifs_writev_requeue(wdata);
2016
2017         for (i = 0; i < wdata->nr_pages; i++) {
2018                 struct page *page = wdata->pages[i];
2019                 if (wdata->result == -EAGAIN)
2020                         __set_page_dirty_nobuffers(page);
2021                 else if (wdata->result < 0)
2022                         SetPageError(page);
2023                 end_page_writeback(page);
2024                 put_page(page);
2025         }
2026         if (wdata->result != -EAGAIN)
2027                 mapping_set_error(inode->i_mapping, wdata->result);
2028         kref_put(&wdata->refcount, cifs_writedata_release);
2029 }
2030
2031 struct cifs_writedata *
2032 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2033 {
2034         struct cifs_writedata *wdata;
2035
2036         /* writedata + number of page pointers */
2037         wdata = kzalloc(sizeof(*wdata) +
2038                         sizeof(struct page *) * nr_pages, GFP_NOFS);
2039         if (wdata != NULL) {
2040                 kref_init(&wdata->refcount);
2041                 INIT_LIST_HEAD(&wdata->list);
2042                 init_completion(&wdata->done);
2043                 INIT_WORK(&wdata->work, complete);
2044         }
2045         return wdata;
2046 }
2047
2048 /*
2049  * Check the mid_state and signature on received buffer (if any), and queue the
2050  * workqueue completion task.
2051  */
2052 static void
2053 cifs_writev_callback(struct mid_q_entry *mid)
2054 {
2055         struct cifs_writedata *wdata = mid->callback_data;
2056         struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2057         unsigned int written;
2058         WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2059
2060         switch (mid->mid_state) {
2061         case MID_RESPONSE_RECEIVED:
2062                 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2063                 if (wdata->result != 0)
2064                         break;
2065
2066                 written = le16_to_cpu(smb->CountHigh);
2067                 written <<= 16;
2068                 written += le16_to_cpu(smb->Count);
2069                 /*
2070                  * Mask off high 16 bits when bytes written as returned
2071                  * by the server is greater than bytes requested by the
2072                  * client. OS/2 servers are known to set incorrect
2073                  * CountHigh values.
2074                  */
2075                 if (written > wdata->bytes)
2076                         written &= 0xFFFF;
2077
2078                 if (written < wdata->bytes)
2079                         wdata->result = -ENOSPC;
2080                 else
2081                         wdata->bytes = written;
2082                 break;
2083         case MID_REQUEST_SUBMITTED:
2084         case MID_RETRY_NEEDED:
2085                 wdata->result = -EAGAIN;
2086                 break;
2087         default:
2088                 wdata->result = -EIO;
2089                 break;
2090         }
2091
2092         queue_work(cifsiod_wq, &wdata->work);
2093         DeleteMidQEntry(mid);
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) != 0);
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                 struct cifs_sb_info *cifs_sb)
6073 {
6074                 /* BB assumes one setup word */
6075         TRANSACTION2_QPI_REQ *pSMB = NULL;
6076         TRANSACTION2_QPI_RSP *pSMBr = NULL;
6077         int remap = cifs_remap(cifs_sb);
6078         struct nls_table *nls_codepage = cifs_sb->local_nls;
6079         int rc = 0;
6080         int bytes_returned;
6081         int list_len;
6082         struct fealist *ea_response_data;
6083         struct fea *temp_fea;
6084         char *temp_ptr;
6085         char *end_of_smb;
6086         __u16 params, byte_count, data_offset;
6087         unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6088
6089         cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6090 QAllEAsRetry:
6091         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6092                       (void **) &pSMBr);
6093         if (rc)
6094                 return rc;
6095
6096         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6097                 list_len =
6098                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6099                                        PATH_MAX, nls_codepage, remap);
6100                 list_len++;     /* trailing null */
6101                 list_len *= 2;
6102         } else {        /* BB improve the check for buffer overruns BB */
6103                 list_len = strnlen(searchName, PATH_MAX);
6104                 list_len++;     /* trailing null */
6105                 strncpy(pSMB->FileName, searchName, list_len);
6106         }
6107
6108         params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6109         pSMB->TotalDataCount = 0;
6110         pSMB->MaxParameterCount = cpu_to_le16(2);
6111         /* BB find exact max SMB PDU from sess structure BB */
6112         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6113         pSMB->MaxSetupCount = 0;
6114         pSMB->Reserved = 0;
6115         pSMB->Flags = 0;
6116         pSMB->Timeout = 0;
6117         pSMB->Reserved2 = 0;
6118         pSMB->ParameterOffset = cpu_to_le16(offsetof(
6119         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6120         pSMB->DataCount = 0;
6121         pSMB->DataOffset = 0;
6122         pSMB->SetupCount = 1;
6123         pSMB->Reserved3 = 0;
6124         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6125         byte_count = params + 1 /* pad */ ;
6126         pSMB->TotalParameterCount = cpu_to_le16(params);
6127         pSMB->ParameterCount = pSMB->TotalParameterCount;
6128         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6129         pSMB->Reserved4 = 0;
6130         inc_rfc1001_len(pSMB, byte_count);
6131         pSMB->ByteCount = cpu_to_le16(byte_count);
6132
6133         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6134                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6135         if (rc) {
6136                 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6137                 goto QAllEAsOut;
6138         }
6139
6140
6141         /* BB also check enough total bytes returned */
6142         /* BB we need to improve the validity checking
6143         of these trans2 responses */
6144
6145         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6146         if (rc || get_bcc(&pSMBr->hdr) < 4) {
6147                 rc = -EIO;      /* bad smb */
6148                 goto QAllEAsOut;
6149         }
6150
6151         /* check that length of list is not more than bcc */
6152         /* check that each entry does not go beyond length
6153            of list */
6154         /* check that each element of each entry does not
6155            go beyond end of list */
6156         /* validate_trans2_offsets() */
6157         /* BB check if start of smb + data_offset > &bcc+ bcc */
6158
6159         data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6160         ea_response_data = (struct fealist *)
6161                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6162
6163         list_len = le32_to_cpu(ea_response_data->list_len);
6164         cifs_dbg(FYI, "ea length %d\n", list_len);
6165         if (list_len <= 8) {
6166                 cifs_dbg(FYI, "empty EA list returned from server\n");
6167                 /* didn't find the named attribute */
6168                 if (ea_name)
6169                         rc = -ENODATA;
6170                 goto QAllEAsOut;
6171         }
6172
6173         /* make sure list_len doesn't go past end of SMB */
6174         end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6175         if ((char *)ea_response_data + list_len > end_of_smb) {
6176                 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6177                 rc = -EIO;
6178                 goto QAllEAsOut;
6179         }
6180
6181         /* account for ea list len */
6182         list_len -= 4;
6183         temp_fea = ea_response_data->list;
6184         temp_ptr = (char *)temp_fea;
6185         while (list_len > 0) {
6186                 unsigned int name_len;
6187                 __u16 value_len;
6188
6189                 list_len -= 4;
6190                 temp_ptr += 4;
6191                 /* make sure we can read name_len and value_len */
6192                 if (list_len < 0) {
6193                         cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6194                         rc = -EIO;
6195                         goto QAllEAsOut;
6196                 }
6197
6198                 name_len = temp_fea->name_len;
6199                 value_len = le16_to_cpu(temp_fea->value_len);
6200                 list_len -= name_len + 1 + value_len;
6201                 if (list_len < 0) {
6202                         cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6203                         rc = -EIO;
6204                         goto QAllEAsOut;
6205                 }
6206
6207                 if (ea_name) {
6208                         if (ea_name_len == name_len &&
6209                             memcmp(ea_name, temp_ptr, name_len) == 0) {
6210                                 temp_ptr += name_len + 1;
6211                                 rc = value_len;
6212                                 if (buf_size == 0)
6213                                         goto QAllEAsOut;
6214                                 if ((size_t)value_len > buf_size) {
6215                                         rc = -ERANGE;
6216                                         goto QAllEAsOut;
6217                                 }
6218                                 memcpy(EAData, temp_ptr, value_len);
6219                                 goto QAllEAsOut;
6220                         }
6221                 } else {
6222                         /* account for prefix user. and trailing null */
6223                         rc += (5 + 1 + name_len);
6224                         if (rc < (int) buf_size) {
6225                                 memcpy(EAData, "user.", 5);
6226                                 EAData += 5;
6227                                 memcpy(EAData, temp_ptr, name_len);
6228                                 EAData += name_len;
6229                                 /* null terminate name */
6230                                 *EAData = 0;
6231                                 ++EAData;
6232                         } else if (buf_size == 0) {
6233                                 /* skip copy - calc size only */
6234                         } else {
6235                                 /* stop before overrun buffer */
6236                                 rc = -ERANGE;
6237                                 break;
6238                         }
6239                 }
6240                 temp_ptr += name_len + 1 + value_len;
6241                 temp_fea = (struct fea *)temp_ptr;
6242         }
6243
6244         /* didn't find the named attribute */
6245         if (ea_name)
6246                 rc = -ENODATA;
6247
6248 QAllEAsOut:
6249         cifs_buf_release(pSMB);
6250         if (rc == -EAGAIN)
6251                 goto QAllEAsRetry;
6252
6253         return (ssize_t)rc;
6254 }
6255
6256 int
6257 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6258              const char *fileName, const char *ea_name, const void *ea_value,
6259              const __u16 ea_value_len, const struct nls_table *nls_codepage,
6260              int remap)
6261 {
6262         struct smb_com_transaction2_spi_req *pSMB = NULL;
6263         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6264         struct fealist *parm_data;
6265         int name_len;
6266         int rc = 0;
6267         int bytes_returned = 0;
6268         __u16 params, param_offset, byte_count, offset, count;
6269
6270         cifs_dbg(FYI, "In SetEA\n");
6271 SetEARetry:
6272         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6273                       (void **) &pSMBr);
6274         if (rc)
6275                 return rc;
6276
6277         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6278                 name_len =
6279                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6280                                        PATH_MAX, nls_codepage, remap);
6281                 name_len++;     /* trailing null */
6282                 name_len *= 2;
6283         } else {        /* BB improve the check for buffer overruns BB */
6284                 name_len = strnlen(fileName, PATH_MAX);
6285                 name_len++;     /* trailing null */
6286                 strncpy(pSMB->FileName, fileName, name_len);
6287         }
6288
6289         params = 6 + name_len;
6290
6291         /* done calculating parms using name_len of file name,
6292         now use name_len to calculate length of ea name
6293         we are going to create in the inode xattrs */
6294         if (ea_name == NULL)
6295                 name_len = 0;
6296         else
6297                 name_len = strnlen(ea_name, 255);
6298
6299         count = sizeof(*parm_data) + ea_value_len + name_len;
6300         pSMB->MaxParameterCount = cpu_to_le16(2);
6301         /* BB find max SMB PDU from sess */
6302         pSMB->MaxDataCount = cpu_to_le16(1000);
6303         pSMB->MaxSetupCount = 0;
6304         pSMB->Reserved = 0;
6305         pSMB->Flags = 0;
6306         pSMB->Timeout = 0;
6307         pSMB->Reserved2 = 0;
6308         param_offset = offsetof(struct smb_com_transaction2_spi_req,
6309                                 InformationLevel) - 4;
6310         offset = param_offset + params;
6311         pSMB->InformationLevel =
6312                 cpu_to_le16(SMB_SET_FILE_EA);
6313
6314         parm_data =
6315                 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6316                                        offset);
6317         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6318         pSMB->DataOffset = cpu_to_le16(offset);
6319         pSMB->SetupCount = 1;
6320         pSMB->Reserved3 = 0;
6321         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6322         byte_count = 3 /* pad */  + params + count;
6323         pSMB->DataCount = cpu_to_le16(count);
6324         parm_data->list_len = cpu_to_le32(count);
6325         parm_data->list[0].EA_flags = 0;
6326         /* we checked above that name len is less than 255 */
6327         parm_data->list[0].name_len = (__u8)name_len;
6328         /* EA names are always ASCII */
6329         if (ea_name)
6330                 strncpy(parm_data->list[0].name, ea_name, name_len);
6331         parm_data->list[0].name[name_len] = 0;
6332         parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6333         /* caller ensures that ea_value_len is less than 64K but
6334         we need to ensure that it fits within the smb */
6335
6336         /*BB add length check to see if it would fit in
6337              negotiated SMB buffer size BB */
6338         /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6339         if (ea_value_len)
6340                 memcpy(parm_data->list[0].name+name_len+1,
6341                        ea_value, ea_value_len);
6342
6343         pSMB->TotalDataCount = pSMB->DataCount;
6344         pSMB->ParameterCount = cpu_to_le16(params);
6345         pSMB->TotalParameterCount = pSMB->ParameterCount;
6346         pSMB->Reserved4 = 0;
6347         inc_rfc1001_len(pSMB, byte_count);
6348         pSMB->ByteCount = cpu_to_le16(byte_count);
6349         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6350                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6351         if (rc)
6352                 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6353
6354         cifs_buf_release(pSMB);
6355
6356         if (rc == -EAGAIN)
6357                 goto SetEARetry;
6358
6359         return rc;
6360 }
6361 #endif
6362
6363 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6364 /*
6365  *      Years ago the kernel added a "dnotify" function for Samba server,
6366  *      to allow network clients (such as Windows) to display updated
6367  *      lists of files in directory listings automatically when
6368  *      files are added by one user when another user has the
6369  *      same directory open on their desktop.  The Linux cifs kernel
6370  *      client hooked into the kernel side of this interface for
6371  *      the same reason, but ironically when the VFS moved from
6372  *      "dnotify" to "inotify" it became harder to plug in Linux
6373  *      network file system clients (the most obvious use case
6374  *      for notify interfaces is when multiple users can update
6375  *      the contents of the same directory - exactly what network
6376  *      file systems can do) although the server (Samba) could
6377  *      still use it.  For the short term we leave the worker
6378  *      function ifdeffed out (below) until inotify is fixed
6379  *      in the VFS to make it easier to plug in network file
6380  *      system clients.  If inotify turns out to be permanently
6381  *      incompatible for network fs clients, we could instead simply
6382  *      expose this config flag by adding a future cifs (and smb2) notify ioctl.
6383  */
6384 int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
6385                   const int notify_subdirs, const __u16 netfid,
6386                   __u32 filter, struct file *pfile, int multishot,
6387                   const struct nls_table *nls_codepage)
6388 {
6389         int rc = 0;
6390         struct smb_com_transaction_change_notify_req *pSMB = NULL;
6391         struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6392         struct dir_notify_req *dnotify_req;
6393         int bytes_returned;
6394
6395         cifs_dbg(FYI, "In CIFSSMBNotify for file handle %d\n", (int)netfid);
6396         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6397                       (void **) &pSMBr);
6398         if (rc)
6399                 return rc;
6400
6401         pSMB->TotalParameterCount = 0 ;
6402         pSMB->TotalDataCount = 0;
6403         pSMB->MaxParameterCount = cpu_to_le32(2);
6404         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6405         pSMB->MaxSetupCount = 4;
6406         pSMB->Reserved = 0;
6407         pSMB->ParameterOffset = 0;
6408         pSMB->DataCount = 0;
6409         pSMB->DataOffset = 0;
6410         pSMB->SetupCount = 4; /* single byte does not need le conversion */
6411         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6412         pSMB->ParameterCount = pSMB->TotalParameterCount;
6413         if (notify_subdirs)
6414                 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6415         pSMB->Reserved2 = 0;
6416         pSMB->CompletionFilter = cpu_to_le32(filter);
6417         pSMB->Fid = netfid; /* file handle always le */
6418         pSMB->ByteCount = 0;
6419
6420         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6421                          (struct smb_hdr *)pSMBr, &bytes_returned,
6422                          CIFS_ASYNC_OP);
6423         if (rc) {
6424                 cifs_dbg(FYI, "Error in Notify = %d\n", rc);
6425         } else {
6426                 /* Add file to outstanding requests */
6427                 /* BB change to kmem cache alloc */
6428                 dnotify_req = kmalloc(
6429                                                 sizeof(struct dir_notify_req),
6430                                                  GFP_KERNEL);
6431                 if (dnotify_req) {
6432                         dnotify_req->Pid = pSMB->hdr.Pid;
6433                         dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6434                         dnotify_req->Mid = pSMB->hdr.Mid;
6435                         dnotify_req->Tid = pSMB->hdr.Tid;
6436                         dnotify_req->Uid = pSMB->hdr.Uid;
6437                         dnotify_req->netfid = netfid;
6438                         dnotify_req->pfile = pfile;
6439                         dnotify_req->filter = filter;
6440                         dnotify_req->multishot = multishot;
6441                         spin_lock(&GlobalMid_Lock);
6442                         list_add_tail(&dnotify_req->lhead,
6443                                         &GlobalDnotifyReqList);
6444                         spin_unlock(&GlobalMid_Lock);
6445                 } else
6446                         rc = -ENOMEM;
6447         }
6448         cifs_buf_release(pSMB);
6449         return rc;
6450 }
6451 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */