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