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