1 // SPDX-License-Identifier: LGPL-2.1
4 * Copyright (C) International Business Machines Corp., 2002,2010
7 * Contains the routines for constructing the SMB PDUs themselves
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 */
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>
29 #include "cifsproto.h"
30 #include "cifs_unicode.h"
31 #include "cifs_debug.h"
33 #include "smbdirect.h"
34 #ifdef CONFIG_CIFS_DFS_UPCALL
35 #include "dfs_cache.h"
38 #ifdef CONFIG_CIFS_POSIX
43 {CIFS_PROT, "\2NT LM 0.12"},
44 {POSIX_PROT, "\2POSIX 2"},
52 {CIFS_PROT, "\2NT LM 0.12"},
57 /* define the number of elements in the cifs dialect array */
58 #ifdef CONFIG_CIFS_POSIX
59 #define CIFS_NUM_PROT 2
61 #define CIFS_NUM_PROT 1
62 #endif /* CIFS_POSIX */
65 /* reconnect the socket, tcon, and smb session if needed */
67 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
71 struct TCP_Server_Info *server;
72 struct nls_table *nls_codepage;
76 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
77 * tcp and smb session status done differently for those three - in the
87 * only tree disconnect, open, and write, (and ulogoff which does not
88 * have tcon) are allowed as we start force umount
90 spin_lock(&tcon->tc_lock);
91 if (tcon->status == TID_EXITING) {
92 if (smb_command != SMB_COM_WRITE_ANDX &&
93 smb_command != SMB_COM_OPEN_ANDX &&
94 smb_command != SMB_COM_TREE_DISCONNECT) {
95 spin_unlock(&tcon->tc_lock);
96 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
101 spin_unlock(&tcon->tc_lock);
103 retries = server->nr_targets;
106 * Give demultiplex thread up to 10 seconds to each target available for
107 * reconnect -- should be greater than cifs socket timeout which is 7
110 while (server->tcpStatus == CifsNeedReconnect) {
111 rc = wait_event_interruptible_timeout(server->response_q,
112 (server->tcpStatus != CifsNeedReconnect),
115 cifs_dbg(FYI, "%s: aborting reconnect due to a received signal by the process\n",
120 /* are we still trying to reconnect? */
121 spin_lock(&server->srv_lock);
122 if (server->tcpStatus != CifsNeedReconnect) {
123 spin_unlock(&server->srv_lock);
126 spin_unlock(&server->srv_lock);
128 if (retries && --retries)
132 * on "soft" mounts we wait once. Hard mounts keep
133 * retrying until process is killed or server comes
137 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
140 retries = server->nr_targets;
143 spin_lock(&ses->chan_lock);
144 if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
145 spin_unlock(&ses->chan_lock);
148 spin_unlock(&ses->chan_lock);
150 nls_codepage = load_nls_default();
153 * Recheck after acquire mutex. If another thread is negotiating
154 * and the server never sends an answer the socket will be closed
155 * and tcpStatus set to reconnect.
157 spin_lock(&server->srv_lock);
158 if (server->tcpStatus == CifsNeedReconnect) {
159 spin_unlock(&server->srv_lock);
163 spin_unlock(&server->srv_lock);
166 * need to prevent multiple threads trying to simultaneously
167 * reconnect the same SMB session
169 spin_lock(&ses->chan_lock);
170 if (!cifs_chan_needs_reconnect(ses, server)) {
171 spin_unlock(&ses->chan_lock);
173 /* this means that we only need to tree connect */
174 if (tcon->need_reconnect)
175 goto skip_sess_setup;
180 spin_unlock(&ses->chan_lock);
182 mutex_lock(&ses->session_mutex);
183 rc = cifs_negotiate_protocol(0, ses, server);
185 rc = cifs_setup_session(0, ses, server, nls_codepage);
187 /* do we need to reconnect tcon? */
188 if (rc || !tcon->need_reconnect) {
189 mutex_unlock(&ses->session_mutex);
194 cifs_mark_open_files_invalid(tcon);
195 rc = cifs_tree_connect(0, tcon, nls_codepage);
196 mutex_unlock(&ses->session_mutex);
197 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
200 pr_warn_once("reconnect tcon failed rc = %d\n", rc);
204 atomic_inc(&tconInfoReconnectCount);
206 /* tell server Unix caps we support */
208 reset_cifs_unix_caps(0, tcon, NULL, NULL);
211 * Removed call to reopen open files here. It is safer (and faster) to
212 * reopen files one at a time as needed in read and write.
214 * FIXME: what about file locks? don't we need to reclaim them ASAP?
219 * Check if handle based operation so we know whether we can continue
220 * or not without returning to caller to reset file handle
222 switch (smb_command) {
223 case SMB_COM_READ_ANDX:
224 case SMB_COM_WRITE_ANDX:
226 case SMB_COM_FIND_CLOSE2:
227 case SMB_COM_LOCKING_ANDX:
231 unload_nls(nls_codepage);
235 /* Allocate and return pointer to an SMB request buffer, and set basic
236 SMB information in the SMB header. If the return code is zero, this
237 function must have filled in request_buf pointer */
239 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
244 rc = cifs_reconnect_tcon(tcon, smb_command);
248 *request_buf = cifs_small_buf_get();
249 if (*request_buf == NULL) {
250 /* BB should we add a retry in here if not a writepage? */
254 header_assemble((struct smb_hdr *) *request_buf, smb_command,
258 cifs_stats_inc(&tcon->num_smbs_sent);
264 small_smb_init_no_tc(const int smb_command, const int wct,
265 struct cifs_ses *ses, void **request_buf)
268 struct smb_hdr *buffer;
270 rc = small_smb_init(smb_command, wct, NULL, request_buf);
274 buffer = (struct smb_hdr *)*request_buf;
275 buffer->Mid = get_next_mid(ses->server);
276 if (ses->capabilities & CAP_UNICODE)
277 buffer->Flags2 |= SMBFLG2_UNICODE;
278 if (ses->capabilities & CAP_STATUS32)
279 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
281 /* uid, tid can stay at zero as set in header assemble */
283 /* BB add support for turning on the signing when
284 this function is used after 1st of session setup requests */
289 /* If the return code is zero, this function must fill in request_buf pointer */
291 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
292 void **request_buf, void **response_buf)
294 *request_buf = cifs_buf_get();
295 if (*request_buf == NULL) {
296 /* BB should we add a retry in here if not a writepage? */
299 /* Although the original thought was we needed the response buf for */
300 /* potential retries of smb operations it turns out we can determine */
301 /* from the mid flags when the request buffer can be resent without */
302 /* having to use a second distinct buffer for the response */
304 *response_buf = *request_buf;
306 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
310 cifs_stats_inc(&tcon->num_smbs_sent);
315 /* If the return code is zero, this function must fill in request_buf pointer */
317 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
318 void **request_buf, void **response_buf)
322 rc = cifs_reconnect_tcon(tcon, smb_command);
326 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
330 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
331 void **request_buf, void **response_buf)
333 spin_lock(&tcon->ses->chan_lock);
334 if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) ||
335 tcon->need_reconnect) {
336 spin_unlock(&tcon->ses->chan_lock);
339 spin_unlock(&tcon->ses->chan_lock);
341 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
344 static int validate_t2(struct smb_t2_rsp *pSMB)
346 unsigned int total_size;
348 /* check for plausible wct */
349 if (pSMB->hdr.WordCount < 10)
352 /* check for parm and data offset going beyond end of smb */
353 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
354 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
357 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
358 if (total_size >= 512)
361 /* check that bcc is at least as big as parms + data, and that it is
362 * less than negotiated smb buffer
364 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
365 if (total_size > get_bcc(&pSMB->hdr) ||
366 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
371 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
372 sizeof(struct smb_t2_rsp) + 16);
377 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
381 char *guid = pSMBr->u.extended_response.GUID;
382 struct TCP_Server_Info *server = ses->server;
384 count = get_bcc(&pSMBr->hdr);
385 if (count < SMB1_CLIENT_GUID_SIZE)
388 spin_lock(&cifs_tcp_ses_lock);
389 if (server->srv_count > 1) {
390 spin_unlock(&cifs_tcp_ses_lock);
391 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
392 cifs_dbg(FYI, "server UID changed\n");
393 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
396 spin_unlock(&cifs_tcp_ses_lock);
397 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
400 if (count == SMB1_CLIENT_GUID_SIZE) {
401 server->sec_ntlmssp = true;
403 count -= SMB1_CLIENT_GUID_SIZE;
404 rc = decode_negTokenInit(
405 pSMBr->u.extended_response.SecurityBlob, count, server);
414 should_set_ext_sec_flag(enum securityEnum sectype)
421 if (global_secflags &
422 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
431 CIFSSMBNegotiate(const unsigned int xid,
432 struct cifs_ses *ses,
433 struct TCP_Server_Info *server)
436 NEGOTIATE_RSP *pSMBr;
443 WARN(1, "%s: server is NULL!\n", __func__);
447 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
448 (void **) &pSMB, (void **) &pSMBr);
452 pSMB->hdr.Mid = get_next_mid(server);
453 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
455 if (should_set_ext_sec_flag(ses->sectype)) {
456 cifs_dbg(FYI, "Requesting extended security\n");
457 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
462 * We know that all the name entries in the protocols array
463 * are short (< 16 bytes anyway) and are NUL terminated.
465 for (i = 0; i < CIFS_NUM_PROT; i++) {
466 size_t len = strlen(protocols[i].name) + 1;
468 memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
471 inc_rfc1001_len(pSMB, count);
472 pSMB->ByteCount = cpu_to_le16(count);
474 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
475 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
479 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
480 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
481 /* Check wct = 1 error case */
482 if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
483 /* core returns wct = 1, but we do not ask for core - otherwise
484 small wct just comes when dialect index is -1 indicating we
485 could not negotiate a common dialect */
488 } else if (pSMBr->hdr.WordCount != 17) {
493 /* else wct == 17, NTLM or better */
495 server->sec_mode = pSMBr->SecurityMode;
496 if ((server->sec_mode & SECMODE_USER) == 0)
497 cifs_dbg(FYI, "share mode security\n");
499 /* one byte, so no need to convert this or EncryptionKeyLen from
501 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
503 set_credits(server, server->maxReq);
504 /* probably no need to store and check maxvcs */
505 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
506 /* set up max_read for readahead check */
507 server->max_read = server->maxBuf;
508 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
509 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
510 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
511 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
512 server->timeAdj *= 60;
514 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
515 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
516 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
517 CIFS_CRYPTO_KEY_SIZE);
518 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
519 server->capabilities & CAP_EXTENDED_SECURITY) {
520 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
521 rc = decode_ext_sec_blob(ses, pSMBr);
522 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
523 rc = -EIO; /* no crypt key only if plain text pwd */
525 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
526 server->capabilities &= ~CAP_EXTENDED_SECURITY;
530 rc = cifs_enable_signing(server, ses->sign);
532 cifs_buf_release(pSMB);
534 cifs_dbg(FYI, "negprot rc %d\n", rc);
539 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
541 struct smb_hdr *smb_buffer;
544 cifs_dbg(FYI, "In tree disconnect\n");
546 /* BB: do we need to check this? These should never be NULL. */
547 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
551 * No need to return error on this operation if tid invalidated and
552 * closed on server already e.g. due to tcp session crashing. Also,
553 * the tcon is no longer on the list, so no need to take lock before
556 spin_lock(&tcon->ses->chan_lock);
557 if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
558 spin_unlock(&tcon->ses->chan_lock);
561 spin_unlock(&tcon->ses->chan_lock);
563 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
564 (void **)&smb_buffer);
568 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
569 cifs_small_buf_release(smb_buffer);
571 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
573 /* No need to return error on this operation if tid invalidated and
574 closed on server already e.g. due to tcp session crashing */
582 * This is a no-op for now. We're not really interested in the reply, but
583 * rather in the fact that the server sent one and that server->lstrp
586 * FIXME: maybe we should consider checking that the reply matches request?
589 cifs_echo_callback(struct mid_q_entry *mid)
591 struct TCP_Server_Info *server = mid->callback_data;
592 struct cifs_credits credits = { .value = 1, .instance = 0 };
595 add_credits(server, &credits, CIFS_ECHO_OP);
599 CIFSSMBEcho(struct TCP_Server_Info *server)
604 struct smb_rqst rqst = { .rq_iov = iov,
607 cifs_dbg(FYI, "In echo request\n");
609 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
613 if (server->capabilities & CAP_UNICODE)
614 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
616 /* set up echo request */
617 smb->hdr.Tid = 0xffff;
618 smb->hdr.WordCount = 1;
619 put_unaligned_le16(1, &smb->EchoCount);
620 put_bcc(1, &smb->hdr);
622 inc_rfc1001_len(smb, 3);
625 iov[0].iov_base = smb;
626 iov[1].iov_len = get_rfc1002_length(smb);
627 iov[1].iov_base = (char *)smb + 4;
629 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
630 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
632 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
634 cifs_small_buf_release(smb);
640 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
642 LOGOFF_ANDX_REQ *pSMB;
645 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
648 * BB: do we need to check validity of ses and server? They should
649 * always be valid since we have an active reference. If not, that
650 * should probably be a BUG()
652 if (!ses || !ses->server)
655 mutex_lock(&ses->session_mutex);
656 spin_lock(&ses->chan_lock);
657 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
658 spin_unlock(&ses->chan_lock);
659 goto session_already_dead; /* no need to send SMBlogoff if uid
660 already closed due to reconnect */
662 spin_unlock(&ses->chan_lock);
664 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
666 mutex_unlock(&ses->session_mutex);
670 pSMB->hdr.Mid = get_next_mid(ses->server);
672 if (ses->server->sign)
673 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
675 pSMB->hdr.Uid = ses->Suid;
677 pSMB->AndXCommand = 0xFF;
678 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
679 cifs_small_buf_release(pSMB);
680 session_already_dead:
681 mutex_unlock(&ses->session_mutex);
683 /* if session dead then we do not need to do ulogoff,
684 since server closed smb session, no sense reporting
692 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
693 const char *fileName, __u16 type,
694 const struct nls_table *nls_codepage, int remap)
696 TRANSACTION2_SPI_REQ *pSMB = NULL;
697 TRANSACTION2_SPI_RSP *pSMBr = NULL;
698 struct unlink_psx_rq *pRqD;
701 int bytes_returned = 0;
702 __u16 params, param_offset, offset, byte_count;
704 cifs_dbg(FYI, "In POSIX delete\n");
706 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
711 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
713 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
714 PATH_MAX, nls_codepage, remap);
715 name_len++; /* trailing null */
718 name_len = copy_path_name(pSMB->FileName, fileName);
721 params = 6 + name_len;
722 pSMB->MaxParameterCount = cpu_to_le16(2);
723 pSMB->MaxDataCount = 0; /* BB double check this with jra */
724 pSMB->MaxSetupCount = 0;
729 param_offset = offsetof(struct smb_com_transaction2_spi_req,
730 InformationLevel) - 4;
731 offset = param_offset + params;
733 /* Setup pointer to Request Data (inode type).
734 * Note that SMB offsets are from the beginning of SMB which is 4 bytes
735 * in, after RFC1001 field
737 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
738 pRqD->type = cpu_to_le16(type);
739 pSMB->ParameterOffset = cpu_to_le16(param_offset);
740 pSMB->DataOffset = cpu_to_le16(offset);
741 pSMB->SetupCount = 1;
743 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
744 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
746 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
747 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
748 pSMB->ParameterCount = cpu_to_le16(params);
749 pSMB->TotalParameterCount = pSMB->ParameterCount;
750 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
752 inc_rfc1001_len(pSMB, byte_count);
753 pSMB->ByteCount = cpu_to_le16(byte_count);
754 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
755 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
757 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
758 cifs_buf_release(pSMB);
760 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
769 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
770 struct cifs_sb_info *cifs_sb)
772 DELETE_FILE_REQ *pSMB = NULL;
773 DELETE_FILE_RSP *pSMBr = NULL;
777 int remap = cifs_remap(cifs_sb);
780 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
785 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
786 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
787 PATH_MAX, cifs_sb->local_nls,
789 name_len++; /* trailing null */
792 name_len = copy_path_name(pSMB->fileName, name);
794 pSMB->SearchAttributes =
795 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
796 pSMB->BufferFormat = 0x04;
797 inc_rfc1001_len(pSMB, name_len + 1);
798 pSMB->ByteCount = cpu_to_le16(name_len + 1);
799 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
800 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
801 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
803 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
805 cifs_buf_release(pSMB);
813 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
814 struct cifs_sb_info *cifs_sb)
816 DELETE_DIRECTORY_REQ *pSMB = NULL;
817 DELETE_DIRECTORY_RSP *pSMBr = NULL;
821 int remap = cifs_remap(cifs_sb);
823 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
825 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
830 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
831 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
832 PATH_MAX, cifs_sb->local_nls,
834 name_len++; /* trailing null */
837 name_len = copy_path_name(pSMB->DirName, name);
840 pSMB->BufferFormat = 0x04;
841 inc_rfc1001_len(pSMB, name_len + 1);
842 pSMB->ByteCount = cpu_to_le16(name_len + 1);
843 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
844 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
845 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
847 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
849 cifs_buf_release(pSMB);
856 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
857 struct cifs_tcon *tcon, const char *name,
858 struct cifs_sb_info *cifs_sb)
861 CREATE_DIRECTORY_REQ *pSMB = NULL;
862 CREATE_DIRECTORY_RSP *pSMBr = NULL;
865 int remap = cifs_remap(cifs_sb);
867 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
869 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
874 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
875 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
876 PATH_MAX, cifs_sb->local_nls,
878 name_len++; /* trailing null */
881 name_len = copy_path_name(pSMB->DirName, name);
884 pSMB->BufferFormat = 0x04;
885 inc_rfc1001_len(pSMB, name_len + 1);
886 pSMB->ByteCount = cpu_to_le16(name_len + 1);
887 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
888 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
889 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
891 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
893 cifs_buf_release(pSMB);
900 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
901 __u32 posix_flags, __u64 mode, __u16 *netfid,
902 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
903 const char *name, const struct nls_table *nls_codepage,
906 TRANSACTION2_SPI_REQ *pSMB = NULL;
907 TRANSACTION2_SPI_RSP *pSMBr = NULL;
910 int bytes_returned = 0;
911 __u16 params, param_offset, offset, byte_count, count;
913 OPEN_PSX_RSP *psx_rsp;
915 cifs_dbg(FYI, "In POSIX Create\n");
917 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
922 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
924 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
925 PATH_MAX, nls_codepage, remap);
926 name_len++; /* trailing null */
929 name_len = copy_path_name(pSMB->FileName, name);
932 params = 6 + name_len;
933 count = sizeof(OPEN_PSX_REQ);
934 pSMB->MaxParameterCount = cpu_to_le16(2);
935 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
936 pSMB->MaxSetupCount = 0;
941 param_offset = offsetof(struct smb_com_transaction2_spi_req,
942 InformationLevel) - 4;
943 offset = param_offset + params;
944 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
945 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
946 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
947 pdata->Permissions = cpu_to_le64(mode);
948 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
949 pdata->OpenFlags = cpu_to_le32(*pOplock);
950 pSMB->ParameterOffset = cpu_to_le16(param_offset);
951 pSMB->DataOffset = cpu_to_le16(offset);
952 pSMB->SetupCount = 1;
954 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
955 byte_count = 3 /* pad */ + params + count;
957 pSMB->DataCount = cpu_to_le16(count);
958 pSMB->ParameterCount = cpu_to_le16(params);
959 pSMB->TotalDataCount = pSMB->DataCount;
960 pSMB->TotalParameterCount = pSMB->ParameterCount;
961 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
963 inc_rfc1001_len(pSMB, byte_count);
964 pSMB->ByteCount = cpu_to_le16(byte_count);
965 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
966 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
968 cifs_dbg(FYI, "Posix create returned %d\n", rc);
972 cifs_dbg(FYI, "copying inode info\n");
973 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
975 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
976 rc = -EIO; /* bad smb */
980 /* copy return information to pRetData */
981 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
982 + le16_to_cpu(pSMBr->t2.DataOffset));
984 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
986 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
987 /* Let caller know file was created so we can set the mode. */
988 /* Do we care about the CreateAction in any other cases? */
989 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
990 *pOplock |= CIFS_CREATE_ACTION;
991 /* check to make sure response data is there */
992 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
993 pRetData->Type = cpu_to_le32(-1); /* unknown */
994 cifs_dbg(NOISY, "unknown type\n");
996 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
997 + sizeof(FILE_UNIX_BASIC_INFO)) {
998 cifs_dbg(VFS, "Open response data too small\n");
999 pRetData->Type = cpu_to_le32(-1);
1000 goto psx_create_err;
1002 memcpy((char *) pRetData,
1003 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1004 sizeof(FILE_UNIX_BASIC_INFO));
1008 cifs_buf_release(pSMB);
1010 if (posix_flags & SMB_O_DIRECTORY)
1011 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1013 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1021 static __u16 convert_disposition(int disposition)
1025 switch (disposition) {
1026 case FILE_SUPERSEDE:
1027 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1030 ofun = SMBOPEN_OAPPEND;
1033 ofun = SMBOPEN_OCREATE;
1036 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1038 case FILE_OVERWRITE:
1039 ofun = SMBOPEN_OTRUNC;
1041 case FILE_OVERWRITE_IF:
1042 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1045 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1046 ofun = SMBOPEN_OAPPEND; /* regular open */
1052 access_flags_to_smbopen_mode(const int access_flags)
1054 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1056 if (masked_flags == GENERIC_READ)
1057 return SMBOPEN_READ;
1058 else if (masked_flags == GENERIC_WRITE)
1059 return SMBOPEN_WRITE;
1061 /* just go for read/write */
1062 return SMBOPEN_READWRITE;
1066 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1067 const char *fileName, const int openDisposition,
1068 const int access_flags, const int create_options, __u16 *netfid,
1069 int *pOplock, FILE_ALL_INFO *pfile_info,
1070 const struct nls_table *nls_codepage, int remap)
1073 OPENX_REQ *pSMB = NULL;
1074 OPENX_RSP *pSMBr = NULL;
1080 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1085 pSMB->AndXCommand = 0xFF; /* none */
1087 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1088 count = 1; /* account for one byte pad to word boundary */
1090 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1091 fileName, PATH_MAX, nls_codepage, remap);
1092 name_len++; /* trailing null */
1095 count = 0; /* no pad */
1096 name_len = copy_path_name(pSMB->fileName, fileName);
1098 if (*pOplock & REQ_OPLOCK)
1099 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1100 else if (*pOplock & REQ_BATCHOPLOCK)
1101 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1103 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1104 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1105 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1106 /* set file as system file if special file such
1107 as fifo and server expecting SFU style and
1108 no Unix extensions */
1110 if (create_options & CREATE_OPTION_SPECIAL)
1111 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1112 else /* BB FIXME BB */
1113 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1115 if (create_options & CREATE_OPTION_READONLY)
1116 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1119 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1120 CREATE_OPTIONS_MASK); */
1121 /* BB FIXME END BB */
1123 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1124 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1126 inc_rfc1001_len(pSMB, count);
1128 pSMB->ByteCount = cpu_to_le16(count);
1129 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1130 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1131 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1133 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1135 /* BB verify if wct == 15 */
1137 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1139 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1140 /* Let caller know file was created so we can set the mode. */
1141 /* Do we care about the CreateAction in any other cases? */
1143 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1144 *pOplock |= CIFS_CREATE_ACTION; */
1148 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1149 pfile_info->LastAccessTime = 0; /* BB fixme */
1150 pfile_info->LastWriteTime = 0; /* BB fixme */
1151 pfile_info->ChangeTime = 0; /* BB fixme */
1152 pfile_info->Attributes =
1153 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1154 /* the file_info buf is endian converted by caller */
1155 pfile_info->AllocationSize =
1156 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1157 pfile_info->EndOfFile = pfile_info->AllocationSize;
1158 pfile_info->NumberOfLinks = cpu_to_le32(1);
1159 pfile_info->DeletePending = 0;
1163 cifs_buf_release(pSMB);
1170 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1174 OPEN_REQ *req = NULL;
1175 OPEN_RSP *rsp = NULL;
1179 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1180 struct cifs_tcon *tcon = oparms->tcon;
1181 int remap = cifs_remap(cifs_sb);
1182 const struct nls_table *nls = cifs_sb->local_nls;
1183 int create_options = oparms->create_options;
1184 int desired_access = oparms->desired_access;
1185 int disposition = oparms->disposition;
1186 const char *path = oparms->path;
1189 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1194 /* no commands go after this */
1195 req->AndXCommand = 0xFF;
1197 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1198 /* account for one byte pad to word boundary */
1200 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1201 path, PATH_MAX, nls, remap);
1205 req->NameLength = cpu_to_le16(name_len);
1207 /* BB improve check for buffer overruns BB */
1210 name_len = copy_path_name(req->fileName, path);
1211 req->NameLength = cpu_to_le16(name_len);
1214 if (*oplock & REQ_OPLOCK)
1215 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1216 else if (*oplock & REQ_BATCHOPLOCK)
1217 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1219 req->DesiredAccess = cpu_to_le32(desired_access);
1220 req->AllocationSize = 0;
1223 * Set file as system file if special file such as fifo and server
1224 * expecting SFU style and no Unix extensions.
1226 if (create_options & CREATE_OPTION_SPECIAL)
1227 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1229 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1232 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1233 * sensitive checks for other servers such as Samba.
1235 if (tcon->ses->capabilities & CAP_UNIX)
1236 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1238 if (create_options & CREATE_OPTION_READONLY)
1239 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1241 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1242 req->CreateDisposition = cpu_to_le32(disposition);
1243 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1245 /* BB Expirement with various impersonation levels and verify */
1246 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1247 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1250 inc_rfc1001_len(req, count);
1252 req->ByteCount = cpu_to_le16(count);
1253 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1254 (struct smb_hdr *)rsp, &bytes_returned, 0);
1255 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1257 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1258 cifs_buf_release(req);
1264 /* 1 byte no need to le_to_cpu */
1265 *oplock = rsp->OplockLevel;
1266 /* cifs fid stays in le */
1267 oparms->fid->netfid = rsp->Fid;
1268 oparms->fid->access = desired_access;
1270 /* Let caller know file was created so we can set the mode. */
1271 /* Do we care about the CreateAction in any other cases? */
1272 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1273 *oplock |= CIFS_CREATE_ACTION;
1276 /* copy from CreationTime to Attributes */
1277 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1278 /* the file_info buf is endian converted by caller */
1279 buf->AllocationSize = rsp->AllocationSize;
1280 buf->EndOfFile = rsp->EndOfFile;
1281 buf->NumberOfLinks = cpu_to_le32(1);
1282 buf->DeletePending = 0;
1285 cifs_buf_release(req);
1290 cifs_readv_callback(struct mid_q_entry *mid)
1292 struct cifs_readdata *rdata = mid->callback_data;
1293 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1294 struct TCP_Server_Info *server = tcon->ses->server;
1295 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1297 .rq_pages = rdata->pages,
1298 .rq_offset = rdata->page_offset,
1299 .rq_npages = rdata->nr_pages,
1300 .rq_pagesz = rdata->pagesz,
1301 .rq_tailsz = rdata->tailsz };
1302 struct cifs_credits credits = { .value = 1, .instance = 0 };
1304 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1305 __func__, mid->mid, mid->mid_state, rdata->result,
1308 switch (mid->mid_state) {
1309 case MID_RESPONSE_RECEIVED:
1310 /* result already set, check signature */
1314 rc = cifs_verify_signature(&rqst, server,
1315 mid->sequence_number);
1317 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1320 /* FIXME: should this be counted toward the initiating task? */
1321 task_io_account_read(rdata->got_bytes);
1322 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1324 case MID_REQUEST_SUBMITTED:
1325 case MID_RETRY_NEEDED:
1326 rdata->result = -EAGAIN;
1327 if (server->sign && rdata->got_bytes)
1328 /* reset bytes number since we can not check a sign */
1329 rdata->got_bytes = 0;
1330 /* FIXME: should this be counted toward the initiating task? */
1331 task_io_account_read(rdata->got_bytes);
1332 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1335 rdata->result = -EIO;
1338 queue_work(cifsiod_wq, &rdata->work);
1340 add_credits(server, &credits, 0);
1343 /* cifs_async_readv - send an async write, and set up mid to handle result */
1345 cifs_async_readv(struct cifs_readdata *rdata)
1348 READ_REQ *smb = NULL;
1350 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1351 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1354 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1355 __func__, rdata->offset, rdata->bytes);
1357 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1360 wct = 10; /* old style read */
1361 if ((rdata->offset >> 32) > 0) {
1362 /* can not handle this big offset for old */
1367 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1371 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1372 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1374 smb->AndXCommand = 0xFF; /* none */
1375 smb->Fid = rdata->cfile->fid.netfid;
1376 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1378 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1380 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1381 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1385 /* old style read */
1386 struct smb_com_readx_req *smbr =
1387 (struct smb_com_readx_req *)smb;
1388 smbr->ByteCount = 0;
1391 /* 4 for RFC1001 length + 1 for BCC */
1392 rdata->iov[0].iov_base = smb;
1393 rdata->iov[0].iov_len = 4;
1394 rdata->iov[1].iov_base = (char *)smb + 4;
1395 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1397 kref_get(&rdata->refcount);
1398 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1399 cifs_readv_callback, NULL, rdata, 0, NULL);
1402 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1404 kref_put(&rdata->refcount, cifs_readdata_release);
1406 cifs_small_buf_release(smb);
1411 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1412 unsigned int *nbytes, char **buf, int *pbuf_type)
1415 READ_REQ *pSMB = NULL;
1416 READ_RSP *pSMBr = NULL;
1417 char *pReadData = NULL;
1419 int resp_buf_type = 0;
1421 struct kvec rsp_iov;
1422 __u32 pid = io_parms->pid;
1423 __u16 netfid = io_parms->netfid;
1424 __u64 offset = io_parms->offset;
1425 struct cifs_tcon *tcon = io_parms->tcon;
1426 unsigned int count = io_parms->length;
1428 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1429 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1432 wct = 10; /* old style read */
1433 if ((offset >> 32) > 0) {
1434 /* can not handle this big offset for old */
1440 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1444 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1445 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1447 /* tcon and ses pointer are checked in smb_init */
1448 if (tcon->ses->server == NULL)
1449 return -ECONNABORTED;
1451 pSMB->AndXCommand = 0xFF; /* none */
1453 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1455 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1457 pSMB->Remaining = 0;
1458 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1459 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1461 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1463 /* old style read */
1464 struct smb_com_readx_req *pSMBW =
1465 (struct smb_com_readx_req *)pSMB;
1466 pSMBW->ByteCount = 0;
1469 iov[0].iov_base = (char *)pSMB;
1470 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1471 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1472 CIFS_LOG_ERROR, &rsp_iov);
1473 cifs_small_buf_release(pSMB);
1474 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1475 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1477 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1479 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1480 data_length = data_length << 16;
1481 data_length += le16_to_cpu(pSMBr->DataLength);
1482 *nbytes = data_length;
1484 /*check that DataLength would not go beyond end of SMB */
1485 if ((data_length > CIFSMaxBufSize)
1486 || (data_length > count)) {
1487 cifs_dbg(FYI, "bad length %d for count %d\n",
1488 data_length, count);
1492 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1493 le16_to_cpu(pSMBr->DataOffset);
1494 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1495 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1497 }*/ /* can not use copy_to_user when using page cache*/
1499 memcpy(*buf, pReadData, data_length);
1504 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1505 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1506 /* return buffer to caller to free */
1507 *buf = rsp_iov.iov_base;
1508 if (resp_buf_type == CIFS_SMALL_BUFFER)
1509 *pbuf_type = CIFS_SMALL_BUFFER;
1510 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1511 *pbuf_type = CIFS_LARGE_BUFFER;
1512 } /* else no valid buffer on return - leave as null */
1514 /* Note: On -EAGAIN error only caller can retry on handle based calls
1515 since file handle passed in no longer valid */
1521 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1522 unsigned int *nbytes, const char *buf)
1525 WRITE_REQ *pSMB = NULL;
1526 WRITE_RSP *pSMBr = NULL;
1527 int bytes_returned, wct;
1530 __u32 pid = io_parms->pid;
1531 __u16 netfid = io_parms->netfid;
1532 __u64 offset = io_parms->offset;
1533 struct cifs_tcon *tcon = io_parms->tcon;
1534 unsigned int count = io_parms->length;
1538 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1539 if (tcon->ses == NULL)
1540 return -ECONNABORTED;
1542 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1546 if ((offset >> 32) > 0) {
1547 /* can not handle big offset for old srv */
1552 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1557 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1558 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1560 /* tcon and ses pointer are checked in smb_init */
1561 if (tcon->ses->server == NULL)
1562 return -ECONNABORTED;
1564 pSMB->AndXCommand = 0xFF; /* none */
1566 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1568 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1570 pSMB->Reserved = 0xFFFFFFFF;
1571 pSMB->WriteMode = 0;
1572 pSMB->Remaining = 0;
1574 /* Can increase buffer size if buffer is big enough in some cases ie we
1575 can send more if LARGE_WRITE_X capability returned by the server and if
1576 our buffer is big enough or if we convert to iovecs on socket writes
1577 and eliminate the copy to the CIFS buffer */
1578 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1579 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1581 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1585 if (bytes_sent > count)
1588 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1590 memcpy(pSMB->Data, buf, bytes_sent);
1591 else if (count != 0) {
1593 cifs_buf_release(pSMB);
1595 } /* else setting file size with write of zero bytes */
1597 byte_count = bytes_sent + 1; /* pad */
1598 else /* wct == 12 */
1599 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1601 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1602 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1603 inc_rfc1001_len(pSMB, byte_count);
1606 pSMB->ByteCount = cpu_to_le16(byte_count);
1607 else { /* old style write has byte count 4 bytes earlier
1609 struct smb_com_writex_req *pSMBW =
1610 (struct smb_com_writex_req *)pSMB;
1611 pSMBW->ByteCount = cpu_to_le16(byte_count);
1614 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1615 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1616 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1618 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1620 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1621 *nbytes = (*nbytes) << 16;
1622 *nbytes += le16_to_cpu(pSMBr->Count);
1625 * Mask off high 16 bits when bytes written as returned by the
1626 * server is greater than bytes requested by the client. Some
1627 * OS/2 servers are known to set incorrect CountHigh values.
1629 if (*nbytes > count)
1633 cifs_buf_release(pSMB);
1635 /* Note: On -EAGAIN error only caller can retry on handle based calls
1636 since file handle passed in no longer valid */
1642 * Check the mid_state and signature on received buffer (if any), and queue the
1643 * workqueue completion task.
1646 cifs_writev_callback(struct mid_q_entry *mid)
1648 struct cifs_writedata *wdata = mid->callback_data;
1649 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1650 unsigned int written;
1651 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1652 struct cifs_credits credits = { .value = 1, .instance = 0 };
1654 switch (mid->mid_state) {
1655 case MID_RESPONSE_RECEIVED:
1656 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
1657 if (wdata->result != 0)
1660 written = le16_to_cpu(smb->CountHigh);
1662 written += le16_to_cpu(smb->Count);
1664 * Mask off high 16 bits when bytes written as returned
1665 * by the server is greater than bytes requested by the
1666 * client. OS/2 servers are known to set incorrect
1669 if (written > wdata->bytes)
1672 if (written < wdata->bytes)
1673 wdata->result = -ENOSPC;
1675 wdata->bytes = written;
1677 case MID_REQUEST_SUBMITTED:
1678 case MID_RETRY_NEEDED:
1679 wdata->result = -EAGAIN;
1682 wdata->result = -EIO;
1686 queue_work(cifsiod_wq, &wdata->work);
1688 add_credits(tcon->ses->server, &credits, 0);
1691 /* cifs_async_writev - send an async write, and set up mid to handle result */
1693 cifs_async_writev(struct cifs_writedata *wdata,
1694 void (*release)(struct kref *kref))
1697 WRITE_REQ *smb = NULL;
1699 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1701 struct smb_rqst rqst = { };
1703 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1707 if (wdata->offset >> 32 > 0) {
1708 /* can not handle big offset for old srv */
1713 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
1715 goto async_writev_out;
1717 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
1718 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
1720 smb->AndXCommand = 0xFF; /* none */
1721 smb->Fid = wdata->cfile->fid.netfid;
1722 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
1724 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
1725 smb->Reserved = 0xFFFFFFFF;
1730 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1732 /* 4 for RFC1001 length + 1 for BCC */
1734 iov[0].iov_base = smb;
1735 iov[1].iov_len = get_rfc1002_length(smb) + 1;
1736 iov[1].iov_base = (char *)smb + 4;
1740 rqst.rq_pages = wdata->pages;
1741 rqst.rq_offset = wdata->page_offset;
1742 rqst.rq_npages = wdata->nr_pages;
1743 rqst.rq_pagesz = wdata->pagesz;
1744 rqst.rq_tailsz = wdata->tailsz;
1746 cifs_dbg(FYI, "async write at %llu %u bytes\n",
1747 wdata->offset, wdata->bytes);
1749 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
1750 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
1753 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
1754 put_bcc(wdata->bytes + 1, &smb->hdr);
1757 struct smb_com_writex_req *smbw =
1758 (struct smb_com_writex_req *)smb;
1759 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
1760 put_bcc(wdata->bytes + 5, &smbw->hdr);
1761 iov[1].iov_len += 4; /* pad bigger by four bytes */
1764 kref_get(&wdata->refcount);
1765 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
1766 cifs_writev_callback, NULL, wdata, 0, NULL);
1769 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1771 kref_put(&wdata->refcount, release);
1774 cifs_small_buf_release(smb);
1779 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
1780 unsigned int *nbytes, struct kvec *iov, int n_vec)
1783 WRITE_REQ *pSMB = NULL;
1786 int resp_buf_type = 0;
1787 __u32 pid = io_parms->pid;
1788 __u16 netfid = io_parms->netfid;
1789 __u64 offset = io_parms->offset;
1790 struct cifs_tcon *tcon = io_parms->tcon;
1791 unsigned int count = io_parms->length;
1792 struct kvec rsp_iov;
1796 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
1798 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1802 if ((offset >> 32) > 0) {
1803 /* can not handle big offset for old srv */
1807 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
1811 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1812 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1814 /* tcon and ses pointer are checked in smb_init */
1815 if (tcon->ses->server == NULL)
1816 return -ECONNABORTED;
1818 pSMB->AndXCommand = 0xFF; /* none */
1820 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1822 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1823 pSMB->Reserved = 0xFFFFFFFF;
1824 pSMB->WriteMode = 0;
1825 pSMB->Remaining = 0;
1828 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1830 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1831 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1832 /* header + 1 byte pad */
1833 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
1835 inc_rfc1001_len(pSMB, count + 1);
1836 else /* wct == 12 */
1837 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
1839 pSMB->ByteCount = cpu_to_le16(count + 1);
1840 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1841 struct smb_com_writex_req *pSMBW =
1842 (struct smb_com_writex_req *)pSMB;
1843 pSMBW->ByteCount = cpu_to_le16(count + 5);
1845 iov[0].iov_base = pSMB;
1847 iov[0].iov_len = smb_hdr_len + 4;
1848 else /* wct == 12 pad bigger by four bytes */
1849 iov[0].iov_len = smb_hdr_len + 8;
1851 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
1853 cifs_small_buf_release(pSMB);
1854 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1856 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
1857 } else if (resp_buf_type == 0) {
1858 /* presumably this can not happen, but best to be safe */
1861 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
1862 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1863 *nbytes = (*nbytes) << 16;
1864 *nbytes += le16_to_cpu(pSMBr->Count);
1867 * Mask off high 16 bits when bytes written as returned by the
1868 * server is greater than bytes requested by the client. OS/2
1869 * servers are known to set incorrect CountHigh values.
1871 if (*nbytes > count)
1875 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1877 /* Note: On -EAGAIN error only caller can retry on handle based calls
1878 since file handle passed in no longer valid */
1883 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
1884 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
1885 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
1888 LOCK_REQ *pSMB = NULL;
1890 struct kvec rsp_iov;
1894 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
1895 num_lock, num_unlock);
1897 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1902 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
1903 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
1904 pSMB->LockType = lock_type;
1905 pSMB->AndXCommand = 0xFF; /* none */
1906 pSMB->Fid = netfid; /* netfid stays le */
1908 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1909 inc_rfc1001_len(pSMB, count);
1910 pSMB->ByteCount = cpu_to_le16(count);
1912 iov[0].iov_base = (char *)pSMB;
1913 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
1914 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1915 iov[1].iov_base = (char *)buf;
1916 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1918 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1919 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
1920 CIFS_NO_RSP_BUF, &rsp_iov);
1921 cifs_small_buf_release(pSMB);
1923 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
1929 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
1930 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
1931 const __u64 offset, const __u32 numUnlock,
1932 const __u32 numLock, const __u8 lockType,
1933 const bool waitFlag, const __u8 oplock_level)
1936 LOCK_REQ *pSMB = NULL;
1937 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
1942 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
1943 (int)waitFlag, numLock);
1944 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1949 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1950 /* no response expected */
1951 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
1953 } else if (waitFlag) {
1954 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1955 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
1960 pSMB->NumberOfLocks = cpu_to_le16(numLock);
1961 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
1962 pSMB->LockType = lockType;
1963 pSMB->OplockLevel = oplock_level;
1964 pSMB->AndXCommand = 0xFF; /* none */
1965 pSMB->Fid = smb_file_id; /* netfid stays le */
1967 if ((numLock != 0) || (numUnlock != 0)) {
1968 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
1969 /* BB where to store pid high? */
1970 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
1971 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
1972 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
1973 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
1974 count = sizeof(LOCKING_ANDX_RANGE);
1979 inc_rfc1001_len(pSMB, count);
1980 pSMB->ByteCount = cpu_to_le16(count);
1983 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1984 (struct smb_hdr *) pSMB, &bytes_returned);
1986 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
1987 cifs_small_buf_release(pSMB);
1988 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1990 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
1992 /* Note: On -EAGAIN error only caller can retry on handle based calls
1993 since file handle passed in no longer valid */
1998 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
1999 const __u16 smb_file_id, const __u32 netpid,
2000 const loff_t start_offset, const __u64 len,
2001 struct file_lock *pLockData, const __u16 lock_type,
2002 const bool waitFlag)
2004 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2005 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2006 struct cifs_posix_lock *parm_data;
2009 int bytes_returned = 0;
2010 int resp_buf_type = 0;
2011 __u16 params, param_offset, offset, byte_count, count;
2013 struct kvec rsp_iov;
2015 cifs_dbg(FYI, "Posix Lock\n");
2017 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2022 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2025 pSMB->MaxSetupCount = 0;
2028 pSMB->Reserved2 = 0;
2029 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2030 offset = param_offset + params;
2032 count = sizeof(struct cifs_posix_lock);
2033 pSMB->MaxParameterCount = cpu_to_le16(2);
2034 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2035 pSMB->SetupCount = 1;
2036 pSMB->Reserved3 = 0;
2038 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2040 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2041 byte_count = 3 /* pad */ + params + count;
2042 pSMB->DataCount = cpu_to_le16(count);
2043 pSMB->ParameterCount = cpu_to_le16(params);
2044 pSMB->TotalDataCount = pSMB->DataCount;
2045 pSMB->TotalParameterCount = pSMB->ParameterCount;
2046 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2047 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2048 parm_data = (struct cifs_posix_lock *)
2049 (((char *)pSMB) + offset + 4);
2051 parm_data->lock_type = cpu_to_le16(lock_type);
2053 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2054 parm_data->lock_flags = cpu_to_le16(1);
2055 pSMB->Timeout = cpu_to_le32(-1);
2059 parm_data->pid = cpu_to_le32(netpid);
2060 parm_data->start = cpu_to_le64(start_offset);
2061 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2063 pSMB->DataOffset = cpu_to_le16(offset);
2064 pSMB->Fid = smb_file_id;
2065 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2066 pSMB->Reserved4 = 0;
2067 inc_rfc1001_len(pSMB, byte_count);
2068 pSMB->ByteCount = cpu_to_le16(byte_count);
2070 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2071 (struct smb_hdr *) pSMBr, &bytes_returned);
2073 iov[0].iov_base = (char *)pSMB;
2074 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2075 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2076 &resp_buf_type, timeout, &rsp_iov);
2077 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2079 cifs_small_buf_release(pSMB);
2082 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2083 } else if (pLockData) {
2084 /* lock structure can be returned on get */
2087 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2089 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2090 rc = -EIO; /* bad smb */
2093 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2094 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2095 if (data_count < sizeof(struct cifs_posix_lock)) {
2099 parm_data = (struct cifs_posix_lock *)
2100 ((char *)&pSMBr->hdr.Protocol + data_offset);
2101 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2102 pLockData->fl_type = F_UNLCK;
2104 if (parm_data->lock_type ==
2105 cpu_to_le16(CIFS_RDLCK))
2106 pLockData->fl_type = F_RDLCK;
2107 else if (parm_data->lock_type ==
2108 cpu_to_le16(CIFS_WRLCK))
2109 pLockData->fl_type = F_WRLCK;
2111 pLockData->fl_start = le64_to_cpu(parm_data->start);
2112 pLockData->fl_end = pLockData->fl_start +
2113 (le64_to_cpu(parm_data->length) ?
2114 le64_to_cpu(parm_data->length) - 1 : 0);
2115 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2120 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2122 /* Note: On -EAGAIN error only caller can retry on handle based calls
2123 since file handle passed in no longer valid */
2130 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2133 CLOSE_REQ *pSMB = NULL;
2134 cifs_dbg(FYI, "In CIFSSMBClose\n");
2136 /* do not retry on dead session on close */
2137 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2143 pSMB->FileID = (__u16) smb_file_id;
2144 pSMB->LastWriteTime = 0xFFFFFFFF;
2145 pSMB->ByteCount = 0;
2146 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2147 cifs_small_buf_release(pSMB);
2148 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2151 /* EINTR is expected when user ctl-c to kill app */
2152 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2156 /* Since session is dead, file will be closed on server already */
2164 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2167 FLUSH_REQ *pSMB = NULL;
2168 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2170 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2174 pSMB->FileID = (__u16) smb_file_id;
2175 pSMB->ByteCount = 0;
2176 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2177 cifs_small_buf_release(pSMB);
2178 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2180 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2186 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2187 const char *from_name, const char *to_name,
2188 struct cifs_sb_info *cifs_sb)
2191 RENAME_REQ *pSMB = NULL;
2192 RENAME_RSP *pSMBr = NULL;
2194 int name_len, name_len2;
2196 int remap = cifs_remap(cifs_sb);
2198 cifs_dbg(FYI, "In CIFSSMBRename\n");
2200 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2205 pSMB->BufferFormat = 0x04;
2206 pSMB->SearchAttributes =
2207 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2210 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2211 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2212 from_name, PATH_MAX,
2213 cifs_sb->local_nls, remap);
2214 name_len++; /* trailing null */
2216 pSMB->OldFileName[name_len] = 0x04; /* pad */
2217 /* protocol requires ASCII signature byte on Unicode string */
2218 pSMB->OldFileName[name_len + 1] = 0x00;
2220 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2221 to_name, PATH_MAX, cifs_sb->local_nls,
2223 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2224 name_len2 *= 2; /* convert to bytes */
2226 name_len = copy_path_name(pSMB->OldFileName, from_name);
2227 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2228 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2229 name_len2++; /* signature byte */
2232 count = 1 /* 1st signature byte */ + name_len + name_len2;
2233 inc_rfc1001_len(pSMB, count);
2234 pSMB->ByteCount = cpu_to_le16(count);
2236 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2237 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2238 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2240 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2242 cifs_buf_release(pSMB);
2250 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2251 int netfid, const char *target_name,
2252 const struct nls_table *nls_codepage, int remap)
2254 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2255 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2256 struct set_file_rename *rename_info;
2258 char dummy_string[30];
2260 int bytes_returned = 0;
2262 __u16 params, param_offset, offset, count, byte_count;
2264 cifs_dbg(FYI, "Rename to File by handle\n");
2265 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2271 pSMB->MaxSetupCount = 0;
2275 pSMB->Reserved2 = 0;
2276 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2277 offset = param_offset + params;
2279 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2280 data_offset = (char *)(pSMB) + offset + 4;
2281 rename_info = (struct set_file_rename *) data_offset;
2282 pSMB->MaxParameterCount = cpu_to_le16(2);
2283 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2284 pSMB->SetupCount = 1;
2285 pSMB->Reserved3 = 0;
2286 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2287 byte_count = 3 /* pad */ + params;
2288 pSMB->ParameterCount = cpu_to_le16(params);
2289 pSMB->TotalParameterCount = pSMB->ParameterCount;
2290 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2291 pSMB->DataOffset = cpu_to_le16(offset);
2292 /* construct random name ".cifs_tmp<inodenum><mid>" */
2293 rename_info->overwrite = cpu_to_le32(1);
2294 rename_info->root_fid = 0;
2295 /* unicode only call */
2296 if (target_name == NULL) {
2297 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2299 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2300 dummy_string, 24, nls_codepage, remap);
2303 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2304 target_name, PATH_MAX, nls_codepage,
2307 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2308 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2309 byte_count += count;
2310 pSMB->DataCount = cpu_to_le16(count);
2311 pSMB->TotalDataCount = pSMB->DataCount;
2313 pSMB->InformationLevel =
2314 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2315 pSMB->Reserved4 = 0;
2316 inc_rfc1001_len(pSMB, byte_count);
2317 pSMB->ByteCount = cpu_to_le16(byte_count);
2318 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2319 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2320 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2322 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2325 cifs_buf_release(pSMB);
2327 /* Note: On -EAGAIN error only caller can retry on handle based calls
2328 since file handle passed in no longer valid */
2334 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2335 const char *fromName, const __u16 target_tid, const char *toName,
2336 const int flags, const struct nls_table *nls_codepage, int remap)
2339 COPY_REQ *pSMB = NULL;
2340 COPY_RSP *pSMBr = NULL;
2342 int name_len, name_len2;
2345 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2347 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2352 pSMB->BufferFormat = 0x04;
2353 pSMB->Tid2 = target_tid;
2355 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2357 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2358 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2359 fromName, PATH_MAX, nls_codepage,
2361 name_len++; /* trailing null */
2363 pSMB->OldFileName[name_len] = 0x04; /* pad */
2364 /* protocol requires ASCII signature byte on Unicode string */
2365 pSMB->OldFileName[name_len + 1] = 0x00;
2367 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2368 toName, PATH_MAX, nls_codepage, remap);
2369 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2370 name_len2 *= 2; /* convert to bytes */
2372 name_len = copy_path_name(pSMB->OldFileName, fromName);
2373 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2374 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2375 name_len2++; /* signature byte */
2378 count = 1 /* 1st signature byte */ + name_len + name_len2;
2379 inc_rfc1001_len(pSMB, count);
2380 pSMB->ByteCount = cpu_to_le16(count);
2382 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2383 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2385 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2386 rc, le16_to_cpu(pSMBr->CopyCount));
2388 cifs_buf_release(pSMB);
2397 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2398 const char *fromName, const char *toName,
2399 const struct nls_table *nls_codepage, int remap)
2401 TRANSACTION2_SPI_REQ *pSMB = NULL;
2402 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2405 int name_len_target;
2407 int bytes_returned = 0;
2408 __u16 params, param_offset, offset, byte_count;
2410 cifs_dbg(FYI, "In Symlink Unix style\n");
2412 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2417 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2419 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2420 /* find define for this maxpathcomponent */
2421 PATH_MAX, nls_codepage, remap);
2422 name_len++; /* trailing null */
2426 name_len = copy_path_name(pSMB->FileName, fromName);
2428 params = 6 + name_len;
2429 pSMB->MaxSetupCount = 0;
2433 pSMB->Reserved2 = 0;
2434 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2435 InformationLevel) - 4;
2436 offset = param_offset + params;
2438 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2439 data_offset = (char *)pSMB + offset + 4;
2440 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2442 cifsConvertToUTF16((__le16 *) data_offset, toName,
2443 /* find define for this maxpathcomponent */
2444 PATH_MAX, nls_codepage, remap);
2445 name_len_target++; /* trailing null */
2446 name_len_target *= 2;
2448 name_len_target = copy_path_name(data_offset, toName);
2451 pSMB->MaxParameterCount = cpu_to_le16(2);
2452 /* BB find exact max on data count below from sess */
2453 pSMB->MaxDataCount = cpu_to_le16(1000);
2454 pSMB->SetupCount = 1;
2455 pSMB->Reserved3 = 0;
2456 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2457 byte_count = 3 /* pad */ + params + name_len_target;
2458 pSMB->DataCount = cpu_to_le16(name_len_target);
2459 pSMB->ParameterCount = cpu_to_le16(params);
2460 pSMB->TotalDataCount = pSMB->DataCount;
2461 pSMB->TotalParameterCount = pSMB->ParameterCount;
2462 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2463 pSMB->DataOffset = cpu_to_le16(offset);
2464 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2465 pSMB->Reserved4 = 0;
2466 inc_rfc1001_len(pSMB, byte_count);
2467 pSMB->ByteCount = cpu_to_le16(byte_count);
2468 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2469 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2470 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2472 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2475 cifs_buf_release(pSMB);
2478 goto createSymLinkRetry;
2484 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2485 const char *fromName, const char *toName,
2486 const struct nls_table *nls_codepage, int remap)
2488 TRANSACTION2_SPI_REQ *pSMB = NULL;
2489 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2492 int name_len_target;
2494 int bytes_returned = 0;
2495 __u16 params, param_offset, offset, byte_count;
2497 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2498 createHardLinkRetry:
2499 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2504 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2505 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2506 PATH_MAX, nls_codepage, remap);
2507 name_len++; /* trailing null */
2511 name_len = copy_path_name(pSMB->FileName, toName);
2513 params = 6 + name_len;
2514 pSMB->MaxSetupCount = 0;
2518 pSMB->Reserved2 = 0;
2519 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2520 InformationLevel) - 4;
2521 offset = param_offset + params;
2523 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2524 data_offset = (char *)pSMB + offset + 4;
2525 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2527 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2528 PATH_MAX, nls_codepage, remap);
2529 name_len_target++; /* trailing null */
2530 name_len_target *= 2;
2532 name_len_target = copy_path_name(data_offset, fromName);
2535 pSMB->MaxParameterCount = cpu_to_le16(2);
2536 /* BB find exact max on data count below from sess*/
2537 pSMB->MaxDataCount = cpu_to_le16(1000);
2538 pSMB->SetupCount = 1;
2539 pSMB->Reserved3 = 0;
2540 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2541 byte_count = 3 /* pad */ + params + name_len_target;
2542 pSMB->ParameterCount = cpu_to_le16(params);
2543 pSMB->TotalParameterCount = pSMB->ParameterCount;
2544 pSMB->DataCount = cpu_to_le16(name_len_target);
2545 pSMB->TotalDataCount = pSMB->DataCount;
2546 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2547 pSMB->DataOffset = cpu_to_le16(offset);
2548 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2549 pSMB->Reserved4 = 0;
2550 inc_rfc1001_len(pSMB, byte_count);
2551 pSMB->ByteCount = cpu_to_le16(byte_count);
2552 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2553 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2554 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2556 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2559 cifs_buf_release(pSMB);
2561 goto createHardLinkRetry;
2567 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2568 const char *from_name, const char *to_name,
2569 struct cifs_sb_info *cifs_sb)
2572 NT_RENAME_REQ *pSMB = NULL;
2573 RENAME_RSP *pSMBr = NULL;
2575 int name_len, name_len2;
2577 int remap = cifs_remap(cifs_sb);
2579 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2580 winCreateHardLinkRetry:
2582 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2587 pSMB->SearchAttributes =
2588 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2590 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2591 pSMB->ClusterCount = 0;
2593 pSMB->BufferFormat = 0x04;
2595 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2597 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2598 PATH_MAX, cifs_sb->local_nls, remap);
2599 name_len++; /* trailing null */
2602 /* protocol specifies ASCII buffer format (0x04) for unicode */
2603 pSMB->OldFileName[name_len] = 0x04;
2604 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2606 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2607 to_name, PATH_MAX, cifs_sb->local_nls,
2609 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2610 name_len2 *= 2; /* convert to bytes */
2612 name_len = copy_path_name(pSMB->OldFileName, from_name);
2613 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2614 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2615 name_len2++; /* signature byte */
2618 count = 1 /* string type byte */ + name_len + name_len2;
2619 inc_rfc1001_len(pSMB, count);
2620 pSMB->ByteCount = cpu_to_le16(count);
2622 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2623 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2624 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2626 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2628 cifs_buf_release(pSMB);
2630 goto winCreateHardLinkRetry;
2636 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2637 const unsigned char *searchName, char **symlinkinfo,
2638 const struct nls_table *nls_codepage, int remap)
2640 /* SMB_QUERY_FILE_UNIX_LINK */
2641 TRANSACTION2_QPI_REQ *pSMB = NULL;
2642 TRANSACTION2_QPI_RSP *pSMBr = NULL;
2646 __u16 params, byte_count;
2649 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
2652 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2657 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2659 cifsConvertToUTF16((__le16 *) pSMB->FileName,
2660 searchName, PATH_MAX, nls_codepage,
2662 name_len++; /* trailing null */
2665 name_len = copy_path_name(pSMB->FileName, searchName);
2668 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
2669 pSMB->TotalDataCount = 0;
2670 pSMB->MaxParameterCount = cpu_to_le16(2);
2671 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2672 pSMB->MaxSetupCount = 0;
2676 pSMB->Reserved2 = 0;
2677 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2678 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
2679 pSMB->DataCount = 0;
2680 pSMB->DataOffset = 0;
2681 pSMB->SetupCount = 1;
2682 pSMB->Reserved3 = 0;
2683 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2684 byte_count = params + 1 /* pad */ ;
2685 pSMB->TotalParameterCount = cpu_to_le16(params);
2686 pSMB->ParameterCount = pSMB->TotalParameterCount;
2687 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2688 pSMB->Reserved4 = 0;
2689 inc_rfc1001_len(pSMB, byte_count);
2690 pSMB->ByteCount = cpu_to_le16(byte_count);
2692 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2693 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2695 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
2697 /* decode response */
2699 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2700 /* BB also check enough total bytes returned */
2701 if (rc || get_bcc(&pSMBr->hdr) < 2)
2705 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2707 data_start = ((char *) &pSMBr->hdr.Protocol) +
2708 le16_to_cpu(pSMBr->t2.DataOffset);
2710 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2715 /* BB FIXME investigate remapping reserved chars here */
2716 *symlinkinfo = cifs_strndup_from_utf16(data_start,
2717 count, is_unicode, nls_codepage);
2722 cifs_buf_release(pSMB);
2724 goto querySymLinkRetry;
2729 * Recent Windows versions now create symlinks more frequently
2730 * and they use the "reparse point" mechanism below. We can of course
2731 * do symlinks nicely to Samba and other servers which support the
2732 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
2733 * "MF" symlinks optionally, but for recent Windows we really need to
2734 * reenable the code below and fix the cifs_symlink callers to handle this.
2735 * In the interim this code has been moved to its own config option so
2736 * it is not compiled in by default until callers fixed up and more tested.
2739 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2740 __u16 fid, char **symlinkinfo,
2741 const struct nls_table *nls_codepage)
2745 struct smb_com_transaction_ioctl_req *pSMB;
2746 struct smb_com_transaction_ioctl_rsp *pSMBr;
2748 unsigned int sub_len;
2750 struct reparse_symlink_data *reparse_buf;
2751 struct reparse_posix_data *posix_buf;
2752 __u32 data_offset, data_count;
2755 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
2756 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2761 pSMB->TotalParameterCount = 0 ;
2762 pSMB->TotalDataCount = 0;
2763 pSMB->MaxParameterCount = cpu_to_le32(2);
2764 /* BB find exact data count max from sess structure BB */
2765 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
2766 pSMB->MaxSetupCount = 4;
2768 pSMB->ParameterOffset = 0;
2769 pSMB->DataCount = 0;
2770 pSMB->DataOffset = 0;
2771 pSMB->SetupCount = 4;
2772 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2773 pSMB->ParameterCount = pSMB->TotalParameterCount;
2774 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
2775 pSMB->IsFsctl = 1; /* FSCTL */
2776 pSMB->IsRootFlag = 0;
2777 pSMB->Fid = fid; /* file handle always le */
2778 pSMB->ByteCount = 0;
2780 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2781 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2783 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
2787 data_offset = le32_to_cpu(pSMBr->DataOffset);
2788 data_count = le32_to_cpu(pSMBr->DataCount);
2789 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
2790 /* BB also check enough total bytes returned */
2791 rc = -EIO; /* bad smb */
2794 if (!data_count || (data_count > 2048)) {
2796 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
2799 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
2800 reparse_buf = (struct reparse_symlink_data *)
2801 ((char *)&pSMBr->hdr.Protocol + data_offset);
2802 if ((char *)reparse_buf >= end_of_smb) {
2806 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
2807 cifs_dbg(FYI, "NFS style reparse tag\n");
2808 posix_buf = (struct reparse_posix_data *)reparse_buf;
2810 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
2811 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
2812 le64_to_cpu(posix_buf->InodeType));
2817 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
2818 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
2819 cifs_dbg(FYI, "reparse buf beyond SMB\n");
2823 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
2824 sub_len, is_unicode, nls_codepage);
2826 } else if (reparse_buf->ReparseTag !=
2827 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
2832 /* Reparse tag is NTFS symlink */
2833 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
2834 reparse_buf->PathBuffer;
2835 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
2836 if (sub_start + sub_len > end_of_smb) {
2837 cifs_dbg(FYI, "reparse buf beyond SMB\n");
2841 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2846 /* BB FIXME investigate remapping reserved chars here */
2847 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
2852 cifs_buf_release(pSMB);
2855 * Note: On -EAGAIN error only caller can retry on handle based calls
2856 * since file handle passed in no longer valid.
2862 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
2867 struct smb_com_transaction_compr_ioctl_req *pSMB;
2868 struct smb_com_transaction_ioctl_rsp *pSMBr;
2870 cifs_dbg(FYI, "Set compression for %u\n", fid);
2871 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2876 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
2878 pSMB->TotalParameterCount = 0;
2879 pSMB->TotalDataCount = cpu_to_le32(2);
2880 pSMB->MaxParameterCount = 0;
2881 pSMB->MaxDataCount = 0;
2882 pSMB->MaxSetupCount = 4;
2884 pSMB->ParameterOffset = 0;
2885 pSMB->DataCount = cpu_to_le32(2);
2887 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
2888 compression_state) - 4); /* 84 */
2889 pSMB->SetupCount = 4;
2890 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2891 pSMB->ParameterCount = 0;
2892 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
2893 pSMB->IsFsctl = 1; /* FSCTL */
2894 pSMB->IsRootFlag = 0;
2895 pSMB->Fid = fid; /* file handle always le */
2896 /* 3 byte pad, followed by 2 byte compress state */
2897 pSMB->ByteCount = cpu_to_le16(5);
2898 inc_rfc1001_len(pSMB, 5);
2900 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2901 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2903 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
2905 cifs_buf_release(pSMB);
2908 * Note: On -EAGAIN error only caller can retry on handle based calls
2909 * since file handle passed in no longer valid.
2915 #ifdef CONFIG_CIFS_POSIX
2917 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
2918 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
2919 struct cifs_posix_ace *cifs_ace)
2921 /* u8 cifs fields do not need le conversion */
2922 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
2923 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
2924 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
2926 cifs_dbg(FYI, "perm %d tag %d id %d\n",
2927 ace->e_perm, ace->e_tag, ace->e_id);
2933 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
2934 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
2935 const int acl_type, const int size_of_data_area)
2940 struct cifs_posix_ace *pACE;
2941 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
2942 struct posix_acl_xattr_header *local_acl = (void *)trgt;
2944 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
2947 if (acl_type == ACL_TYPE_ACCESS) {
2948 count = le16_to_cpu(cifs_acl->access_entry_count);
2949 pACE = &cifs_acl->ace_array[0];
2950 size = sizeof(struct cifs_posix_acl);
2951 size += sizeof(struct cifs_posix_ace) * count;
2952 /* check if we would go beyond end of SMB */
2953 if (size_of_data_area < size) {
2954 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
2955 size_of_data_area, size);
2958 } else if (acl_type == ACL_TYPE_DEFAULT) {
2959 count = le16_to_cpu(cifs_acl->access_entry_count);
2960 size = sizeof(struct cifs_posix_acl);
2961 size += sizeof(struct cifs_posix_ace) * count;
2962 /* skip past access ACEs to get to default ACEs */
2963 pACE = &cifs_acl->ace_array[count];
2964 count = le16_to_cpu(cifs_acl->default_entry_count);
2965 size += sizeof(struct cifs_posix_ace) * count;
2966 /* check if we would go beyond end of SMB */
2967 if (size_of_data_area < size)
2974 size = posix_acl_xattr_size(count);
2975 if ((buflen == 0) || (local_acl == NULL)) {
2976 /* used to query ACL EA size */
2977 } else if (size > buflen) {
2979 } else /* buffer big enough */ {
2980 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
2982 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
2983 for (i = 0; i < count ; i++) {
2984 cifs_convert_ace(&ace[i], pACE);
2991 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
2992 const struct posix_acl_xattr_entry *local_ace)
2994 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
2995 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
2996 /* BB is there a better way to handle the large uid? */
2997 if (local_ace->e_id == cpu_to_le32(-1)) {
2998 /* Probably no need to le convert -1 on any arch but can not hurt */
2999 cifs_ace->cifs_uid = cpu_to_le64(-1);
3001 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3003 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3004 ace->e_perm, ace->e_tag, ace->e_id);
3008 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3009 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3010 const int buflen, const int acl_type)
3013 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3014 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3015 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3019 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3022 count = posix_acl_xattr_count((size_t)buflen);
3023 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3024 count, buflen, le32_to_cpu(local_acl->a_version));
3025 if (le32_to_cpu(local_acl->a_version) != 2) {
3026 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3027 le32_to_cpu(local_acl->a_version));
3030 cifs_acl->version = cpu_to_le16(1);
3031 if (acl_type == ACL_TYPE_ACCESS) {
3032 cifs_acl->access_entry_count = cpu_to_le16(count);
3033 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3034 } else if (acl_type == ACL_TYPE_DEFAULT) {
3035 cifs_acl->default_entry_count = cpu_to_le16(count);
3036 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3038 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3041 for (i = 0; i < count; i++)
3042 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3044 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3045 rc += sizeof(struct cifs_posix_acl);
3046 /* BB add check to make sure ACL does not overflow SMB */
3052 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3053 const unsigned char *searchName,
3054 char *acl_inf, const int buflen, const int acl_type,
3055 const struct nls_table *nls_codepage, int remap)
3057 /* SMB_QUERY_POSIX_ACL */
3058 TRANSACTION2_QPI_REQ *pSMB = NULL;
3059 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3063 __u16 params, byte_count;
3065 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3068 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3073 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3075 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3076 searchName, PATH_MAX, nls_codepage,
3078 name_len++; /* trailing null */
3080 pSMB->FileName[name_len] = 0;
3081 pSMB->FileName[name_len+1] = 0;
3083 name_len = copy_path_name(pSMB->FileName, searchName);
3086 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3087 pSMB->TotalDataCount = 0;
3088 pSMB->MaxParameterCount = cpu_to_le16(2);
3089 /* BB find exact max data count below from sess structure BB */
3090 pSMB->MaxDataCount = cpu_to_le16(4000);
3091 pSMB->MaxSetupCount = 0;
3095 pSMB->Reserved2 = 0;
3096 pSMB->ParameterOffset = cpu_to_le16(
3097 offsetof(struct smb_com_transaction2_qpi_req,
3098 InformationLevel) - 4);
3099 pSMB->DataCount = 0;
3100 pSMB->DataOffset = 0;
3101 pSMB->SetupCount = 1;
3102 pSMB->Reserved3 = 0;
3103 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3104 byte_count = params + 1 /* pad */ ;
3105 pSMB->TotalParameterCount = cpu_to_le16(params);
3106 pSMB->ParameterCount = pSMB->TotalParameterCount;
3107 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3108 pSMB->Reserved4 = 0;
3109 inc_rfc1001_len(pSMB, byte_count);
3110 pSMB->ByteCount = cpu_to_le16(byte_count);
3112 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3113 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3114 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3116 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3118 /* decode response */
3120 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3121 /* BB also check enough total bytes returned */
3122 if (rc || get_bcc(&pSMBr->hdr) < 2)
3123 rc = -EIO; /* bad smb */
3125 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3126 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3127 rc = cifs_copy_posix_acl(acl_inf,
3128 (char *)&pSMBr->hdr.Protocol+data_offset,
3129 buflen, acl_type, count);
3132 cifs_buf_release(pSMB);
3139 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3140 const unsigned char *fileName,
3141 const char *local_acl, const int buflen,
3143 const struct nls_table *nls_codepage, int remap)
3145 struct smb_com_transaction2_spi_req *pSMB = NULL;
3146 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3150 int bytes_returned = 0;
3151 __u16 params, byte_count, data_count, param_offset, offset;
3153 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3155 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3159 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3161 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3162 PATH_MAX, nls_codepage, remap);
3163 name_len++; /* trailing null */
3166 name_len = copy_path_name(pSMB->FileName, fileName);
3168 params = 6 + name_len;
3169 pSMB->MaxParameterCount = cpu_to_le16(2);
3170 /* BB find max SMB size from sess */
3171 pSMB->MaxDataCount = cpu_to_le16(1000);
3172 pSMB->MaxSetupCount = 0;
3176 pSMB->Reserved2 = 0;
3177 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3178 InformationLevel) - 4;
3179 offset = param_offset + params;
3180 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3181 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3183 /* convert to on the wire format for POSIX ACL */
3184 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3186 if (data_count == 0) {
3188 goto setACLerrorExit;
3190 pSMB->DataOffset = cpu_to_le16(offset);
3191 pSMB->SetupCount = 1;
3192 pSMB->Reserved3 = 0;
3193 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3194 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3195 byte_count = 3 /* pad */ + params + data_count;
3196 pSMB->DataCount = cpu_to_le16(data_count);
3197 pSMB->TotalDataCount = pSMB->DataCount;
3198 pSMB->ParameterCount = cpu_to_le16(params);
3199 pSMB->TotalParameterCount = pSMB->ParameterCount;
3200 pSMB->Reserved4 = 0;
3201 inc_rfc1001_len(pSMB, byte_count);
3202 pSMB->ByteCount = cpu_to_le16(byte_count);
3203 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3204 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3206 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3209 cifs_buf_release(pSMB);
3216 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3217 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3220 struct smb_t2_qfi_req *pSMB = NULL;
3221 struct smb_t2_qfi_rsp *pSMBr = NULL;
3223 __u16 params, byte_count;
3225 cifs_dbg(FYI, "In GetExtAttr\n");
3230 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3235 params = 2 /* level */ + 2 /* fid */;
3236 pSMB->t2.TotalDataCount = 0;
3237 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3238 /* BB find exact max data count below from sess structure BB */
3239 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3240 pSMB->t2.MaxSetupCount = 0;
3241 pSMB->t2.Reserved = 0;
3243 pSMB->t2.Timeout = 0;
3244 pSMB->t2.Reserved2 = 0;
3245 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3247 pSMB->t2.DataCount = 0;
3248 pSMB->t2.DataOffset = 0;
3249 pSMB->t2.SetupCount = 1;
3250 pSMB->t2.Reserved3 = 0;
3251 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3252 byte_count = params + 1 /* pad */ ;
3253 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3254 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3255 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3258 inc_rfc1001_len(pSMB, byte_count);
3259 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3261 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3262 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3264 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3266 /* decode response */
3267 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3268 /* BB also check enough total bytes returned */
3269 if (rc || get_bcc(&pSMBr->hdr) < 2)
3270 /* If rc should we check for EOPNOSUPP and
3271 disable the srvino flag? or in caller? */
3272 rc = -EIO; /* bad smb */
3274 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3275 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3276 struct file_chattr_info *pfinfo;
3279 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3283 pfinfo = (struct file_chattr_info *)
3284 (data_offset + (char *) &pSMBr->hdr.Protocol);
3285 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3286 *pMask = le64_to_cpu(pfinfo->mask);
3290 cifs_buf_release(pSMB);
3292 goto GetExtAttrRetry;
3296 #endif /* CONFIG_POSIX */
3299 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3300 * all NT TRANSACTS that we init here have total parm and data under about 400
3301 * bytes (to fit in small cifs buffer size), which is the case so far, it
3302 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3303 * returned setup area) and MaxParameterCount (returned parms size) must be set
3307 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3308 const int parm_len, struct cifs_tcon *tcon,
3313 struct smb_com_ntransact_req *pSMB;
3315 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3319 *ret_buf = (void *)pSMB;
3321 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3322 pSMB->TotalDataCount = 0;
3323 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3324 pSMB->ParameterCount = pSMB->TotalParameterCount;
3325 pSMB->DataCount = pSMB->TotalDataCount;
3326 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3327 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3328 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3329 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3330 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3331 pSMB->SubCommand = cpu_to_le16(sub_command);
3336 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3337 __u32 *pparmlen, __u32 *pdatalen)
3340 __u32 data_count, data_offset, parm_count, parm_offset;
3341 struct smb_com_ntransact_rsp *pSMBr;
3350 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3352 bcc = get_bcc(&pSMBr->hdr);
3353 end_of_smb = 2 /* sizeof byte count */ + bcc +
3354 (char *)&pSMBr->ByteCount;
3356 data_offset = le32_to_cpu(pSMBr->DataOffset);
3357 data_count = le32_to_cpu(pSMBr->DataCount);
3358 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3359 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3361 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3362 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3364 /* should we also check that parm and data areas do not overlap? */
3365 if (*ppparm > end_of_smb) {
3366 cifs_dbg(FYI, "parms start after end of smb\n");
3368 } else if (parm_count + *ppparm > end_of_smb) {
3369 cifs_dbg(FYI, "parm end after end of smb\n");
3371 } else if (*ppdata > end_of_smb) {
3372 cifs_dbg(FYI, "data starts after end of smb\n");
3374 } else if (data_count + *ppdata > end_of_smb) {
3375 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3376 *ppdata, data_count, (data_count + *ppdata),
3379 } else if (parm_count + data_count > bcc) {
3380 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3383 *pdatalen = data_count;
3384 *pparmlen = parm_count;
3388 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3390 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3391 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3395 QUERY_SEC_DESC_REQ *pSMB;
3397 struct kvec rsp_iov;
3399 cifs_dbg(FYI, "GetCifsACL\n");
3404 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3405 8 /* parm len */, tcon, (void **) &pSMB);
3409 pSMB->MaxParameterCount = cpu_to_le32(4);
3410 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3411 pSMB->MaxSetupCount = 0;
3412 pSMB->Fid = fid; /* file handle always le */
3413 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3415 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3416 inc_rfc1001_len(pSMB, 11);
3417 iov[0].iov_base = (char *)pSMB;
3418 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3420 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3422 cifs_small_buf_release(pSMB);
3423 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3425 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3426 } else { /* decode response */
3430 struct smb_com_ntransact_rsp *pSMBr;
3433 /* validate_nttransact */
3434 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3435 &pdata, &parm_len, pbuflen);
3438 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3440 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3441 pSMBr, parm, *acl_inf);
3443 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3444 rc = -EIO; /* bad smb */
3449 /* BB check that data area is minimum length and as big as acl_len */
3451 acl_len = le32_to_cpu(*parm);
3452 if (acl_len != *pbuflen) {
3453 cifs_dbg(VFS, "acl length %d does not match %d\n",
3455 if (*pbuflen > acl_len)
3459 /* check if buffer is big enough for the acl
3460 header followed by the smallest SID */
3461 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3462 (*pbuflen >= 64 * 1024)) {
3463 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3467 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3468 if (*acl_inf == NULL) {
3475 free_rsp_buf(buf_type, rsp_iov.iov_base);
3480 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3481 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3483 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3485 int bytes_returned = 0;
3486 SET_SEC_DESC_REQ *pSMB = NULL;
3490 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3494 pSMB->MaxSetupCount = 0;
3498 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3499 data_count = acllen;
3500 data_offset = param_offset + param_count;
3501 byte_count = 3 /* pad */ + param_count;
3503 pSMB->DataCount = cpu_to_le32(data_count);
3504 pSMB->TotalDataCount = pSMB->DataCount;
3505 pSMB->MaxParameterCount = cpu_to_le32(4);
3506 pSMB->MaxDataCount = cpu_to_le32(16384);
3507 pSMB->ParameterCount = cpu_to_le32(param_count);
3508 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3509 pSMB->TotalParameterCount = pSMB->ParameterCount;
3510 pSMB->DataOffset = cpu_to_le32(data_offset);
3511 pSMB->SetupCount = 0;
3512 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3513 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3515 pSMB->Fid = fid; /* file handle always le */
3516 pSMB->Reserved2 = 0;
3517 pSMB->AclFlags = cpu_to_le32(aclflag);
3519 if (pntsd && acllen) {
3520 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3521 data_offset, pntsd, acllen);
3522 inc_rfc1001_len(pSMB, byte_count + data_count);
3524 inc_rfc1001_len(pSMB, byte_count);
3526 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3527 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3529 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3530 bytes_returned, rc);
3532 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3533 cifs_buf_release(pSMB);
3536 goto setCifsAclRetry;
3542 /* Legacy Query Path Information call for lookup to old servers such
3545 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3546 const char *search_name, FILE_ALL_INFO *data,
3547 const struct nls_table *nls_codepage, int remap)
3549 QUERY_INFORMATION_REQ *pSMB;
3550 QUERY_INFORMATION_RSP *pSMBr;
3555 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3557 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3562 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3564 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3565 search_name, PATH_MAX, nls_codepage,
3567 name_len++; /* trailing null */
3570 name_len = copy_path_name(pSMB->FileName, search_name);
3572 pSMB->BufferFormat = 0x04;
3573 name_len++; /* account for buffer type byte */
3574 inc_rfc1001_len(pSMB, (__u16)name_len);
3575 pSMB->ByteCount = cpu_to_le16(name_len);
3577 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3578 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3580 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3582 struct timespec64 ts;
3583 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3585 /* decode response */
3586 /* BB FIXME - add time zone adjustment BB */
3587 memset(data, 0, sizeof(FILE_ALL_INFO));
3590 /* decode time fields */
3591 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3592 data->LastWriteTime = data->ChangeTime;
3593 data->LastAccessTime = 0;
3594 data->AllocationSize =
3595 cpu_to_le64(le32_to_cpu(pSMBr->size));
3596 data->EndOfFile = data->AllocationSize;
3598 cpu_to_le32(le16_to_cpu(pSMBr->attr));
3600 rc = -EIO; /* bad buffer passed in */
3602 cifs_buf_release(pSMB);
3611 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3612 u16 netfid, FILE_ALL_INFO *pFindData)
3614 struct smb_t2_qfi_req *pSMB = NULL;
3615 struct smb_t2_qfi_rsp *pSMBr = NULL;
3618 __u16 params, byte_count;
3621 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3626 params = 2 /* level */ + 2 /* fid */;
3627 pSMB->t2.TotalDataCount = 0;
3628 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3629 /* BB find exact max data count below from sess structure BB */
3630 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3631 pSMB->t2.MaxSetupCount = 0;
3632 pSMB->t2.Reserved = 0;
3634 pSMB->t2.Timeout = 0;
3635 pSMB->t2.Reserved2 = 0;
3636 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3638 pSMB->t2.DataCount = 0;
3639 pSMB->t2.DataOffset = 0;
3640 pSMB->t2.SetupCount = 1;
3641 pSMB->t2.Reserved3 = 0;
3642 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3643 byte_count = params + 1 /* pad */ ;
3644 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3645 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3646 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3649 inc_rfc1001_len(pSMB, byte_count);
3650 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3652 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3653 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3655 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
3656 } else { /* decode response */
3657 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3659 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3661 else if (get_bcc(&pSMBr->hdr) < 40)
3662 rc = -EIO; /* bad smb */
3663 else if (pFindData) {
3664 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3665 memcpy((char *) pFindData,
3666 (char *) &pSMBr->hdr.Protocol +
3667 data_offset, sizeof(FILE_ALL_INFO));
3671 cifs_buf_release(pSMB);
3673 goto QFileInfoRetry;
3679 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3680 const char *search_name, FILE_ALL_INFO *data,
3681 int legacy /* old style infolevel */,
3682 const struct nls_table *nls_codepage, int remap)
3684 /* level 263 SMB_QUERY_FILE_ALL_INFO */
3685 TRANSACTION2_QPI_REQ *pSMB = NULL;
3686 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3690 __u16 params, byte_count;
3692 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3694 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3699 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3701 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3702 PATH_MAX, nls_codepage, remap);
3703 name_len++; /* trailing null */
3706 name_len = copy_path_name(pSMB->FileName, search_name);
3709 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3710 pSMB->TotalDataCount = 0;
3711 pSMB->MaxParameterCount = cpu_to_le16(2);
3712 /* BB find exact max SMB PDU from sess structure BB */
3713 pSMB->MaxDataCount = cpu_to_le16(4000);
3714 pSMB->MaxSetupCount = 0;
3718 pSMB->Reserved2 = 0;
3719 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3720 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3721 pSMB->DataCount = 0;
3722 pSMB->DataOffset = 0;
3723 pSMB->SetupCount = 1;
3724 pSMB->Reserved3 = 0;
3725 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3726 byte_count = params + 1 /* pad */ ;
3727 pSMB->TotalParameterCount = cpu_to_le16(params);
3728 pSMB->ParameterCount = pSMB->TotalParameterCount;
3730 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3732 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3733 pSMB->Reserved4 = 0;
3734 inc_rfc1001_len(pSMB, byte_count);
3735 pSMB->ByteCount = cpu_to_le16(byte_count);
3737 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3738 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3740 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3741 } else { /* decode response */
3742 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3744 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3746 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3747 rc = -EIO; /* bad smb */
3748 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3749 rc = -EIO; /* 24 or 26 expected but we do not read
3753 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3756 * On legacy responses we do not read the last field,
3757 * EAsize, fortunately since it varies by subdialect and
3758 * also note it differs on Set vs Get, ie two bytes or 4
3759 * bytes depending but we don't care here.
3762 size = sizeof(FILE_INFO_STANDARD);
3764 size = sizeof(FILE_ALL_INFO);
3765 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
3770 cifs_buf_release(pSMB);
3772 goto QPathInfoRetry;
3778 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3779 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3781 struct smb_t2_qfi_req *pSMB = NULL;
3782 struct smb_t2_qfi_rsp *pSMBr = NULL;
3785 __u16 params, byte_count;
3788 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3793 params = 2 /* level */ + 2 /* fid */;
3794 pSMB->t2.TotalDataCount = 0;
3795 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3796 /* BB find exact max data count below from sess structure BB */
3797 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3798 pSMB->t2.MaxSetupCount = 0;
3799 pSMB->t2.Reserved = 0;
3801 pSMB->t2.Timeout = 0;
3802 pSMB->t2.Reserved2 = 0;
3803 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3805 pSMB->t2.DataCount = 0;
3806 pSMB->t2.DataOffset = 0;
3807 pSMB->t2.SetupCount = 1;
3808 pSMB->t2.Reserved3 = 0;
3809 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3810 byte_count = params + 1 /* pad */ ;
3811 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3812 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3813 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3816 inc_rfc1001_len(pSMB, byte_count);
3817 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3819 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3820 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3822 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
3823 } else { /* decode response */
3824 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3826 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3827 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3828 rc = -EIO; /* bad smb */
3830 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3831 memcpy((char *) pFindData,
3832 (char *) &pSMBr->hdr.Protocol +
3834 sizeof(FILE_UNIX_BASIC_INFO));
3838 cifs_buf_release(pSMB);
3840 goto UnixQFileInfoRetry;
3846 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3847 const unsigned char *searchName,
3848 FILE_UNIX_BASIC_INFO *pFindData,
3849 const struct nls_table *nls_codepage, int remap)
3851 /* SMB_QUERY_FILE_UNIX_BASIC */
3852 TRANSACTION2_QPI_REQ *pSMB = NULL;
3853 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3855 int bytes_returned = 0;
3857 __u16 params, byte_count;
3859 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
3861 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3866 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3868 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3869 PATH_MAX, nls_codepage, remap);
3870 name_len++; /* trailing null */
3873 name_len = copy_path_name(pSMB->FileName, searchName);
3876 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3877 pSMB->TotalDataCount = 0;
3878 pSMB->MaxParameterCount = cpu_to_le16(2);
3879 /* BB find exact max SMB PDU from sess structure BB */
3880 pSMB->MaxDataCount = cpu_to_le16(4000);
3881 pSMB->MaxSetupCount = 0;
3885 pSMB->Reserved2 = 0;
3886 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3887 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3888 pSMB->DataCount = 0;
3889 pSMB->DataOffset = 0;
3890 pSMB->SetupCount = 1;
3891 pSMB->Reserved3 = 0;
3892 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3893 byte_count = params + 1 /* pad */ ;
3894 pSMB->TotalParameterCount = cpu_to_le16(params);
3895 pSMB->ParameterCount = pSMB->TotalParameterCount;
3896 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3897 pSMB->Reserved4 = 0;
3898 inc_rfc1001_len(pSMB, byte_count);
3899 pSMB->ByteCount = cpu_to_le16(byte_count);
3901 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3902 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3904 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
3905 } else { /* decode response */
3906 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3908 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3909 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3910 rc = -EIO; /* bad smb */
3912 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3913 memcpy((char *) pFindData,
3914 (char *) &pSMBr->hdr.Protocol +
3916 sizeof(FILE_UNIX_BASIC_INFO));
3919 cifs_buf_release(pSMB);
3921 goto UnixQPathInfoRetry;
3926 /* xid, tcon, searchName and codepage are input parms, rest are returned */
3928 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
3929 const char *searchName, struct cifs_sb_info *cifs_sb,
3930 __u16 *pnetfid, __u16 search_flags,
3931 struct cifs_search_info *psrch_inf, bool msearch)
3933 /* level 257 SMB_ */
3934 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
3935 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
3936 T2_FFIRST_RSP_PARMS *parms;
3938 int bytes_returned = 0;
3939 int name_len, remap;
3940 __u16 params, byte_count;
3941 struct nls_table *nls_codepage;
3943 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
3946 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3951 nls_codepage = cifs_sb->local_nls;
3952 remap = cifs_remap(cifs_sb);
3954 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3956 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3957 PATH_MAX, nls_codepage, remap);
3958 /* We can not add the asterik earlier in case
3959 it got remapped to 0xF03A as if it were part of the
3960 directory name instead of a wildcard */
3963 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
3964 pSMB->FileName[name_len+1] = 0;
3965 pSMB->FileName[name_len+2] = '*';
3966 pSMB->FileName[name_len+3] = 0;
3967 name_len += 4; /* now the trailing null */
3968 /* null terminate just in case */
3969 pSMB->FileName[name_len] = 0;
3970 pSMB->FileName[name_len+1] = 0;
3974 name_len = copy_path_name(pSMB->FileName, searchName);
3976 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
3977 name_len = PATH_MAX-2;
3978 /* overwrite nul byte */
3979 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
3980 pSMB->FileName[name_len] = '*';
3981 pSMB->FileName[name_len+1] = 0;
3986 params = 12 + name_len /* includes null */ ;
3987 pSMB->TotalDataCount = 0; /* no EAs */
3988 pSMB->MaxParameterCount = cpu_to_le16(10);
3989 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
3990 pSMB->MaxSetupCount = 0;
3994 pSMB->Reserved2 = 0;
3995 byte_count = params + 1 /* pad */ ;
3996 pSMB->TotalParameterCount = cpu_to_le16(params);
3997 pSMB->ParameterCount = pSMB->TotalParameterCount;
3998 pSMB->ParameterOffset = cpu_to_le16(
3999 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4001 pSMB->DataCount = 0;
4002 pSMB->DataOffset = 0;
4003 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4004 pSMB->Reserved3 = 0;
4005 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4006 pSMB->SearchAttributes =
4007 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4009 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4010 pSMB->SearchFlags = cpu_to_le16(search_flags);
4011 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4013 /* BB what should we set StorageType to? Does it matter? BB */
4014 pSMB->SearchStorageType = 0;
4015 inc_rfc1001_len(pSMB, byte_count);
4016 pSMB->ByteCount = cpu_to_le16(byte_count);
4018 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4019 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4020 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4022 if (rc) {/* BB add logic to retry regular search if Unix search
4023 rejected unexpectedly by server */
4024 /* BB Add code to handle unsupported level rc */
4025 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4027 cifs_buf_release(pSMB);
4029 /* BB eventually could optimize out free and realloc of buf */
4032 goto findFirstRetry;
4033 } else { /* decode response */
4034 /* BB remember to free buffer if error BB */
4035 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4039 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4040 psrch_inf->unicode = true;
4042 psrch_inf->unicode = false;
4044 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4045 psrch_inf->smallBuf = false;
4046 psrch_inf->srch_entries_start =
4047 (char *) &pSMBr->hdr.Protocol +
4048 le16_to_cpu(pSMBr->t2.DataOffset);
4049 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4050 le16_to_cpu(pSMBr->t2.ParameterOffset));
4052 if (parms->EndofSearch)
4053 psrch_inf->endOfSearch = true;
4055 psrch_inf->endOfSearch = false;
4057 psrch_inf->entries_in_buffer =
4058 le16_to_cpu(parms->SearchCount);
4059 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4060 psrch_inf->entries_in_buffer;
4061 lnoff = le16_to_cpu(parms->LastNameOffset);
4062 if (CIFSMaxBufSize < lnoff) {
4063 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4064 psrch_inf->last_entry = NULL;
4068 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4072 *pnetfid = parms->SearchHandle;
4074 cifs_buf_release(pSMB);
4081 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4082 __u16 searchHandle, __u16 search_flags,
4083 struct cifs_search_info *psrch_inf)
4085 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4086 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4087 T2_FNEXT_RSP_PARMS *parms;
4088 char *response_data;
4091 unsigned int name_len;
4092 __u16 params, byte_count;
4094 cifs_dbg(FYI, "In FindNext\n");
4096 if (psrch_inf->endOfSearch)
4099 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4104 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4106 pSMB->TotalDataCount = 0; /* no EAs */
4107 pSMB->MaxParameterCount = cpu_to_le16(8);
4108 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4109 pSMB->MaxSetupCount = 0;
4113 pSMB->Reserved2 = 0;
4114 pSMB->ParameterOffset = cpu_to_le16(
4115 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4116 pSMB->DataCount = 0;
4117 pSMB->DataOffset = 0;
4118 pSMB->SetupCount = 1;
4119 pSMB->Reserved3 = 0;
4120 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4121 pSMB->SearchHandle = searchHandle; /* always kept as le */
4123 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4124 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4125 pSMB->ResumeKey = psrch_inf->resume_key;
4126 pSMB->SearchFlags = cpu_to_le16(search_flags);
4128 name_len = psrch_inf->resume_name_len;
4130 if (name_len < PATH_MAX) {
4131 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4132 byte_count += name_len;
4133 /* 14 byte parm len above enough for 2 byte null terminator */
4134 pSMB->ResumeFileName[name_len] = 0;
4135 pSMB->ResumeFileName[name_len+1] = 0;
4138 goto FNext2_err_exit;
4140 byte_count = params + 1 /* pad */ ;
4141 pSMB->TotalParameterCount = cpu_to_le16(params);
4142 pSMB->ParameterCount = pSMB->TotalParameterCount;
4143 inc_rfc1001_len(pSMB, byte_count);
4144 pSMB->ByteCount = cpu_to_le16(byte_count);
4146 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4147 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4148 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4151 psrch_inf->endOfSearch = true;
4152 cifs_buf_release(pSMB);
4153 rc = 0; /* search probably was closed at end of search*/
4155 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4156 } else { /* decode response */
4157 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4162 /* BB fixme add lock for file (srch_info) struct here */
4163 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4164 psrch_inf->unicode = true;
4166 psrch_inf->unicode = false;
4167 response_data = (char *) &pSMBr->hdr.Protocol +
4168 le16_to_cpu(pSMBr->t2.ParameterOffset);
4169 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4170 response_data = (char *)&pSMBr->hdr.Protocol +
4171 le16_to_cpu(pSMBr->t2.DataOffset);
4172 if (psrch_inf->smallBuf)
4173 cifs_small_buf_release(
4174 psrch_inf->ntwrk_buf_start);
4176 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4177 psrch_inf->srch_entries_start = response_data;
4178 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4179 psrch_inf->smallBuf = false;
4180 if (parms->EndofSearch)
4181 psrch_inf->endOfSearch = true;
4183 psrch_inf->endOfSearch = false;
4184 psrch_inf->entries_in_buffer =
4185 le16_to_cpu(parms->SearchCount);
4186 psrch_inf->index_of_last_entry +=
4187 psrch_inf->entries_in_buffer;
4188 lnoff = le16_to_cpu(parms->LastNameOffset);
4189 if (CIFSMaxBufSize < lnoff) {
4190 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4191 psrch_inf->last_entry = NULL;
4194 psrch_inf->last_entry =
4195 psrch_inf->srch_entries_start + lnoff;
4197 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4198 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4200 /* BB fixme add unlock here */
4205 /* BB On error, should we leave previous search buf (and count and
4206 last entry fields) intact or free the previous one? */
4208 /* Note: On -EAGAIN error only caller can retry on handle based calls
4209 since file handle passed in no longer valid */
4212 cifs_buf_release(pSMB);
4217 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4218 const __u16 searchHandle)
4221 FINDCLOSE_REQ *pSMB = NULL;
4223 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4224 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4226 /* no sense returning error if session restarted
4227 as file handle has been closed */
4233 pSMB->FileID = searchHandle;
4234 pSMB->ByteCount = 0;
4235 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4236 cifs_small_buf_release(pSMB);
4238 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4240 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4242 /* Since session is dead, search handle closed on server already */
4250 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4251 const char *search_name, __u64 *inode_number,
4252 const struct nls_table *nls_codepage, int remap)
4255 TRANSACTION2_QPI_REQ *pSMB = NULL;
4256 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4257 int name_len, bytes_returned;
4258 __u16 params, byte_count;
4260 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4264 GetInodeNumberRetry:
4265 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4270 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4272 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4273 search_name, PATH_MAX, nls_codepage,
4275 name_len++; /* trailing null */
4278 name_len = copy_path_name(pSMB->FileName, search_name);
4281 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4282 pSMB->TotalDataCount = 0;
4283 pSMB->MaxParameterCount = cpu_to_le16(2);
4284 /* BB find exact max data count below from sess structure BB */
4285 pSMB->MaxDataCount = cpu_to_le16(4000);
4286 pSMB->MaxSetupCount = 0;
4290 pSMB->Reserved2 = 0;
4291 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4292 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4293 pSMB->DataCount = 0;
4294 pSMB->DataOffset = 0;
4295 pSMB->SetupCount = 1;
4296 pSMB->Reserved3 = 0;
4297 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4298 byte_count = params + 1 /* pad */ ;
4299 pSMB->TotalParameterCount = cpu_to_le16(params);
4300 pSMB->ParameterCount = pSMB->TotalParameterCount;
4301 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4302 pSMB->Reserved4 = 0;
4303 inc_rfc1001_len(pSMB, byte_count);
4304 pSMB->ByteCount = cpu_to_le16(byte_count);
4306 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4307 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4309 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4311 /* decode response */
4312 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4313 /* BB also check enough total bytes returned */
4314 if (rc || get_bcc(&pSMBr->hdr) < 2)
4315 /* If rc should we check for EOPNOSUPP and
4316 disable the srvino flag? or in caller? */
4317 rc = -EIO; /* bad smb */
4319 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4320 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4321 struct file_internal_info *pfinfo;
4322 /* BB Do we need a cast or hash here ? */
4324 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4326 goto GetInodeNumOut;
4328 pfinfo = (struct file_internal_info *)
4329 (data_offset + (char *) &pSMBr->hdr.Protocol);
4330 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4334 cifs_buf_release(pSMB);
4336 goto GetInodeNumberRetry;
4341 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4342 const char *search_name, struct dfs_info3_param **target_nodes,
4343 unsigned int *num_of_nodes,
4344 const struct nls_table *nls_codepage, int remap)
4346 /* TRANS2_GET_DFS_REFERRAL */
4347 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4348 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4352 __u16 params, byte_count;
4354 *target_nodes = NULL;
4356 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4357 if (ses == NULL || ses->tcon_ipc == NULL)
4361 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4366 /* server pointer checked in called function,
4367 but should never be null here anyway */
4368 pSMB->hdr.Mid = get_next_mid(ses->server);
4369 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4370 pSMB->hdr.Uid = ses->Suid;
4371 if (ses->capabilities & CAP_STATUS32)
4372 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4373 if (ses->capabilities & CAP_DFS)
4374 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4376 if (ses->capabilities & CAP_UNICODE) {
4377 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4379 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4380 search_name, PATH_MAX, nls_codepage,
4382 name_len++; /* trailing null */
4384 } else { /* BB improve the check for buffer overruns BB */
4385 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4388 if (ses->server->sign)
4389 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4391 pSMB->hdr.Uid = ses->Suid;
4393 params = 2 /* level */ + name_len /*includes null */ ;
4394 pSMB->TotalDataCount = 0;
4395 pSMB->DataCount = 0;
4396 pSMB->DataOffset = 0;
4397 pSMB->MaxParameterCount = 0;
4398 /* BB find exact max SMB PDU from sess structure BB */
4399 pSMB->MaxDataCount = cpu_to_le16(4000);
4400 pSMB->MaxSetupCount = 0;
4404 pSMB->Reserved2 = 0;
4405 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4406 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4407 pSMB->SetupCount = 1;
4408 pSMB->Reserved3 = 0;
4409 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4410 byte_count = params + 3 /* pad */ ;
4411 pSMB->ParameterCount = cpu_to_le16(params);
4412 pSMB->TotalParameterCount = pSMB->ParameterCount;
4413 pSMB->MaxReferralLevel = cpu_to_le16(3);
4414 inc_rfc1001_len(pSMB, byte_count);
4415 pSMB->ByteCount = cpu_to_le16(byte_count);
4417 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4418 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4420 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4423 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4425 /* BB Also check if enough total bytes returned? */
4426 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4427 rc = -EIO; /* bad smb */
4431 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4432 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4434 /* parse returned result into more usable form */
4435 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4436 le16_to_cpu(pSMBr->t2.DataCount),
4437 num_of_nodes, target_nodes, nls_codepage,
4439 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4442 cifs_buf_release(pSMB);
4450 /* Query File System Info such as free space to old servers such as Win 9x */
4452 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4453 struct kstatfs *FSData)
4455 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4456 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4457 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4458 FILE_SYSTEM_ALLOC_INFO *response_data;
4460 int bytes_returned = 0;
4461 __u16 params, byte_count;
4463 cifs_dbg(FYI, "OldQFSInfo\n");
4465 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4470 params = 2; /* level */
4471 pSMB->TotalDataCount = 0;
4472 pSMB->MaxParameterCount = cpu_to_le16(2);
4473 pSMB->MaxDataCount = cpu_to_le16(1000);
4474 pSMB->MaxSetupCount = 0;
4478 pSMB->Reserved2 = 0;
4479 byte_count = params + 1 /* pad */ ;
4480 pSMB->TotalParameterCount = cpu_to_le16(params);
4481 pSMB->ParameterCount = pSMB->TotalParameterCount;
4482 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4483 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4484 pSMB->DataCount = 0;
4485 pSMB->DataOffset = 0;
4486 pSMB->SetupCount = 1;
4487 pSMB->Reserved3 = 0;
4488 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4489 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4490 inc_rfc1001_len(pSMB, byte_count);
4491 pSMB->ByteCount = cpu_to_le16(byte_count);
4493 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4494 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4496 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4497 } else { /* decode response */
4498 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4500 if (rc || get_bcc(&pSMBr->hdr) < 18)
4501 rc = -EIO; /* bad smb */
4503 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4504 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4505 get_bcc(&pSMBr->hdr), data_offset);
4507 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4508 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4510 le16_to_cpu(response_data->BytesPerSector) *
4511 le32_to_cpu(response_data->
4512 SectorsPerAllocationUnit);
4514 * much prefer larger but if server doesn't report
4515 * a valid size than 4K is a reasonable minimum
4517 if (FSData->f_bsize < 512)
4518 FSData->f_bsize = 4096;
4521 le32_to_cpu(response_data->TotalAllocationUnits);
4522 FSData->f_bfree = FSData->f_bavail =
4523 le32_to_cpu(response_data->FreeAllocationUnits);
4524 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4525 (unsigned long long)FSData->f_blocks,
4526 (unsigned long long)FSData->f_bfree,
4530 cifs_buf_release(pSMB);
4533 goto oldQFSInfoRetry;
4539 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4540 struct kstatfs *FSData)
4542 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4543 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4544 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4545 FILE_SYSTEM_INFO *response_data;
4547 int bytes_returned = 0;
4548 __u16 params, byte_count;
4550 cifs_dbg(FYI, "In QFSInfo\n");
4552 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4557 params = 2; /* level */
4558 pSMB->TotalDataCount = 0;
4559 pSMB->MaxParameterCount = cpu_to_le16(2);
4560 pSMB->MaxDataCount = cpu_to_le16(1000);
4561 pSMB->MaxSetupCount = 0;
4565 pSMB->Reserved2 = 0;
4566 byte_count = params + 1 /* pad */ ;
4567 pSMB->TotalParameterCount = cpu_to_le16(params);
4568 pSMB->ParameterCount = pSMB->TotalParameterCount;
4569 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4570 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4571 pSMB->DataCount = 0;
4572 pSMB->DataOffset = 0;
4573 pSMB->SetupCount = 1;
4574 pSMB->Reserved3 = 0;
4575 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4576 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4577 inc_rfc1001_len(pSMB, byte_count);
4578 pSMB->ByteCount = cpu_to_le16(byte_count);
4580 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4581 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4583 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4584 } else { /* decode response */
4585 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4587 if (rc || get_bcc(&pSMBr->hdr) < 24)
4588 rc = -EIO; /* bad smb */
4590 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4594 *) (((char *) &pSMBr->hdr.Protocol) +
4597 le32_to_cpu(response_data->BytesPerSector) *
4598 le32_to_cpu(response_data->
4599 SectorsPerAllocationUnit);
4601 * much prefer larger but if server doesn't report
4602 * a valid size than 4K is a reasonable minimum
4604 if (FSData->f_bsize < 512)
4605 FSData->f_bsize = 4096;
4608 le64_to_cpu(response_data->TotalAllocationUnits);
4609 FSData->f_bfree = FSData->f_bavail =
4610 le64_to_cpu(response_data->FreeAllocationUnits);
4611 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4612 (unsigned long long)FSData->f_blocks,
4613 (unsigned long long)FSData->f_bfree,
4617 cifs_buf_release(pSMB);
4626 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
4628 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
4629 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4630 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4631 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
4633 int bytes_returned = 0;
4634 __u16 params, byte_count;
4636 cifs_dbg(FYI, "In QFSAttributeInfo\n");
4638 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4643 params = 2; /* level */
4644 pSMB->TotalDataCount = 0;
4645 pSMB->MaxParameterCount = cpu_to_le16(2);
4646 /* BB find exact max SMB PDU from sess structure BB */
4647 pSMB->MaxDataCount = cpu_to_le16(1000);
4648 pSMB->MaxSetupCount = 0;
4652 pSMB->Reserved2 = 0;
4653 byte_count = params + 1 /* pad */ ;
4654 pSMB->TotalParameterCount = cpu_to_le16(params);
4655 pSMB->ParameterCount = pSMB->TotalParameterCount;
4656 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4657 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4658 pSMB->DataCount = 0;
4659 pSMB->DataOffset = 0;
4660 pSMB->SetupCount = 1;
4661 pSMB->Reserved3 = 0;
4662 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4663 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4664 inc_rfc1001_len(pSMB, byte_count);
4665 pSMB->ByteCount = cpu_to_le16(byte_count);
4667 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4668 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4670 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
4671 } else { /* decode response */
4672 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4674 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4675 /* BB also check if enough bytes returned */
4676 rc = -EIO; /* bad smb */
4678 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4680 (FILE_SYSTEM_ATTRIBUTE_INFO
4681 *) (((char *) &pSMBr->hdr.Protocol) +
4683 memcpy(&tcon->fsAttrInfo, response_data,
4684 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
4687 cifs_buf_release(pSMB);
4690 goto QFSAttributeRetry;
4696 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
4698 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4699 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4700 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4701 FILE_SYSTEM_DEVICE_INFO *response_data;
4703 int bytes_returned = 0;
4704 __u16 params, byte_count;
4706 cifs_dbg(FYI, "In QFSDeviceInfo\n");
4708 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4713 params = 2; /* level */
4714 pSMB->TotalDataCount = 0;
4715 pSMB->MaxParameterCount = cpu_to_le16(2);
4716 /* BB find exact max SMB PDU from sess structure BB */
4717 pSMB->MaxDataCount = cpu_to_le16(1000);
4718 pSMB->MaxSetupCount = 0;
4722 pSMB->Reserved2 = 0;
4723 byte_count = params + 1 /* pad */ ;
4724 pSMB->TotalParameterCount = cpu_to_le16(params);
4725 pSMB->ParameterCount = pSMB->TotalParameterCount;
4726 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4727 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4729 pSMB->DataCount = 0;
4730 pSMB->DataOffset = 0;
4731 pSMB->SetupCount = 1;
4732 pSMB->Reserved3 = 0;
4733 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4734 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4735 inc_rfc1001_len(pSMB, byte_count);
4736 pSMB->ByteCount = cpu_to_le16(byte_count);
4738 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4739 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4741 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
4742 } else { /* decode response */
4743 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4745 if (rc || get_bcc(&pSMBr->hdr) <
4746 sizeof(FILE_SYSTEM_DEVICE_INFO))
4747 rc = -EIO; /* bad smb */
4749 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4751 (FILE_SYSTEM_DEVICE_INFO *)
4752 (((char *) &pSMBr->hdr.Protocol) +
4754 memcpy(&tcon->fsDevInfo, response_data,
4755 sizeof(FILE_SYSTEM_DEVICE_INFO));
4758 cifs_buf_release(pSMB);
4761 goto QFSDeviceRetry;
4767 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
4769 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
4770 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4771 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4772 FILE_SYSTEM_UNIX_INFO *response_data;
4774 int bytes_returned = 0;
4775 __u16 params, byte_count;
4777 cifs_dbg(FYI, "In QFSUnixInfo\n");
4779 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4780 (void **) &pSMB, (void **) &pSMBr);
4784 params = 2; /* level */
4785 pSMB->TotalDataCount = 0;
4786 pSMB->DataCount = 0;
4787 pSMB->DataOffset = 0;
4788 pSMB->MaxParameterCount = cpu_to_le16(2);
4789 /* BB find exact max SMB PDU from sess structure BB */
4790 pSMB->MaxDataCount = cpu_to_le16(100);
4791 pSMB->MaxSetupCount = 0;
4795 pSMB->Reserved2 = 0;
4796 byte_count = params + 1 /* pad */ ;
4797 pSMB->ParameterCount = cpu_to_le16(params);
4798 pSMB->TotalParameterCount = pSMB->ParameterCount;
4799 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4800 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4801 pSMB->SetupCount = 1;
4802 pSMB->Reserved3 = 0;
4803 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4804 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4805 inc_rfc1001_len(pSMB, byte_count);
4806 pSMB->ByteCount = cpu_to_le16(byte_count);
4808 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4809 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4811 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
4812 } else { /* decode response */
4813 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4815 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4816 rc = -EIO; /* bad smb */
4818 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4820 (FILE_SYSTEM_UNIX_INFO
4821 *) (((char *) &pSMBr->hdr.Protocol) +
4823 memcpy(&tcon->fsUnixInfo, response_data,
4824 sizeof(FILE_SYSTEM_UNIX_INFO));
4827 cifs_buf_release(pSMB);
4837 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
4839 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
4840 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
4841 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
4843 int bytes_returned = 0;
4844 __u16 params, param_offset, offset, byte_count;
4846 cifs_dbg(FYI, "In SETFSUnixInfo\n");
4848 /* BB switch to small buf init to save memory */
4849 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4850 (void **) &pSMB, (void **) &pSMBr);
4854 params = 4; /* 2 bytes zero followed by info level. */
4855 pSMB->MaxSetupCount = 0;
4859 pSMB->Reserved2 = 0;
4860 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
4862 offset = param_offset + params;
4864 pSMB->MaxParameterCount = cpu_to_le16(4);
4865 /* BB find exact max SMB PDU from sess structure BB */
4866 pSMB->MaxDataCount = cpu_to_le16(100);
4867 pSMB->SetupCount = 1;
4868 pSMB->Reserved3 = 0;
4869 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
4870 byte_count = 1 /* pad */ + params + 12;
4872 pSMB->DataCount = cpu_to_le16(12);
4873 pSMB->ParameterCount = cpu_to_le16(params);
4874 pSMB->TotalDataCount = pSMB->DataCount;
4875 pSMB->TotalParameterCount = pSMB->ParameterCount;
4876 pSMB->ParameterOffset = cpu_to_le16(param_offset);
4877 pSMB->DataOffset = cpu_to_le16(offset);
4881 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
4884 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
4885 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4886 pSMB->ClientUnixCap = cpu_to_le64(cap);
4888 inc_rfc1001_len(pSMB, byte_count);
4889 pSMB->ByteCount = cpu_to_le16(byte_count);
4891 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4892 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4894 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
4895 } else { /* decode response */
4896 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4898 rc = -EIO; /* bad smb */
4900 cifs_buf_release(pSMB);
4903 goto SETFSUnixRetry;
4911 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
4912 struct kstatfs *FSData)
4914 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
4915 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4916 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4917 FILE_SYSTEM_POSIX_INFO *response_data;
4919 int bytes_returned = 0;
4920 __u16 params, byte_count;
4922 cifs_dbg(FYI, "In QFSPosixInfo\n");
4924 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4929 params = 2; /* level */
4930 pSMB->TotalDataCount = 0;
4931 pSMB->DataCount = 0;
4932 pSMB->DataOffset = 0;
4933 pSMB->MaxParameterCount = cpu_to_le16(2);
4934 /* BB find exact max SMB PDU from sess structure BB */
4935 pSMB->MaxDataCount = cpu_to_le16(100);
4936 pSMB->MaxSetupCount = 0;
4940 pSMB->Reserved2 = 0;
4941 byte_count = params + 1 /* pad */ ;
4942 pSMB->ParameterCount = cpu_to_le16(params);
4943 pSMB->TotalParameterCount = pSMB->ParameterCount;
4944 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4945 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4946 pSMB->SetupCount = 1;
4947 pSMB->Reserved3 = 0;
4948 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4949 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4950 inc_rfc1001_len(pSMB, byte_count);
4951 pSMB->ByteCount = cpu_to_le16(byte_count);
4953 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4954 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4956 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
4957 } else { /* decode response */
4958 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4960 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4961 rc = -EIO; /* bad smb */
4963 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4965 (FILE_SYSTEM_POSIX_INFO
4966 *) (((char *) &pSMBr->hdr.Protocol) +
4969 le32_to_cpu(response_data->BlockSize);
4971 * much prefer larger but if server doesn't report
4972 * a valid size than 4K is a reasonable minimum
4974 if (FSData->f_bsize < 512)
4975 FSData->f_bsize = 4096;
4978 le64_to_cpu(response_data->TotalBlocks);
4980 le64_to_cpu(response_data->BlocksAvail);
4981 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
4982 FSData->f_bavail = FSData->f_bfree;
4985 le64_to_cpu(response_data->UserBlocksAvail);
4987 if (response_data->TotalFileNodes != cpu_to_le64(-1))
4989 le64_to_cpu(response_data->TotalFileNodes);
4990 if (response_data->FreeFileNodes != cpu_to_le64(-1))
4992 le64_to_cpu(response_data->FreeFileNodes);
4995 cifs_buf_release(pSMB);
5005 * We can not use write of zero bytes trick to set file size due to need for
5006 * large file support. Also note that this SetPathInfo is preferred to
5007 * SetFileInfo based method in next routine which is only needed to work around
5008 * a sharing violation bugin Samba which this routine can run into.
5011 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5012 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5013 bool set_allocation)
5015 struct smb_com_transaction2_spi_req *pSMB = NULL;
5016 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5017 struct file_end_of_file_info *parm_data;
5020 int bytes_returned = 0;
5021 int remap = cifs_remap(cifs_sb);
5023 __u16 params, byte_count, data_count, param_offset, offset;
5025 cifs_dbg(FYI, "In SetEOF\n");
5027 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5032 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5034 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5035 PATH_MAX, cifs_sb->local_nls, remap);
5036 name_len++; /* trailing null */
5039 name_len = copy_path_name(pSMB->FileName, file_name);
5041 params = 6 + name_len;
5042 data_count = sizeof(struct file_end_of_file_info);
5043 pSMB->MaxParameterCount = cpu_to_le16(2);
5044 pSMB->MaxDataCount = cpu_to_le16(4100);
5045 pSMB->MaxSetupCount = 0;
5049 pSMB->Reserved2 = 0;
5050 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5051 InformationLevel) - 4;
5052 offset = param_offset + params;
5053 if (set_allocation) {
5054 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5055 pSMB->InformationLevel =
5056 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5058 pSMB->InformationLevel =
5059 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5060 } else /* Set File Size */ {
5061 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5062 pSMB->InformationLevel =
5063 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5065 pSMB->InformationLevel =
5066 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5070 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5072 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5073 pSMB->DataOffset = cpu_to_le16(offset);
5074 pSMB->SetupCount = 1;
5075 pSMB->Reserved3 = 0;
5076 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5077 byte_count = 3 /* pad */ + params + data_count;
5078 pSMB->DataCount = cpu_to_le16(data_count);
5079 pSMB->TotalDataCount = pSMB->DataCount;
5080 pSMB->ParameterCount = cpu_to_le16(params);
5081 pSMB->TotalParameterCount = pSMB->ParameterCount;
5082 pSMB->Reserved4 = 0;
5083 inc_rfc1001_len(pSMB, byte_count);
5084 parm_data->FileSize = cpu_to_le64(size);
5085 pSMB->ByteCount = cpu_to_le16(byte_count);
5086 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5087 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5089 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5091 cifs_buf_release(pSMB);
5100 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5101 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5103 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5104 struct file_end_of_file_info *parm_data;
5106 __u16 params, param_offset, offset, byte_count, count;
5108 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5110 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5115 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5116 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5119 pSMB->MaxSetupCount = 0;
5123 pSMB->Reserved2 = 0;
5124 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5125 offset = param_offset + params;
5127 count = sizeof(struct file_end_of_file_info);
5128 pSMB->MaxParameterCount = cpu_to_le16(2);
5129 /* BB find exact max SMB PDU from sess structure BB */
5130 pSMB->MaxDataCount = cpu_to_le16(1000);
5131 pSMB->SetupCount = 1;
5132 pSMB->Reserved3 = 0;
5133 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5134 byte_count = 3 /* pad */ + params + count;
5135 pSMB->DataCount = cpu_to_le16(count);
5136 pSMB->ParameterCount = cpu_to_le16(params);
5137 pSMB->TotalDataCount = pSMB->DataCount;
5138 pSMB->TotalParameterCount = pSMB->ParameterCount;
5139 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5140 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5142 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5143 pSMB->DataOffset = cpu_to_le16(offset);
5144 parm_data->FileSize = cpu_to_le64(size);
5145 pSMB->Fid = cfile->fid.netfid;
5146 if (set_allocation) {
5147 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5148 pSMB->InformationLevel =
5149 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5151 pSMB->InformationLevel =
5152 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5153 } else /* Set File Size */ {
5154 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5155 pSMB->InformationLevel =
5156 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5158 pSMB->InformationLevel =
5159 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5161 pSMB->Reserved4 = 0;
5162 inc_rfc1001_len(pSMB, byte_count);
5163 pSMB->ByteCount = cpu_to_le16(byte_count);
5164 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5165 cifs_small_buf_release(pSMB);
5167 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5171 /* Note: On -EAGAIN error only caller can retry on handle based calls
5172 since file handle passed in no longer valid */
5177 /* Some legacy servers such as NT4 require that the file times be set on
5178 an open handle, rather than by pathname - this is awkward due to
5179 potential access conflicts on the open, but it is unavoidable for these
5180 old servers since the only other choice is to go from 100 nanosecond DCE
5181 time and resort to the original setpathinfo level which takes the ancient
5182 DOS time format with 2 second granularity */
5184 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5185 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5187 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5190 __u16 params, param_offset, offset, byte_count, count;
5192 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5193 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5198 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5199 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5202 pSMB->MaxSetupCount = 0;
5206 pSMB->Reserved2 = 0;
5207 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5208 offset = param_offset + params;
5210 data_offset = (char *)pSMB +
5211 offsetof(struct smb_hdr, Protocol) + offset;
5213 count = sizeof(FILE_BASIC_INFO);
5214 pSMB->MaxParameterCount = cpu_to_le16(2);
5215 /* BB find max SMB PDU from sess */
5216 pSMB->MaxDataCount = cpu_to_le16(1000);
5217 pSMB->SetupCount = 1;
5218 pSMB->Reserved3 = 0;
5219 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5220 byte_count = 3 /* pad */ + params + count;
5221 pSMB->DataCount = cpu_to_le16(count);
5222 pSMB->ParameterCount = cpu_to_le16(params);
5223 pSMB->TotalDataCount = pSMB->DataCount;
5224 pSMB->TotalParameterCount = pSMB->ParameterCount;
5225 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5226 pSMB->DataOffset = cpu_to_le16(offset);
5228 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5229 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5231 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5232 pSMB->Reserved4 = 0;
5233 inc_rfc1001_len(pSMB, byte_count);
5234 pSMB->ByteCount = cpu_to_le16(byte_count);
5235 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5236 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5237 cifs_small_buf_release(pSMB);
5239 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5242 /* Note: On -EAGAIN error only caller can retry on handle based calls
5243 since file handle passed in no longer valid */
5249 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5250 bool delete_file, __u16 fid, __u32 pid_of_opener)
5252 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5255 __u16 params, param_offset, offset, byte_count, count;
5257 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5258 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5263 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5264 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5267 pSMB->MaxSetupCount = 0;
5271 pSMB->Reserved2 = 0;
5272 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5273 offset = param_offset + params;
5275 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5276 data_offset = (char *)(pSMB) + offset + 4;
5279 pSMB->MaxParameterCount = cpu_to_le16(2);
5280 /* BB find max SMB PDU from sess */
5281 pSMB->MaxDataCount = cpu_to_le16(1000);
5282 pSMB->SetupCount = 1;
5283 pSMB->Reserved3 = 0;
5284 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5285 byte_count = 3 /* pad */ + params + count;
5286 pSMB->DataCount = cpu_to_le16(count);
5287 pSMB->ParameterCount = cpu_to_le16(params);
5288 pSMB->TotalDataCount = pSMB->DataCount;
5289 pSMB->TotalParameterCount = pSMB->ParameterCount;
5290 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5291 pSMB->DataOffset = cpu_to_le16(offset);
5293 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5294 pSMB->Reserved4 = 0;
5295 inc_rfc1001_len(pSMB, byte_count);
5296 pSMB->ByteCount = cpu_to_le16(byte_count);
5297 *data_offset = delete_file ? 1 : 0;
5298 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5299 cifs_small_buf_release(pSMB);
5301 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5307 CIFSSMBSetPathInfoFB(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)
5313 struct cifs_open_parms oparms;
5314 struct cifs_fid fid;
5318 oparms.cifs_sb = cifs_sb;
5319 oparms.desired_access = GENERIC_WRITE;
5320 oparms.create_options = cifs_create_options(cifs_sb, 0);
5321 oparms.disposition = FILE_OPEN;
5322 oparms.path = fileName;
5324 oparms.reconnect = false;
5326 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5330 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5331 CIFSSMBClose(xid, tcon, fid.netfid);
5338 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5339 const char *fileName, const FILE_BASIC_INFO *data,
5340 const struct nls_table *nls_codepage,
5341 struct cifs_sb_info *cifs_sb)
5343 TRANSACTION2_SPI_REQ *pSMB = NULL;
5344 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5347 int bytes_returned = 0;
5349 __u16 params, param_offset, offset, byte_count, count;
5350 int remap = cifs_remap(cifs_sb);
5352 cifs_dbg(FYI, "In SetTimes\n");
5355 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5360 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5362 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5363 PATH_MAX, nls_codepage, remap);
5364 name_len++; /* trailing null */
5367 name_len = copy_path_name(pSMB->FileName, fileName);
5370 params = 6 + name_len;
5371 count = sizeof(FILE_BASIC_INFO);
5372 pSMB->MaxParameterCount = cpu_to_le16(2);
5373 /* BB find max SMB PDU from sess structure BB */
5374 pSMB->MaxDataCount = cpu_to_le16(1000);
5375 pSMB->MaxSetupCount = 0;
5379 pSMB->Reserved2 = 0;
5380 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5381 InformationLevel) - 4;
5382 offset = param_offset + params;
5383 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5384 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5385 pSMB->DataOffset = cpu_to_le16(offset);
5386 pSMB->SetupCount = 1;
5387 pSMB->Reserved3 = 0;
5388 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5389 byte_count = 3 /* pad */ + params + count;
5391 pSMB->DataCount = cpu_to_le16(count);
5392 pSMB->ParameterCount = cpu_to_le16(params);
5393 pSMB->TotalDataCount = pSMB->DataCount;
5394 pSMB->TotalParameterCount = pSMB->ParameterCount;
5395 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5396 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5398 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5399 pSMB->Reserved4 = 0;
5400 inc_rfc1001_len(pSMB, byte_count);
5401 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5402 pSMB->ByteCount = cpu_to_le16(byte_count);
5403 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5404 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5406 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5408 cifs_buf_release(pSMB);
5413 if (rc == -EOPNOTSUPP)
5414 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5415 nls_codepage, cifs_sb);
5421 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5422 const struct cifs_unix_set_info_args *args)
5424 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5425 u64 mode = args->mode;
5427 if (uid_valid(args->uid))
5428 uid = from_kuid(&init_user_ns, args->uid);
5429 if (gid_valid(args->gid))
5430 gid = from_kgid(&init_user_ns, args->gid);
5433 * Samba server ignores set of file size to zero due to bugs in some
5434 * older clients, but we should be precise - we use SetFileSize to
5435 * set file size and do not want to truncate file size to zero
5436 * accidentally as happened on one Samba server beta by putting
5437 * zero instead of -1 here
5439 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5440 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5441 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5442 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5443 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5444 data_offset->Uid = cpu_to_le64(uid);
5445 data_offset->Gid = cpu_to_le64(gid);
5446 /* better to leave device as zero when it is */
5447 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5448 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5449 data_offset->Permissions = cpu_to_le64(mode);
5452 data_offset->Type = cpu_to_le32(UNIX_FILE);
5453 else if (S_ISDIR(mode))
5454 data_offset->Type = cpu_to_le32(UNIX_DIR);
5455 else if (S_ISLNK(mode))
5456 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5457 else if (S_ISCHR(mode))
5458 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5459 else if (S_ISBLK(mode))
5460 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5461 else if (S_ISFIFO(mode))
5462 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5463 else if (S_ISSOCK(mode))
5464 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5468 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5469 const struct cifs_unix_set_info_args *args,
5470 u16 fid, u32 pid_of_opener)
5472 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5475 u16 params, param_offset, offset, byte_count, count;
5477 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5478 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5483 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5484 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5487 pSMB->MaxSetupCount = 0;
5491 pSMB->Reserved2 = 0;
5492 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5493 offset = param_offset + params;
5495 data_offset = (char *)pSMB +
5496 offsetof(struct smb_hdr, Protocol) + offset;
5498 count = sizeof(FILE_UNIX_BASIC_INFO);
5500 pSMB->MaxParameterCount = cpu_to_le16(2);
5501 /* BB find max SMB PDU from sess */
5502 pSMB->MaxDataCount = cpu_to_le16(1000);
5503 pSMB->SetupCount = 1;
5504 pSMB->Reserved3 = 0;
5505 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5506 byte_count = 3 /* pad */ + params + count;
5507 pSMB->DataCount = cpu_to_le16(count);
5508 pSMB->ParameterCount = cpu_to_le16(params);
5509 pSMB->TotalDataCount = pSMB->DataCount;
5510 pSMB->TotalParameterCount = pSMB->ParameterCount;
5511 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5512 pSMB->DataOffset = cpu_to_le16(offset);
5514 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5515 pSMB->Reserved4 = 0;
5516 inc_rfc1001_len(pSMB, byte_count);
5517 pSMB->ByteCount = cpu_to_le16(byte_count);
5519 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5521 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5522 cifs_small_buf_release(pSMB);
5524 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5527 /* Note: On -EAGAIN error only caller can retry on handle based calls
5528 since file handle passed in no longer valid */
5534 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5535 const char *file_name,
5536 const struct cifs_unix_set_info_args *args,
5537 const struct nls_table *nls_codepage, int remap)
5539 TRANSACTION2_SPI_REQ *pSMB = NULL;
5540 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5543 int bytes_returned = 0;
5544 FILE_UNIX_BASIC_INFO *data_offset;
5545 __u16 params, param_offset, offset, count, byte_count;
5547 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5549 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5554 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5556 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5557 PATH_MAX, nls_codepage, remap);
5558 name_len++; /* trailing null */
5561 name_len = copy_path_name(pSMB->FileName, file_name);
5564 params = 6 + name_len;
5565 count = sizeof(FILE_UNIX_BASIC_INFO);
5566 pSMB->MaxParameterCount = cpu_to_le16(2);
5567 /* BB find max SMB PDU from sess structure BB */
5568 pSMB->MaxDataCount = cpu_to_le16(1000);
5569 pSMB->MaxSetupCount = 0;
5573 pSMB->Reserved2 = 0;
5574 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5575 InformationLevel) - 4;
5576 offset = param_offset + params;
5577 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5578 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
5579 memset(data_offset, 0, count);
5580 pSMB->DataOffset = cpu_to_le16(offset);
5581 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5582 pSMB->SetupCount = 1;
5583 pSMB->Reserved3 = 0;
5584 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5585 byte_count = 3 /* pad */ + params + count;
5586 pSMB->ParameterCount = cpu_to_le16(params);
5587 pSMB->DataCount = cpu_to_le16(count);
5588 pSMB->TotalParameterCount = pSMB->ParameterCount;
5589 pSMB->TotalDataCount = pSMB->DataCount;
5590 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5591 pSMB->Reserved4 = 0;
5592 inc_rfc1001_len(pSMB, byte_count);
5594 cifs_fill_unix_set_info(data_offset, args);
5596 pSMB->ByteCount = cpu_to_le16(byte_count);
5597 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5598 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5600 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
5602 cifs_buf_release(pSMB);
5608 #ifdef CONFIG_CIFS_XATTR
5610 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
5611 * function used by listxattr and getxattr type calls. When ea_name is set,
5612 * it looks for that attribute name and stuffs that value into the EAData
5613 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
5614 * buffer. In both cases, the return value is either the length of the
5615 * resulting data or a negative error code. If EAData is a NULL pointer then
5616 * the data isn't copied to it, but the length is returned.
5619 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
5620 const unsigned char *searchName, const unsigned char *ea_name,
5621 char *EAData, size_t buf_size,
5622 struct cifs_sb_info *cifs_sb)
5624 /* BB assumes one setup word */
5625 TRANSACTION2_QPI_REQ *pSMB = NULL;
5626 TRANSACTION2_QPI_RSP *pSMBr = NULL;
5627 int remap = cifs_remap(cifs_sb);
5628 struct nls_table *nls_codepage = cifs_sb->local_nls;
5632 struct fealist *ea_response_data;
5633 struct fea *temp_fea;
5636 __u16 params, byte_count, data_offset;
5637 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
5639 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
5641 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5646 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5648 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
5649 PATH_MAX, nls_codepage, remap);
5650 list_len++; /* trailing null */
5653 list_len = copy_path_name(pSMB->FileName, searchName);
5656 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
5657 pSMB->TotalDataCount = 0;
5658 pSMB->MaxParameterCount = cpu_to_le16(2);
5659 /* BB find exact max SMB PDU from sess structure BB */
5660 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
5661 pSMB->MaxSetupCount = 0;
5665 pSMB->Reserved2 = 0;
5666 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5667 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5668 pSMB->DataCount = 0;
5669 pSMB->DataOffset = 0;
5670 pSMB->SetupCount = 1;
5671 pSMB->Reserved3 = 0;
5672 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
5673 byte_count = params + 1 /* pad */ ;
5674 pSMB->TotalParameterCount = cpu_to_le16(params);
5675 pSMB->ParameterCount = pSMB->TotalParameterCount;
5676 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5677 pSMB->Reserved4 = 0;
5678 inc_rfc1001_len(pSMB, byte_count);
5679 pSMB->ByteCount = cpu_to_le16(byte_count);
5681 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5682 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5684 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
5689 /* BB also check enough total bytes returned */
5690 /* BB we need to improve the validity checking
5691 of these trans2 responses */
5693 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5694 if (rc || get_bcc(&pSMBr->hdr) < 4) {
5695 rc = -EIO; /* bad smb */
5699 /* check that length of list is not more than bcc */
5700 /* check that each entry does not go beyond length
5702 /* check that each element of each entry does not
5703 go beyond end of list */
5704 /* validate_trans2_offsets() */
5705 /* BB check if start of smb + data_offset > &bcc+ bcc */
5707 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5708 ea_response_data = (struct fealist *)
5709 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5711 list_len = le32_to_cpu(ea_response_data->list_len);
5712 cifs_dbg(FYI, "ea length %d\n", list_len);
5713 if (list_len <= 8) {
5714 cifs_dbg(FYI, "empty EA list returned from server\n");
5715 /* didn't find the named attribute */
5721 /* make sure list_len doesn't go past end of SMB */
5722 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
5723 if ((char *)ea_response_data + list_len > end_of_smb) {
5724 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
5729 /* account for ea list len */
5731 temp_fea = ea_response_data->list;
5732 temp_ptr = (char *)temp_fea;
5733 while (list_len > 0) {
5734 unsigned int name_len;
5739 /* make sure we can read name_len and value_len */
5741 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5746 name_len = temp_fea->name_len;
5747 value_len = le16_to_cpu(temp_fea->value_len);
5748 list_len -= name_len + 1 + value_len;
5750 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5756 if (ea_name_len == name_len &&
5757 memcmp(ea_name, temp_ptr, name_len) == 0) {
5758 temp_ptr += name_len + 1;
5762 if ((size_t)value_len > buf_size) {
5766 memcpy(EAData, temp_ptr, value_len);
5770 /* account for prefix user. and trailing null */
5771 rc += (5 + 1 + name_len);
5772 if (rc < (int) buf_size) {
5773 memcpy(EAData, "user.", 5);
5775 memcpy(EAData, temp_ptr, name_len);
5777 /* null terminate name */
5780 } else if (buf_size == 0) {
5781 /* skip copy - calc size only */
5783 /* stop before overrun buffer */
5788 temp_ptr += name_len + 1 + value_len;
5789 temp_fea = (struct fea *)temp_ptr;
5792 /* didn't find the named attribute */
5797 cifs_buf_release(pSMB);
5805 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
5806 const char *fileName, const char *ea_name, const void *ea_value,
5807 const __u16 ea_value_len, const struct nls_table *nls_codepage,
5808 struct cifs_sb_info *cifs_sb)
5810 struct smb_com_transaction2_spi_req *pSMB = NULL;
5811 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5812 struct fealist *parm_data;
5815 int bytes_returned = 0;
5816 __u16 params, param_offset, byte_count, offset, count;
5817 int remap = cifs_remap(cifs_sb);
5819 cifs_dbg(FYI, "In SetEA\n");
5821 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5826 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5828 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5829 PATH_MAX, nls_codepage, remap);
5830 name_len++; /* trailing null */
5833 name_len = copy_path_name(pSMB->FileName, fileName);
5836 params = 6 + name_len;
5838 /* done calculating parms using name_len of file name,
5839 now use name_len to calculate length of ea name
5840 we are going to create in the inode xattrs */
5841 if (ea_name == NULL)
5844 name_len = strnlen(ea_name, 255);
5846 count = sizeof(*parm_data) + ea_value_len + name_len;
5847 pSMB->MaxParameterCount = cpu_to_le16(2);
5848 /* BB find max SMB PDU from sess */
5849 pSMB->MaxDataCount = cpu_to_le16(1000);
5850 pSMB->MaxSetupCount = 0;
5854 pSMB->Reserved2 = 0;
5855 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5856 InformationLevel) - 4;
5857 offset = param_offset + params;
5858 pSMB->InformationLevel =
5859 cpu_to_le16(SMB_SET_FILE_EA);
5861 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
5862 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5863 pSMB->DataOffset = cpu_to_le16(offset);
5864 pSMB->SetupCount = 1;
5865 pSMB->Reserved3 = 0;
5866 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5867 byte_count = 3 /* pad */ + params + count;
5868 pSMB->DataCount = cpu_to_le16(count);
5869 parm_data->list_len = cpu_to_le32(count);
5870 parm_data->list[0].EA_flags = 0;
5871 /* we checked above that name len is less than 255 */
5872 parm_data->list[0].name_len = (__u8)name_len;
5873 /* EA names are always ASCII */
5875 strncpy(parm_data->list[0].name, ea_name, name_len);
5876 parm_data->list[0].name[name_len] = 0;
5877 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
5878 /* caller ensures that ea_value_len is less than 64K but
5879 we need to ensure that it fits within the smb */
5881 /*BB add length check to see if it would fit in
5882 negotiated SMB buffer size BB */
5883 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
5885 memcpy(parm_data->list[0].name+name_len+1,
5886 ea_value, ea_value_len);
5888 pSMB->TotalDataCount = pSMB->DataCount;
5889 pSMB->ParameterCount = cpu_to_le16(params);
5890 pSMB->TotalParameterCount = pSMB->ParameterCount;
5891 pSMB->Reserved4 = 0;
5892 inc_rfc1001_len(pSMB, byte_count);
5893 pSMB->ByteCount = cpu_to_le16(byte_count);
5894 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5895 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5897 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
5899 cifs_buf_release(pSMB);