Merge tag '4.14-smb3-xattr-enable' of git://git.samba.org/sfrench/cifs-2.6
[muen/linux.git] / fs / cifs / cifssmb.c
1 /*
2  *   fs/cifs/cifssmb.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002,2010
5  *   Author(s): Steve French (sfrench@us.ibm.com)
6  *
7  *   Contains the routines for constructing the SMB PDUs themselves
8  *
9  *   This library is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU Lesser General Public License as published
11  *   by the Free Software Foundation; either version 2.1 of the License, or
12  *   (at your option) any later version.
13  *
14  *   This library is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17  *   the GNU Lesser General Public License for more details.
18  *
19  *   You should have received a copy of the GNU Lesser General Public License
20  *   along with this library; if not, write to the Free Software
21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23
24  /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c   */
25  /* These are mostly routines that operate on a pathname, or on a tree id     */
26  /* (mounted volume), but there are eight handle based routines which must be */
27  /* treated slightly differently for reconnection purposes since we never     */
28  /* want to reuse a stale file handle and only the caller knows the file info */
29
30 #include <linux/fs.h>
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <linux/uaccess.h>
39 #include "cifspdu.h"
40 #include "cifsglob.h"
41 #include "cifsacl.h"
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
45 #include "fscache.h"
46
47 #ifdef CONFIG_CIFS_POSIX
48 static struct {
49         int index;
50         char *name;
51 } protocols[] = {
52 #ifdef CONFIG_CIFS_WEAK_PW_HASH
53         {LANMAN_PROT, "\2LM1.2X002"},
54         {LANMAN2_PROT, "\2LANMAN2.1"},
55 #endif /* weak password hashing for legacy clients */
56         {CIFS_PROT, "\2NT LM 0.12"},
57         {POSIX_PROT, "\2POSIX 2"},
58         {BAD_PROT, "\2"}
59 };
60 #else
61 static struct {
62         int index;
63         char *name;
64 } protocols[] = {
65 #ifdef CONFIG_CIFS_WEAK_PW_HASH
66         {LANMAN_PROT, "\2LM1.2X002"},
67         {LANMAN2_PROT, "\2LANMAN2.1"},
68 #endif /* weak password hashing for legacy clients */
69         {CIFS_PROT, "\2NT LM 0.12"},
70         {BAD_PROT, "\2"}
71 };
72 #endif
73
74 /* define the number of elements in the cifs dialect array */
75 #ifdef CONFIG_CIFS_POSIX
76 #ifdef CONFIG_CIFS_WEAK_PW_HASH
77 #define CIFS_NUM_PROT 4
78 #else
79 #define CIFS_NUM_PROT 2
80 #endif /* CIFS_WEAK_PW_HASH */
81 #else /* not posix */
82 #ifdef CONFIG_CIFS_WEAK_PW_HASH
83 #define CIFS_NUM_PROT 3
84 #else
85 #define CIFS_NUM_PROT 1
86 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
87 #endif /* CIFS_POSIX */
88
89 /*
90  * Mark as invalid, all open files on tree connections since they
91  * were closed when session to server was lost.
92  */
93 void
94 cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
95 {
96         struct cifsFileInfo *open_file = NULL;
97         struct list_head *tmp;
98         struct list_head *tmp1;
99
100         /* list all files open on tree connection and mark them invalid */
101         spin_lock(&tcon->open_file_lock);
102         list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
103                 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
104                 open_file->invalidHandle = true;
105                 open_file->oplock_break_cancelled = true;
106         }
107         spin_unlock(&tcon->open_file_lock);
108         /*
109          * BB Add call to invalidate_inodes(sb) for all superblocks mounted
110          * to this tcon.
111          */
112 }
113
114 /* reconnect the socket, tcon, and smb session if needed */
115 static int
116 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
117 {
118         int rc;
119         struct cifs_ses *ses;
120         struct TCP_Server_Info *server;
121         struct nls_table *nls_codepage;
122
123         /*
124          * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
125          * tcp and smb session status done differently for those three - in the
126          * calling routine
127          */
128         if (!tcon)
129                 return 0;
130
131         ses = tcon->ses;
132         server = ses->server;
133
134         /*
135          * only tree disconnect, open, and write, (and ulogoff which does not
136          * have tcon) are allowed as we start force umount
137          */
138         if (tcon->tidStatus == CifsExiting) {
139                 if (smb_command != SMB_COM_WRITE_ANDX &&
140                     smb_command != SMB_COM_OPEN_ANDX &&
141                     smb_command != SMB_COM_TREE_DISCONNECT) {
142                         cifs_dbg(FYI, "can not send cmd %d while umounting\n",
143                                  smb_command);
144                         return -ENODEV;
145                 }
146         }
147
148         /*
149          * Give demultiplex thread up to 10 seconds to reconnect, should be
150          * greater than cifs socket timeout which is 7 seconds
151          */
152         while (server->tcpStatus == CifsNeedReconnect) {
153                 wait_event_interruptible_timeout(server->response_q,
154                         (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
155
156                 /* are we still trying to reconnect? */
157                 if (server->tcpStatus != CifsNeedReconnect)
158                         break;
159
160                 /*
161                  * on "soft" mounts we wait once. Hard mounts keep
162                  * retrying until process is killed or server comes
163                  * back on-line
164                  */
165                 if (!tcon->retry) {
166                         cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
167                         return -EHOSTDOWN;
168                 }
169         }
170
171         if (!ses->need_reconnect && !tcon->need_reconnect)
172                 return 0;
173
174         nls_codepage = load_nls_default();
175
176         /*
177          * need to prevent multiple threads trying to simultaneously
178          * reconnect the same SMB session
179          */
180         mutex_lock(&ses->session_mutex);
181
182         /*
183          * Recheck after acquire mutex. If another thread is negotiating
184          * and the server never sends an answer the socket will be closed
185          * and tcpStatus set to reconnect.
186          */
187         if (server->tcpStatus == CifsNeedReconnect) {
188                 rc = -EHOSTDOWN;
189                 mutex_unlock(&ses->session_mutex);
190                 goto out;
191         }
192
193         rc = cifs_negotiate_protocol(0, ses);
194         if (rc == 0 && ses->need_reconnect)
195                 rc = cifs_setup_session(0, ses, nls_codepage);
196
197         /* do we need to reconnect tcon? */
198         if (rc || !tcon->need_reconnect) {
199                 mutex_unlock(&ses->session_mutex);
200                 goto out;
201         }
202
203         cifs_mark_open_files_invalid(tcon);
204         rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
205         mutex_unlock(&ses->session_mutex);
206         cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
207
208         if (rc)
209                 goto out;
210
211         atomic_inc(&tconInfoReconnectCount);
212
213         /* tell server Unix caps we support */
214         if (ses->capabilities & CAP_UNIX)
215                 reset_cifs_unix_caps(0, tcon, NULL, NULL);
216
217         /*
218          * Removed call to reopen open files here. It is safer (and faster) to
219          * reopen files one at a time as needed in read and write.
220          *
221          * FIXME: what about file locks? don't we need to reclaim them ASAP?
222          */
223
224 out:
225         /*
226          * Check if handle based operation so we know whether we can continue
227          * or not without returning to caller to reset file handle
228          */
229         switch (smb_command) {
230         case SMB_COM_READ_ANDX:
231         case SMB_COM_WRITE_ANDX:
232         case SMB_COM_CLOSE:
233         case SMB_COM_FIND_CLOSE2:
234         case SMB_COM_LOCKING_ANDX:
235                 rc = -EAGAIN;
236         }
237
238         unload_nls(nls_codepage);
239         return rc;
240 }
241
242 /* Allocate and return pointer to an SMB request buffer, and set basic
243    SMB information in the SMB header.  If the return code is zero, this
244    function must have filled in request_buf pointer */
245 static int
246 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
247                 void **request_buf)
248 {
249         int rc;
250
251         rc = cifs_reconnect_tcon(tcon, smb_command);
252         if (rc)
253                 return rc;
254
255         *request_buf = cifs_small_buf_get();
256         if (*request_buf == NULL) {
257                 /* BB should we add a retry in here if not a writepage? */
258                 return -ENOMEM;
259         }
260
261         header_assemble((struct smb_hdr *) *request_buf, smb_command,
262                         tcon, wct);
263
264         if (tcon != NULL)
265                 cifs_stats_inc(&tcon->num_smbs_sent);
266
267         return 0;
268 }
269
270 int
271 small_smb_init_no_tc(const int smb_command, const int wct,
272                      struct cifs_ses *ses, void **request_buf)
273 {
274         int rc;
275         struct smb_hdr *buffer;
276
277         rc = small_smb_init(smb_command, wct, NULL, request_buf);
278         if (rc)
279                 return rc;
280
281         buffer = (struct smb_hdr *)*request_buf;
282         buffer->Mid = get_next_mid(ses->server);
283         if (ses->capabilities & CAP_UNICODE)
284                 buffer->Flags2 |= SMBFLG2_UNICODE;
285         if (ses->capabilities & CAP_STATUS32)
286                 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
287
288         /* uid, tid can stay at zero as set in header assemble */
289
290         /* BB add support for turning on the signing when
291         this function is used after 1st of session setup requests */
292
293         return rc;
294 }
295
296 /* If the return code is zero, this function must fill in request_buf pointer */
297 static int
298 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
299                         void **request_buf, void **response_buf)
300 {
301         *request_buf = cifs_buf_get();
302         if (*request_buf == NULL) {
303                 /* BB should we add a retry in here if not a writepage? */
304                 return -ENOMEM;
305         }
306     /* Although the original thought was we needed the response buf for  */
307     /* potential retries of smb operations it turns out we can determine */
308     /* from the mid flags when the request buffer can be resent without  */
309     /* having to use a second distinct buffer for the response */
310         if (response_buf)
311                 *response_buf = *request_buf;
312
313         header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
314                         wct);
315
316         if (tcon != NULL)
317                 cifs_stats_inc(&tcon->num_smbs_sent);
318
319         return 0;
320 }
321
322 /* If the return code is zero, this function must fill in request_buf pointer */
323 static int
324 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
325          void **request_buf, void **response_buf)
326 {
327         int rc;
328
329         rc = cifs_reconnect_tcon(tcon, smb_command);
330         if (rc)
331                 return rc;
332
333         return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
334 }
335
336 static int
337 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
338                         void **request_buf, void **response_buf)
339 {
340         if (tcon->ses->need_reconnect || tcon->need_reconnect)
341                 return -EHOSTDOWN;
342
343         return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
344 }
345
346 static int validate_t2(struct smb_t2_rsp *pSMB)
347 {
348         unsigned int total_size;
349
350         /* check for plausible wct */
351         if (pSMB->hdr.WordCount < 10)
352                 goto vt2_err;
353
354         /* check for parm and data offset going beyond end of smb */
355         if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
356             get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
357                 goto vt2_err;
358
359         total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
360         if (total_size >= 512)
361                 goto vt2_err;
362
363         /* check that bcc is at least as big as parms + data, and that it is
364          * less than negotiated smb buffer
365          */
366         total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
367         if (total_size > get_bcc(&pSMB->hdr) ||
368             total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
369                 goto vt2_err;
370
371         return 0;
372 vt2_err:
373         cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
374                 sizeof(struct smb_t2_rsp) + 16);
375         return -EINVAL;
376 }
377
378 static int
379 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
380 {
381         int     rc = 0;
382         u16     count;
383         char    *guid = pSMBr->u.extended_response.GUID;
384         struct TCP_Server_Info *server = ses->server;
385
386         count = get_bcc(&pSMBr->hdr);
387         if (count < SMB1_CLIENT_GUID_SIZE)
388                 return -EIO;
389
390         spin_lock(&cifs_tcp_ses_lock);
391         if (server->srv_count > 1) {
392                 spin_unlock(&cifs_tcp_ses_lock);
393                 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
394                         cifs_dbg(FYI, "server UID changed\n");
395                         memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
396                 }
397         } else {
398                 spin_unlock(&cifs_tcp_ses_lock);
399                 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
400         }
401
402         if (count == SMB1_CLIENT_GUID_SIZE) {
403                 server->sec_ntlmssp = true;
404         } else {
405                 count -= SMB1_CLIENT_GUID_SIZE;
406                 rc = decode_negTokenInit(
407                         pSMBr->u.extended_response.SecurityBlob, count, server);
408                 if (rc != 1)
409                         return -EINVAL;
410         }
411
412         return 0;
413 }
414
415 int
416 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
417 {
418         bool srv_sign_required = server->sec_mode & server->vals->signing_required;
419         bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
420         bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
421
422         /*
423          * Is signing required by mnt options? If not then check
424          * global_secflags to see if it is there.
425          */
426         if (!mnt_sign_required)
427                 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
428                                                 CIFSSEC_MUST_SIGN);
429
430         /*
431          * If signing is required then it's automatically enabled too,
432          * otherwise, check to see if the secflags allow it.
433          */
434         mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
435                                 (global_secflags & CIFSSEC_MAY_SIGN);
436
437         /* If server requires signing, does client allow it? */
438         if (srv_sign_required) {
439                 if (!mnt_sign_enabled) {
440                         cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!");
441                         return -ENOTSUPP;
442                 }
443                 server->sign = true;
444         }
445
446         /* If client requires signing, does server allow it? */
447         if (mnt_sign_required) {
448                 if (!srv_sign_enabled) {
449                         cifs_dbg(VFS, "Server does not support signing!");
450                         return -ENOTSUPP;
451                 }
452                 server->sign = true;
453         }
454
455         return 0;
456 }
457
458 #ifdef CONFIG_CIFS_WEAK_PW_HASH
459 static int
460 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
461 {
462         __s16 tmp;
463         struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
464
465         if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
466                 return -EOPNOTSUPP;
467
468         server->sec_mode = le16_to_cpu(rsp->SecurityMode);
469         server->maxReq = min_t(unsigned int,
470                                le16_to_cpu(rsp->MaxMpxCount),
471                                cifs_max_pending);
472         set_credits(server, server->maxReq);
473         server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
474         /* even though we do not use raw we might as well set this
475         accurately, in case we ever find a need for it */
476         if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
477                 server->max_rw = 0xFF00;
478                 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
479         } else {
480                 server->max_rw = 0;/* do not need to use raw anyway */
481                 server->capabilities = CAP_MPX_MODE;
482         }
483         tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
484         if (tmp == -1) {
485                 /* OS/2 often does not set timezone therefore
486                  * we must use server time to calc time zone.
487                  * Could deviate slightly from the right zone.
488                  * Smallest defined timezone difference is 15 minutes
489                  * (i.e. Nepal).  Rounding up/down is done to match
490                  * this requirement.
491                  */
492                 int val, seconds, remain, result;
493                 struct timespec ts;
494                 unsigned long utc = ktime_get_real_seconds();
495                 ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
496                                     rsp->SrvTime.Time, 0);
497                 cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
498                          (int)ts.tv_sec, (int)utc,
499                          (int)(utc - ts.tv_sec));
500                 val = (int)(utc - ts.tv_sec);
501                 seconds = abs(val);
502                 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
503                 remain = seconds % MIN_TZ_ADJ;
504                 if (remain >= (MIN_TZ_ADJ / 2))
505                         result += MIN_TZ_ADJ;
506                 if (val < 0)
507                         result = -result;
508                 server->timeAdj = result;
509         } else {
510                 server->timeAdj = (int)tmp;
511                 server->timeAdj *= 60; /* also in seconds */
512         }
513         cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
514
515
516         /* BB get server time for time conversions and add
517         code to use it and timezone since this is not UTC */
518
519         if (rsp->EncryptionKeyLength ==
520                         cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
521                 memcpy(server->cryptkey, rsp->EncryptionKey,
522                         CIFS_CRYPTO_KEY_SIZE);
523         } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
524                 return -EIO; /* need cryptkey unless plain text */
525         }
526
527         cifs_dbg(FYI, "LANMAN negotiated\n");
528         return 0;
529 }
530 #else
531 static inline int
532 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
533 {
534         cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
535         return -EOPNOTSUPP;
536 }
537 #endif
538
539 static bool
540 should_set_ext_sec_flag(enum securityEnum sectype)
541 {
542         switch (sectype) {
543         case RawNTLMSSP:
544         case Kerberos:
545                 return true;
546         case Unspecified:
547                 if (global_secflags &
548                     (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
549                         return true;
550                 /* Fallthrough */
551         default:
552                 return false;
553         }
554 }
555
556 int
557 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
558 {
559         NEGOTIATE_REQ *pSMB;
560         NEGOTIATE_RSP *pSMBr;
561         int rc = 0;
562         int bytes_returned;
563         int i;
564         struct TCP_Server_Info *server = ses->server;
565         u16 count;
566
567         if (!server) {
568                 WARN(1, "%s: server is NULL!\n", __func__);
569                 return -EIO;
570         }
571
572         rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
573                       (void **) &pSMB, (void **) &pSMBr);
574         if (rc)
575                 return rc;
576
577         pSMB->hdr.Mid = get_next_mid(server);
578         pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
579
580         if (should_set_ext_sec_flag(ses->sectype)) {
581                 cifs_dbg(FYI, "Requesting extended security.");
582                 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
583         }
584
585         count = 0;
586         for (i = 0; i < CIFS_NUM_PROT; i++) {
587                 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
588                 count += strlen(protocols[i].name) + 1;
589                 /* null at end of source and target buffers anyway */
590         }
591         inc_rfc1001_len(pSMB, count);
592         pSMB->ByteCount = cpu_to_le16(count);
593
594         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
595                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
596         if (rc != 0)
597                 goto neg_err_exit;
598
599         server->dialect = le16_to_cpu(pSMBr->DialectIndex);
600         cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
601         /* Check wct = 1 error case */
602         if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
603                 /* core returns wct = 1, but we do not ask for core - otherwise
604                 small wct just comes when dialect index is -1 indicating we
605                 could not negotiate a common dialect */
606                 rc = -EOPNOTSUPP;
607                 goto neg_err_exit;
608         } else if (pSMBr->hdr.WordCount == 13) {
609                 server->negflavor = CIFS_NEGFLAVOR_LANMAN;
610                 rc = decode_lanman_negprot_rsp(server, pSMBr);
611                 goto signing_check;
612         } else if (pSMBr->hdr.WordCount != 17) {
613                 /* unknown wct */
614                 rc = -EOPNOTSUPP;
615                 goto neg_err_exit;
616         }
617         /* else wct == 17, NTLM or better */
618
619         server->sec_mode = pSMBr->SecurityMode;
620         if ((server->sec_mode & SECMODE_USER) == 0)
621                 cifs_dbg(FYI, "share mode security\n");
622
623         /* one byte, so no need to convert this or EncryptionKeyLen from
624            little endian */
625         server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
626                                cifs_max_pending);
627         set_credits(server, server->maxReq);
628         /* probably no need to store and check maxvcs */
629         server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
630         server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
631         cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
632         server->capabilities = le32_to_cpu(pSMBr->Capabilities);
633         server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
634         server->timeAdj *= 60;
635
636         if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
637                 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
638                 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
639                        CIFS_CRYPTO_KEY_SIZE);
640         } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
641                         server->capabilities & CAP_EXTENDED_SECURITY) {
642                 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
643                 rc = decode_ext_sec_blob(ses, pSMBr);
644         } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
645                 rc = -EIO; /* no crypt key only if plain text pwd */
646         } else {
647                 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
648                 server->capabilities &= ~CAP_EXTENDED_SECURITY;
649         }
650
651 signing_check:
652         if (!rc)
653                 rc = cifs_enable_signing(server, ses->sign);
654 neg_err_exit:
655         cifs_buf_release(pSMB);
656
657         cifs_dbg(FYI, "negprot rc %d\n", rc);
658         return rc;
659 }
660
661 int
662 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
663 {
664         struct smb_hdr *smb_buffer;
665         int rc = 0;
666
667         cifs_dbg(FYI, "In tree disconnect\n");
668
669         /* BB: do we need to check this? These should never be NULL. */
670         if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
671                 return -EIO;
672
673         /*
674          * No need to return error on this operation if tid invalidated and
675          * closed on server already e.g. due to tcp session crashing. Also,
676          * the tcon is no longer on the list, so no need to take lock before
677          * checking this.
678          */
679         if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
680                 return 0;
681
682         rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
683                             (void **)&smb_buffer);
684         if (rc)
685                 return rc;
686
687         rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
688         cifs_small_buf_release(smb_buffer);
689         if (rc)
690                 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
691
692         /* No need to return error on this operation if tid invalidated and
693            closed on server already e.g. due to tcp session crashing */
694         if (rc == -EAGAIN)
695                 rc = 0;
696
697         return rc;
698 }
699
700 /*
701  * This is a no-op for now. We're not really interested in the reply, but
702  * rather in the fact that the server sent one and that server->lstrp
703  * gets updated.
704  *
705  * FIXME: maybe we should consider checking that the reply matches request?
706  */
707 static void
708 cifs_echo_callback(struct mid_q_entry *mid)
709 {
710         struct TCP_Server_Info *server = mid->callback_data;
711
712         DeleteMidQEntry(mid);
713         add_credits(server, 1, CIFS_ECHO_OP);
714 }
715
716 int
717 CIFSSMBEcho(struct TCP_Server_Info *server)
718 {
719         ECHO_REQ *smb;
720         int rc = 0;
721         struct kvec iov[2];
722         struct smb_rqst rqst = { .rq_iov = iov,
723                                  .rq_nvec = 2 };
724
725         cifs_dbg(FYI, "In echo request\n");
726
727         rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
728         if (rc)
729                 return rc;
730
731         if (server->capabilities & CAP_UNICODE)
732                 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
733
734         /* set up echo request */
735         smb->hdr.Tid = 0xffff;
736         smb->hdr.WordCount = 1;
737         put_unaligned_le16(1, &smb->EchoCount);
738         put_bcc(1, &smb->hdr);
739         smb->Data[0] = 'a';
740         inc_rfc1001_len(smb, 3);
741
742         iov[0].iov_len = 4;
743         iov[0].iov_base = smb;
744         iov[1].iov_len = get_rfc1002_length(smb);
745         iov[1].iov_base = (char *)smb + 4;
746
747         rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
748                              server, CIFS_ASYNC_OP | CIFS_ECHO_OP);
749         if (rc)
750                 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
751
752         cifs_small_buf_release(smb);
753
754         return rc;
755 }
756
757 int
758 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
759 {
760         LOGOFF_ANDX_REQ *pSMB;
761         int rc = 0;
762
763         cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
764
765         /*
766          * BB: do we need to check validity of ses and server? They should
767          * always be valid since we have an active reference. If not, that
768          * should probably be a BUG()
769          */
770         if (!ses || !ses->server)
771                 return -EIO;
772
773         mutex_lock(&ses->session_mutex);
774         if (ses->need_reconnect)
775                 goto session_already_dead; /* no need to send SMBlogoff if uid
776                                               already closed due to reconnect */
777         rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
778         if (rc) {
779                 mutex_unlock(&ses->session_mutex);
780                 return rc;
781         }
782
783         pSMB->hdr.Mid = get_next_mid(ses->server);
784
785         if (ses->server->sign)
786                 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
787
788         pSMB->hdr.Uid = ses->Suid;
789
790         pSMB->AndXCommand = 0xFF;
791         rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
792         cifs_small_buf_release(pSMB);
793 session_already_dead:
794         mutex_unlock(&ses->session_mutex);
795
796         /* if session dead then we do not need to do ulogoff,
797                 since server closed smb session, no sense reporting
798                 error */
799         if (rc == -EAGAIN)
800                 rc = 0;
801         return rc;
802 }
803
804 int
805 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
806                  const char *fileName, __u16 type,
807                  const struct nls_table *nls_codepage, int remap)
808 {
809         TRANSACTION2_SPI_REQ *pSMB = NULL;
810         TRANSACTION2_SPI_RSP *pSMBr = NULL;
811         struct unlink_psx_rq *pRqD;
812         int name_len;
813         int rc = 0;
814         int bytes_returned = 0;
815         __u16 params, param_offset, offset, byte_count;
816
817         cifs_dbg(FYI, "In POSIX delete\n");
818 PsxDelete:
819         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
820                       (void **) &pSMBr);
821         if (rc)
822                 return rc;
823
824         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
825                 name_len =
826                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
827                                        PATH_MAX, nls_codepage, remap);
828                 name_len++;     /* trailing null */
829                 name_len *= 2;
830         } else { /* BB add path length overrun check */
831                 name_len = strnlen(fileName, PATH_MAX);
832                 name_len++;     /* trailing null */
833                 strncpy(pSMB->FileName, fileName, name_len);
834         }
835
836         params = 6 + name_len;
837         pSMB->MaxParameterCount = cpu_to_le16(2);
838         pSMB->MaxDataCount = 0; /* BB double check this with jra */
839         pSMB->MaxSetupCount = 0;
840         pSMB->Reserved = 0;
841         pSMB->Flags = 0;
842         pSMB->Timeout = 0;
843         pSMB->Reserved2 = 0;
844         param_offset = offsetof(struct smb_com_transaction2_spi_req,
845                                 InformationLevel) - 4;
846         offset = param_offset + params;
847
848         /* Setup pointer to Request Data (inode type) */
849         pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
850         pRqD->type = cpu_to_le16(type);
851         pSMB->ParameterOffset = cpu_to_le16(param_offset);
852         pSMB->DataOffset = cpu_to_le16(offset);
853         pSMB->SetupCount = 1;
854         pSMB->Reserved3 = 0;
855         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
856         byte_count = 3 /* pad */  + params + sizeof(struct unlink_psx_rq);
857
858         pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
859         pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
860         pSMB->ParameterCount = cpu_to_le16(params);
861         pSMB->TotalParameterCount = pSMB->ParameterCount;
862         pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
863         pSMB->Reserved4 = 0;
864         inc_rfc1001_len(pSMB, byte_count);
865         pSMB->ByteCount = cpu_to_le16(byte_count);
866         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
867                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
868         if (rc)
869                 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
870         cifs_buf_release(pSMB);
871
872         cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
873
874         if (rc == -EAGAIN)
875                 goto PsxDelete;
876
877         return rc;
878 }
879
880 int
881 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
882                struct cifs_sb_info *cifs_sb)
883 {
884         DELETE_FILE_REQ *pSMB = NULL;
885         DELETE_FILE_RSP *pSMBr = NULL;
886         int rc = 0;
887         int bytes_returned;
888         int name_len;
889         int remap = cifs_remap(cifs_sb);
890
891 DelFileRetry:
892         rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
893                       (void **) &pSMBr);
894         if (rc)
895                 return rc;
896
897         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
898                 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
899                                               PATH_MAX, cifs_sb->local_nls,
900                                               remap);
901                 name_len++;     /* trailing null */
902                 name_len *= 2;
903         } else {                /* BB improve check for buffer overruns BB */
904                 name_len = strnlen(name, PATH_MAX);
905                 name_len++;     /* trailing null */
906                 strncpy(pSMB->fileName, name, name_len);
907         }
908         pSMB->SearchAttributes =
909             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
910         pSMB->BufferFormat = 0x04;
911         inc_rfc1001_len(pSMB, name_len + 1);
912         pSMB->ByteCount = cpu_to_le16(name_len + 1);
913         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
914                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
915         cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
916         if (rc)
917                 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
918
919         cifs_buf_release(pSMB);
920         if (rc == -EAGAIN)
921                 goto DelFileRetry;
922
923         return rc;
924 }
925
926 int
927 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
928              struct cifs_sb_info *cifs_sb)
929 {
930         DELETE_DIRECTORY_REQ *pSMB = NULL;
931         DELETE_DIRECTORY_RSP *pSMBr = NULL;
932         int rc = 0;
933         int bytes_returned;
934         int name_len;
935         int remap = cifs_remap(cifs_sb);
936
937         cifs_dbg(FYI, "In CIFSSMBRmDir\n");
938 RmDirRetry:
939         rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
940                       (void **) &pSMBr);
941         if (rc)
942                 return rc;
943
944         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
945                 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
946                                               PATH_MAX, cifs_sb->local_nls,
947                                               remap);
948                 name_len++;     /* trailing null */
949                 name_len *= 2;
950         } else {                /* BB improve check for buffer overruns BB */
951                 name_len = strnlen(name, PATH_MAX);
952                 name_len++;     /* trailing null */
953                 strncpy(pSMB->DirName, name, name_len);
954         }
955
956         pSMB->BufferFormat = 0x04;
957         inc_rfc1001_len(pSMB, name_len + 1);
958         pSMB->ByteCount = cpu_to_le16(name_len + 1);
959         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
960                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
961         cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
962         if (rc)
963                 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
964
965         cifs_buf_release(pSMB);
966         if (rc == -EAGAIN)
967                 goto RmDirRetry;
968         return rc;
969 }
970
971 int
972 CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
973              struct cifs_sb_info *cifs_sb)
974 {
975         int rc = 0;
976         CREATE_DIRECTORY_REQ *pSMB = NULL;
977         CREATE_DIRECTORY_RSP *pSMBr = NULL;
978         int bytes_returned;
979         int name_len;
980         int remap = cifs_remap(cifs_sb);
981
982         cifs_dbg(FYI, "In CIFSSMBMkDir\n");
983 MkDirRetry:
984         rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
985                       (void **) &pSMBr);
986         if (rc)
987                 return rc;
988
989         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
990                 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
991                                               PATH_MAX, cifs_sb->local_nls,
992                                               remap);
993                 name_len++;     /* trailing null */
994                 name_len *= 2;
995         } else {                /* BB improve check for buffer overruns BB */
996                 name_len = strnlen(name, PATH_MAX);
997                 name_len++;     /* trailing null */
998                 strncpy(pSMB->DirName, name, name_len);
999         }
1000
1001         pSMB->BufferFormat = 0x04;
1002         inc_rfc1001_len(pSMB, name_len + 1);
1003         pSMB->ByteCount = cpu_to_le16(name_len + 1);
1004         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1005                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1006         cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1007         if (rc)
1008                 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
1009
1010         cifs_buf_release(pSMB);
1011         if (rc == -EAGAIN)
1012                 goto MkDirRetry;
1013         return rc;
1014 }
1015
1016 int
1017 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1018                 __u32 posix_flags, __u64 mode, __u16 *netfid,
1019                 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1020                 const char *name, const struct nls_table *nls_codepage,
1021                 int remap)
1022 {
1023         TRANSACTION2_SPI_REQ *pSMB = NULL;
1024         TRANSACTION2_SPI_RSP *pSMBr = NULL;
1025         int name_len;
1026         int rc = 0;
1027         int bytes_returned = 0;
1028         __u16 params, param_offset, offset, byte_count, count;
1029         OPEN_PSX_REQ *pdata;
1030         OPEN_PSX_RSP *psx_rsp;
1031
1032         cifs_dbg(FYI, "In POSIX Create\n");
1033 PsxCreat:
1034         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1035                       (void **) &pSMBr);
1036         if (rc)
1037                 return rc;
1038
1039         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1040                 name_len =
1041                     cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1042                                        PATH_MAX, nls_codepage, remap);
1043                 name_len++;     /* trailing null */
1044                 name_len *= 2;
1045         } else {        /* BB improve the check for buffer overruns BB */
1046                 name_len = strnlen(name, PATH_MAX);
1047                 name_len++;     /* trailing null */
1048                 strncpy(pSMB->FileName, name, name_len);
1049         }
1050
1051         params = 6 + name_len;
1052         count = sizeof(OPEN_PSX_REQ);
1053         pSMB->MaxParameterCount = cpu_to_le16(2);
1054         pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1055         pSMB->MaxSetupCount = 0;
1056         pSMB->Reserved = 0;
1057         pSMB->Flags = 0;
1058         pSMB->Timeout = 0;
1059         pSMB->Reserved2 = 0;
1060         param_offset = offsetof(struct smb_com_transaction2_spi_req,
1061                                 InformationLevel) - 4;
1062         offset = param_offset + params;
1063         pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1064         pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1065         pdata->Permissions = cpu_to_le64(mode);
1066         pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1067         pdata->OpenFlags =  cpu_to_le32(*pOplock);
1068         pSMB->ParameterOffset = cpu_to_le16(param_offset);
1069         pSMB->DataOffset = cpu_to_le16(offset);
1070         pSMB->SetupCount = 1;
1071         pSMB->Reserved3 = 0;
1072         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1073         byte_count = 3 /* pad */  + params + count;
1074
1075         pSMB->DataCount = cpu_to_le16(count);
1076         pSMB->ParameterCount = cpu_to_le16(params);
1077         pSMB->TotalDataCount = pSMB->DataCount;
1078         pSMB->TotalParameterCount = pSMB->ParameterCount;
1079         pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1080         pSMB->Reserved4 = 0;
1081         inc_rfc1001_len(pSMB, byte_count);
1082         pSMB->ByteCount = cpu_to_le16(byte_count);
1083         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1084                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1085         if (rc) {
1086                 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1087                 goto psx_create_err;
1088         }
1089
1090         cifs_dbg(FYI, "copying inode info\n");
1091         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1092
1093         if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1094                 rc = -EIO;      /* bad smb */
1095                 goto psx_create_err;
1096         }
1097
1098         /* copy return information to pRetData */
1099         psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1100                         + le16_to_cpu(pSMBr->t2.DataOffset));
1101
1102         *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1103         if (netfid)
1104                 *netfid = psx_rsp->Fid;   /* cifs fid stays in le */
1105         /* Let caller know file was created so we can set the mode. */
1106         /* Do we care about the CreateAction in any other cases? */
1107         if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1108                 *pOplock |= CIFS_CREATE_ACTION;
1109         /* check to make sure response data is there */
1110         if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1111                 pRetData->Type = cpu_to_le32(-1); /* unknown */
1112                 cifs_dbg(NOISY, "unknown type\n");
1113         } else {
1114                 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1115                                         + sizeof(FILE_UNIX_BASIC_INFO)) {
1116                         cifs_dbg(VFS, "Open response data too small\n");
1117                         pRetData->Type = cpu_to_le32(-1);
1118                         goto psx_create_err;
1119                 }
1120                 memcpy((char *) pRetData,
1121                         (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1122                         sizeof(FILE_UNIX_BASIC_INFO));
1123         }
1124
1125 psx_create_err:
1126         cifs_buf_release(pSMB);
1127
1128         if (posix_flags & SMB_O_DIRECTORY)
1129                 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1130         else
1131                 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1132
1133         if (rc == -EAGAIN)
1134                 goto PsxCreat;
1135
1136         return rc;
1137 }
1138
1139 static __u16 convert_disposition(int disposition)
1140 {
1141         __u16 ofun = 0;
1142
1143         switch (disposition) {
1144                 case FILE_SUPERSEDE:
1145                         ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1146                         break;
1147                 case FILE_OPEN:
1148                         ofun = SMBOPEN_OAPPEND;
1149                         break;
1150                 case FILE_CREATE:
1151                         ofun = SMBOPEN_OCREATE;
1152                         break;
1153                 case FILE_OPEN_IF:
1154                         ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1155                         break;
1156                 case FILE_OVERWRITE:
1157                         ofun = SMBOPEN_OTRUNC;
1158                         break;
1159                 case FILE_OVERWRITE_IF:
1160                         ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1161                         break;
1162                 default:
1163                         cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1164                         ofun =  SMBOPEN_OAPPEND; /* regular open */
1165         }
1166         return ofun;
1167 }
1168
1169 static int
1170 access_flags_to_smbopen_mode(const int access_flags)
1171 {
1172         int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1173
1174         if (masked_flags == GENERIC_READ)
1175                 return SMBOPEN_READ;
1176         else if (masked_flags == GENERIC_WRITE)
1177                 return SMBOPEN_WRITE;
1178
1179         /* just go for read/write */
1180         return SMBOPEN_READWRITE;
1181 }
1182
1183 int
1184 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1185             const char *fileName, const int openDisposition,
1186             const int access_flags, const int create_options, __u16 *netfid,
1187             int *pOplock, FILE_ALL_INFO *pfile_info,
1188             const struct nls_table *nls_codepage, int remap)
1189 {
1190         int rc = -EACCES;
1191         OPENX_REQ *pSMB = NULL;
1192         OPENX_RSP *pSMBr = NULL;
1193         int bytes_returned;
1194         int name_len;
1195         __u16 count;
1196
1197 OldOpenRetry:
1198         rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1199                       (void **) &pSMBr);
1200         if (rc)
1201                 return rc;
1202
1203         pSMB->AndXCommand = 0xFF;       /* none */
1204
1205         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1206                 count = 1;      /* account for one byte pad to word boundary */
1207                 name_len =
1208                    cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1209                                       fileName, PATH_MAX, nls_codepage, remap);
1210                 name_len++;     /* trailing null */
1211                 name_len *= 2;
1212         } else {                /* BB improve check for buffer overruns BB */
1213                 count = 0;      /* no pad */
1214                 name_len = strnlen(fileName, PATH_MAX);
1215                 name_len++;     /* trailing null */
1216                 strncpy(pSMB->fileName, fileName, name_len);
1217         }
1218         if (*pOplock & REQ_OPLOCK)
1219                 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1220         else if (*pOplock & REQ_BATCHOPLOCK)
1221                 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1222
1223         pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1224         pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1225         pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1226         /* set file as system file if special file such
1227            as fifo and server expecting SFU style and
1228            no Unix extensions */
1229
1230         if (create_options & CREATE_OPTION_SPECIAL)
1231                 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1232         else /* BB FIXME BB */
1233                 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1234
1235         if (create_options & CREATE_OPTION_READONLY)
1236                 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1237
1238         /* BB FIXME BB */
1239 /*      pSMB->CreateOptions = cpu_to_le32(create_options &
1240                                                  CREATE_OPTIONS_MASK); */
1241         /* BB FIXME END BB */
1242
1243         pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1244         pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1245         count += name_len;
1246         inc_rfc1001_len(pSMB, count);
1247
1248         pSMB->ByteCount = cpu_to_le16(count);
1249         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1250                         (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1251         cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1252         if (rc) {
1253                 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1254         } else {
1255         /* BB verify if wct == 15 */
1256
1257 /*              *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1258
1259                 *netfid = pSMBr->Fid;   /* cifs fid stays in le */
1260                 /* Let caller know file was created so we can set the mode. */
1261                 /* Do we care about the CreateAction in any other cases? */
1262         /* BB FIXME BB */
1263 /*              if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1264                         *pOplock |= CIFS_CREATE_ACTION; */
1265         /* BB FIXME END */
1266
1267                 if (pfile_info) {
1268                         pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1269                         pfile_info->LastAccessTime = 0; /* BB fixme */
1270                         pfile_info->LastWriteTime = 0; /* BB fixme */
1271                         pfile_info->ChangeTime = 0;  /* BB fixme */
1272                         pfile_info->Attributes =
1273                                 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1274                         /* the file_info buf is endian converted by caller */
1275                         pfile_info->AllocationSize =
1276                                 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1277                         pfile_info->EndOfFile = pfile_info->AllocationSize;
1278                         pfile_info->NumberOfLinks = cpu_to_le32(1);
1279                         pfile_info->DeletePending = 0;
1280                 }
1281         }
1282
1283         cifs_buf_release(pSMB);
1284         if (rc == -EAGAIN)
1285                 goto OldOpenRetry;
1286         return rc;
1287 }
1288
1289 int
1290 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1291           FILE_ALL_INFO *buf)
1292 {
1293         int rc = -EACCES;
1294         OPEN_REQ *req = NULL;
1295         OPEN_RSP *rsp = NULL;
1296         int bytes_returned;
1297         int name_len;
1298         __u16 count;
1299         struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1300         struct cifs_tcon *tcon = oparms->tcon;
1301         int remap = cifs_remap(cifs_sb);
1302         const struct nls_table *nls = cifs_sb->local_nls;
1303         int create_options = oparms->create_options;
1304         int desired_access = oparms->desired_access;
1305         int disposition = oparms->disposition;
1306         const char *path = oparms->path;
1307
1308 openRetry:
1309         rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1310                       (void **)&rsp);
1311         if (rc)
1312                 return rc;
1313
1314         /* no commands go after this */
1315         req->AndXCommand = 0xFF;
1316
1317         if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1318                 /* account for one byte pad to word boundary */
1319                 count = 1;
1320                 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1321                                               path, PATH_MAX, nls, remap);
1322                 /* trailing null */
1323                 name_len++;
1324                 name_len *= 2;
1325                 req->NameLength = cpu_to_le16(name_len);
1326         } else {
1327                 /* BB improve check for buffer overruns BB */
1328                 /* no pad */
1329                 count = 0;
1330                 name_len = strnlen(path, PATH_MAX);
1331                 /* trailing null */
1332                 name_len++;
1333                 req->NameLength = cpu_to_le16(name_len);
1334                 strncpy(req->fileName, path, name_len);
1335         }
1336
1337         if (*oplock & REQ_OPLOCK)
1338                 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1339         else if (*oplock & REQ_BATCHOPLOCK)
1340                 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1341
1342         req->DesiredAccess = cpu_to_le32(desired_access);
1343         req->AllocationSize = 0;
1344
1345         /*
1346          * Set file as system file if special file such as fifo and server
1347          * expecting SFU style and no Unix extensions.
1348          */
1349         if (create_options & CREATE_OPTION_SPECIAL)
1350                 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1351         else
1352                 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1353
1354         /*
1355          * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1356          * sensitive checks for other servers such as Samba.
1357          */
1358         if (tcon->ses->capabilities & CAP_UNIX)
1359                 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1360
1361         if (create_options & CREATE_OPTION_READONLY)
1362                 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1363
1364         req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1365         req->CreateDisposition = cpu_to_le32(disposition);
1366         req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1367
1368         /* BB Expirement with various impersonation levels and verify */
1369         req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1370         req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1371
1372         count += name_len;
1373         inc_rfc1001_len(req, count);
1374
1375         req->ByteCount = cpu_to_le16(count);
1376         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1377                          (struct smb_hdr *)rsp, &bytes_returned, 0);
1378         cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1379         if (rc) {
1380                 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1381                 cifs_buf_release(req);
1382                 if (rc == -EAGAIN)
1383                         goto openRetry;
1384                 return rc;
1385         }
1386
1387         /* 1 byte no need to le_to_cpu */
1388         *oplock = rsp->OplockLevel;
1389         /* cifs fid stays in le */
1390         oparms->fid->netfid = rsp->Fid;
1391
1392         /* Let caller know file was created so we can set the mode. */
1393         /* Do we care about the CreateAction in any other cases? */
1394         if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1395                 *oplock |= CIFS_CREATE_ACTION;
1396
1397         if (buf) {
1398                 /* copy from CreationTime to Attributes */
1399                 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1400                 /* the file_info buf is endian converted by caller */
1401                 buf->AllocationSize = rsp->AllocationSize;
1402                 buf->EndOfFile = rsp->EndOfFile;
1403                 buf->NumberOfLinks = cpu_to_le32(1);
1404                 buf->DeletePending = 0;
1405         }
1406
1407         cifs_buf_release(req);
1408         return rc;
1409 }
1410
1411 /*
1412  * Discard any remaining data in the current SMB. To do this, we borrow the
1413  * current bigbuf.
1414  */
1415 int
1416 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1417 {
1418         unsigned int rfclen = get_rfc1002_length(server->smallbuf);
1419         int remaining = rfclen + 4 - server->total_read;
1420
1421         while (remaining > 0) {
1422                 int length;
1423
1424                 length = cifs_read_from_socket(server, server->bigbuf,
1425                                 min_t(unsigned int, remaining,
1426                                     CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1427                 if (length < 0)
1428                         return length;
1429                 server->total_read += length;
1430                 remaining -= length;
1431         }
1432
1433         return 0;
1434 }
1435
1436 static int
1437 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1438 {
1439         int length;
1440         struct cifs_readdata *rdata = mid->callback_data;
1441
1442         length = cifs_discard_remaining_data(server);
1443         dequeue_mid(mid, rdata->result);
1444         mid->resp_buf = server->smallbuf;
1445         server->smallbuf = NULL;
1446         return length;
1447 }
1448
1449 int
1450 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1451 {
1452         int length, len;
1453         unsigned int data_offset, data_len;
1454         struct cifs_readdata *rdata = mid->callback_data;
1455         char *buf = server->smallbuf;
1456         unsigned int buflen = get_rfc1002_length(buf) + 4;
1457
1458         cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1459                  __func__, mid->mid, rdata->offset, rdata->bytes);
1460
1461         /*
1462          * read the rest of READ_RSP header (sans Data array), or whatever we
1463          * can if there's not enough data. At this point, we've read down to
1464          * the Mid.
1465          */
1466         len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1467                                                         HEADER_SIZE(server) + 1;
1468
1469         length = cifs_read_from_socket(server,
1470                                        buf + HEADER_SIZE(server) - 1, len);
1471         if (length < 0)
1472                 return length;
1473         server->total_read += length;
1474
1475         if (server->ops->is_session_expired &&
1476             server->ops->is_session_expired(buf)) {
1477                 cifs_reconnect(server);
1478                 wake_up(&server->response_q);
1479                 return -1;
1480         }
1481
1482         if (server->ops->is_status_pending &&
1483             server->ops->is_status_pending(buf, server, 0)) {
1484                 cifs_discard_remaining_data(server);
1485                 return -1;
1486         }
1487
1488         /* Was the SMB read successful? */
1489         rdata->result = server->ops->map_error(buf, false);
1490         if (rdata->result != 0) {
1491                 cifs_dbg(FYI, "%s: server returned error %d\n",
1492                          __func__, rdata->result);
1493                 return cifs_readv_discard(server, mid);
1494         }
1495
1496         /* Is there enough to get to the rest of the READ_RSP header? */
1497         if (server->total_read < server->vals->read_rsp_size) {
1498                 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1499                          __func__, server->total_read,
1500                          server->vals->read_rsp_size);
1501                 rdata->result = -EIO;
1502                 return cifs_readv_discard(server, mid);
1503         }
1504
1505         data_offset = server->ops->read_data_offset(buf) + 4;
1506         if (data_offset < server->total_read) {
1507                 /*
1508                  * win2k8 sometimes sends an offset of 0 when the read
1509                  * is beyond the EOF. Treat it as if the data starts just after
1510                  * the header.
1511                  */
1512                 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1513                          __func__, data_offset);
1514                 data_offset = server->total_read;
1515         } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1516                 /* data_offset is beyond the end of smallbuf */
1517                 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1518                          __func__, data_offset);
1519                 rdata->result = -EIO;
1520                 return cifs_readv_discard(server, mid);
1521         }
1522
1523         cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1524                  __func__, server->total_read, data_offset);
1525
1526         len = data_offset - server->total_read;
1527         if (len > 0) {
1528                 /* read any junk before data into the rest of smallbuf */
1529                 length = cifs_read_from_socket(server,
1530                                                buf + server->total_read, len);
1531                 if (length < 0)
1532                         return length;
1533                 server->total_read += length;
1534         }
1535
1536         /* set up first iov for signature check */
1537         rdata->iov[0].iov_base = buf;
1538         rdata->iov[0].iov_len = 4;
1539         rdata->iov[1].iov_base = buf + 4;
1540         rdata->iov[1].iov_len = server->total_read - 4;
1541         cifs_dbg(FYI, "0: iov_base=%p iov_len=%u\n",
1542                  rdata->iov[0].iov_base, server->total_read);
1543
1544         /* how much data is in the response? */
1545         data_len = server->ops->read_data_length(buf);
1546         if (data_offset + data_len > buflen) {
1547                 /* data_len is corrupt -- discard frame */
1548                 rdata->result = -EIO;
1549                 return cifs_readv_discard(server, mid);
1550         }
1551
1552         length = rdata->read_into_pages(server, rdata, data_len);
1553         if (length < 0)
1554                 return length;
1555
1556         server->total_read += length;
1557
1558         cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1559                  server->total_read, buflen, data_len);
1560
1561         /* discard anything left over */
1562         if (server->total_read < buflen)
1563                 return cifs_readv_discard(server, mid);
1564
1565         dequeue_mid(mid, false);
1566         mid->resp_buf = server->smallbuf;
1567         server->smallbuf = NULL;
1568         return length;
1569 }
1570
1571 static void
1572 cifs_readv_callback(struct mid_q_entry *mid)
1573 {
1574         struct cifs_readdata *rdata = mid->callback_data;
1575         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1576         struct TCP_Server_Info *server = tcon->ses->server;
1577         struct smb_rqst rqst = { .rq_iov = rdata->iov,
1578                                  .rq_nvec = 2,
1579                                  .rq_pages = rdata->pages,
1580                                  .rq_npages = rdata->nr_pages,
1581                                  .rq_pagesz = rdata->pagesz,
1582                                  .rq_tailsz = rdata->tailsz };
1583
1584         cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1585                  __func__, mid->mid, mid->mid_state, rdata->result,
1586                  rdata->bytes);
1587
1588         switch (mid->mid_state) {
1589         case MID_RESPONSE_RECEIVED:
1590                 /* result already set, check signature */
1591                 if (server->sign) {
1592                         int rc = 0;
1593
1594                         rc = cifs_verify_signature(&rqst, server,
1595                                                   mid->sequence_number);
1596                         if (rc)
1597                                 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1598                                          rc);
1599                 }
1600                 /* FIXME: should this be counted toward the initiating task? */
1601                 task_io_account_read(rdata->got_bytes);
1602                 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1603                 break;
1604         case MID_REQUEST_SUBMITTED:
1605         case MID_RETRY_NEEDED:
1606                 rdata->result = -EAGAIN;
1607                 if (server->sign && rdata->got_bytes)
1608                         /* reset bytes number since we can not check a sign */
1609                         rdata->got_bytes = 0;
1610                 /* FIXME: should this be counted toward the initiating task? */
1611                 task_io_account_read(rdata->got_bytes);
1612                 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1613                 break;
1614         default:
1615                 rdata->result = -EIO;
1616         }
1617
1618         queue_work(cifsiod_wq, &rdata->work);
1619         DeleteMidQEntry(mid);
1620         add_credits(server, 1, 0);
1621 }
1622
1623 /* cifs_async_readv - send an async write, and set up mid to handle result */
1624 int
1625 cifs_async_readv(struct cifs_readdata *rdata)
1626 {
1627         int rc;
1628         READ_REQ *smb = NULL;
1629         int wct;
1630         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1631         struct smb_rqst rqst = { .rq_iov = rdata->iov,
1632                                  .rq_nvec = 2 };
1633
1634         cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1635                  __func__, rdata->offset, rdata->bytes);
1636
1637         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1638                 wct = 12;
1639         else {
1640                 wct = 10; /* old style read */
1641                 if ((rdata->offset >> 32) > 0)  {
1642                         /* can not handle this big offset for old */
1643                         return -EIO;
1644                 }
1645         }
1646
1647         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1648         if (rc)
1649                 return rc;
1650
1651         smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1652         smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1653
1654         smb->AndXCommand = 0xFF;        /* none */
1655         smb->Fid = rdata->cfile->fid.netfid;
1656         smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1657         if (wct == 12)
1658                 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1659         smb->Remaining = 0;
1660         smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1661         smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1662         if (wct == 12)
1663                 smb->ByteCount = 0;
1664         else {
1665                 /* old style read */
1666                 struct smb_com_readx_req *smbr =
1667                         (struct smb_com_readx_req *)smb;
1668                 smbr->ByteCount = 0;
1669         }
1670
1671         /* 4 for RFC1001 length + 1 for BCC */
1672         rdata->iov[0].iov_base = smb;
1673         rdata->iov[0].iov_len = 4;
1674         rdata->iov[1].iov_base = (char *)smb + 4;
1675         rdata->iov[1].iov_len = get_rfc1002_length(smb);
1676
1677         kref_get(&rdata->refcount);
1678         rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1679                              cifs_readv_callback, NULL, rdata, 0);
1680
1681         if (rc == 0)
1682                 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1683         else
1684                 kref_put(&rdata->refcount, cifs_readdata_release);
1685
1686         cifs_small_buf_release(smb);
1687         return rc;
1688 }
1689
1690 int
1691 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1692             unsigned int *nbytes, char **buf, int *pbuf_type)
1693 {
1694         int rc = -EACCES;
1695         READ_REQ *pSMB = NULL;
1696         READ_RSP *pSMBr = NULL;
1697         char *pReadData = NULL;
1698         int wct;
1699         int resp_buf_type = 0;
1700         struct kvec iov[1];
1701         struct kvec rsp_iov;
1702         __u32 pid = io_parms->pid;
1703         __u16 netfid = io_parms->netfid;
1704         __u64 offset = io_parms->offset;
1705         struct cifs_tcon *tcon = io_parms->tcon;
1706         unsigned int count = io_parms->length;
1707
1708         cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1709         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1710                 wct = 12;
1711         else {
1712                 wct = 10; /* old style read */
1713                 if ((offset >> 32) > 0)  {
1714                         /* can not handle this big offset for old */
1715                         return -EIO;
1716                 }
1717         }
1718
1719         *nbytes = 0;
1720         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1721         if (rc)
1722                 return rc;
1723
1724         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1725         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1726
1727         /* tcon and ses pointer are checked in smb_init */
1728         if (tcon->ses->server == NULL)
1729                 return -ECONNABORTED;
1730
1731         pSMB->AndXCommand = 0xFF;       /* none */
1732         pSMB->Fid = netfid;
1733         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1734         if (wct == 12)
1735                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1736
1737         pSMB->Remaining = 0;
1738         pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1739         pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1740         if (wct == 12)
1741                 pSMB->ByteCount = 0;  /* no need to do le conversion since 0 */
1742         else {
1743                 /* old style read */
1744                 struct smb_com_readx_req *pSMBW =
1745                         (struct smb_com_readx_req *)pSMB;
1746                 pSMBW->ByteCount = 0;
1747         }
1748
1749         iov[0].iov_base = (char *)pSMB;
1750         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1751         rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1752                           CIFS_LOG_ERROR, &rsp_iov);
1753         cifs_small_buf_release(pSMB);
1754         cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1755         pSMBr = (READ_RSP *)rsp_iov.iov_base;
1756         if (rc) {
1757                 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1758         } else {
1759                 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1760                 data_length = data_length << 16;
1761                 data_length += le16_to_cpu(pSMBr->DataLength);
1762                 *nbytes = data_length;
1763
1764                 /*check that DataLength would not go beyond end of SMB */
1765                 if ((data_length > CIFSMaxBufSize)
1766                                 || (data_length > count)) {
1767                         cifs_dbg(FYI, "bad length %d for count %d\n",
1768                                  data_length, count);
1769                         rc = -EIO;
1770                         *nbytes = 0;
1771                 } else {
1772                         pReadData = (char *) (&pSMBr->hdr.Protocol) +
1773                                         le16_to_cpu(pSMBr->DataOffset);
1774 /*                      if (rc = copy_to_user(buf, pReadData, data_length)) {
1775                                 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1776                                 rc = -EFAULT;
1777                         }*/ /* can not use copy_to_user when using page cache*/
1778                         if (*buf)
1779                                 memcpy(*buf, pReadData, data_length);
1780                 }
1781         }
1782
1783         if (*buf) {
1784                 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1785         } else if (resp_buf_type != CIFS_NO_BUFFER) {
1786                 /* return buffer to caller to free */
1787                 *buf = rsp_iov.iov_base;
1788                 if (resp_buf_type == CIFS_SMALL_BUFFER)
1789                         *pbuf_type = CIFS_SMALL_BUFFER;
1790                 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1791                         *pbuf_type = CIFS_LARGE_BUFFER;
1792         } /* else no valid buffer on return - leave as null */
1793
1794         /* Note: On -EAGAIN error only caller can retry on handle based calls
1795                 since file handle passed in no longer valid */
1796         return rc;
1797 }
1798
1799
1800 int
1801 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1802              unsigned int *nbytes, const char *buf)
1803 {
1804         int rc = -EACCES;
1805         WRITE_REQ *pSMB = NULL;
1806         WRITE_RSP *pSMBr = NULL;
1807         int bytes_returned, wct;
1808         __u32 bytes_sent;
1809         __u16 byte_count;
1810         __u32 pid = io_parms->pid;
1811         __u16 netfid = io_parms->netfid;
1812         __u64 offset = io_parms->offset;
1813         struct cifs_tcon *tcon = io_parms->tcon;
1814         unsigned int count = io_parms->length;
1815
1816         *nbytes = 0;
1817
1818         /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1819         if (tcon->ses == NULL)
1820                 return -ECONNABORTED;
1821
1822         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1823                 wct = 14;
1824         else {
1825                 wct = 12;
1826                 if ((offset >> 32) > 0) {
1827                         /* can not handle big offset for old srv */
1828                         return -EIO;
1829                 }
1830         }
1831
1832         rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1833                       (void **) &pSMBr);
1834         if (rc)
1835                 return rc;
1836
1837         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1838         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1839
1840         /* tcon and ses pointer are checked in smb_init */
1841         if (tcon->ses->server == NULL)
1842                 return -ECONNABORTED;
1843
1844         pSMB->AndXCommand = 0xFF;       /* none */
1845         pSMB->Fid = netfid;
1846         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1847         if (wct == 14)
1848                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1849
1850         pSMB->Reserved = 0xFFFFFFFF;
1851         pSMB->WriteMode = 0;
1852         pSMB->Remaining = 0;
1853
1854         /* Can increase buffer size if buffer is big enough in some cases ie we
1855         can send more if LARGE_WRITE_X capability returned by the server and if
1856         our buffer is big enough or if we convert to iovecs on socket writes
1857         and eliminate the copy to the CIFS buffer */
1858         if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1859                 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1860         } else {
1861                 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1862                          & ~0xFF;
1863         }
1864
1865         if (bytes_sent > count)
1866                 bytes_sent = count;
1867         pSMB->DataOffset =
1868                 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1869         if (buf)
1870                 memcpy(pSMB->Data, buf, bytes_sent);
1871         else if (count != 0) {
1872                 /* No buffer */
1873                 cifs_buf_release(pSMB);
1874                 return -EINVAL;
1875         } /* else setting file size with write of zero bytes */
1876         if (wct == 14)
1877                 byte_count = bytes_sent + 1; /* pad */
1878         else /* wct == 12 */
1879                 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1880
1881         pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1882         pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1883         inc_rfc1001_len(pSMB, byte_count);
1884
1885         if (wct == 14)
1886                 pSMB->ByteCount = cpu_to_le16(byte_count);
1887         else { /* old style write has byte count 4 bytes earlier
1888                   so 4 bytes pad  */
1889                 struct smb_com_writex_req *pSMBW =
1890                         (struct smb_com_writex_req *)pSMB;
1891                 pSMBW->ByteCount = cpu_to_le16(byte_count);
1892         }
1893
1894         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1895                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1896         cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1897         if (rc) {
1898                 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1899         } else {
1900                 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1901                 *nbytes = (*nbytes) << 16;
1902                 *nbytes += le16_to_cpu(pSMBr->Count);
1903
1904                 /*
1905                  * Mask off high 16 bits when bytes written as returned by the
1906                  * server is greater than bytes requested by the client. Some
1907                  * OS/2 servers are known to set incorrect CountHigh values.
1908                  */
1909                 if (*nbytes > count)
1910                         *nbytes &= 0xFFFF;
1911         }
1912
1913         cifs_buf_release(pSMB);
1914
1915         /* Note: On -EAGAIN error only caller can retry on handle based calls
1916                 since file handle passed in no longer valid */
1917
1918         return rc;
1919 }
1920
1921 void
1922 cifs_writedata_release(struct kref *refcount)
1923 {
1924         struct cifs_writedata *wdata = container_of(refcount,
1925                                         struct cifs_writedata, refcount);
1926
1927         if (wdata->cfile)
1928                 cifsFileInfo_put(wdata->cfile);
1929
1930         kfree(wdata);
1931 }
1932
1933 /*
1934  * Write failed with a retryable error. Resend the write request. It's also
1935  * possible that the page was redirtied so re-clean the page.
1936  */
1937 static void
1938 cifs_writev_requeue(struct cifs_writedata *wdata)
1939 {
1940         int i, rc = 0;
1941         struct inode *inode = d_inode(wdata->cfile->dentry);
1942         struct TCP_Server_Info *server;
1943         unsigned int rest_len;
1944
1945         server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1946         i = 0;
1947         rest_len = wdata->bytes;
1948         do {
1949                 struct cifs_writedata *wdata2;
1950                 unsigned int j, nr_pages, wsize, tailsz, cur_len;
1951
1952                 wsize = server->ops->wp_retry_size(inode);
1953                 if (wsize < rest_len) {
1954                         nr_pages = wsize / PAGE_SIZE;
1955                         if (!nr_pages) {
1956                                 rc = -ENOTSUPP;
1957                                 break;
1958                         }
1959                         cur_len = nr_pages * PAGE_SIZE;
1960                         tailsz = PAGE_SIZE;
1961                 } else {
1962                         nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
1963                         cur_len = rest_len;
1964                         tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
1965                 }
1966
1967                 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
1968                 if (!wdata2) {
1969                         rc = -ENOMEM;
1970                         break;
1971                 }
1972
1973                 for (j = 0; j < nr_pages; j++) {
1974                         wdata2->pages[j] = wdata->pages[i + j];
1975                         lock_page(wdata2->pages[j]);
1976                         clear_page_dirty_for_io(wdata2->pages[j]);
1977                 }
1978
1979                 wdata2->sync_mode = wdata->sync_mode;
1980                 wdata2->nr_pages = nr_pages;
1981                 wdata2->offset = page_offset(wdata2->pages[0]);
1982                 wdata2->pagesz = PAGE_SIZE;
1983                 wdata2->tailsz = tailsz;
1984                 wdata2->bytes = cur_len;
1985
1986                 wdata2->cfile = find_writable_file(CIFS_I(inode), false);
1987                 if (!wdata2->cfile) {
1988                         cifs_dbg(VFS, "No writable handles for inode\n");
1989                         rc = -EBADF;
1990                         break;
1991                 }
1992                 wdata2->pid = wdata2->cfile->pid;
1993                 rc = server->ops->async_writev(wdata2, cifs_writedata_release);
1994
1995                 for (j = 0; j < nr_pages; j++) {
1996                         unlock_page(wdata2->pages[j]);
1997                         if (rc != 0 && rc != -EAGAIN) {
1998                                 SetPageError(wdata2->pages[j]);
1999                                 end_page_writeback(wdata2->pages[j]);
2000                                 put_page(wdata2->pages[j]);
2001                         }
2002                 }
2003
2004                 if (rc) {
2005                         kref_put(&wdata2->refcount, cifs_writedata_release);
2006                         if (rc == -EAGAIN)
2007                                 continue;
2008                         break;
2009                 }
2010
2011                 rest_len -= cur_len;
2012                 i += nr_pages;
2013         } while (i < wdata->nr_pages);
2014
2015         mapping_set_error(inode->i_mapping, rc);
2016         kref_put(&wdata->refcount, cifs_writedata_release);
2017 }
2018
2019 void
2020 cifs_writev_complete(struct work_struct *work)
2021 {
2022         struct cifs_writedata *wdata = container_of(work,
2023                                                 struct cifs_writedata, work);
2024         struct inode *inode = d_inode(wdata->cfile->dentry);
2025         int i = 0;
2026
2027         if (wdata->result == 0) {
2028                 spin_lock(&inode->i_lock);
2029                 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2030                 spin_unlock(&inode->i_lock);
2031                 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2032                                          wdata->bytes);
2033         } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2034                 return cifs_writev_requeue(wdata);
2035
2036         for (i = 0; i < wdata->nr_pages; i++) {
2037                 struct page *page = wdata->pages[i];
2038                 if (wdata->result == -EAGAIN)
2039                         __set_page_dirty_nobuffers(page);
2040                 else if (wdata->result < 0)
2041                         SetPageError(page);
2042                 end_page_writeback(page);
2043                 put_page(page);
2044         }
2045         if (wdata->result != -EAGAIN)
2046                 mapping_set_error(inode->i_mapping, wdata->result);
2047         kref_put(&wdata->refcount, cifs_writedata_release);
2048 }
2049
2050 struct cifs_writedata *
2051 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2052 {
2053         struct cifs_writedata *wdata;
2054
2055         /* writedata + number of page pointers */
2056         wdata = kzalloc(sizeof(*wdata) +
2057                         sizeof(struct page *) * nr_pages, GFP_NOFS);
2058         if (wdata != NULL) {
2059                 kref_init(&wdata->refcount);
2060                 INIT_LIST_HEAD(&wdata->list);
2061                 init_completion(&wdata->done);
2062                 INIT_WORK(&wdata->work, complete);
2063         }
2064         return wdata;
2065 }
2066
2067 /*
2068  * Check the mid_state and signature on received buffer (if any), and queue the
2069  * workqueue completion task.
2070  */
2071 static void
2072 cifs_writev_callback(struct mid_q_entry *mid)
2073 {
2074         struct cifs_writedata *wdata = mid->callback_data;
2075         struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2076         unsigned int written;
2077         WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2078
2079         switch (mid->mid_state) {
2080         case MID_RESPONSE_RECEIVED:
2081                 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2082                 if (wdata->result != 0)
2083                         break;
2084
2085                 written = le16_to_cpu(smb->CountHigh);
2086                 written <<= 16;
2087                 written += le16_to_cpu(smb->Count);
2088                 /*
2089                  * Mask off high 16 bits when bytes written as returned
2090                  * by the server is greater than bytes requested by the
2091                  * client. OS/2 servers are known to set incorrect
2092                  * CountHigh values.
2093                  */
2094                 if (written > wdata->bytes)
2095                         written &= 0xFFFF;
2096
2097                 if (written < wdata->bytes)
2098                         wdata->result = -ENOSPC;
2099                 else
2100                         wdata->bytes = written;
2101                 break;
2102         case MID_REQUEST_SUBMITTED:
2103         case MID_RETRY_NEEDED:
2104                 wdata->result = -EAGAIN;
2105                 break;
2106         default:
2107                 wdata->result = -EIO;
2108                 break;
2109         }
2110
2111         queue_work(cifsiod_wq, &wdata->work);
2112         DeleteMidQEntry(mid);
2113         add_credits(tcon->ses->server, 1, 0);
2114 }
2115
2116 /* cifs_async_writev - send an async write, and set up mid to handle result */
2117 int
2118 cifs_async_writev(struct cifs_writedata *wdata,
2119                   void (*release)(struct kref *kref))
2120 {
2121         int rc = -EACCES;
2122         WRITE_REQ *smb = NULL;
2123         int wct;
2124         struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2125         struct kvec iov[2];
2126         struct smb_rqst rqst = { };
2127
2128         if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2129                 wct = 14;
2130         } else {
2131                 wct = 12;
2132                 if (wdata->offset >> 32 > 0) {
2133                         /* can not handle big offset for old srv */
2134                         return -EIO;
2135                 }
2136         }
2137
2138         rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2139         if (rc)
2140                 goto async_writev_out;
2141
2142         smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2143         smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2144
2145         smb->AndXCommand = 0xFF;        /* none */
2146         smb->Fid = wdata->cfile->fid.netfid;
2147         smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2148         if (wct == 14)
2149                 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2150         smb->Reserved = 0xFFFFFFFF;
2151         smb->WriteMode = 0;
2152         smb->Remaining = 0;
2153
2154         smb->DataOffset =
2155             cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2156
2157         /* 4 for RFC1001 length + 1 for BCC */
2158         iov[0].iov_len = 4;
2159         iov[0].iov_base = smb;
2160         iov[1].iov_len = get_rfc1002_length(smb) + 1;
2161         iov[1].iov_base = (char *)smb + 4;
2162
2163         rqst.rq_iov = iov;
2164         rqst.rq_nvec = 2;
2165         rqst.rq_pages = wdata->pages;
2166         rqst.rq_npages = wdata->nr_pages;
2167         rqst.rq_pagesz = wdata->pagesz;
2168         rqst.rq_tailsz = wdata->tailsz;
2169
2170         cifs_dbg(FYI, "async write at %llu %u bytes\n",
2171                  wdata->offset, wdata->bytes);
2172
2173         smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2174         smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2175
2176         if (wct == 14) {
2177                 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2178                 put_bcc(wdata->bytes + 1, &smb->hdr);
2179         } else {
2180                 /* wct == 12 */
2181                 struct smb_com_writex_req *smbw =
2182                                 (struct smb_com_writex_req *)smb;
2183                 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2184                 put_bcc(wdata->bytes + 5, &smbw->hdr);
2185                 iov[1].iov_len += 4; /* pad bigger by four bytes */
2186         }
2187
2188         kref_get(&wdata->refcount);
2189         rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2190                                 cifs_writev_callback, NULL, wdata, 0);
2191
2192         if (rc == 0)
2193                 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2194         else
2195                 kref_put(&wdata->refcount, release);
2196
2197 async_writev_out:
2198         cifs_small_buf_release(smb);
2199         return rc;
2200 }
2201
2202 int
2203 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2204               unsigned int *nbytes, struct kvec *iov, int n_vec)
2205 {
2206         int rc = -EACCES;
2207         WRITE_REQ *pSMB = NULL;
2208         int wct;
2209         int smb_hdr_len;
2210         int resp_buf_type = 0;
2211         __u32 pid = io_parms->pid;
2212         __u16 netfid = io_parms->netfid;
2213         __u64 offset = io_parms->offset;
2214         struct cifs_tcon *tcon = io_parms->tcon;
2215         unsigned int count = io_parms->length;
2216         struct kvec rsp_iov;
2217
2218         *nbytes = 0;
2219
2220         cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2221
2222         if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2223                 wct = 14;
2224         } else {
2225                 wct = 12;
2226                 if ((offset >> 32) > 0) {
2227                         /* can not handle big offset for old srv */
2228                         return -EIO;
2229                 }
2230         }
2231         rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2232         if (rc)
2233                 return rc;
2234
2235         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2236         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2237
2238         /* tcon and ses pointer are checked in smb_init */
2239         if (tcon->ses->server == NULL)
2240                 return -ECONNABORTED;
2241
2242         pSMB->AndXCommand = 0xFF;       /* none */
2243         pSMB->Fid = netfid;
2244         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2245         if (wct == 14)
2246                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2247         pSMB->Reserved = 0xFFFFFFFF;
2248         pSMB->WriteMode = 0;
2249         pSMB->Remaining = 0;
2250
2251         pSMB->DataOffset =
2252             cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2253
2254         pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2255         pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2256         /* header + 1 byte pad */
2257         smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2258         if (wct == 14)
2259                 inc_rfc1001_len(pSMB, count + 1);
2260         else /* wct == 12 */
2261                 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2262         if (wct == 14)
2263                 pSMB->ByteCount = cpu_to_le16(count + 1);
2264         else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2265                 struct smb_com_writex_req *pSMBW =
2266                                 (struct smb_com_writex_req *)pSMB;
2267                 pSMBW->ByteCount = cpu_to_le16(count + 5);
2268         }
2269         iov[0].iov_base = pSMB;
2270         if (wct == 14)
2271                 iov[0].iov_len = smb_hdr_len + 4;
2272         else /* wct == 12 pad bigger by four bytes */
2273                 iov[0].iov_len = smb_hdr_len + 8;
2274
2275         rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2276                           &rsp_iov);
2277         cifs_small_buf_release(pSMB);
2278         cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2279         if (rc) {
2280                 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2281         } else if (resp_buf_type == 0) {
2282                 /* presumably this can not happen, but best to be safe */
2283                 rc = -EIO;
2284         } else {
2285                 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2286                 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2287                 *nbytes = (*nbytes) << 16;
2288                 *nbytes += le16_to_cpu(pSMBr->Count);
2289
2290                 /*
2291                  * Mask off high 16 bits when bytes written as returned by the
2292                  * server is greater than bytes requested by the client. OS/2
2293                  * servers are known to set incorrect CountHigh values.
2294                  */
2295                 if (*nbytes > count)
2296                         *nbytes &= 0xFFFF;
2297         }
2298
2299         free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2300
2301         /* Note: On -EAGAIN error only caller can retry on handle based calls
2302                 since file handle passed in no longer valid */
2303
2304         return rc;
2305 }
2306
2307 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2308                const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2309                const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2310 {
2311         int rc = 0;
2312         LOCK_REQ *pSMB = NULL;
2313         struct kvec iov[2];
2314         struct kvec rsp_iov;
2315         int resp_buf_type;
2316         __u16 count;
2317
2318         cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2319                  num_lock, num_unlock);
2320
2321         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2322         if (rc)
2323                 return rc;
2324
2325         pSMB->Timeout = 0;
2326         pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2327         pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2328         pSMB->LockType = lock_type;
2329         pSMB->AndXCommand = 0xFF; /* none */
2330         pSMB->Fid = netfid; /* netfid stays le */
2331
2332         count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2333         inc_rfc1001_len(pSMB, count);
2334         pSMB->ByteCount = cpu_to_le16(count);
2335
2336         iov[0].iov_base = (char *)pSMB;
2337         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2338                          (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2339         iov[1].iov_base = (char *)buf;
2340         iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2341
2342         cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2343         rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP,
2344                           &rsp_iov);
2345         cifs_small_buf_release(pSMB);
2346         if (rc)
2347                 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2348
2349         return rc;
2350 }
2351
2352 int
2353 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2354             const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2355             const __u64 offset, const __u32 numUnlock,
2356             const __u32 numLock, const __u8 lockType,
2357             const bool waitFlag, const __u8 oplock_level)
2358 {
2359         int rc = 0;
2360         LOCK_REQ *pSMB = NULL;
2361 /*      LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2362         int bytes_returned;
2363         int flags = 0;
2364         __u16 count;
2365
2366         cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2367                  (int)waitFlag, numLock);
2368         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2369
2370         if (rc)
2371                 return rc;
2372
2373         if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2374                 /* no response expected */
2375                 flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP;
2376                 pSMB->Timeout = 0;
2377         } else if (waitFlag) {
2378                 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2379                 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2380         } else {
2381                 pSMB->Timeout = 0;
2382         }
2383
2384         pSMB->NumberOfLocks = cpu_to_le16(numLock);
2385         pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2386         pSMB->LockType = lockType;
2387         pSMB->OplockLevel = oplock_level;
2388         pSMB->AndXCommand = 0xFF;       /* none */
2389         pSMB->Fid = smb_file_id; /* netfid stays le */
2390
2391         if ((numLock != 0) || (numUnlock != 0)) {
2392                 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2393                 /* BB where to store pid high? */
2394                 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2395                 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2396                 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2397                 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2398                 count = sizeof(LOCKING_ANDX_RANGE);
2399         } else {
2400                 /* oplock break */
2401                 count = 0;
2402         }
2403         inc_rfc1001_len(pSMB, count);
2404         pSMB->ByteCount = cpu_to_le16(count);
2405
2406         if (waitFlag)
2407                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2408                         (struct smb_hdr *) pSMB, &bytes_returned);
2409         else
2410                 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2411         cifs_small_buf_release(pSMB);
2412         cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2413         if (rc)
2414                 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2415
2416         /* Note: On -EAGAIN error only caller can retry on handle based calls
2417         since file handle passed in no longer valid */
2418         return rc;
2419 }
2420
2421 int
2422 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2423                 const __u16 smb_file_id, const __u32 netpid,
2424                 const loff_t start_offset, const __u64 len,
2425                 struct file_lock *pLockData, const __u16 lock_type,
2426                 const bool waitFlag)
2427 {
2428         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2429         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2430         struct cifs_posix_lock *parm_data;
2431         int rc = 0;
2432         int timeout = 0;
2433         int bytes_returned = 0;
2434         int resp_buf_type = 0;
2435         __u16 params, param_offset, offset, byte_count, count;
2436         struct kvec iov[1];
2437         struct kvec rsp_iov;
2438
2439         cifs_dbg(FYI, "Posix Lock\n");
2440
2441         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2442
2443         if (rc)
2444                 return rc;
2445
2446         pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2447
2448         params = 6;
2449         pSMB->MaxSetupCount = 0;
2450         pSMB->Reserved = 0;
2451         pSMB->Flags = 0;
2452         pSMB->Reserved2 = 0;
2453         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2454         offset = param_offset + params;
2455
2456         count = sizeof(struct cifs_posix_lock);
2457         pSMB->MaxParameterCount = cpu_to_le16(2);
2458         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2459         pSMB->SetupCount = 1;
2460         pSMB->Reserved3 = 0;
2461         if (pLockData)
2462                 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2463         else
2464                 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2465         byte_count = 3 /* pad */  + params + count;
2466         pSMB->DataCount = cpu_to_le16(count);
2467         pSMB->ParameterCount = cpu_to_le16(params);
2468         pSMB->TotalDataCount = pSMB->DataCount;
2469         pSMB->TotalParameterCount = pSMB->ParameterCount;
2470         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2471         parm_data = (struct cifs_posix_lock *)
2472                         (((char *) &pSMB->hdr.Protocol) + offset);
2473
2474         parm_data->lock_type = cpu_to_le16(lock_type);
2475         if (waitFlag) {
2476                 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2477                 parm_data->lock_flags = cpu_to_le16(1);
2478                 pSMB->Timeout = cpu_to_le32(-1);
2479         } else
2480                 pSMB->Timeout = 0;
2481
2482         parm_data->pid = cpu_to_le32(netpid);
2483         parm_data->start = cpu_to_le64(start_offset);
2484         parm_data->length = cpu_to_le64(len);  /* normalize negative numbers */
2485
2486         pSMB->DataOffset = cpu_to_le16(offset);
2487         pSMB->Fid = smb_file_id;
2488         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2489         pSMB->Reserved4 = 0;
2490         inc_rfc1001_len(pSMB, byte_count);
2491         pSMB->ByteCount = cpu_to_le16(byte_count);
2492         if (waitFlag) {
2493                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2494                         (struct smb_hdr *) pSMBr, &bytes_returned);
2495         } else {
2496                 iov[0].iov_base = (char *)pSMB;
2497                 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2498                 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2499                                 &resp_buf_type, timeout, &rsp_iov);
2500                 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2501         }
2502         cifs_small_buf_release(pSMB);
2503
2504         if (rc) {
2505                 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2506         } else if (pLockData) {
2507                 /* lock structure can be returned on get */
2508                 __u16 data_offset;
2509                 __u16 data_count;
2510                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2511
2512                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2513                         rc = -EIO;      /* bad smb */
2514                         goto plk_err_exit;
2515                 }
2516                 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2517                 data_count  = le16_to_cpu(pSMBr->t2.DataCount);
2518                 if (data_count < sizeof(struct cifs_posix_lock)) {
2519                         rc = -EIO;
2520                         goto plk_err_exit;
2521                 }
2522                 parm_data = (struct cifs_posix_lock *)
2523                         ((char *)&pSMBr->hdr.Protocol + data_offset);
2524                 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2525                         pLockData->fl_type = F_UNLCK;
2526                 else {
2527                         if (parm_data->lock_type ==
2528                                         cpu_to_le16(CIFS_RDLCK))
2529                                 pLockData->fl_type = F_RDLCK;
2530                         else if (parm_data->lock_type ==
2531                                         cpu_to_le16(CIFS_WRLCK))
2532                                 pLockData->fl_type = F_WRLCK;
2533
2534                         pLockData->fl_start = le64_to_cpu(parm_data->start);
2535                         pLockData->fl_end = pLockData->fl_start +
2536                                         le64_to_cpu(parm_data->length) - 1;
2537                         pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2538                 }
2539         }
2540
2541 plk_err_exit:
2542         free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2543
2544         /* Note: On -EAGAIN error only caller can retry on handle based calls
2545            since file handle passed in no longer valid */
2546
2547         return rc;
2548 }
2549
2550
2551 int
2552 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2553 {
2554         int rc = 0;
2555         CLOSE_REQ *pSMB = NULL;
2556         cifs_dbg(FYI, "In CIFSSMBClose\n");
2557
2558 /* do not retry on dead session on close */
2559         rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2560         if (rc == -EAGAIN)
2561                 return 0;
2562         if (rc)
2563                 return rc;
2564
2565         pSMB->FileID = (__u16) smb_file_id;
2566         pSMB->LastWriteTime = 0xFFFFFFFF;
2567         pSMB->ByteCount = 0;
2568         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2569         cifs_small_buf_release(pSMB);
2570         cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2571         if (rc) {
2572                 if (rc != -EINTR) {
2573                         /* EINTR is expected when user ctl-c to kill app */
2574                         cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2575                 }
2576         }
2577
2578         /* Since session is dead, file will be closed on server already */
2579         if (rc == -EAGAIN)
2580                 rc = 0;
2581
2582         return rc;
2583 }
2584
2585 int
2586 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2587 {
2588         int rc = 0;
2589         FLUSH_REQ *pSMB = NULL;
2590         cifs_dbg(FYI, "In CIFSSMBFlush\n");
2591
2592         rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2593         if (rc)
2594                 return rc;
2595
2596         pSMB->FileID = (__u16) smb_file_id;
2597         pSMB->ByteCount = 0;
2598         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2599         cifs_small_buf_release(pSMB);
2600         cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2601         if (rc)
2602                 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2603
2604         return rc;
2605 }
2606
2607 int
2608 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2609               const char *from_name, const char *to_name,
2610               struct cifs_sb_info *cifs_sb)
2611 {
2612         int rc = 0;
2613         RENAME_REQ *pSMB = NULL;
2614         RENAME_RSP *pSMBr = NULL;
2615         int bytes_returned;
2616         int name_len, name_len2;
2617         __u16 count;
2618         int remap = cifs_remap(cifs_sb);
2619
2620         cifs_dbg(FYI, "In CIFSSMBRename\n");
2621 renameRetry:
2622         rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2623                       (void **) &pSMBr);
2624         if (rc)
2625                 return rc;
2626
2627         pSMB->BufferFormat = 0x04;
2628         pSMB->SearchAttributes =
2629             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2630                         ATTR_DIRECTORY);
2631
2632         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2633                 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2634                                               from_name, PATH_MAX,
2635                                               cifs_sb->local_nls, remap);
2636                 name_len++;     /* trailing null */
2637                 name_len *= 2;
2638                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2639         /* protocol requires ASCII signature byte on Unicode string */
2640                 pSMB->OldFileName[name_len + 1] = 0x00;
2641                 name_len2 =
2642                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2643                                        to_name, PATH_MAX, cifs_sb->local_nls,
2644                                        remap);
2645                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2646                 name_len2 *= 2; /* convert to bytes */
2647         } else {        /* BB improve the check for buffer overruns BB */
2648                 name_len = strnlen(from_name, PATH_MAX);
2649                 name_len++;     /* trailing null */
2650                 strncpy(pSMB->OldFileName, from_name, name_len);
2651                 name_len2 = strnlen(to_name, PATH_MAX);
2652                 name_len2++;    /* trailing null */
2653                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2654                 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
2655                 name_len2++;    /* trailing null */
2656                 name_len2++;    /* signature byte */
2657         }
2658
2659         count = 1 /* 1st signature byte */  + name_len + name_len2;
2660         inc_rfc1001_len(pSMB, count);
2661         pSMB->ByteCount = cpu_to_le16(count);
2662
2663         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2664                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2665         cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2666         if (rc)
2667                 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2668
2669         cifs_buf_release(pSMB);
2670
2671         if (rc == -EAGAIN)
2672                 goto renameRetry;
2673
2674         return rc;
2675 }
2676
2677 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2678                 int netfid, const char *target_name,
2679                 const struct nls_table *nls_codepage, int remap)
2680 {
2681         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2682         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2683         struct set_file_rename *rename_info;
2684         char *data_offset;
2685         char dummy_string[30];
2686         int rc = 0;
2687         int bytes_returned = 0;
2688         int len_of_str;
2689         __u16 params, param_offset, offset, count, byte_count;
2690
2691         cifs_dbg(FYI, "Rename to File by handle\n");
2692         rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2693                         (void **) &pSMBr);
2694         if (rc)
2695                 return rc;
2696
2697         params = 6;
2698         pSMB->MaxSetupCount = 0;
2699         pSMB->Reserved = 0;
2700         pSMB->Flags = 0;
2701         pSMB->Timeout = 0;
2702         pSMB->Reserved2 = 0;
2703         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2704         offset = param_offset + params;
2705
2706         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2707         rename_info = (struct set_file_rename *) data_offset;
2708         pSMB->MaxParameterCount = cpu_to_le16(2);
2709         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2710         pSMB->SetupCount = 1;
2711         pSMB->Reserved3 = 0;
2712         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2713         byte_count = 3 /* pad */  + params;
2714         pSMB->ParameterCount = cpu_to_le16(params);
2715         pSMB->TotalParameterCount = pSMB->ParameterCount;
2716         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2717         pSMB->DataOffset = cpu_to_le16(offset);
2718         /* construct random name ".cifs_tmp<inodenum><mid>" */
2719         rename_info->overwrite = cpu_to_le32(1);
2720         rename_info->root_fid  = 0;
2721         /* unicode only call */
2722         if (target_name == NULL) {
2723                 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2724                 len_of_str =
2725                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2726                                         dummy_string, 24, nls_codepage, remap);
2727         } else {
2728                 len_of_str =
2729                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2730                                         target_name, PATH_MAX, nls_codepage,
2731                                         remap);
2732         }
2733         rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2734         count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2735         byte_count += count;
2736         pSMB->DataCount = cpu_to_le16(count);
2737         pSMB->TotalDataCount = pSMB->DataCount;
2738         pSMB->Fid = netfid;
2739         pSMB->InformationLevel =
2740                 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2741         pSMB->Reserved4 = 0;
2742         inc_rfc1001_len(pSMB, byte_count);
2743         pSMB->ByteCount = cpu_to_le16(byte_count);
2744         rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2745                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2746         cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2747         if (rc)
2748                 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2749                          rc);
2750
2751         cifs_buf_release(pSMB);
2752
2753         /* Note: On -EAGAIN error only caller can retry on handle based calls
2754                 since file handle passed in no longer valid */
2755
2756         return rc;
2757 }
2758
2759 int
2760 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2761             const char *fromName, const __u16 target_tid, const char *toName,
2762             const int flags, const struct nls_table *nls_codepage, int remap)
2763 {
2764         int rc = 0;
2765         COPY_REQ *pSMB = NULL;
2766         COPY_RSP *pSMBr = NULL;
2767         int bytes_returned;
2768         int name_len, name_len2;
2769         __u16 count;
2770
2771         cifs_dbg(FYI, "In CIFSSMBCopy\n");
2772 copyRetry:
2773         rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2774                         (void **) &pSMBr);
2775         if (rc)
2776                 return rc;
2777
2778         pSMB->BufferFormat = 0x04;
2779         pSMB->Tid2 = target_tid;
2780
2781         pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2782
2783         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2784                 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2785                                               fromName, PATH_MAX, nls_codepage,
2786                                               remap);
2787                 name_len++;     /* trailing null */
2788                 name_len *= 2;
2789                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2790                 /* protocol requires ASCII signature byte on Unicode string */
2791                 pSMB->OldFileName[name_len + 1] = 0x00;
2792                 name_len2 =
2793                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2794                                        toName, PATH_MAX, nls_codepage, remap);
2795                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2796                 name_len2 *= 2; /* convert to bytes */
2797         } else {        /* BB improve the check for buffer overruns BB */
2798                 name_len = strnlen(fromName, PATH_MAX);
2799                 name_len++;     /* trailing null */
2800                 strncpy(pSMB->OldFileName, fromName, name_len);
2801                 name_len2 = strnlen(toName, PATH_MAX);
2802                 name_len2++;    /* trailing null */
2803                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2804                 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2805                 name_len2++;    /* trailing null */
2806                 name_len2++;    /* signature byte */
2807         }
2808
2809         count = 1 /* 1st signature byte */  + name_len + name_len2;
2810         inc_rfc1001_len(pSMB, count);
2811         pSMB->ByteCount = cpu_to_le16(count);
2812
2813         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2814                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2815         if (rc) {
2816                 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2817                          rc, le16_to_cpu(pSMBr->CopyCount));
2818         }
2819         cifs_buf_release(pSMB);
2820
2821         if (rc == -EAGAIN)
2822                 goto copyRetry;
2823
2824         return rc;
2825 }
2826
2827 int
2828 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2829                       const char *fromName, const char *toName,
2830                       const struct nls_table *nls_codepage, int remap)
2831 {
2832         TRANSACTION2_SPI_REQ *pSMB = NULL;
2833         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2834         char *data_offset;
2835         int name_len;
2836         int name_len_target;
2837         int rc = 0;
2838         int bytes_returned = 0;
2839         __u16 params, param_offset, offset, byte_count;
2840
2841         cifs_dbg(FYI, "In Symlink Unix style\n");
2842 createSymLinkRetry:
2843         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2844                       (void **) &pSMBr);
2845         if (rc)
2846                 return rc;
2847
2848         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2849                 name_len =
2850                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2851                                 /* find define for this maxpathcomponent */
2852                                         PATH_MAX, nls_codepage, remap);
2853                 name_len++;     /* trailing null */
2854                 name_len *= 2;
2855
2856         } else {        /* BB improve the check for buffer overruns BB */
2857                 name_len = strnlen(fromName, PATH_MAX);
2858                 name_len++;     /* trailing null */
2859                 strncpy(pSMB->FileName, fromName, name_len);
2860         }
2861         params = 6 + name_len;
2862         pSMB->MaxSetupCount = 0;
2863         pSMB->Reserved = 0;
2864         pSMB->Flags = 0;
2865         pSMB->Timeout = 0;
2866         pSMB->Reserved2 = 0;
2867         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2868                                 InformationLevel) - 4;
2869         offset = param_offset + params;
2870
2871         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2872         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2873                 name_len_target =
2874                     cifsConvertToUTF16((__le16 *) data_offset, toName,
2875                                 /* find define for this maxpathcomponent */
2876                                         PATH_MAX, nls_codepage, remap);
2877                 name_len_target++;      /* trailing null */
2878                 name_len_target *= 2;
2879         } else {        /* BB improve the check for buffer overruns BB */
2880                 name_len_target = strnlen(toName, PATH_MAX);
2881                 name_len_target++;      /* trailing null */
2882                 strncpy(data_offset, toName, name_len_target);
2883         }
2884
2885         pSMB->MaxParameterCount = cpu_to_le16(2);
2886         /* BB find exact max on data count below from sess */
2887         pSMB->MaxDataCount = cpu_to_le16(1000);
2888         pSMB->SetupCount = 1;
2889         pSMB->Reserved3 = 0;
2890         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2891         byte_count = 3 /* pad */  + params + name_len_target;
2892         pSMB->DataCount = cpu_to_le16(name_len_target);
2893         pSMB->ParameterCount = cpu_to_le16(params);
2894         pSMB->TotalDataCount = pSMB->DataCount;
2895         pSMB->TotalParameterCount = pSMB->ParameterCount;
2896         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2897         pSMB->DataOffset = cpu_to_le16(offset);
2898         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2899         pSMB->Reserved4 = 0;
2900         inc_rfc1001_len(pSMB, byte_count);
2901         pSMB->ByteCount = cpu_to_le16(byte_count);
2902         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2903                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2904         cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2905         if (rc)
2906                 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2907                          rc);
2908
2909         cifs_buf_release(pSMB);
2910
2911         if (rc == -EAGAIN)
2912                 goto createSymLinkRetry;
2913
2914         return rc;
2915 }
2916
2917 int
2918 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2919                        const char *fromName, const char *toName,
2920                        const struct nls_table *nls_codepage, int remap)
2921 {
2922         TRANSACTION2_SPI_REQ *pSMB = NULL;
2923         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2924         char *data_offset;
2925         int name_len;
2926         int name_len_target;
2927         int rc = 0;
2928         int bytes_returned = 0;
2929         __u16 params, param_offset, offset, byte_count;
2930
2931         cifs_dbg(FYI, "In Create Hard link Unix style\n");
2932 createHardLinkRetry:
2933         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2934                       (void **) &pSMBr);
2935         if (rc)
2936                 return rc;
2937
2938         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2939                 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2940                                               PATH_MAX, nls_codepage, remap);
2941                 name_len++;     /* trailing null */
2942                 name_len *= 2;
2943
2944         } else {        /* BB improve the check for buffer overruns BB */
2945                 name_len = strnlen(toName, PATH_MAX);
2946                 name_len++;     /* trailing null */
2947                 strncpy(pSMB->FileName, toName, name_len);
2948         }
2949         params = 6 + name_len;
2950         pSMB->MaxSetupCount = 0;
2951         pSMB->Reserved = 0;
2952         pSMB->Flags = 0;
2953         pSMB->Timeout = 0;
2954         pSMB->Reserved2 = 0;
2955         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2956                                 InformationLevel) - 4;
2957         offset = param_offset + params;
2958
2959         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2960         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2961                 name_len_target =
2962                     cifsConvertToUTF16((__le16 *) data_offset, fromName,
2963                                        PATH_MAX, nls_codepage, remap);
2964                 name_len_target++;      /* trailing null */
2965                 name_len_target *= 2;
2966         } else {        /* BB improve the check for buffer overruns BB */
2967                 name_len_target = strnlen(fromName, PATH_MAX);
2968                 name_len_target++;      /* trailing null */
2969                 strncpy(data_offset, fromName, name_len_target);
2970         }
2971
2972         pSMB->MaxParameterCount = cpu_to_le16(2);
2973         /* BB find exact max on data count below from sess*/
2974         pSMB->MaxDataCount = cpu_to_le16(1000);
2975         pSMB->SetupCount = 1;
2976         pSMB->Reserved3 = 0;
2977         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2978         byte_count = 3 /* pad */  + params + name_len_target;
2979         pSMB->ParameterCount = cpu_to_le16(params);
2980         pSMB->TotalParameterCount = pSMB->ParameterCount;
2981         pSMB->DataCount = cpu_to_le16(name_len_target);
2982         pSMB->TotalDataCount = pSMB->DataCount;
2983         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2984         pSMB->DataOffset = cpu_to_le16(offset);
2985         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2986         pSMB->Reserved4 = 0;
2987         inc_rfc1001_len(pSMB, byte_count);
2988         pSMB->ByteCount = cpu_to_le16(byte_count);
2989         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2990                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2991         cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2992         if (rc)
2993                 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2994                          rc);
2995
2996         cifs_buf_release(pSMB);
2997         if (rc == -EAGAIN)
2998                 goto createHardLinkRetry;
2999
3000         return rc;
3001 }
3002
3003 int
3004 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3005                    const char *from_name, const char *to_name,
3006                    struct cifs_sb_info *cifs_sb)
3007 {
3008         int rc = 0;
3009         NT_RENAME_REQ *pSMB = NULL;
3010         RENAME_RSP *pSMBr = NULL;
3011         int bytes_returned;
3012         int name_len, name_len2;
3013         __u16 count;
3014         int remap = cifs_remap(cifs_sb);
3015
3016         cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3017 winCreateHardLinkRetry:
3018
3019         rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3020                       (void **) &pSMBr);
3021         if (rc)
3022                 return rc;
3023
3024         pSMB->SearchAttributes =
3025             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3026                         ATTR_DIRECTORY);
3027         pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3028         pSMB->ClusterCount = 0;
3029
3030         pSMB->BufferFormat = 0x04;
3031
3032         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3033                 name_len =
3034                     cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3035                                        PATH_MAX, cifs_sb->local_nls, remap);
3036                 name_len++;     /* trailing null */
3037                 name_len *= 2;
3038
3039                 /* protocol specifies ASCII buffer format (0x04) for unicode */
3040                 pSMB->OldFileName[name_len] = 0x04;
3041                 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3042                 name_len2 =
3043                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3044                                        to_name, PATH_MAX, cifs_sb->local_nls,
3045                                        remap);
3046                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
3047                 name_len2 *= 2; /* convert to bytes */
3048         } else {        /* BB improve the check for buffer overruns BB */
3049                 name_len = strnlen(from_name, PATH_MAX);
3050                 name_len++;     /* trailing null */
3051                 strncpy(pSMB->OldFileName, from_name, name_len);
3052                 name_len2 = strnlen(to_name, PATH_MAX);
3053                 name_len2++;    /* trailing null */
3054                 pSMB->OldFileName[name_len] = 0x04;     /* 2nd buffer format */
3055                 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
3056                 name_len2++;    /* trailing null */
3057                 name_len2++;    /* signature byte */
3058         }
3059
3060         count = 1 /* string type byte */  + name_len + name_len2;
3061         inc_rfc1001_len(pSMB, count);
3062         pSMB->ByteCount = cpu_to_le16(count);
3063
3064         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3065                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3066         cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3067         if (rc)
3068                 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3069
3070         cifs_buf_release(pSMB);
3071         if (rc == -EAGAIN)
3072                 goto winCreateHardLinkRetry;
3073
3074         return rc;
3075 }
3076
3077 int
3078 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3079                         const unsigned char *searchName, char **symlinkinfo,
3080                         const struct nls_table *nls_codepage, int remap)
3081 {
3082 /* SMB_QUERY_FILE_UNIX_LINK */
3083         TRANSACTION2_QPI_REQ *pSMB = NULL;
3084         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3085         int rc = 0;
3086         int bytes_returned;
3087         int name_len;
3088         __u16 params, byte_count;
3089         char *data_start;
3090
3091         cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3092
3093 querySymLinkRetry:
3094         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3095                       (void **) &pSMBr);
3096         if (rc)
3097                 return rc;
3098
3099         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3100                 name_len =
3101                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3102                                            searchName, PATH_MAX, nls_codepage,
3103                                            remap);
3104                 name_len++;     /* trailing null */
3105                 name_len *= 2;
3106         } else {        /* BB improve the check for buffer overruns BB */
3107                 name_len = strnlen(searchName, PATH_MAX);
3108                 name_len++;     /* trailing null */
3109                 strncpy(pSMB->FileName, searchName, name_len);
3110         }
3111
3112         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3113         pSMB->TotalDataCount = 0;
3114         pSMB->MaxParameterCount = cpu_to_le16(2);
3115         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3116         pSMB->MaxSetupCount = 0;
3117         pSMB->Reserved = 0;
3118         pSMB->Flags = 0;
3119         pSMB->Timeout = 0;
3120         pSMB->Reserved2 = 0;
3121         pSMB->ParameterOffset = cpu_to_le16(offsetof(
3122         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3123         pSMB->DataCount = 0;
3124         pSMB->DataOffset = 0;
3125         pSMB->SetupCount = 1;
3126         pSMB->Reserved3 = 0;
3127         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3128         byte_count = params + 1 /* pad */ ;
3129         pSMB->TotalParameterCount = cpu_to_le16(params);
3130         pSMB->ParameterCount = pSMB->TotalParameterCount;
3131         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3132         pSMB->Reserved4 = 0;
3133         inc_rfc1001_len(pSMB, byte_count);
3134         pSMB->ByteCount = cpu_to_le16(byte_count);
3135
3136         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3137                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3138         if (rc) {
3139                 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3140         } else {
3141                 /* decode response */
3142
3143                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3144                 /* BB also check enough total bytes returned */
3145                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3146                         rc = -EIO;
3147                 else {
3148                         bool is_unicode;
3149                         u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3150
3151                         data_start = ((char *) &pSMBr->hdr.Protocol) +
3152                                            le16_to_cpu(pSMBr->t2.DataOffset);
3153
3154                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3155                                 is_unicode = true;
3156                         else
3157                                 is_unicode = false;
3158
3159                         /* BB FIXME investigate remapping reserved chars here */
3160                         *symlinkinfo = cifs_strndup_from_utf16(data_start,
3161                                         count, is_unicode, nls_codepage);
3162                         if (!*symlinkinfo)
3163                                 rc = -ENOMEM;
3164                 }
3165         }
3166         cifs_buf_release(pSMB);
3167         if (rc == -EAGAIN)
3168                 goto querySymLinkRetry;
3169         return rc;
3170 }
3171
3172 /*
3173  *      Recent Windows versions now create symlinks more frequently
3174  *      and they use the "reparse point" mechanism below.  We can of course
3175  *      do symlinks nicely to Samba and other servers which support the
3176  *      CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3177  *      "MF" symlinks optionally, but for recent Windows we really need to
3178  *      reenable the code below and fix the cifs_symlink callers to handle this.
3179  *      In the interim this code has been moved to its own config option so
3180  *      it is not compiled in by default until callers fixed up and more tested.
3181  */
3182 int
3183 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3184                     __u16 fid, char **symlinkinfo,
3185                     const struct nls_table *nls_codepage)
3186 {
3187         int rc = 0;
3188         int bytes_returned;
3189         struct smb_com_transaction_ioctl_req *pSMB;
3190         struct smb_com_transaction_ioctl_rsp *pSMBr;
3191         bool is_unicode;
3192         unsigned int sub_len;
3193         char *sub_start;
3194         struct reparse_symlink_data *reparse_buf;
3195         struct reparse_posix_data *posix_buf;
3196         __u32 data_offset, data_count;
3197         char *end_of_smb;
3198
3199         cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3200         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3201                       (void **) &pSMBr);
3202         if (rc)
3203                 return rc;
3204
3205         pSMB->TotalParameterCount = 0 ;
3206         pSMB->TotalDataCount = 0;
3207         pSMB->MaxParameterCount = cpu_to_le32(2);
3208         /* BB find exact data count max from sess structure BB */
3209         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3210         pSMB->MaxSetupCount = 4;
3211         pSMB->Reserved = 0;
3212         pSMB->ParameterOffset = 0;
3213         pSMB->DataCount = 0;
3214         pSMB->DataOffset = 0;
3215         pSMB->SetupCount = 4;
3216         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3217         pSMB->ParameterCount = pSMB->TotalParameterCount;
3218         pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3219         pSMB->IsFsctl = 1; /* FSCTL */
3220         pSMB->IsRootFlag = 0;
3221         pSMB->Fid = fid; /* file handle always le */
3222         pSMB->ByteCount = 0;
3223
3224         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3225                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3226         if (rc) {
3227                 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3228                 goto qreparse_out;
3229         }
3230
3231         data_offset = le32_to_cpu(pSMBr->DataOffset);
3232         data_count = le32_to_cpu(pSMBr->DataCount);
3233         if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3234                 /* BB also check enough total bytes returned */
3235                 rc = -EIO;      /* bad smb */
3236                 goto qreparse_out;
3237         }
3238         if (!data_count || (data_count > 2048)) {
3239                 rc = -EIO;
3240                 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3241                 goto qreparse_out;
3242         }
3243         end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3244         reparse_buf = (struct reparse_symlink_data *)
3245                                 ((char *)&pSMBr->hdr.Protocol + data_offset);
3246         if ((char *)reparse_buf >= end_of_smb) {
3247                 rc = -EIO;
3248                 goto qreparse_out;
3249         }
3250         if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3251                 cifs_dbg(FYI, "NFS style reparse tag\n");
3252                 posix_buf =  (struct reparse_posix_data *)reparse_buf;
3253
3254                 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3255                         cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3256                                  le64_to_cpu(posix_buf->InodeType));
3257                         rc = -EOPNOTSUPP;
3258                         goto qreparse_out;
3259                 }
3260                 is_unicode = true;
3261                 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3262                 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3263                         cifs_dbg(FYI, "reparse buf beyond SMB\n");
3264                         rc = -EIO;
3265                         goto qreparse_out;
3266                 }
3267                 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3268                                 sub_len, is_unicode, nls_codepage);
3269                 goto qreparse_out;
3270         } else if (reparse_buf->ReparseTag !=
3271                         cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3272                 rc = -EOPNOTSUPP;
3273                 goto qreparse_out;
3274         }
3275
3276         /* Reparse tag is NTFS symlink */
3277         sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3278                                 reparse_buf->PathBuffer;
3279         sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3280         if (sub_start + sub_len > end_of_smb) {
3281                 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3282                 rc = -EIO;
3283                 goto qreparse_out;
3284         }
3285         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3286                 is_unicode = true;
3287         else
3288                 is_unicode = false;
3289
3290         /* BB FIXME investigate remapping reserved chars here */
3291         *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3292                                                nls_codepage);
3293         if (!*symlinkinfo)
3294                 rc = -ENOMEM;
3295 qreparse_out:
3296         cifs_buf_release(pSMB);
3297
3298         /*
3299          * Note: On -EAGAIN error only caller can retry on handle based calls
3300          * since file handle passed in no longer valid.
3301          */
3302         return rc;
3303 }
3304
3305 int
3306 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3307                     __u16 fid)
3308 {
3309         int rc = 0;
3310         int bytes_returned;
3311         struct smb_com_transaction_compr_ioctl_req *pSMB;
3312         struct smb_com_transaction_ioctl_rsp *pSMBr;
3313
3314         cifs_dbg(FYI, "Set compression for %u\n", fid);
3315         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3316                       (void **) &pSMBr);
3317         if (rc)
3318                 return rc;
3319
3320         pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3321
3322         pSMB->TotalParameterCount = 0;
3323         pSMB->TotalDataCount = cpu_to_le32(2);
3324         pSMB->MaxParameterCount = 0;
3325         pSMB->MaxDataCount = 0;
3326         pSMB->MaxSetupCount = 4;
3327         pSMB->Reserved = 0;
3328         pSMB->ParameterOffset = 0;
3329         pSMB->DataCount = cpu_to_le32(2);
3330         pSMB->DataOffset =
3331                 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3332                                 compression_state) - 4);  /* 84 */
3333         pSMB->SetupCount = 4;
3334         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3335         pSMB->ParameterCount = 0;
3336         pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3337         pSMB->IsFsctl = 1; /* FSCTL */
3338         pSMB->IsRootFlag = 0;
3339         pSMB->Fid = fid; /* file handle always le */
3340         /* 3 byte pad, followed by 2 byte compress state */
3341         pSMB->ByteCount = cpu_to_le16(5);
3342         inc_rfc1001_len(pSMB, 5);
3343
3344         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3345                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3346         if (rc)
3347                 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3348
3349         cifs_buf_release(pSMB);
3350
3351         /*
3352          * Note: On -EAGAIN error only caller can retry on handle based calls
3353          * since file handle passed in no longer valid.
3354          */
3355         return rc;
3356 }
3357
3358
3359 #ifdef CONFIG_CIFS_POSIX
3360
3361 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3362 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3363                              struct cifs_posix_ace *cifs_ace)
3364 {
3365         /* u8 cifs fields do not need le conversion */
3366         ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3367         ace->e_tag  = cpu_to_le16(cifs_ace->cifs_e_tag);
3368         ace->e_id   = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3369 /*
3370         cifs_dbg(FYI, "perm %d tag %d id %d\n",
3371                  ace->e_perm, ace->e_tag, ace->e_id);
3372 */
3373
3374         return;
3375 }
3376
3377 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3378 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3379                                const int acl_type, const int size_of_data_area)
3380 {
3381         int size =  0;
3382         int i;