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