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