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