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