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