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/filelock.h>
19 #include <linux/kernel.h>
20 #include <linux/vfs.h>
21 #include <linux/slab.h>
22 #include <linux/posix_acl_xattr.h>
23 #include <linux/pagemap.h>
24 #include <linux/swap.h>
25 #include <linux/task_io_accounting_ops.h>
26 #include <linux/uaccess.h>
27 #include <linux/netfs.h>
28 #include <trace/events/netfs.h>
33 #include "cifsproto.h"
34 #include "cifs_unicode.h"
35 #include "cifs_debug.h"
37 #include "smbdirect.h"
38 #ifdef CONFIG_CIFS_DFS_UPCALL
39 #include "dfs_cache.h"
42 #ifdef CONFIG_CIFS_POSIX
47 {CIFS_PROT, "\2NT LM 0.12"},
48 {POSIX_PROT, "\2POSIX 2"},
56 {CIFS_PROT, "\2NT LM 0.12"},
61 /* define the number of elements in the cifs dialect array */
62 #ifdef CONFIG_CIFS_POSIX
63 #define CIFS_NUM_PROT 2
65 #define CIFS_NUM_PROT 1
66 #endif /* CIFS_POSIX */
69 /* reconnect the socket, tcon, and smb session if needed */
71 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
75 struct TCP_Server_Info *server;
76 struct nls_table *nls_codepage = NULL;
79 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
80 * tcp and smb session status done differently for those three - in the
90 * only tree disconnect, open, and write, (and ulogoff which does not
91 * have tcon) are allowed as we start umount
93 spin_lock(&tcon->tc_lock);
94 if (tcon->status == TID_EXITING) {
95 if (smb_command != SMB_COM_TREE_DISCONNECT) {
96 spin_unlock(&tcon->tc_lock);
97 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
102 spin_unlock(&tcon->tc_lock);
105 rc = cifs_wait_for_server_reconnect(server, tcon->retry);
109 spin_lock(&ses->chan_lock);
110 if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
111 spin_unlock(&ses->chan_lock);
114 spin_unlock(&ses->chan_lock);
116 mutex_lock(&ses->session_mutex);
118 * Recheck after acquire mutex. If another thread is negotiating
119 * and the server never sends an answer the socket will be closed
120 * and tcpStatus set to reconnect.
122 spin_lock(&server->srv_lock);
123 if (server->tcpStatus == CifsNeedReconnect) {
124 spin_unlock(&server->srv_lock);
125 mutex_unlock(&ses->session_mutex);
132 spin_unlock(&server->srv_lock);
134 nls_codepage = ses->local_nls;
137 * need to prevent multiple threads trying to simultaneously
138 * reconnect the same SMB session
140 spin_lock(&ses->ses_lock);
141 spin_lock(&ses->chan_lock);
142 if (!cifs_chan_needs_reconnect(ses, server) &&
143 ses->ses_status == SES_GOOD) {
144 spin_unlock(&ses->chan_lock);
145 spin_unlock(&ses->ses_lock);
147 /* this means that we only need to tree connect */
148 if (tcon->need_reconnect)
149 goto skip_sess_setup;
151 mutex_unlock(&ses->session_mutex);
154 spin_unlock(&ses->chan_lock);
155 spin_unlock(&ses->ses_lock);
157 rc = cifs_negotiate_protocol(0, ses, server);
159 rc = cifs_setup_session(0, ses, server, nls_codepage);
161 /* do we need to reconnect tcon? */
162 if (rc || !tcon->need_reconnect) {
163 mutex_unlock(&ses->session_mutex);
168 cifs_mark_open_files_invalid(tcon);
169 rc = cifs_tree_connect(0, tcon, nls_codepage);
170 mutex_unlock(&ses->session_mutex);
171 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
174 pr_warn_once("reconnect tcon failed rc = %d\n", rc);
178 atomic_inc(&tconInfoReconnectCount);
180 /* tell server Unix caps we support */
182 reset_cifs_unix_caps(0, tcon, NULL, NULL);
185 * Removed call to reopen open files here. It is safer (and faster) to
186 * reopen files one at a time as needed in read and write.
188 * FIXME: what about file locks? don't we need to reclaim them ASAP?
193 * Check if handle based operation so we know whether we can continue
194 * or not without returning to caller to reset file handle
196 switch (smb_command) {
197 case SMB_COM_READ_ANDX:
198 case SMB_COM_WRITE_ANDX:
200 case SMB_COM_FIND_CLOSE2:
201 case SMB_COM_LOCKING_ANDX:
208 /* Allocate and return pointer to an SMB request buffer, and set basic
209 SMB information in the SMB header. If the return code is zero, this
210 function must have filled in request_buf pointer */
212 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
217 rc = cifs_reconnect_tcon(tcon, smb_command);
221 *request_buf = cifs_small_buf_get();
222 if (*request_buf == NULL) {
223 /* BB should we add a retry in here if not a writepage? */
227 header_assemble((struct smb_hdr *) *request_buf, smb_command,
231 cifs_stats_inc(&tcon->num_smbs_sent);
237 small_smb_init_no_tc(const int smb_command, const int wct,
238 struct cifs_ses *ses, void **request_buf)
241 struct smb_hdr *buffer;
243 rc = small_smb_init(smb_command, wct, NULL, request_buf);
247 buffer = (struct smb_hdr *)*request_buf;
248 buffer->Mid = get_next_mid(ses->server);
249 if (ses->capabilities & CAP_UNICODE)
250 buffer->Flags2 |= SMBFLG2_UNICODE;
251 if (ses->capabilities & CAP_STATUS32)
252 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
254 /* uid, tid can stay at zero as set in header assemble */
256 /* BB add support for turning on the signing when
257 this function is used after 1st of session setup requests */
262 /* If the return code is zero, this function must fill in request_buf pointer */
264 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
265 void **request_buf, void **response_buf)
267 *request_buf = cifs_buf_get();
268 if (*request_buf == NULL) {
269 /* BB should we add a retry in here if not a writepage? */
272 /* Although the original thought was we needed the response buf for */
273 /* potential retries of smb operations it turns out we can determine */
274 /* from the mid flags when the request buffer can be resent without */
275 /* having to use a second distinct buffer for the response */
277 *response_buf = *request_buf;
279 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
283 cifs_stats_inc(&tcon->num_smbs_sent);
288 /* If the return code is zero, this function must fill in request_buf pointer */
290 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
291 void **request_buf, void **response_buf)
295 rc = cifs_reconnect_tcon(tcon, smb_command);
299 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
303 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
304 void **request_buf, void **response_buf)
306 spin_lock(&tcon->ses->chan_lock);
307 if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) ||
308 tcon->need_reconnect) {
309 spin_unlock(&tcon->ses->chan_lock);
312 spin_unlock(&tcon->ses->chan_lock);
314 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
317 static int validate_t2(struct smb_t2_rsp *pSMB)
319 unsigned int total_size;
321 /* check for plausible wct */
322 if (pSMB->hdr.WordCount < 10)
325 /* check for parm and data offset going beyond end of smb */
326 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
327 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
330 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
331 if (total_size >= 512)
334 /* check that bcc is at least as big as parms + data, and that it is
335 * less than negotiated smb buffer
337 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
338 if (total_size > get_bcc(&pSMB->hdr) ||
339 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
344 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
345 sizeof(struct smb_t2_rsp) + 16);
350 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
354 char *guid = pSMBr->u.extended_response.GUID;
355 struct TCP_Server_Info *server = ses->server;
357 count = get_bcc(&pSMBr->hdr);
358 if (count < SMB1_CLIENT_GUID_SIZE)
361 spin_lock(&cifs_tcp_ses_lock);
362 if (server->srv_count > 1) {
363 spin_unlock(&cifs_tcp_ses_lock);
364 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
365 cifs_dbg(FYI, "server UID changed\n");
366 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
369 spin_unlock(&cifs_tcp_ses_lock);
370 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
373 if (count == SMB1_CLIENT_GUID_SIZE) {
374 server->sec_ntlmssp = true;
376 count -= SMB1_CLIENT_GUID_SIZE;
377 rc = decode_negTokenInit(
378 pSMBr->u.extended_response.SecurityBlob, count, server);
387 should_set_ext_sec_flag(enum securityEnum sectype)
394 if (global_secflags &
395 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
404 CIFSSMBNegotiate(const unsigned int xid,
405 struct cifs_ses *ses,
406 struct TCP_Server_Info *server)
409 NEGOTIATE_RSP *pSMBr;
416 WARN(1, "%s: server is NULL!\n", __func__);
420 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
421 (void **) &pSMB, (void **) &pSMBr);
425 pSMB->hdr.Mid = get_next_mid(server);
426 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
428 if (should_set_ext_sec_flag(ses->sectype)) {
429 cifs_dbg(FYI, "Requesting extended security\n");
430 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
435 * We know that all the name entries in the protocols array
436 * are short (< 16 bytes anyway) and are NUL terminated.
438 for (i = 0; i < CIFS_NUM_PROT; i++) {
439 size_t len = strlen(protocols[i].name) + 1;
441 memcpy(&pSMB->DialectsArray[count], protocols[i].name, len);
444 inc_rfc1001_len(pSMB, count);
445 pSMB->ByteCount = cpu_to_le16(count);
447 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
448 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
452 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
453 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
454 /* Check wct = 1 error case */
455 if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
456 /* core returns wct = 1, but we do not ask for core - otherwise
457 small wct just comes when dialect index is -1 indicating we
458 could not negotiate a common dialect */
461 } else if (pSMBr->hdr.WordCount != 17) {
466 /* else wct == 17, NTLM or better */
468 server->sec_mode = pSMBr->SecurityMode;
469 if ((server->sec_mode & SECMODE_USER) == 0)
470 cifs_dbg(FYI, "share mode security\n");
472 /* one byte, so no need to convert this or EncryptionKeyLen from
474 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
476 set_credits(server, server->maxReq);
477 /* probably no need to store and check maxvcs */
478 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
479 /* set up max_read for readahead check */
480 server->max_read = server->maxBuf;
481 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
482 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
483 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
484 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
485 server->timeAdj *= 60;
487 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
488 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
489 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
490 CIFS_CRYPTO_KEY_SIZE);
491 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
492 server->capabilities & CAP_EXTENDED_SECURITY) {
493 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
494 rc = decode_ext_sec_blob(ses, pSMBr);
495 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
496 rc = -EIO; /* no crypt key only if plain text pwd */
498 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
499 server->capabilities &= ~CAP_EXTENDED_SECURITY;
503 rc = cifs_enable_signing(server, ses->sign);
505 cifs_buf_release(pSMB);
507 cifs_dbg(FYI, "negprot rc %d\n", rc);
512 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
514 struct smb_hdr *smb_buffer;
517 cifs_dbg(FYI, "In tree disconnect\n");
519 /* BB: do we need to check this? These should never be NULL. */
520 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
524 * No need to return error on this operation if tid invalidated and
525 * closed on server already e.g. due to tcp session crashing. Also,
526 * the tcon is no longer on the list, so no need to take lock before
529 spin_lock(&tcon->ses->chan_lock);
530 if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
531 spin_unlock(&tcon->ses->chan_lock);
534 spin_unlock(&tcon->ses->chan_lock);
536 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
537 (void **)&smb_buffer);
541 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
542 cifs_small_buf_release(smb_buffer);
544 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
546 /* No need to return error on this operation if tid invalidated and
547 closed on server already e.g. due to tcp session crashing */
555 * This is a no-op for now. We're not really interested in the reply, but
556 * rather in the fact that the server sent one and that server->lstrp
559 * FIXME: maybe we should consider checking that the reply matches request?
562 cifs_echo_callback(struct mid_q_entry *mid)
564 struct TCP_Server_Info *server = mid->callback_data;
565 struct cifs_credits credits = { .value = 1, .instance = 0 };
568 add_credits(server, &credits, CIFS_ECHO_OP);
572 CIFSSMBEcho(struct TCP_Server_Info *server)
577 struct smb_rqst rqst = { .rq_iov = iov,
580 cifs_dbg(FYI, "In echo request\n");
582 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
586 if (server->capabilities & CAP_UNICODE)
587 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
589 /* set up echo request */
590 smb->hdr.Tid = 0xffff;
591 smb->hdr.WordCount = 1;
592 put_unaligned_le16(1, &smb->EchoCount);
593 put_bcc(1, &smb->hdr);
595 inc_rfc1001_len(smb, 3);
598 iov[0].iov_base = smb;
599 iov[1].iov_len = get_rfc1002_length(smb);
600 iov[1].iov_base = (char *)smb + 4;
602 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
603 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
605 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
607 cifs_small_buf_release(smb);
613 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
615 LOGOFF_ANDX_REQ *pSMB;
618 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
621 * BB: do we need to check validity of ses and server? They should
622 * always be valid since we have an active reference. If not, that
623 * should probably be a BUG()
625 if (!ses || !ses->server)
628 mutex_lock(&ses->session_mutex);
629 spin_lock(&ses->chan_lock);
630 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
631 spin_unlock(&ses->chan_lock);
632 goto session_already_dead; /* no need to send SMBlogoff if uid
633 already closed due to reconnect */
635 spin_unlock(&ses->chan_lock);
637 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
639 mutex_unlock(&ses->session_mutex);
643 pSMB->hdr.Mid = get_next_mid(ses->server);
645 if (ses->server->sign)
646 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
648 pSMB->hdr.Uid = ses->Suid;
650 pSMB->AndXCommand = 0xFF;
651 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
652 cifs_small_buf_release(pSMB);
653 session_already_dead:
654 mutex_unlock(&ses->session_mutex);
656 /* if session dead then we do not need to do ulogoff,
657 since server closed smb session, no sense reporting
665 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
666 const char *fileName, __u16 type,
667 const struct nls_table *nls_codepage, int remap)
669 TRANSACTION2_SPI_REQ *pSMB = NULL;
670 TRANSACTION2_SPI_RSP *pSMBr = NULL;
671 struct unlink_psx_rq *pRqD;
674 int bytes_returned = 0;
675 __u16 params, param_offset, offset, byte_count;
677 cifs_dbg(FYI, "In POSIX delete\n");
679 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
684 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
686 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
687 PATH_MAX, nls_codepage, remap);
688 name_len++; /* trailing null */
691 name_len = copy_path_name(pSMB->FileName, fileName);
694 params = 6 + name_len;
695 pSMB->MaxParameterCount = cpu_to_le16(2);
696 pSMB->MaxDataCount = 0; /* BB double check this with jra */
697 pSMB->MaxSetupCount = 0;
702 param_offset = offsetof(struct smb_com_transaction2_spi_req,
703 InformationLevel) - 4;
704 offset = param_offset + params;
706 /* Setup pointer to Request Data (inode type).
707 * Note that SMB offsets are from the beginning of SMB which is 4 bytes
708 * in, after RFC1001 field
710 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
711 pRqD->type = cpu_to_le16(type);
712 pSMB->ParameterOffset = cpu_to_le16(param_offset);
713 pSMB->DataOffset = cpu_to_le16(offset);
714 pSMB->SetupCount = 1;
716 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
717 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
719 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
720 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
721 pSMB->ParameterCount = cpu_to_le16(params);
722 pSMB->TotalParameterCount = pSMB->ParameterCount;
723 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
725 inc_rfc1001_len(pSMB, byte_count);
726 pSMB->ByteCount = cpu_to_le16(byte_count);
727 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
728 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
730 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
731 cifs_buf_release(pSMB);
733 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
742 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
743 struct cifs_sb_info *cifs_sb, struct dentry *dentry)
745 DELETE_FILE_REQ *pSMB = NULL;
746 DELETE_FILE_RSP *pSMBr = NULL;
750 int remap = cifs_remap(cifs_sb);
753 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
758 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
759 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
760 PATH_MAX, cifs_sb->local_nls,
762 name_len++; /* trailing null */
765 name_len = copy_path_name(pSMB->fileName, name);
767 pSMB->SearchAttributes =
768 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
769 pSMB->BufferFormat = 0x04;
770 inc_rfc1001_len(pSMB, name_len + 1);
771 pSMB->ByteCount = cpu_to_le16(name_len + 1);
772 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
773 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
774 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
776 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
778 cifs_buf_release(pSMB);
786 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
787 struct cifs_sb_info *cifs_sb)
789 DELETE_DIRECTORY_REQ *pSMB = NULL;
790 DELETE_DIRECTORY_RSP *pSMBr = NULL;
794 int remap = cifs_remap(cifs_sb);
796 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
798 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
803 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
804 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
805 PATH_MAX, cifs_sb->local_nls,
807 name_len++; /* trailing null */
810 name_len = copy_path_name(pSMB->DirName, name);
813 pSMB->BufferFormat = 0x04;
814 inc_rfc1001_len(pSMB, name_len + 1);
815 pSMB->ByteCount = cpu_to_le16(name_len + 1);
816 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
817 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
818 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
820 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
822 cifs_buf_release(pSMB);
829 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
830 struct cifs_tcon *tcon, const char *name,
831 struct cifs_sb_info *cifs_sb)
834 CREATE_DIRECTORY_REQ *pSMB = NULL;
835 CREATE_DIRECTORY_RSP *pSMBr = NULL;
838 int remap = cifs_remap(cifs_sb);
840 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
842 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
847 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
848 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
849 PATH_MAX, cifs_sb->local_nls,
851 name_len++; /* trailing null */
854 name_len = copy_path_name(pSMB->DirName, name);
857 pSMB->BufferFormat = 0x04;
858 inc_rfc1001_len(pSMB, name_len + 1);
859 pSMB->ByteCount = cpu_to_le16(name_len + 1);
860 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
861 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
862 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
864 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
866 cifs_buf_release(pSMB);
873 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
874 __u32 posix_flags, __u64 mode, __u16 *netfid,
875 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
876 const char *name, const struct nls_table *nls_codepage,
879 TRANSACTION2_SPI_REQ *pSMB = NULL;
880 TRANSACTION2_SPI_RSP *pSMBr = NULL;
883 int bytes_returned = 0;
884 __u16 params, param_offset, offset, byte_count, count;
886 OPEN_PSX_RSP *psx_rsp;
888 cifs_dbg(FYI, "In POSIX Create\n");
890 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
895 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
897 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
898 PATH_MAX, nls_codepage, remap);
899 name_len++; /* trailing null */
902 name_len = copy_path_name(pSMB->FileName, name);
905 params = 6 + name_len;
906 count = sizeof(OPEN_PSX_REQ);
907 pSMB->MaxParameterCount = cpu_to_le16(2);
908 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
909 pSMB->MaxSetupCount = 0;
914 param_offset = offsetof(struct smb_com_transaction2_spi_req,
915 InformationLevel) - 4;
916 offset = param_offset + params;
917 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
918 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
919 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
920 pdata->Permissions = cpu_to_le64(mode);
921 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
922 pdata->OpenFlags = cpu_to_le32(*pOplock);
923 pSMB->ParameterOffset = cpu_to_le16(param_offset);
924 pSMB->DataOffset = cpu_to_le16(offset);
925 pSMB->SetupCount = 1;
927 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
928 byte_count = 3 /* pad */ + params + count;
930 pSMB->DataCount = cpu_to_le16(count);
931 pSMB->ParameterCount = cpu_to_le16(params);
932 pSMB->TotalDataCount = pSMB->DataCount;
933 pSMB->TotalParameterCount = pSMB->ParameterCount;
934 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
936 inc_rfc1001_len(pSMB, byte_count);
937 pSMB->ByteCount = cpu_to_le16(byte_count);
938 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
939 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
941 cifs_dbg(FYI, "Posix create returned %d\n", rc);
945 cifs_dbg(FYI, "copying inode info\n");
946 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
948 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
949 rc = -EIO; /* bad smb */
953 /* copy return information to pRetData */
954 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
955 + le16_to_cpu(pSMBr->t2.DataOffset));
957 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
959 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
960 /* Let caller know file was created so we can set the mode. */
961 /* Do we care about the CreateAction in any other cases? */
962 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
963 *pOplock |= CIFS_CREATE_ACTION;
964 /* check to make sure response data is there */
965 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
966 pRetData->Type = cpu_to_le32(-1); /* unknown */
967 cifs_dbg(NOISY, "unknown type\n");
969 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
970 + sizeof(FILE_UNIX_BASIC_INFO)) {
971 cifs_dbg(VFS, "Open response data too small\n");
972 pRetData->Type = cpu_to_le32(-1);
975 memcpy((char *) pRetData,
976 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
977 sizeof(FILE_UNIX_BASIC_INFO));
981 cifs_buf_release(pSMB);
983 if (posix_flags & SMB_O_DIRECTORY)
984 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
986 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
994 static __u16 convert_disposition(int disposition)
998 switch (disposition) {
1000 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1003 ofun = SMBOPEN_OAPPEND;
1006 ofun = SMBOPEN_OCREATE;
1009 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1011 case FILE_OVERWRITE:
1012 ofun = SMBOPEN_OTRUNC;
1014 case FILE_OVERWRITE_IF:
1015 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1018 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1019 ofun = SMBOPEN_OAPPEND; /* regular open */
1025 access_flags_to_smbopen_mode(const int access_flags)
1027 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1029 if (masked_flags == GENERIC_READ)
1030 return SMBOPEN_READ;
1031 else if (masked_flags == GENERIC_WRITE)
1032 return SMBOPEN_WRITE;
1034 /* just go for read/write */
1035 return SMBOPEN_READWRITE;
1039 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1040 const char *fileName, const int openDisposition,
1041 const int access_flags, const int create_options, __u16 *netfid,
1042 int *pOplock, FILE_ALL_INFO *pfile_info,
1043 const struct nls_table *nls_codepage, int remap)
1046 OPENX_REQ *pSMB = NULL;
1047 OPENX_RSP *pSMBr = NULL;
1053 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1058 pSMB->AndXCommand = 0xFF; /* none */
1060 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1061 count = 1; /* account for one byte pad to word boundary */
1063 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1064 fileName, PATH_MAX, nls_codepage, remap);
1065 name_len++; /* trailing null */
1068 count = 0; /* no pad */
1069 name_len = copy_path_name(pSMB->fileName, fileName);
1071 if (*pOplock & REQ_OPLOCK)
1072 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1073 else if (*pOplock & REQ_BATCHOPLOCK)
1074 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1076 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1077 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1078 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1079 /* set file as system file if special file such
1080 as fifo and server expecting SFU style and
1081 no Unix extensions */
1083 if (create_options & CREATE_OPTION_SPECIAL)
1084 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1085 else /* BB FIXME BB */
1086 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1088 if (create_options & CREATE_OPTION_READONLY)
1089 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1092 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1093 CREATE_OPTIONS_MASK); */
1094 /* BB FIXME END BB */
1096 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1097 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1099 inc_rfc1001_len(pSMB, count);
1101 pSMB->ByteCount = cpu_to_le16(count);
1102 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1103 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1104 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1106 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1108 /* BB verify if wct == 15 */
1110 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1112 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1113 /* Let caller know file was created so we can set the mode. */
1114 /* Do we care about the CreateAction in any other cases? */
1116 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1117 *pOplock |= CIFS_CREATE_ACTION; */
1121 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1122 pfile_info->LastAccessTime = 0; /* BB fixme */
1123 pfile_info->LastWriteTime = 0; /* BB fixme */
1124 pfile_info->ChangeTime = 0; /* BB fixme */
1125 pfile_info->Attributes =
1126 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1127 /* the file_info buf is endian converted by caller */
1128 pfile_info->AllocationSize =
1129 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1130 pfile_info->EndOfFile = pfile_info->AllocationSize;
1131 pfile_info->NumberOfLinks = cpu_to_le32(1);
1132 pfile_info->DeletePending = 0;
1136 cifs_buf_release(pSMB);
1143 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1147 OPEN_REQ *req = NULL;
1148 OPEN_RSP *rsp = NULL;
1152 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1153 struct cifs_tcon *tcon = oparms->tcon;
1154 int remap = cifs_remap(cifs_sb);
1155 const struct nls_table *nls = cifs_sb->local_nls;
1156 int create_options = oparms->create_options;
1157 int desired_access = oparms->desired_access;
1158 int disposition = oparms->disposition;
1159 const char *path = oparms->path;
1162 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1167 /* no commands go after this */
1168 req->AndXCommand = 0xFF;
1170 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1171 /* account for one byte pad to word boundary */
1173 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1174 path, PATH_MAX, nls, remap);
1178 req->NameLength = cpu_to_le16(name_len);
1180 /* BB improve check for buffer overruns BB */
1183 name_len = copy_path_name(req->fileName, path);
1184 req->NameLength = cpu_to_le16(name_len);
1187 if (*oplock & REQ_OPLOCK)
1188 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1189 else if (*oplock & REQ_BATCHOPLOCK)
1190 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1192 req->DesiredAccess = cpu_to_le32(desired_access);
1193 req->AllocationSize = 0;
1196 * Set file as system file if special file such as fifo and server
1197 * expecting SFU style and no Unix extensions.
1199 if (create_options & CREATE_OPTION_SPECIAL)
1200 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1202 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1205 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1206 * sensitive checks for other servers such as Samba.
1208 if (tcon->ses->capabilities & CAP_UNIX)
1209 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1211 if (create_options & CREATE_OPTION_READONLY)
1212 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1214 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1215 req->CreateDisposition = cpu_to_le32(disposition);
1216 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1218 /* BB Expirement with various impersonation levels and verify */
1219 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1220 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1223 inc_rfc1001_len(req, count);
1225 req->ByteCount = cpu_to_le16(count);
1226 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1227 (struct smb_hdr *)rsp, &bytes_returned, 0);
1228 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1230 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1231 cifs_buf_release(req);
1237 /* 1 byte no need to le_to_cpu */
1238 *oplock = rsp->OplockLevel;
1239 /* cifs fid stays in le */
1240 oparms->fid->netfid = rsp->Fid;
1241 oparms->fid->access = desired_access;
1243 /* Let caller know file was created so we can set the mode. */
1244 /* Do we care about the CreateAction in any other cases? */
1245 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1246 *oplock |= CIFS_CREATE_ACTION;
1249 /* copy commonly used attributes */
1250 memcpy(&buf->common_attributes,
1251 &rsp->common_attributes,
1252 sizeof(buf->common_attributes));
1253 /* the file_info buf is endian converted by caller */
1254 buf->AllocationSize = rsp->AllocationSize;
1255 buf->EndOfFile = rsp->EndOfFile;
1256 buf->NumberOfLinks = cpu_to_le32(1);
1257 buf->DeletePending = 0;
1260 cifs_buf_release(req);
1264 static void cifs_readv_worker(struct work_struct *work)
1266 struct cifs_io_subrequest *rdata =
1267 container_of(work, struct cifs_io_subrequest, subreq.work);
1269 netfs_subreq_terminated(&rdata->subreq,
1270 (rdata->result == 0 || rdata->result == -EAGAIN) ?
1271 rdata->got_bytes : rdata->result, true);
1275 cifs_readv_callback(struct mid_q_entry *mid)
1277 struct cifs_io_subrequest *rdata = mid->callback_data;
1278 struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode);
1279 struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
1280 struct TCP_Server_Info *server = tcon->ses->server;
1281 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1283 .rq_iter = rdata->subreq.io_iter };
1284 struct cifs_credits credits = {
1287 .rreq_debug_id = rdata->rreq->debug_id,
1288 .rreq_debug_index = rdata->subreq.debug_index,
1291 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n",
1292 __func__, mid->mid, mid->mid_state, rdata->result,
1295 switch (mid->mid_state) {
1296 case MID_RESPONSE_RECEIVED:
1297 /* result already set, check signature */
1301 iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes);
1302 rc = cifs_verify_signature(&rqst, server,
1303 mid->sequence_number);
1305 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1308 /* FIXME: should this be counted toward the initiating task? */
1309 task_io_account_read(rdata->got_bytes);
1310 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1312 case MID_REQUEST_SUBMITTED:
1313 case MID_RETRY_NEEDED:
1314 rdata->result = -EAGAIN;
1315 if (server->sign && rdata->got_bytes)
1316 /* reset bytes number since we can not check a sign */
1317 rdata->got_bytes = 0;
1318 /* FIXME: should this be counted toward the initiating task? */
1319 task_io_account_read(rdata->got_bytes);
1320 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1323 rdata->result = -EIO;
1326 if (rdata->result == -ENODATA) {
1327 __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
1330 if (rdata->got_bytes < rdata->actual_len &&
1331 rdata->subreq.start + rdata->subreq.transferred + rdata->got_bytes ==
1332 ictx->remote_i_size) {
1333 __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
1338 rdata->credits.value = 0;
1339 INIT_WORK(&rdata->subreq.work, cifs_readv_worker);
1340 queue_work(cifsiod_wq, &rdata->subreq.work);
1342 add_credits(server, &credits, 0);
1345 /* cifs_async_readv - send an async write, and set up mid to handle result */
1347 cifs_async_readv(struct cifs_io_subrequest *rdata)
1350 READ_REQ *smb = NULL;
1352 struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
1353 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1356 cifs_dbg(FYI, "%s: offset=%llu bytes=%zu\n",
1357 __func__, rdata->subreq.start, rdata->subreq.len);
1359 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1362 wct = 10; /* old style read */
1363 if ((rdata->subreq.start >> 32) > 0) {
1364 /* can not handle this big offset for old */
1369 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1373 smb->hdr.Pid = cpu_to_le16((__u16)rdata->req->pid);
1374 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->req->pid >> 16));
1376 smb->AndXCommand = 0xFF; /* none */
1377 smb->Fid = rdata->req->cfile->fid.netfid;
1378 smb->OffsetLow = cpu_to_le32(rdata->subreq.start & 0xFFFFFFFF);
1380 smb->OffsetHigh = cpu_to_le32(rdata->subreq.start >> 32);
1382 smb->MaxCount = cpu_to_le16(rdata->subreq.len & 0xFFFF);
1383 smb->MaxCountHigh = cpu_to_le32(rdata->subreq.len >> 16);
1387 /* old style read */
1388 struct smb_com_readx_req *smbr =
1389 (struct smb_com_readx_req *)smb;
1390 smbr->ByteCount = 0;
1393 /* 4 for RFC1001 length + 1 for BCC */
1394 rdata->iov[0].iov_base = smb;
1395 rdata->iov[0].iov_len = 4;
1396 rdata->iov[1].iov_base = (char *)smb + 4;
1397 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1399 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1400 cifs_readv_callback, NULL, rdata, 0, NULL);
1403 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1404 cifs_small_buf_release(smb);
1409 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1410 unsigned int *nbytes, char **buf, int *pbuf_type)
1413 READ_REQ *pSMB = NULL;
1414 READ_RSP *pSMBr = NULL;
1415 char *pReadData = NULL;
1417 int resp_buf_type = 0;
1419 struct kvec rsp_iov;
1420 __u32 pid = io_parms->pid;
1421 __u16 netfid = io_parms->netfid;
1422 __u64 offset = io_parms->offset;
1423 struct cifs_tcon *tcon = io_parms->tcon;
1424 unsigned int count = io_parms->length;
1426 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1427 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1430 wct = 10; /* old style read */
1431 if ((offset >> 32) > 0) {
1432 /* can not handle this big offset for old */
1438 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1442 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1443 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1445 /* tcon and ses pointer are checked in smb_init */
1446 if (tcon->ses->server == NULL)
1447 return -ECONNABORTED;
1449 pSMB->AndXCommand = 0xFF; /* none */
1451 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1453 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1455 pSMB->Remaining = 0;
1456 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1457 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1459 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1461 /* old style read */
1462 struct smb_com_readx_req *pSMBW =
1463 (struct smb_com_readx_req *)pSMB;
1464 pSMBW->ByteCount = 0;
1467 iov[0].iov_base = (char *)pSMB;
1468 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1469 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1470 CIFS_LOG_ERROR, &rsp_iov);
1471 cifs_small_buf_release(pSMB);
1472 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1473 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1475 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1477 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1478 data_length = data_length << 16;
1479 data_length += le16_to_cpu(pSMBr->DataLength);
1480 *nbytes = data_length;
1482 /*check that DataLength would not go beyond end of SMB */
1483 if ((data_length > CIFSMaxBufSize)
1484 || (data_length > count)) {
1485 cifs_dbg(FYI, "bad length %d for count %d\n",
1486 data_length, count);
1490 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1491 le16_to_cpu(pSMBr->DataOffset);
1492 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1493 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1495 }*/ /* can not use copy_to_user when using page cache*/
1497 memcpy(*buf, pReadData, data_length);
1502 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1503 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1504 /* return buffer to caller to free */
1505 *buf = rsp_iov.iov_base;
1506 if (resp_buf_type == CIFS_SMALL_BUFFER)
1507 *pbuf_type = CIFS_SMALL_BUFFER;
1508 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1509 *pbuf_type = CIFS_LARGE_BUFFER;
1510 } /* else no valid buffer on return - leave as null */
1512 /* Note: On -EAGAIN error only caller can retry on handle based calls
1513 since file handle passed in no longer valid */
1519 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1520 unsigned int *nbytes, const char *buf)
1523 WRITE_REQ *pSMB = NULL;
1524 WRITE_RSP *pSMBr = NULL;
1525 int bytes_returned, wct;
1528 __u32 pid = io_parms->pid;
1529 __u16 netfid = io_parms->netfid;
1530 __u64 offset = io_parms->offset;
1531 struct cifs_tcon *tcon = io_parms->tcon;
1532 unsigned int count = io_parms->length;
1536 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1537 if (tcon->ses == NULL)
1538 return -ECONNABORTED;
1540 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1544 if ((offset >> 32) > 0) {
1545 /* can not handle big offset for old srv */
1550 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1555 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1556 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1558 /* tcon and ses pointer are checked in smb_init */
1559 if (tcon->ses->server == NULL)
1560 return -ECONNABORTED;
1562 pSMB->AndXCommand = 0xFF; /* none */
1564 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1566 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1568 pSMB->Reserved = 0xFFFFFFFF;
1569 pSMB->WriteMode = 0;
1570 pSMB->Remaining = 0;
1572 /* Can increase buffer size if buffer is big enough in some cases ie we
1573 can send more if LARGE_WRITE_X capability returned by the server and if
1574 our buffer is big enough or if we convert to iovecs on socket writes
1575 and eliminate the copy to the CIFS buffer */
1576 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1577 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1579 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1583 if (bytes_sent > count)
1586 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1588 memcpy(pSMB->Data, buf, bytes_sent);
1589 else if (count != 0) {
1591 cifs_buf_release(pSMB);
1593 } /* else setting file size with write of zero bytes */
1595 byte_count = bytes_sent + 1; /* pad */
1596 else /* wct == 12 */
1597 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1599 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1600 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1601 inc_rfc1001_len(pSMB, byte_count);
1604 pSMB->ByteCount = cpu_to_le16(byte_count);
1605 else { /* old style write has byte count 4 bytes earlier
1607 struct smb_com_writex_req *pSMBW =
1608 (struct smb_com_writex_req *)pSMB;
1609 pSMBW->ByteCount = cpu_to_le16(byte_count);
1612 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1613 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1614 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1616 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1618 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1619 *nbytes = (*nbytes) << 16;
1620 *nbytes += le16_to_cpu(pSMBr->Count);
1623 * Mask off high 16 bits when bytes written as returned by the
1624 * server is greater than bytes requested by the client. Some
1625 * OS/2 servers are known to set incorrect CountHigh values.
1627 if (*nbytes > count)
1631 cifs_buf_release(pSMB);
1633 /* Note: On -EAGAIN error only caller can retry on handle based calls
1634 since file handle passed in no longer valid */
1640 * Check the mid_state and signature on received buffer (if any), and queue the
1641 * workqueue completion task.
1644 cifs_writev_callback(struct mid_q_entry *mid)
1646 struct cifs_io_subrequest *wdata = mid->callback_data;
1647 struct TCP_Server_Info *server = wdata->server;
1648 struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
1649 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1650 struct cifs_credits credits = {
1653 .rreq_debug_id = wdata->rreq->debug_id,
1654 .rreq_debug_index = wdata->subreq.debug_index,
1659 switch (mid->mid_state) {
1660 case MID_RESPONSE_RECEIVED:
1661 result = cifs_check_receive(mid, tcon->ses->server, 0);
1665 written = le16_to_cpu(smb->CountHigh);
1667 written += le16_to_cpu(smb->Count);
1669 * Mask off high 16 bits when bytes written as returned
1670 * by the server is greater than bytes requested by the
1671 * client. OS/2 servers are known to set incorrect
1674 if (written > wdata->subreq.len)
1677 if (written < wdata->subreq.len)
1682 case MID_REQUEST_SUBMITTED:
1683 case MID_RETRY_NEEDED:
1691 trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index,
1692 wdata->credits.value,
1693 server->credits, server->in_flight,
1694 0, cifs_trace_rw_credits_write_response_clear);
1695 wdata->credits.value = 0;
1696 cifs_write_subrequest_terminated(wdata, result, true);
1698 trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0,
1699 server->credits, server->in_flight,
1700 credits.value, cifs_trace_rw_credits_write_response_add);
1701 add_credits(tcon->ses->server, &credits, 0);
1704 /* cifs_async_writev - send an async write, and set up mid to handle result */
1706 cifs_async_writev(struct cifs_io_subrequest *wdata)
1709 WRITE_REQ *smb = NULL;
1711 struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
1713 struct smb_rqst rqst = { };
1715 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1719 if (wdata->subreq.start >> 32 > 0) {
1720 /* can not handle big offset for old srv */
1726 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
1728 goto async_writev_out;
1730 smb->hdr.Pid = cpu_to_le16((__u16)wdata->req->pid);
1731 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->req->pid >> 16));
1733 smb->AndXCommand = 0xFF; /* none */
1734 smb->Fid = wdata->req->cfile->fid.netfid;
1735 smb->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF);
1737 smb->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32);
1738 smb->Reserved = 0xFFFFFFFF;
1743 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1745 /* 4 for RFC1001 length + 1 for BCC */
1747 iov[0].iov_base = smb;
1748 iov[1].iov_len = get_rfc1002_length(smb) + 1;
1749 iov[1].iov_base = (char *)smb + 4;
1753 rqst.rq_iter = wdata->subreq.io_iter;
1755 cifs_dbg(FYI, "async write at %llu %zu bytes\n",
1756 wdata->subreq.start, wdata->subreq.len);
1758 smb->DataLengthLow = cpu_to_le16(wdata->subreq.len & 0xFFFF);
1759 smb->DataLengthHigh = cpu_to_le16(wdata->subreq.len >> 16);
1762 inc_rfc1001_len(&smb->hdr, wdata->subreq.len + 1);
1763 put_bcc(wdata->subreq.len + 1, &smb->hdr);
1766 struct smb_com_writex_req *smbw =
1767 (struct smb_com_writex_req *)smb;
1768 inc_rfc1001_len(&smbw->hdr, wdata->subreq.len + 5);
1769 put_bcc(wdata->subreq.len + 5, &smbw->hdr);
1770 iov[1].iov_len += 4; /* pad bigger by four bytes */
1773 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
1774 cifs_writev_callback, NULL, wdata, 0, NULL);
1775 /* Can't touch wdata if rc == 0 */
1777 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1780 cifs_small_buf_release(smb);
1783 add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
1784 cifs_write_subrequest_terminated(wdata, rc, false);
1789 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
1790 unsigned int *nbytes, struct kvec *iov, int n_vec)
1793 WRITE_REQ *pSMB = NULL;
1796 int resp_buf_type = 0;
1797 __u32 pid = io_parms->pid;
1798 __u16 netfid = io_parms->netfid;
1799 __u64 offset = io_parms->offset;
1800 struct cifs_tcon *tcon = io_parms->tcon;
1801 unsigned int count = io_parms->length;
1802 struct kvec rsp_iov;
1806 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
1808 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1812 if ((offset >> 32) > 0) {
1813 /* can not handle big offset for old srv */
1817 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
1821 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1822 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1824 /* tcon and ses pointer are checked in smb_init */
1825 if (tcon->ses->server == NULL)
1826 return -ECONNABORTED;
1828 pSMB->AndXCommand = 0xFF; /* none */
1830 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1832 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1833 pSMB->Reserved = 0xFFFFFFFF;
1834 pSMB->WriteMode = 0;
1835 pSMB->Remaining = 0;
1838 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1840 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1841 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1842 /* header + 1 byte pad */
1843 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
1845 inc_rfc1001_len(pSMB, count + 1);
1846 else /* wct == 12 */
1847 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
1849 pSMB->ByteCount = cpu_to_le16(count + 1);
1850 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1851 struct smb_com_writex_req *pSMBW =
1852 (struct smb_com_writex_req *)pSMB;
1853 pSMBW->ByteCount = cpu_to_le16(count + 5);
1855 iov[0].iov_base = pSMB;
1857 iov[0].iov_len = smb_hdr_len + 4;
1858 else /* wct == 12 pad bigger by four bytes */
1859 iov[0].iov_len = smb_hdr_len + 8;
1861 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
1863 cifs_small_buf_release(pSMB);
1864 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1866 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
1867 } else if (resp_buf_type == 0) {
1868 /* presumably this can not happen, but best to be safe */
1871 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
1872 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1873 *nbytes = (*nbytes) << 16;
1874 *nbytes += le16_to_cpu(pSMBr->Count);
1877 * Mask off high 16 bits when bytes written as returned by the
1878 * server is greater than bytes requested by the client. OS/2
1879 * servers are known to set incorrect CountHigh values.
1881 if (*nbytes > count)
1885 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1887 /* Note: On -EAGAIN error only caller can retry on handle based calls
1888 since file handle passed in no longer valid */
1893 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
1894 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
1895 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
1898 LOCK_REQ *pSMB = NULL;
1900 struct kvec rsp_iov;
1904 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
1905 num_lock, num_unlock);
1907 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1912 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
1913 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
1914 pSMB->LockType = lock_type;
1915 pSMB->AndXCommand = 0xFF; /* none */
1916 pSMB->Fid = netfid; /* netfid stays le */
1918 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1919 inc_rfc1001_len(pSMB, count);
1920 pSMB->ByteCount = cpu_to_le16(count);
1922 iov[0].iov_base = (char *)pSMB;
1923 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
1924 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1925 iov[1].iov_base = (char *)buf;
1926 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1928 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1929 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
1930 CIFS_NO_RSP_BUF, &rsp_iov);
1931 cifs_small_buf_release(pSMB);
1933 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
1939 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
1940 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
1941 const __u64 offset, const __u32 numUnlock,
1942 const __u32 numLock, const __u8 lockType,
1943 const bool waitFlag, const __u8 oplock_level)
1946 LOCK_REQ *pSMB = NULL;
1947 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
1952 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
1953 (int)waitFlag, numLock);
1954 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1959 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1960 /* no response expected */
1961 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
1963 } else if (waitFlag) {
1964 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1965 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
1970 pSMB->NumberOfLocks = cpu_to_le16(numLock);
1971 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
1972 pSMB->LockType = lockType;
1973 pSMB->OplockLevel = oplock_level;
1974 pSMB->AndXCommand = 0xFF; /* none */
1975 pSMB->Fid = smb_file_id; /* netfid stays le */
1977 if ((numLock != 0) || (numUnlock != 0)) {
1978 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
1979 /* BB where to store pid high? */
1980 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
1981 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
1982 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
1983 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
1984 count = sizeof(LOCKING_ANDX_RANGE);
1989 inc_rfc1001_len(pSMB, count);
1990 pSMB->ByteCount = cpu_to_le16(count);
1993 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1994 (struct smb_hdr *) pSMB, &bytes_returned);
1996 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
1997 cifs_small_buf_release(pSMB);
1998 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2000 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2002 /* Note: On -EAGAIN error only caller can retry on handle based calls
2003 since file handle passed in no longer valid */
2008 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2009 const __u16 smb_file_id, const __u32 netpid,
2010 const loff_t start_offset, const __u64 len,
2011 struct file_lock *pLockData, const __u16 lock_type,
2012 const bool waitFlag)
2014 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2015 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2016 struct cifs_posix_lock *parm_data;
2019 int bytes_returned = 0;
2020 int resp_buf_type = 0;
2021 __u16 params, param_offset, offset, byte_count, count;
2023 struct kvec rsp_iov;
2025 cifs_dbg(FYI, "Posix Lock\n");
2027 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2032 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2035 pSMB->MaxSetupCount = 0;
2038 pSMB->Reserved2 = 0;
2039 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2040 offset = param_offset + params;
2042 count = sizeof(struct cifs_posix_lock);
2043 pSMB->MaxParameterCount = cpu_to_le16(2);
2044 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2045 pSMB->SetupCount = 1;
2046 pSMB->Reserved3 = 0;
2048 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2050 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2051 byte_count = 3 /* pad */ + params + count;
2052 pSMB->DataCount = cpu_to_le16(count);
2053 pSMB->ParameterCount = cpu_to_le16(params);
2054 pSMB->TotalDataCount = pSMB->DataCount;
2055 pSMB->TotalParameterCount = pSMB->ParameterCount;
2056 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2057 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2058 parm_data = (struct cifs_posix_lock *)
2059 (((char *)pSMB) + offset + 4);
2061 parm_data->lock_type = cpu_to_le16(lock_type);
2063 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2064 parm_data->lock_flags = cpu_to_le16(1);
2065 pSMB->Timeout = cpu_to_le32(-1);
2069 parm_data->pid = cpu_to_le32(netpid);
2070 parm_data->start = cpu_to_le64(start_offset);
2071 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2073 pSMB->DataOffset = cpu_to_le16(offset);
2074 pSMB->Fid = smb_file_id;
2075 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2076 pSMB->Reserved4 = 0;
2077 inc_rfc1001_len(pSMB, byte_count);
2078 pSMB->ByteCount = cpu_to_le16(byte_count);
2080 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2081 (struct smb_hdr *) pSMBr, &bytes_returned);
2083 iov[0].iov_base = (char *)pSMB;
2084 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2085 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2086 &resp_buf_type, timeout, &rsp_iov);
2087 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2089 cifs_small_buf_release(pSMB);
2092 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2093 } else if (pLockData) {
2094 /* lock structure can be returned on get */
2097 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2099 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2100 rc = -EIO; /* bad smb */
2103 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2104 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2105 if (data_count < sizeof(struct cifs_posix_lock)) {
2109 parm_data = (struct cifs_posix_lock *)
2110 ((char *)&pSMBr->hdr.Protocol + data_offset);
2111 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2112 pLockData->c.flc_type = F_UNLCK;
2114 if (parm_data->lock_type ==
2115 cpu_to_le16(CIFS_RDLCK))
2116 pLockData->c.flc_type = F_RDLCK;
2117 else if (parm_data->lock_type ==
2118 cpu_to_le16(CIFS_WRLCK))
2119 pLockData->c.flc_type = F_WRLCK;
2121 pLockData->fl_start = le64_to_cpu(parm_data->start);
2122 pLockData->fl_end = pLockData->fl_start +
2123 (le64_to_cpu(parm_data->length) ?
2124 le64_to_cpu(parm_data->length) - 1 : 0);
2125 pLockData->c.flc_pid = -le32_to_cpu(parm_data->pid);
2130 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2132 /* Note: On -EAGAIN error only caller can retry on handle based calls
2133 since file handle passed in no longer valid */
2140 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2143 CLOSE_REQ *pSMB = NULL;
2144 cifs_dbg(FYI, "In CIFSSMBClose\n");
2146 /* do not retry on dead session on close */
2147 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2153 pSMB->FileID = (__u16) smb_file_id;
2154 pSMB->LastWriteTime = 0xFFFFFFFF;
2155 pSMB->ByteCount = 0;
2156 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2157 cifs_small_buf_release(pSMB);
2158 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2161 /* EINTR is expected when user ctl-c to kill app */
2162 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2166 /* Since session is dead, file will be closed on server already */
2174 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2177 FLUSH_REQ *pSMB = NULL;
2178 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2180 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2184 pSMB->FileID = (__u16) smb_file_id;
2185 pSMB->ByteCount = 0;
2186 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2187 cifs_small_buf_release(pSMB);
2188 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2190 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2195 int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2196 struct dentry *source_dentry,
2197 const char *from_name, const char *to_name,
2198 struct cifs_sb_info *cifs_sb)
2201 RENAME_REQ *pSMB = NULL;
2202 RENAME_RSP *pSMBr = NULL;
2204 int name_len, name_len2;
2206 int remap = cifs_remap(cifs_sb);
2208 cifs_dbg(FYI, "In CIFSSMBRename\n");
2210 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2215 pSMB->BufferFormat = 0x04;
2216 pSMB->SearchAttributes =
2217 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2220 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2221 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2222 from_name, PATH_MAX,
2223 cifs_sb->local_nls, remap);
2224 name_len++; /* trailing null */
2226 pSMB->OldFileName[name_len] = 0x04; /* pad */
2227 /* protocol requires ASCII signature byte on Unicode string */
2228 pSMB->OldFileName[name_len + 1] = 0x00;
2230 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2231 to_name, PATH_MAX, cifs_sb->local_nls,
2233 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2234 name_len2 *= 2; /* convert to bytes */
2236 name_len = copy_path_name(pSMB->OldFileName, from_name);
2237 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2238 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2239 name_len2++; /* signature byte */
2242 count = 1 /* 1st signature byte */ + name_len + name_len2;
2243 inc_rfc1001_len(pSMB, count);
2244 pSMB->ByteCount = cpu_to_le16(count);
2246 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2247 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2248 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2250 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2252 cifs_buf_release(pSMB);
2260 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2261 int netfid, const char *target_name,
2262 const struct nls_table *nls_codepage, int remap)
2264 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2265 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2266 struct set_file_rename *rename_info;
2268 char dummy_string[30];
2270 int bytes_returned = 0;
2272 __u16 params, param_offset, offset, count, byte_count;
2274 cifs_dbg(FYI, "Rename to File by handle\n");
2275 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2281 pSMB->MaxSetupCount = 0;
2285 pSMB->Reserved2 = 0;
2286 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2287 offset = param_offset + params;
2289 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2290 data_offset = (char *)(pSMB) + offset + 4;
2291 rename_info = (struct set_file_rename *) data_offset;
2292 pSMB->MaxParameterCount = cpu_to_le16(2);
2293 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2294 pSMB->SetupCount = 1;
2295 pSMB->Reserved3 = 0;
2296 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2297 byte_count = 3 /* pad */ + params;
2298 pSMB->ParameterCount = cpu_to_le16(params);
2299 pSMB->TotalParameterCount = pSMB->ParameterCount;
2300 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2301 pSMB->DataOffset = cpu_to_le16(offset);
2302 /* construct random name ".cifs_tmp<inodenum><mid>" */
2303 rename_info->overwrite = cpu_to_le32(1);
2304 rename_info->root_fid = 0;
2305 /* unicode only call */
2306 if (target_name == NULL) {
2307 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2309 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2310 dummy_string, 24, nls_codepage, remap);
2313 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2314 target_name, PATH_MAX, nls_codepage,
2317 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2318 count = sizeof(struct set_file_rename) + (2 * len_of_str);
2319 byte_count += count;
2320 pSMB->DataCount = cpu_to_le16(count);
2321 pSMB->TotalDataCount = pSMB->DataCount;
2323 pSMB->InformationLevel =
2324 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2325 pSMB->Reserved4 = 0;
2326 inc_rfc1001_len(pSMB, byte_count);
2327 pSMB->ByteCount = cpu_to_le16(byte_count);
2328 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2329 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2330 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2332 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2335 cifs_buf_release(pSMB);
2337 /* Note: On -EAGAIN error only caller can retry on handle based calls
2338 since file handle passed in no longer valid */
2344 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2345 const char *fromName, const __u16 target_tid, const char *toName,
2346 const int flags, const struct nls_table *nls_codepage, int remap)
2349 COPY_REQ *pSMB = NULL;
2350 COPY_RSP *pSMBr = NULL;
2352 int name_len, name_len2;
2355 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2357 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2362 pSMB->BufferFormat = 0x04;
2363 pSMB->Tid2 = target_tid;
2365 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2367 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2368 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2369 fromName, PATH_MAX, nls_codepage,
2371 name_len++; /* trailing null */
2373 pSMB->OldFileName[name_len] = 0x04; /* pad */
2374 /* protocol requires ASCII signature byte on Unicode string */
2375 pSMB->OldFileName[name_len + 1] = 0x00;
2377 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2378 toName, PATH_MAX, nls_codepage, remap);
2379 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2380 name_len2 *= 2; /* convert to bytes */
2382 name_len = copy_path_name(pSMB->OldFileName, fromName);
2383 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2384 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2385 name_len2++; /* signature byte */
2388 count = 1 /* 1st signature byte */ + name_len + name_len2;
2389 inc_rfc1001_len(pSMB, count);
2390 pSMB->ByteCount = cpu_to_le16(count);
2392 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2393 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2395 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2396 rc, le16_to_cpu(pSMBr->CopyCount));
2398 cifs_buf_release(pSMB);
2407 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2408 const char *fromName, const char *toName,
2409 const struct nls_table *nls_codepage, int remap)
2411 TRANSACTION2_SPI_REQ *pSMB = NULL;
2412 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2415 int name_len_target;
2417 int bytes_returned = 0;
2418 __u16 params, param_offset, offset, byte_count;
2420 cifs_dbg(FYI, "In Symlink Unix style\n");
2422 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2427 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2429 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2430 /* find define for this maxpathcomponent */
2431 PATH_MAX, nls_codepage, remap);
2432 name_len++; /* trailing null */
2436 name_len = copy_path_name(pSMB->FileName, fromName);
2438 params = 6 + name_len;
2439 pSMB->MaxSetupCount = 0;
2443 pSMB->Reserved2 = 0;
2444 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2445 InformationLevel) - 4;
2446 offset = param_offset + params;
2448 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2449 data_offset = (char *)pSMB + offset + 4;
2450 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2452 cifsConvertToUTF16((__le16 *) data_offset, toName,
2453 /* find define for this maxpathcomponent */
2454 PATH_MAX, nls_codepage, remap);
2455 name_len_target++; /* trailing null */
2456 name_len_target *= 2;
2458 name_len_target = copy_path_name(data_offset, toName);
2461 pSMB->MaxParameterCount = cpu_to_le16(2);
2462 /* BB find exact max on data count below from sess */
2463 pSMB->MaxDataCount = cpu_to_le16(1000);
2464 pSMB->SetupCount = 1;
2465 pSMB->Reserved3 = 0;
2466 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2467 byte_count = 3 /* pad */ + params + name_len_target;
2468 pSMB->DataCount = cpu_to_le16(name_len_target);
2469 pSMB->ParameterCount = cpu_to_le16(params);
2470 pSMB->TotalDataCount = pSMB->DataCount;
2471 pSMB->TotalParameterCount = pSMB->ParameterCount;
2472 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2473 pSMB->DataOffset = cpu_to_le16(offset);
2474 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2475 pSMB->Reserved4 = 0;
2476 inc_rfc1001_len(pSMB, byte_count);
2477 pSMB->ByteCount = cpu_to_le16(byte_count);
2478 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2479 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2480 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2482 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2485 cifs_buf_release(pSMB);
2488 goto createSymLinkRetry;
2494 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2495 const char *fromName, const char *toName,
2496 const struct nls_table *nls_codepage, int remap)
2498 TRANSACTION2_SPI_REQ *pSMB = NULL;
2499 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2502 int name_len_target;
2504 int bytes_returned = 0;
2505 __u16 params, param_offset, offset, byte_count;
2507 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2508 createHardLinkRetry:
2509 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2514 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2515 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2516 PATH_MAX, nls_codepage, remap);
2517 name_len++; /* trailing null */
2521 name_len = copy_path_name(pSMB->FileName, toName);
2523 params = 6 + name_len;
2524 pSMB->MaxSetupCount = 0;
2528 pSMB->Reserved2 = 0;
2529 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2530 InformationLevel) - 4;
2531 offset = param_offset + params;
2533 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2534 data_offset = (char *)pSMB + offset + 4;
2535 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2537 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2538 PATH_MAX, nls_codepage, remap);
2539 name_len_target++; /* trailing null */
2540 name_len_target *= 2;
2542 name_len_target = copy_path_name(data_offset, fromName);
2545 pSMB->MaxParameterCount = cpu_to_le16(2);
2546 /* BB find exact max on data count below from sess*/
2547 pSMB->MaxDataCount = cpu_to_le16(1000);
2548 pSMB->SetupCount = 1;
2549 pSMB->Reserved3 = 0;
2550 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2551 byte_count = 3 /* pad */ + params + name_len_target;
2552 pSMB->ParameterCount = cpu_to_le16(params);
2553 pSMB->TotalParameterCount = pSMB->ParameterCount;
2554 pSMB->DataCount = cpu_to_le16(name_len_target);
2555 pSMB->TotalDataCount = pSMB->DataCount;
2556 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2557 pSMB->DataOffset = cpu_to_le16(offset);
2558 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2559 pSMB->Reserved4 = 0;
2560 inc_rfc1001_len(pSMB, byte_count);
2561 pSMB->ByteCount = cpu_to_le16(byte_count);
2562 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2563 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2564 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2566 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2569 cifs_buf_release(pSMB);
2571 goto createHardLinkRetry;
2576 int CIFSCreateHardLink(const unsigned int xid,
2577 struct cifs_tcon *tcon,
2578 struct dentry *source_dentry,
2579 const char *from_name, const char *to_name,
2580 struct cifs_sb_info *cifs_sb)
2583 NT_RENAME_REQ *pSMB = NULL;
2584 RENAME_RSP *pSMBr = NULL;
2586 int name_len, name_len2;
2588 int remap = cifs_remap(cifs_sb);
2590 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2591 winCreateHardLinkRetry:
2593 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2598 pSMB->SearchAttributes =
2599 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2601 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2602 pSMB->ClusterCount = 0;
2604 pSMB->BufferFormat = 0x04;
2606 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2608 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2609 PATH_MAX, cifs_sb->local_nls, remap);
2610 name_len++; /* trailing null */
2613 /* protocol specifies ASCII buffer format (0x04) for unicode */
2614 pSMB->OldFileName[name_len] = 0x04;
2615 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2617 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2618 to_name, PATH_MAX, cifs_sb->local_nls,
2620 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2621 name_len2 *= 2; /* convert to bytes */
2623 name_len = copy_path_name(pSMB->OldFileName, from_name);
2624 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2625 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2626 name_len2++; /* signature byte */
2629 count = 1 /* string type byte */ + name_len + name_len2;
2630 inc_rfc1001_len(pSMB, count);
2631 pSMB->ByteCount = cpu_to_le16(count);
2633 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2634 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2635 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2637 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2639 cifs_buf_release(pSMB);
2641 goto winCreateHardLinkRetry;
2647 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2648 const unsigned char *searchName, char **symlinkinfo,
2649 const struct nls_table *nls_codepage, int remap)
2651 /* SMB_QUERY_FILE_UNIX_LINK */
2652 TRANSACTION2_QPI_REQ *pSMB = NULL;
2653 TRANSACTION2_QPI_RSP *pSMBr = NULL;
2657 __u16 params, byte_count;
2660 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
2663 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2668 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2670 cifsConvertToUTF16((__le16 *) pSMB->FileName,
2671 searchName, PATH_MAX, nls_codepage,
2673 name_len++; /* trailing null */
2676 name_len = copy_path_name(pSMB->FileName, searchName);
2679 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
2680 pSMB->TotalDataCount = 0;
2681 pSMB->MaxParameterCount = cpu_to_le16(2);
2682 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2683 pSMB->MaxSetupCount = 0;
2687 pSMB->Reserved2 = 0;
2688 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2689 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
2690 pSMB->DataCount = 0;
2691 pSMB->DataOffset = 0;
2692 pSMB->SetupCount = 1;
2693 pSMB->Reserved3 = 0;
2694 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2695 byte_count = params + 1 /* pad */ ;
2696 pSMB->TotalParameterCount = cpu_to_le16(params);
2697 pSMB->ParameterCount = pSMB->TotalParameterCount;
2698 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2699 pSMB->Reserved4 = 0;
2700 inc_rfc1001_len(pSMB, byte_count);
2701 pSMB->ByteCount = cpu_to_le16(byte_count);
2703 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2704 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2706 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
2708 /* decode response */
2710 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2711 /* BB also check enough total bytes returned */
2712 if (rc || get_bcc(&pSMBr->hdr) < 2)
2716 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2718 data_start = ((char *) &pSMBr->hdr.Protocol) +
2719 le16_to_cpu(pSMBr->t2.DataOffset);
2721 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2726 /* BB FIXME investigate remapping reserved chars here */
2727 *symlinkinfo = cifs_strndup_from_utf16(data_start,
2728 count, is_unicode, nls_codepage);
2733 cifs_buf_release(pSMB);
2735 goto querySymLinkRetry;
2739 int cifs_query_reparse_point(const unsigned int xid,
2740 struct cifs_tcon *tcon,
2741 struct cifs_sb_info *cifs_sb,
2742 const char *full_path,
2743 u32 *tag, struct kvec *rsp,
2746 struct reparse_data_buffer *buf;
2747 struct cifs_open_parms oparms;
2748 TRANSACT_IOCTL_REQ *io_req = NULL;
2749 TRANSACT_IOCTL_RSP *io_rsp = NULL;
2750 struct cifs_fid fid;
2751 __u32 data_offset, data_count, len;
2757 cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
2759 if (cap_unix(tcon->ses))
2762 oparms = (struct cifs_open_parms) {
2765 .desired_access = FILE_READ_ATTRIBUTES,
2766 .create_options = cifs_create_options(cifs_sb,
2767 OPEN_REPARSE_POINT),
2768 .disposition = FILE_OPEN,
2773 rc = CIFS_open(xid, &oparms, &oplock, NULL);
2777 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon,
2778 (void **)&io_req, (void **)&io_rsp);
2782 io_req->TotalParameterCount = 0;
2783 io_req->TotalDataCount = 0;
2784 io_req->MaxParameterCount = cpu_to_le32(2);
2785 /* BB find exact data count max from sess structure BB */
2786 io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
2787 io_req->MaxSetupCount = 4;
2788 io_req->Reserved = 0;
2789 io_req->ParameterOffset = 0;
2790 io_req->DataCount = 0;
2791 io_req->DataOffset = 0;
2792 io_req->SetupCount = 4;
2793 io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2794 io_req->ParameterCount = io_req->TotalParameterCount;
2795 io_req->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
2796 io_req->IsFsctl = 1;
2797 io_req->IsRootFlag = 0;
2798 io_req->Fid = fid.netfid;
2799 io_req->ByteCount = 0;
2801 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req,
2802 (struct smb_hdr *)io_rsp, &io_rsp_len, 0);
2806 data_offset = le32_to_cpu(io_rsp->DataOffset);
2807 data_count = le32_to_cpu(io_rsp->DataCount);
2808 if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 ||
2809 !data_count || data_count > 2048) {
2814 end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
2815 start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
2821 data_count = le16_to_cpu(io_rsp->ByteCount);
2822 buf = (struct reparse_data_buffer *)start;
2824 if (data_count < len ||
2825 data_count < le16_to_cpu(buf->ReparseDataLength) + len) {
2830 *tag = le32_to_cpu(buf->ReparseTag);
2831 rsp->iov_base = io_rsp;
2832 rsp->iov_len = io_rsp_len;
2833 *rsp_buftype = CIFS_LARGE_BUFFER;
2834 CIFSSMBClose(xid, tcon, fid.netfid);
2838 cifs_buf_release(io_req);
2839 CIFSSMBClose(xid, tcon, fid.netfid);
2844 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
2849 struct smb_com_transaction_compr_ioctl_req *pSMB;
2850 struct smb_com_transaction_ioctl_rsp *pSMBr;
2852 cifs_dbg(FYI, "Set compression for %u\n", fid);
2853 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2858 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
2860 pSMB->TotalParameterCount = 0;
2861 pSMB->TotalDataCount = cpu_to_le32(2);
2862 pSMB->MaxParameterCount = 0;
2863 pSMB->MaxDataCount = 0;
2864 pSMB->MaxSetupCount = 4;
2866 pSMB->ParameterOffset = 0;
2867 pSMB->DataCount = cpu_to_le32(2);
2869 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
2870 compression_state) - 4); /* 84 */
2871 pSMB->SetupCount = 4;
2872 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2873 pSMB->ParameterCount = 0;
2874 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
2875 pSMB->IsFsctl = 1; /* FSCTL */
2876 pSMB->IsRootFlag = 0;
2877 pSMB->Fid = fid; /* file handle always le */
2878 /* 3 byte pad, followed by 2 byte compress state */
2879 pSMB->ByteCount = cpu_to_le16(5);
2880 inc_rfc1001_len(pSMB, 5);
2882 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2883 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2885 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
2887 cifs_buf_release(pSMB);
2890 * Note: On -EAGAIN error only caller can retry on handle based calls
2891 * since file handle passed in no longer valid.
2897 #ifdef CONFIG_CIFS_POSIX
2899 #ifdef CONFIG_FS_POSIX_ACL
2901 * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format
2902 * @ace: POSIX ACL entry to store converted ACL into
2903 * @cifs_ace: ACL in cifs format
2905 * Convert an Access Control Entry from wire format to local POSIX xattr
2908 * Note that the @cifs_uid member is used to store both {g,u}id_t.
2910 static void cifs_init_posix_acl(struct posix_acl_entry *ace,
2911 struct cifs_posix_ace *cifs_ace)
2913 /* u8 cifs fields do not need le conversion */
2914 ace->e_perm = cifs_ace->cifs_e_perm;
2915 ace->e_tag = cifs_ace->cifs_e_tag;
2917 switch (ace->e_tag) {
2919 ace->e_uid = make_kuid(&init_user_ns,
2920 le64_to_cpu(cifs_ace->cifs_uid));
2923 ace->e_gid = make_kgid(&init_user_ns,
2924 le64_to_cpu(cifs_ace->cifs_uid));
2931 * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format
2932 * @acl: ACLs returned in POSIX ACL format
2933 * @src: ACLs in cifs format
2934 * @acl_type: type of POSIX ACL requested
2935 * @size_of_data_area: size of SMB we got
2937 * This function converts ACLs from cifs format to POSIX ACL format.
2938 * If @acl is NULL then the size of the buffer required to store POSIX ACLs in
2939 * their uapi format is returned.
2941 static int cifs_to_posix_acl(struct posix_acl **acl, char *src,
2942 const int acl_type, const int size_of_data_area)
2946 struct cifs_posix_ace *pACE;
2947 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
2948 struct posix_acl *kacl = NULL;
2949 struct posix_acl_entry *pa, *pe;
2951 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
2954 if (acl_type == ACL_TYPE_ACCESS) {
2955 count = le16_to_cpu(cifs_acl->access_entry_count);
2956 pACE = &cifs_acl->ace_array[0];
2957 size = sizeof(struct cifs_posix_acl);
2958 size += sizeof(struct cifs_posix_ace) * count;
2959 /* check if we would go beyond end of SMB */
2960 if (size_of_data_area < size) {
2961 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
2962 size_of_data_area, size);
2965 } else if (acl_type == ACL_TYPE_DEFAULT) {
2966 count = le16_to_cpu(cifs_acl->access_entry_count);
2967 size = sizeof(struct cifs_posix_acl);
2968 size += sizeof(struct cifs_posix_ace) * count;
2969 /* skip past access ACEs to get to default ACEs */
2970 pACE = &cifs_acl->ace_array[count];
2971 count = le16_to_cpu(cifs_acl->default_entry_count);
2972 size += sizeof(struct cifs_posix_ace) * count;
2973 /* check if we would go beyond end of SMB */
2974 if (size_of_data_area < size)
2981 /* Allocate number of POSIX ACLs to store in VFS format. */
2982 kacl = posix_acl_alloc(count, GFP_NOFS);
2986 FOREACH_ACL_ENTRY(pa, kacl, pe) {
2987 cifs_init_posix_acl(pa, pACE);
2996 * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format
2997 * @cifs_ace: the cifs ACL entry to store into
2998 * @local_ace: the POSIX ACL entry to convert
3000 static void cifs_init_ace(struct cifs_posix_ace *cifs_ace,
3001 const struct posix_acl_entry *local_ace)
3003 cifs_ace->cifs_e_perm = local_ace->e_perm;
3004 cifs_ace->cifs_e_tag = local_ace->e_tag;
3006 switch (local_ace->e_tag) {
3008 cifs_ace->cifs_uid =
3009 cpu_to_le64(from_kuid(&init_user_ns, local_ace->e_uid));
3012 cifs_ace->cifs_uid =
3013 cpu_to_le64(from_kgid(&init_user_ns, local_ace->e_gid));
3016 cifs_ace->cifs_uid = cpu_to_le64(-1);
3021 * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format
3022 * @parm_data: ACLs in cifs format to conver to
3023 * @acl: ACLs in POSIX ACL format to convert from
3024 * @acl_type: the type of POSIX ACLs stored in @acl
3026 * Return: the number cifs ACL entries after conversion
3028 static __u16 posix_acl_to_cifs(char *parm_data, const struct posix_acl *acl,
3032 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3033 const struct posix_acl_entry *pa, *pe;
3037 if ((acl == NULL) || (cifs_acl == NULL))
3040 count = acl->a_count;
3041 cifs_dbg(FYI, "setting acl with %d entries\n", count);
3044 * Note that the uapi POSIX ACL version is verified by the VFS and is
3045 * independent of the cifs ACL version. Changing the POSIX ACL version
3046 * is a uapi change and if it's changed we will pass down the POSIX ACL
3047 * version in struct posix_acl from the VFS. For now there's really
3048 * only one that all filesystems know how to deal with.
3050 cifs_acl->version = cpu_to_le16(1);
3051 if (acl_type == ACL_TYPE_ACCESS) {
3052 cifs_acl->access_entry_count = cpu_to_le16(count);
3053 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3054 } else if (acl_type == ACL_TYPE_DEFAULT) {
3055 cifs_acl->default_entry_count = cpu_to_le16(count);
3056 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3058 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3061 FOREACH_ACL_ENTRY(pa, acl, pe) {
3062 cifs_init_ace(&cifs_acl->ace_array[i++], pa);
3065 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3066 rc += sizeof(struct cifs_posix_acl);
3067 /* BB add check to make sure ACL does not overflow SMB */
3072 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3073 const unsigned char *searchName, struct posix_acl **acl,
3074 const int acl_type, const struct nls_table *nls_codepage,
3077 /* SMB_QUERY_POSIX_ACL */
3078 TRANSACTION2_QPI_REQ *pSMB = NULL;
3079 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3083 __u16 params, byte_count;
3085 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3088 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3093 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3095 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3096 searchName, PATH_MAX, nls_codepage,
3098 name_len++; /* trailing null */
3100 pSMB->FileName[name_len] = 0;
3101 pSMB->FileName[name_len+1] = 0;
3103 name_len = copy_path_name(pSMB->FileName, searchName);
3106 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3107 pSMB->TotalDataCount = 0;
3108 pSMB->MaxParameterCount = cpu_to_le16(2);
3109 /* BB find exact max data count below from sess structure BB */
3110 pSMB->MaxDataCount = cpu_to_le16(4000);
3111 pSMB->MaxSetupCount = 0;
3115 pSMB->Reserved2 = 0;
3116 pSMB->ParameterOffset = cpu_to_le16(
3117 offsetof(struct smb_com_transaction2_qpi_req,
3118 InformationLevel) - 4);
3119 pSMB->DataCount = 0;
3120 pSMB->DataOffset = 0;
3121 pSMB->SetupCount = 1;
3122 pSMB->Reserved3 = 0;
3123 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3124 byte_count = params + 1 /* pad */ ;
3125 pSMB->TotalParameterCount = cpu_to_le16(params);
3126 pSMB->ParameterCount = pSMB->TotalParameterCount;
3127 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3128 pSMB->Reserved4 = 0;
3129 inc_rfc1001_len(pSMB, byte_count);
3130 pSMB->ByteCount = cpu_to_le16(byte_count);
3132 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3133 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3134 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3136 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3138 /* decode response */
3140 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3141 /* BB also check enough total bytes returned */
3142 if (rc || get_bcc(&pSMBr->hdr) < 2)
3143 rc = -EIO; /* bad smb */
3145 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3146 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3147 rc = cifs_to_posix_acl(acl,
3148 (char *)&pSMBr->hdr.Protocol+data_offset,
3152 cifs_buf_release(pSMB);
3154 * The else branch after SendReceive() doesn't return EAGAIN so if we
3155 * allocated @acl in cifs_to_posix_acl() we are guaranteed to return
3156 * here and don't leak POSIX ACLs.
3163 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3164 const unsigned char *fileName, const struct posix_acl *acl,
3165 const int acl_type, const struct nls_table *nls_codepage,
3168 struct smb_com_transaction2_spi_req *pSMB = NULL;
3169 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3173 int bytes_returned = 0;
3174 __u16 params, byte_count, data_count, param_offset, offset;
3176 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3178 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3182 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3184 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3185 PATH_MAX, nls_codepage, remap);
3186 name_len++; /* trailing null */
3189 name_len = copy_path_name(pSMB->FileName, fileName);
3191 params = 6 + name_len;
3192 pSMB->MaxParameterCount = cpu_to_le16(2);
3193 /* BB find max SMB size from sess */
3194 pSMB->MaxDataCount = cpu_to_le16(1000);
3195 pSMB->MaxSetupCount = 0;
3199 pSMB->Reserved2 = 0;
3200 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3201 InformationLevel) - 4;
3202 offset = param_offset + params;
3203 parm_data = ((char *)pSMB) + sizeof(pSMB->hdr.smb_buf_length) + offset;
3204 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3206 /* convert to on the wire format for POSIX ACL */
3207 data_count = posix_acl_to_cifs(parm_data, acl, acl_type);
3209 if (data_count == 0) {
3211 goto setACLerrorExit;
3213 pSMB->DataOffset = cpu_to_le16(offset);
3214 pSMB->SetupCount = 1;
3215 pSMB->Reserved3 = 0;
3216 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3217 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3218 byte_count = 3 /* pad */ + params + data_count;
3219 pSMB->DataCount = cpu_to_le16(data_count);
3220 pSMB->TotalDataCount = pSMB->DataCount;
3221 pSMB->ParameterCount = cpu_to_le16(params);
3222 pSMB->TotalParameterCount = pSMB->ParameterCount;
3223 pSMB->Reserved4 = 0;
3224 inc_rfc1001_len(pSMB, byte_count);
3225 pSMB->ByteCount = cpu_to_le16(byte_count);
3226 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3227 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3229 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3232 cifs_buf_release(pSMB);
3238 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3239 const unsigned char *searchName, struct posix_acl **acl,
3240 const int acl_type, const struct nls_table *nls_codepage,
3246 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3247 const unsigned char *fileName, const struct posix_acl *acl,
3248 const int acl_type, const struct nls_table *nls_codepage,
3253 #endif /* CONFIG_FS_POSIX_ACL */
3256 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3257 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3260 struct smb_t2_qfi_req *pSMB = NULL;
3261 struct smb_t2_qfi_rsp *pSMBr = NULL;
3263 __u16 params, byte_count;
3265 cifs_dbg(FYI, "In GetExtAttr\n");
3270 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3275 params = 2 /* level */ + 2 /* fid */;
3276 pSMB->t2.TotalDataCount = 0;
3277 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3278 /* BB find exact max data count below from sess structure BB */
3279 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3280 pSMB->t2.MaxSetupCount = 0;
3281 pSMB->t2.Reserved = 0;
3283 pSMB->t2.Timeout = 0;
3284 pSMB->t2.Reserved2 = 0;
3285 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3287 pSMB->t2.DataCount = 0;
3288 pSMB->t2.DataOffset = 0;
3289 pSMB->t2.SetupCount = 1;
3290 pSMB->t2.Reserved3 = 0;
3291 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3292 byte_count = params + 1 /* pad */ ;
3293 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3294 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3295 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3298 inc_rfc1001_len(pSMB, byte_count);
3299 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3301 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3302 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3304 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3306 /* decode response */
3307 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3308 /* BB also check enough total bytes returned */
3309 if (rc || get_bcc(&pSMBr->hdr) < 2)
3310 /* If rc should we check for EOPNOSUPP and
3311 disable the srvino flag? or in caller? */
3312 rc = -EIO; /* bad smb */
3314 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3315 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3316 struct file_chattr_info *pfinfo;
3319 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3323 pfinfo = (struct file_chattr_info *)
3324 (data_offset + (char *) &pSMBr->hdr.Protocol);
3325 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3326 *pMask = le64_to_cpu(pfinfo->mask);
3330 cifs_buf_release(pSMB);
3332 goto GetExtAttrRetry;
3336 #endif /* CONFIG_POSIX */
3339 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3340 * all NT TRANSACTS that we init here have total parm and data under about 400
3341 * bytes (to fit in small cifs buffer size), which is the case so far, it
3342 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3343 * returned setup area) and MaxParameterCount (returned parms size) must be set
3347 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3348 const int parm_len, struct cifs_tcon *tcon,
3353 struct smb_com_ntransact_req *pSMB;
3355 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3359 *ret_buf = (void *)pSMB;
3361 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3362 pSMB->TotalDataCount = 0;
3363 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3364 pSMB->ParameterCount = pSMB->TotalParameterCount;
3365 pSMB->DataCount = pSMB->TotalDataCount;
3366 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3367 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3368 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3369 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3370 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3371 pSMB->SubCommand = cpu_to_le16(sub_command);
3376 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3377 __u32 *pparmlen, __u32 *pdatalen)
3380 __u32 data_count, data_offset, parm_count, parm_offset;
3381 struct smb_com_ntransact_rsp *pSMBr;
3390 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3392 bcc = get_bcc(&pSMBr->hdr);
3393 end_of_smb = 2 /* sizeof byte count */ + bcc +
3394 (char *)&pSMBr->ByteCount;
3396 data_offset = le32_to_cpu(pSMBr->DataOffset);
3397 data_count = le32_to_cpu(pSMBr->DataCount);
3398 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3399 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3401 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3402 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3404 /* should we also check that parm and data areas do not overlap? */
3405 if (*ppparm > end_of_smb) {
3406 cifs_dbg(FYI, "parms start after end of smb\n");
3408 } else if (parm_count + *ppparm > end_of_smb) {
3409 cifs_dbg(FYI, "parm end after end of smb\n");
3411 } else if (*ppdata > end_of_smb) {
3412 cifs_dbg(FYI, "data starts after end of smb\n");
3414 } else if (data_count + *ppdata > end_of_smb) {
3415 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3416 *ppdata, data_count, (data_count + *ppdata),
3419 } else if (parm_count + data_count > bcc) {
3420 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3423 *pdatalen = data_count;
3424 *pparmlen = parm_count;
3428 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3430 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3431 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3435 QUERY_SEC_DESC_REQ *pSMB;
3437 struct kvec rsp_iov;
3439 cifs_dbg(FYI, "GetCifsACL\n");
3444 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3445 8 /* parm len */, tcon, (void **) &pSMB);
3449 pSMB->MaxParameterCount = cpu_to_le32(4);
3450 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3451 pSMB->MaxSetupCount = 0;
3452 pSMB->Fid = fid; /* file handle always le */
3453 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3455 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3456 inc_rfc1001_len(pSMB, 11);
3457 iov[0].iov_base = (char *)pSMB;
3458 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3460 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3462 cifs_small_buf_release(pSMB);
3463 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3465 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3466 } else { /* decode response */
3470 struct smb_com_ntransact_rsp *pSMBr;
3473 /* validate_nttransact */
3474 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3475 &pdata, &parm_len, pbuflen);
3478 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3480 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3481 pSMBr, parm, *acl_inf);
3483 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3484 rc = -EIO; /* bad smb */
3489 /* BB check that data area is minimum length and as big as acl_len */
3491 acl_len = le32_to_cpu(*parm);
3492 if (acl_len != *pbuflen) {
3493 cifs_dbg(VFS, "acl length %d does not match %d\n",
3495 if (*pbuflen > acl_len)
3499 /* check if buffer is big enough for the acl
3500 header followed by the smallest SID */
3501 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3502 (*pbuflen >= 64 * 1024)) {
3503 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3507 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3508 if (*acl_inf == NULL) {
3515 free_rsp_buf(buf_type, rsp_iov.iov_base);
3520 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3521 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3523 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3525 int bytes_returned = 0;
3526 SET_SEC_DESC_REQ *pSMB = NULL;
3530 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3534 pSMB->MaxSetupCount = 0;
3538 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3539 data_count = acllen;
3540 data_offset = param_offset + param_count;
3541 byte_count = 3 /* pad */ + param_count;
3543 pSMB->DataCount = cpu_to_le32(data_count);
3544 pSMB->TotalDataCount = pSMB->DataCount;
3545 pSMB->MaxParameterCount = cpu_to_le32(4);
3546 pSMB->MaxDataCount = cpu_to_le32(16384);
3547 pSMB->ParameterCount = cpu_to_le32(param_count);
3548 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3549 pSMB->TotalParameterCount = pSMB->ParameterCount;
3550 pSMB->DataOffset = cpu_to_le32(data_offset);
3551 pSMB->SetupCount = 0;
3552 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3553 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3555 pSMB->Fid = fid; /* file handle always le */
3556 pSMB->Reserved2 = 0;
3557 pSMB->AclFlags = cpu_to_le32(aclflag);
3559 if (pntsd && acllen) {
3560 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3561 data_offset, pntsd, acllen);
3562 inc_rfc1001_len(pSMB, byte_count + data_count);
3564 inc_rfc1001_len(pSMB, byte_count);
3566 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3567 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3569 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3570 bytes_returned, rc);
3572 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3573 cifs_buf_release(pSMB);
3576 goto setCifsAclRetry;
3582 /* Legacy Query Path Information call for lookup to old servers such
3585 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3586 const char *search_name, FILE_ALL_INFO *data,
3587 const struct nls_table *nls_codepage, int remap)
3589 QUERY_INFORMATION_REQ *pSMB;
3590 QUERY_INFORMATION_RSP *pSMBr;
3595 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3597 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3602 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3604 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3605 search_name, PATH_MAX, nls_codepage,
3607 name_len++; /* trailing null */
3610 name_len = copy_path_name(pSMB->FileName, search_name);
3612 pSMB->BufferFormat = 0x04;
3613 name_len++; /* account for buffer type byte */
3614 inc_rfc1001_len(pSMB, (__u16)name_len);
3615 pSMB->ByteCount = cpu_to_le16(name_len);
3617 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3618 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3620 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3622 struct timespec64 ts;
3623 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3625 /* decode response */
3626 /* BB FIXME - add time zone adjustment BB */
3627 memset(data, 0, sizeof(FILE_ALL_INFO));
3630 /* decode time fields */
3631 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3632 data->LastWriteTime = data->ChangeTime;
3633 data->LastAccessTime = 0;
3634 data->AllocationSize =
3635 cpu_to_le64(le32_to_cpu(pSMBr->size));
3636 data->EndOfFile = data->AllocationSize;
3638 cpu_to_le32(le16_to_cpu(pSMBr->attr));
3640 rc = -EIO; /* bad buffer passed in */
3642 cifs_buf_release(pSMB);
3651 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3652 u16 netfid, FILE_ALL_INFO *pFindData)
3654 struct smb_t2_qfi_req *pSMB = NULL;
3655 struct smb_t2_qfi_rsp *pSMBr = NULL;
3658 __u16 params, byte_count;
3661 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3666 params = 2 /* level */ + 2 /* fid */;
3667 pSMB->t2.TotalDataCount = 0;
3668 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3669 /* BB find exact max data count below from sess structure BB */
3670 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3671 pSMB->t2.MaxSetupCount = 0;
3672 pSMB->t2.Reserved = 0;
3674 pSMB->t2.Timeout = 0;
3675 pSMB->t2.Reserved2 = 0;
3676 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3678 pSMB->t2.DataCount = 0;
3679 pSMB->t2.DataOffset = 0;
3680 pSMB->t2.SetupCount = 1;
3681 pSMB->t2.Reserved3 = 0;
3682 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3683 byte_count = params + 1 /* pad */ ;
3684 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3685 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3686 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3689 inc_rfc1001_len(pSMB, byte_count);
3690 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3692 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3693 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3695 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
3696 } else { /* decode response */
3697 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3699 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3701 else if (get_bcc(&pSMBr->hdr) < 40)
3702 rc = -EIO; /* bad smb */
3703 else if (pFindData) {
3704 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3705 memcpy((char *) pFindData,
3706 (char *) &pSMBr->hdr.Protocol +
3707 data_offset, sizeof(FILE_ALL_INFO));
3711 cifs_buf_release(pSMB);
3713 goto QFileInfoRetry;
3719 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3720 const char *search_name, FILE_ALL_INFO *data,
3721 int legacy /* old style infolevel */,
3722 const struct nls_table *nls_codepage, int remap)
3724 /* level 263 SMB_QUERY_FILE_ALL_INFO */
3725 TRANSACTION2_QPI_REQ *pSMB = NULL;
3726 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3730 __u16 params, byte_count;
3732 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3734 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3739 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3741 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3742 PATH_MAX, nls_codepage, remap);
3743 name_len++; /* trailing null */
3746 name_len = copy_path_name(pSMB->FileName, search_name);
3749 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3750 pSMB->TotalDataCount = 0;
3751 pSMB->MaxParameterCount = cpu_to_le16(2);
3752 /* BB find exact max SMB PDU from sess structure BB */
3753 pSMB->MaxDataCount = cpu_to_le16(4000);
3754 pSMB->MaxSetupCount = 0;
3758 pSMB->Reserved2 = 0;
3759 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3760 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3761 pSMB->DataCount = 0;
3762 pSMB->DataOffset = 0;
3763 pSMB->SetupCount = 1;
3764 pSMB->Reserved3 = 0;
3765 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3766 byte_count = params + 1 /* pad */ ;
3767 pSMB->TotalParameterCount = cpu_to_le16(params);
3768 pSMB->ParameterCount = pSMB->TotalParameterCount;
3770 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3772 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3773 pSMB->Reserved4 = 0;
3774 inc_rfc1001_len(pSMB, byte_count);
3775 pSMB->ByteCount = cpu_to_le16(byte_count);
3777 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3778 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3780 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3781 } else { /* decode response */
3782 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3784 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3786 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3787 rc = -EIO; /* bad smb */
3788 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3789 rc = -EIO; /* 24 or 26 expected but we do not read
3793 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3796 * On legacy responses we do not read the last field,
3797 * EAsize, fortunately since it varies by subdialect and
3798 * also note it differs on Set vs Get, ie two bytes or 4
3799 * bytes depending but we don't care here.
3802 size = sizeof(FILE_INFO_STANDARD);
3804 size = sizeof(FILE_ALL_INFO);
3805 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
3810 cifs_buf_release(pSMB);
3812 goto QPathInfoRetry;
3818 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3819 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3821 struct smb_t2_qfi_req *pSMB = NULL;
3822 struct smb_t2_qfi_rsp *pSMBr = NULL;
3825 __u16 params, byte_count;
3828 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3833 params = 2 /* level */ + 2 /* fid */;
3834 pSMB->t2.TotalDataCount = 0;
3835 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3836 /* BB find exact max data count below from sess structure BB */
3837 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3838 pSMB->t2.MaxSetupCount = 0;
3839 pSMB->t2.Reserved = 0;
3841 pSMB->t2.Timeout = 0;
3842 pSMB->t2.Reserved2 = 0;
3843 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3845 pSMB->t2.DataCount = 0;
3846 pSMB->t2.DataOffset = 0;
3847 pSMB->t2.SetupCount = 1;
3848 pSMB->t2.Reserved3 = 0;
3849 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3850 byte_count = params + 1 /* pad */ ;
3851 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3852 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3853 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3856 inc_rfc1001_len(pSMB, byte_count);
3857 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3859 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3860 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3862 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
3863 } else { /* decode response */
3864 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3866 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3867 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3868 rc = -EIO; /* bad smb */
3870 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3871 memcpy((char *) pFindData,
3872 (char *) &pSMBr->hdr.Protocol +
3874 sizeof(FILE_UNIX_BASIC_INFO));
3878 cifs_buf_release(pSMB);
3880 goto UnixQFileInfoRetry;
3886 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3887 const unsigned char *searchName,
3888 FILE_UNIX_BASIC_INFO *pFindData,
3889 const struct nls_table *nls_codepage, int remap)
3891 /* SMB_QUERY_FILE_UNIX_BASIC */
3892 TRANSACTION2_QPI_REQ *pSMB = NULL;
3893 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3895 int bytes_returned = 0;
3897 __u16 params, byte_count;
3899 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
3901 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3906 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3908 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3909 PATH_MAX, nls_codepage, remap);
3910 name_len++; /* trailing null */
3913 name_len = copy_path_name(pSMB->FileName, searchName);
3916 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3917 pSMB->TotalDataCount = 0;
3918 pSMB->MaxParameterCount = cpu_to_le16(2);
3919 /* BB find exact max SMB PDU from sess structure BB */
3920 pSMB->MaxDataCount = cpu_to_le16(4000);
3921 pSMB->MaxSetupCount = 0;
3925 pSMB->Reserved2 = 0;
3926 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3927 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3928 pSMB->DataCount = 0;
3929 pSMB->DataOffset = 0;
3930 pSMB->SetupCount = 1;
3931 pSMB->Reserved3 = 0;
3932 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3933 byte_count = params + 1 /* pad */ ;
3934 pSMB->TotalParameterCount = cpu_to_le16(params);
3935 pSMB->ParameterCount = pSMB->TotalParameterCount;
3936 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3937 pSMB->Reserved4 = 0;
3938 inc_rfc1001_len(pSMB, byte_count);
3939 pSMB->ByteCount = cpu_to_le16(byte_count);
3941 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3942 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3944 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
3945 } else { /* decode response */
3946 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3948 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3949 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3950 rc = -EIO; /* bad smb */
3952 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3953 memcpy((char *) pFindData,
3954 (char *) &pSMBr->hdr.Protocol +
3956 sizeof(FILE_UNIX_BASIC_INFO));
3959 cifs_buf_release(pSMB);
3961 goto UnixQPathInfoRetry;
3966 /* xid, tcon, searchName and codepage are input parms, rest are returned */
3968 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
3969 const char *searchName, struct cifs_sb_info *cifs_sb,
3970 __u16 *pnetfid, __u16 search_flags,
3971 struct cifs_search_info *psrch_inf, bool msearch)
3973 /* level 257 SMB_ */
3974 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
3975 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
3976 T2_FFIRST_RSP_PARMS *parms;
3977 struct nls_table *nls_codepage;
3979 __u16 params, byte_count;
3980 int bytes_returned = 0;
3981 int name_len, remap;
3984 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
3987 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3992 nls_codepage = cifs_sb->local_nls;
3993 remap = cifs_remap(cifs_sb);
3995 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3997 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3998 PATH_MAX, nls_codepage, remap);
3999 /* We can not add the asterik earlier in case
4000 it got remapped to 0xF03A as if it were part of the
4001 directory name instead of a wildcard */
4004 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4005 pSMB->FileName[name_len+1] = 0;
4006 pSMB->FileName[name_len+2] = '*';
4007 pSMB->FileName[name_len+3] = 0;
4008 name_len += 4; /* now the trailing null */
4009 /* null terminate just in case */
4010 pSMB->FileName[name_len] = 0;
4011 pSMB->FileName[name_len+1] = 0;
4015 name_len = copy_path_name(pSMB->FileName, searchName);
4017 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4018 name_len = PATH_MAX-2;
4019 /* overwrite nul byte */
4020 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4021 pSMB->FileName[name_len] = '*';
4022 pSMB->FileName[name_len+1] = 0;
4027 params = 12 + name_len /* includes null */ ;
4028 pSMB->TotalDataCount = 0; /* no EAs */
4029 pSMB->MaxParameterCount = cpu_to_le16(10);
4030 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4031 pSMB->MaxSetupCount = 0;
4035 pSMB->Reserved2 = 0;
4036 byte_count = params + 1 /* pad */ ;
4037 pSMB->TotalParameterCount = cpu_to_le16(params);
4038 pSMB->ParameterCount = pSMB->TotalParameterCount;
4039 pSMB->ParameterOffset = cpu_to_le16(
4040 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4042 pSMB->DataCount = 0;
4043 pSMB->DataOffset = 0;
4044 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4045 pSMB->Reserved3 = 0;
4046 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4047 pSMB->SearchAttributes =
4048 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4050 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4051 pSMB->SearchFlags = cpu_to_le16(search_flags);
4052 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4054 /* BB what should we set StorageType to? Does it matter? BB */
4055 pSMB->SearchStorageType = 0;
4056 inc_rfc1001_len(pSMB, byte_count);
4057 pSMB->ByteCount = cpu_to_le16(byte_count);
4059 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4060 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4061 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4065 * BB: add logic to retry regular search if Unix search rejected
4066 * unexpectedly by server.
4068 /* BB: add code to handle unsupported level rc */
4069 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4070 cifs_buf_release(pSMB);
4072 * BB: eventually could optimize out free and realloc of buf for
4076 goto findFirstRetry;
4079 /* decode response */
4080 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4082 cifs_buf_release(pSMB);
4086 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4087 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4088 psrch_inf->smallBuf = false;
4089 psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol +
4090 le16_to_cpu(pSMBr->t2.DataOffset);
4092 parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol +
4093 le16_to_cpu(pSMBr->t2.ParameterOffset));
4094 psrch_inf->endOfSearch = !!parms->EndofSearch;
4096 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4097 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4098 psrch_inf->entries_in_buffer;
4099 lnoff = le16_to_cpu(parms->LastNameOffset);
4100 if (CIFSMaxBufSize < lnoff) {
4101 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4102 psrch_inf->last_entry = NULL;
4104 psrch_inf->last_entry = psrch_inf->srch_entries_start + lnoff;
4106 *pnetfid = parms->SearchHandle;
4111 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4112 __u16 searchHandle, __u16 search_flags,
4113 struct cifs_search_info *psrch_inf)
4115 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4116 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4117 T2_FNEXT_RSP_PARMS *parms;
4118 unsigned int name_len;
4120 __u16 params, byte_count;
4121 char *response_data;
4125 cifs_dbg(FYI, "In FindNext\n");
4127 if (psrch_inf->endOfSearch)
4130 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4135 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4137 pSMB->TotalDataCount = 0; /* no EAs */
4138 pSMB->MaxParameterCount = cpu_to_le16(8);
4139 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4140 pSMB->MaxSetupCount = 0;
4144 pSMB->Reserved2 = 0;
4145 pSMB->ParameterOffset = cpu_to_le16(
4146 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4147 pSMB->DataCount = 0;
4148 pSMB->DataOffset = 0;
4149 pSMB->SetupCount = 1;
4150 pSMB->Reserved3 = 0;
4151 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4152 pSMB->SearchHandle = searchHandle; /* always kept as le */
4154 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4155 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4156 pSMB->ResumeKey = psrch_inf->resume_key;
4157 pSMB->SearchFlags = cpu_to_le16(search_flags);
4159 name_len = psrch_inf->resume_name_len;
4161 if (name_len < PATH_MAX) {
4162 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4163 byte_count += name_len;
4164 /* 14 byte parm len above enough for 2 byte null terminator */
4165 pSMB->ResumeFileName[name_len] = 0;
4166 pSMB->ResumeFileName[name_len+1] = 0;
4168 cifs_buf_release(pSMB);
4171 byte_count = params + 1 /* pad */ ;
4172 pSMB->TotalParameterCount = cpu_to_le16(params);
4173 pSMB->ParameterCount = pSMB->TotalParameterCount;
4174 inc_rfc1001_len(pSMB, byte_count);
4175 pSMB->ByteCount = cpu_to_le16(byte_count);
4177 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4178 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4179 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4182 cifs_buf_release(pSMB);
4184 psrch_inf->endOfSearch = true;
4185 rc = 0; /* search probably was closed at end of search*/
4187 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4192 /* decode response */
4193 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4195 cifs_buf_release(pSMB);
4198 /* BB fixme add lock for file (srch_info) struct here */
4199 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4200 response_data = (char *)&pSMBr->hdr.Protocol +
4201 le16_to_cpu(pSMBr->t2.ParameterOffset);
4202 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4203 response_data = (char *)&pSMBr->hdr.Protocol +
4204 le16_to_cpu(pSMBr->t2.DataOffset);
4206 if (psrch_inf->smallBuf)
4207 cifs_small_buf_release(psrch_inf->ntwrk_buf_start);
4209 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4211 psrch_inf->srch_entries_start = response_data;
4212 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4213 psrch_inf->smallBuf = false;
4214 psrch_inf->endOfSearch = !!parms->EndofSearch;
4215 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4216 psrch_inf->index_of_last_entry += psrch_inf->entries_in_buffer;
4217 lnoff = le16_to_cpu(parms->LastNameOffset);
4218 if (CIFSMaxBufSize < lnoff) {
4219 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4220 psrch_inf->last_entry = NULL;
4222 psrch_inf->last_entry =
4223 psrch_inf->srch_entries_start + lnoff;
4225 /* BB fixme add unlock here */
4228 * BB: On error, should we leave previous search buf
4229 * (and count and last entry fields) intact or free the previous one?
4231 * Note: On -EAGAIN error only caller can retry on handle based calls
4232 * since file handle passed in no longer valid.
4238 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4239 const __u16 searchHandle)
4242 FINDCLOSE_REQ *pSMB = NULL;
4244 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4245 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4247 /* no sense returning error if session restarted
4248 as file handle has been closed */
4254 pSMB->FileID = searchHandle;
4255 pSMB->ByteCount = 0;
4256 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4257 cifs_small_buf_release(pSMB);
4259 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4261 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4263 /* Since session is dead, search handle closed on server already */
4271 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4272 const char *search_name, __u64 *inode_number,
4273 const struct nls_table *nls_codepage, int remap)
4276 TRANSACTION2_QPI_REQ *pSMB = NULL;
4277 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4278 int name_len, bytes_returned;
4279 __u16 params, byte_count;
4281 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4285 GetInodeNumberRetry:
4286 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4291 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4293 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4294 search_name, PATH_MAX, nls_codepage,
4296 name_len++; /* trailing null */
4299 name_len = copy_path_name(pSMB->FileName, search_name);
4302 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4303 pSMB->TotalDataCount = 0;
4304 pSMB->MaxParameterCount = cpu_to_le16(2);
4305 /* BB find exact max data count below from sess structure BB */
4306 pSMB->MaxDataCount = cpu_to_le16(4000);
4307 pSMB->MaxSetupCount = 0;
4311 pSMB->Reserved2 = 0;
4312 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4313 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4314 pSMB->DataCount = 0;
4315 pSMB->DataOffset = 0;
4316 pSMB->SetupCount = 1;
4317 pSMB->Reserved3 = 0;
4318 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4319 byte_count = params + 1 /* pad */ ;
4320 pSMB->TotalParameterCount = cpu_to_le16(params);
4321 pSMB->ParameterCount = pSMB->TotalParameterCount;
4322 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4323 pSMB->Reserved4 = 0;
4324 inc_rfc1001_len(pSMB, byte_count);
4325 pSMB->ByteCount = cpu_to_le16(byte_count);
4327 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4328 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4330 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4332 /* decode response */
4333 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4334 /* BB also check enough total bytes returned */
4335 if (rc || get_bcc(&pSMBr->hdr) < 2)
4336 /* If rc should we check for EOPNOSUPP and
4337 disable the srvino flag? or in caller? */
4338 rc = -EIO; /* bad smb */
4340 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4341 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4342 struct file_internal_info *pfinfo;
4343 /* BB Do we need a cast or hash here ? */
4345 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4347 goto GetInodeNumOut;
4349 pfinfo = (struct file_internal_info *)
4350 (data_offset + (char *) &pSMBr->hdr.Protocol);
4351 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4355 cifs_buf_release(pSMB);
4357 goto GetInodeNumberRetry;
4362 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4363 const char *search_name, struct dfs_info3_param **target_nodes,
4364 unsigned int *num_of_nodes,
4365 const struct nls_table *nls_codepage, int remap)
4367 /* TRANS2_GET_DFS_REFERRAL */
4368 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4369 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4373 __u16 params, byte_count;
4375 *target_nodes = NULL;
4377 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4378 if (ses == NULL || ses->tcon_ipc == NULL)
4383 * Use smb_init_no_reconnect() instead of smb_init() as
4384 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4385 * causing an infinite recursion.
4387 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4388 (void **)&pSMB, (void **)&pSMBr);
4392 /* server pointer checked in called function,
4393 but should never be null here anyway */
4394 pSMB->hdr.Mid = get_next_mid(ses->server);
4395 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4396 pSMB->hdr.Uid = ses->Suid;
4397 if (ses->capabilities & CAP_STATUS32)
4398 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4399 if (ses->capabilities & CAP_DFS)
4400 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4402 if (ses->capabilities & CAP_UNICODE) {
4403 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4405 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4406 search_name, PATH_MAX, nls_codepage,
4408 name_len++; /* trailing null */
4410 } else { /* BB improve the check for buffer overruns BB */
4411 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4414 if (ses->server->sign)
4415 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4417 pSMB->hdr.Uid = ses->Suid;
4419 params = 2 /* level */ + name_len /*includes null */ ;
4420 pSMB->TotalDataCount = 0;
4421 pSMB->DataCount = 0;
4422 pSMB->DataOffset = 0;
4423 pSMB->MaxParameterCount = 0;
4424 /* BB find exact max SMB PDU from sess structure BB */
4425 pSMB->MaxDataCount = cpu_to_le16(4000);
4426 pSMB->MaxSetupCount = 0;
4430 pSMB->Reserved2 = 0;
4431 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4432 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4433 pSMB->SetupCount = 1;
4434 pSMB->Reserved3 = 0;
4435 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4436 byte_count = params + 3 /* pad */ ;
4437 pSMB->ParameterCount = cpu_to_le16(params);
4438 pSMB->TotalParameterCount = pSMB->ParameterCount;
4439 pSMB->MaxReferralLevel = cpu_to_le16(3);
4440 inc_rfc1001_len(pSMB, byte_count);
4441 pSMB->ByteCount = cpu_to_le16(byte_count);
4443 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4444 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4446 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4449 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4451 /* BB Also check if enough total bytes returned? */
4452 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4453 rc = -EIO; /* bad smb */
4457 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4458 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4460 /* parse returned result into more usable form */
4461 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4462 le16_to_cpu(pSMBr->t2.DataCount),
4463 num_of_nodes, target_nodes, nls_codepage,
4465 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4468 cifs_buf_release(pSMB);
4476 /* Query File System Info such as free space to old servers such as Win 9x */
4478 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4479 struct kstatfs *FSData)
4481 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4482 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4483 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4484 FILE_SYSTEM_ALLOC_INFO *response_data;
4486 int bytes_returned = 0;
4487 __u16 params, byte_count;
4489 cifs_dbg(FYI, "OldQFSInfo\n");
4491 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4496 params = 2; /* level */
4497 pSMB->TotalDataCount = 0;
4498 pSMB->MaxParameterCount = cpu_to_le16(2);
4499 pSMB->MaxDataCount = cpu_to_le16(1000);
4500 pSMB->MaxSetupCount = 0;
4504 pSMB->Reserved2 = 0;
4505 byte_count = params + 1 /* pad */ ;
4506 pSMB->TotalParameterCount = cpu_to_le16(params);
4507 pSMB->ParameterCount = pSMB->TotalParameterCount;
4508 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4509 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4510 pSMB->DataCount = 0;
4511 pSMB->DataOffset = 0;
4512 pSMB->SetupCount = 1;
4513 pSMB->Reserved3 = 0;
4514 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4515 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4516 inc_rfc1001_len(pSMB, byte_count);
4517 pSMB->ByteCount = cpu_to_le16(byte_count);
4519 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4520 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4522 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4523 } else { /* decode response */
4524 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4526 if (rc || get_bcc(&pSMBr->hdr) < 18)
4527 rc = -EIO; /* bad smb */
4529 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4530 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4531 get_bcc(&pSMBr->hdr), data_offset);
4533 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4534 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4536 le16_to_cpu(response_data->BytesPerSector) *
4537 le32_to_cpu(response_data->
4538 SectorsPerAllocationUnit);
4540 * much prefer larger but if server doesn't report
4541 * a valid size than 4K is a reasonable minimum
4543 if (FSData->f_bsize < 512)
4544 FSData->f_bsize = 4096;
4547 le32_to_cpu(response_data->TotalAllocationUnits);
4548 FSData->f_bfree = FSData->f_bavail =
4549 le32_to_cpu(response_data->FreeAllocationUnits);
4550 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4551 (unsigned long long)FSData->f_blocks,
4552 (unsigned long long)FSData->f_bfree,
4556 cifs_buf_release(pSMB);
4559 goto oldQFSInfoRetry;
4565 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4566 struct kstatfs *FSData)
4568 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4569 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4570 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4571 FILE_SYSTEM_INFO *response_data;
4573 int bytes_returned = 0;
4574 __u16 params, byte_count;
4576 cifs_dbg(FYI, "In QFSInfo\n");
4578 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4583 params = 2; /* level */
4584 pSMB->TotalDataCount = 0;
4585 pSMB->MaxParameterCount = cpu_to_le16(2);
4586 pSMB->MaxDataCount = cpu_to_le16(1000);
4587 pSMB->MaxSetupCount = 0;
4591 pSMB->Reserved2 = 0;
4592 byte_count = params + 1 /* pad */ ;
4593 pSMB->TotalParameterCount = cpu_to_le16(params);
4594 pSMB->ParameterCount = pSMB->TotalParameterCount;
4595 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4596 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4597 pSMB->DataCount = 0;
4598 pSMB->DataOffset = 0;
4599 pSMB->SetupCount = 1;
4600 pSMB->Reserved3 = 0;
4601 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4602 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4603 inc_rfc1001_len(pSMB, byte_count);
4604 pSMB->ByteCount = cpu_to_le16(byte_count);
4606 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4607 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4609 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4610 } else { /* decode response */
4611 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4613 if (rc || get_bcc(&pSMBr->hdr) < 24)
4614 rc = -EIO; /* bad smb */
4616 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4620 *) (((char *) &pSMBr->hdr.Protocol) +
4623 le32_to_cpu(response_data->BytesPerSector) *
4624 le32_to_cpu(response_data->
4625 SectorsPerAllocationUnit);
4627 * much prefer larger but if server doesn't report
4628 * a valid size than 4K is a reasonable minimum
4630 if (FSData->f_bsize < 512)
4631 FSData->f_bsize = 4096;
4634 le64_to_cpu(response_data->TotalAllocationUnits);
4635 FSData->f_bfree = FSData->f_bavail =
4636 le64_to_cpu(response_data->FreeAllocationUnits);
4637 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4638 (unsigned long long)FSData->f_blocks,
4639 (unsigned long long)FSData->f_bfree,
4643 cifs_buf_release(pSMB);
4652 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
4654 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
4655 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4656 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4657 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
4659 int bytes_returned = 0;
4660 __u16 params, byte_count;
4662 cifs_dbg(FYI, "In QFSAttributeInfo\n");
4664 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4669 params = 2; /* level */
4670 pSMB->TotalDataCount = 0;
4671 pSMB->MaxParameterCount = cpu_to_le16(2);
4672 /* BB find exact max SMB PDU from sess structure BB */
4673 pSMB->MaxDataCount = cpu_to_le16(1000);
4674 pSMB->MaxSetupCount = 0;
4678 pSMB->Reserved2 = 0;
4679 byte_count = params + 1 /* pad */ ;
4680 pSMB->TotalParameterCount = cpu_to_le16(params);
4681 pSMB->ParameterCount = pSMB->TotalParameterCount;
4682 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4683 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4684 pSMB->DataCount = 0;
4685 pSMB->DataOffset = 0;
4686 pSMB->SetupCount = 1;
4687 pSMB->Reserved3 = 0;
4688 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4689 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4690 inc_rfc1001_len(pSMB, byte_count);
4691 pSMB->ByteCount = cpu_to_le16(byte_count);
4693 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4694 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4696 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
4697 } else { /* decode response */
4698 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4700 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4701 /* BB also check if enough bytes returned */
4702 rc = -EIO; /* bad smb */
4704 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4706 (FILE_SYSTEM_ATTRIBUTE_INFO
4707 *) (((char *) &pSMBr->hdr.Protocol) +
4709 memcpy(&tcon->fsAttrInfo, response_data,
4710 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
4713 cifs_buf_release(pSMB);
4716 goto QFSAttributeRetry;
4722 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
4724 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4725 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4726 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4727 FILE_SYSTEM_DEVICE_INFO *response_data;
4729 int bytes_returned = 0;
4730 __u16 params, byte_count;
4732 cifs_dbg(FYI, "In QFSDeviceInfo\n");
4734 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4739 params = 2; /* level */
4740 pSMB->TotalDataCount = 0;
4741 pSMB->MaxParameterCount = cpu_to_le16(2);
4742 /* BB find exact max SMB PDU from sess structure BB */
4743 pSMB->MaxDataCount = cpu_to_le16(1000);
4744 pSMB->MaxSetupCount = 0;
4748 pSMB->Reserved2 = 0;
4749 byte_count = params + 1 /* pad */ ;
4750 pSMB->TotalParameterCount = cpu_to_le16(params);
4751 pSMB->ParameterCount = pSMB->TotalParameterCount;
4752 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4753 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4755 pSMB->DataCount = 0;
4756 pSMB->DataOffset = 0;
4757 pSMB->SetupCount = 1;
4758 pSMB->Reserved3 = 0;
4759 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4760 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4761 inc_rfc1001_len(pSMB, byte_count);
4762 pSMB->ByteCount = cpu_to_le16(byte_count);
4764 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4765 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4767 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
4768 } else { /* decode response */
4769 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4771 if (rc || get_bcc(&pSMBr->hdr) <
4772 sizeof(FILE_SYSTEM_DEVICE_INFO))
4773 rc = -EIO; /* bad smb */
4775 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4777 (FILE_SYSTEM_DEVICE_INFO *)
4778 (((char *) &pSMBr->hdr.Protocol) +
4780 memcpy(&tcon->fsDevInfo, response_data,
4781 sizeof(FILE_SYSTEM_DEVICE_INFO));
4784 cifs_buf_release(pSMB);
4787 goto QFSDeviceRetry;
4793 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
4795 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
4796 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4797 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4798 FILE_SYSTEM_UNIX_INFO *response_data;
4800 int bytes_returned = 0;
4801 __u16 params, byte_count;
4803 cifs_dbg(FYI, "In QFSUnixInfo\n");
4805 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4806 (void **) &pSMB, (void **) &pSMBr);
4810 params = 2; /* level */
4811 pSMB->TotalDataCount = 0;
4812 pSMB->DataCount = 0;
4813 pSMB->DataOffset = 0;
4814 pSMB->MaxParameterCount = cpu_to_le16(2);
4815 /* BB find exact max SMB PDU from sess structure BB */
4816 pSMB->MaxDataCount = cpu_to_le16(100);
4817 pSMB->MaxSetupCount = 0;
4821 pSMB->Reserved2 = 0;
4822 byte_count = params + 1 /* pad */ ;
4823 pSMB->ParameterCount = cpu_to_le16(params);
4824 pSMB->TotalParameterCount = pSMB->ParameterCount;
4825 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4826 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4827 pSMB->SetupCount = 1;
4828 pSMB->Reserved3 = 0;
4829 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4830 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4831 inc_rfc1001_len(pSMB, byte_count);
4832 pSMB->ByteCount = cpu_to_le16(byte_count);
4834 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4835 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4837 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
4838 } else { /* decode response */
4839 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4841 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4842 rc = -EIO; /* bad smb */
4844 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4846 (FILE_SYSTEM_UNIX_INFO
4847 *) (((char *) &pSMBr->hdr.Protocol) +
4849 memcpy(&tcon->fsUnixInfo, response_data,
4850 sizeof(FILE_SYSTEM_UNIX_INFO));
4853 cifs_buf_release(pSMB);
4863 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
4865 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
4866 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
4867 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
4869 int bytes_returned = 0;
4870 __u16 params, param_offset, offset, byte_count;
4872 cifs_dbg(FYI, "In SETFSUnixInfo\n");
4874 /* BB switch to small buf init to save memory */
4875 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4876 (void **) &pSMB, (void **) &pSMBr);
4880 params = 4; /* 2 bytes zero followed by info level. */
4881 pSMB->MaxSetupCount = 0;
4885 pSMB->Reserved2 = 0;
4886 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
4888 offset = param_offset + params;
4890 pSMB->MaxParameterCount = cpu_to_le16(4);
4891 /* BB find exact max SMB PDU from sess structure BB */
4892 pSMB->MaxDataCount = cpu_to_le16(100);
4893 pSMB->SetupCount = 1;
4894 pSMB->Reserved3 = 0;
4895 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
4896 byte_count = 1 /* pad */ + params + 12;
4898 pSMB->DataCount = cpu_to_le16(12);
4899 pSMB->ParameterCount = cpu_to_le16(params);
4900 pSMB->TotalDataCount = pSMB->DataCount;
4901 pSMB->TotalParameterCount = pSMB->ParameterCount;
4902 pSMB->ParameterOffset = cpu_to_le16(param_offset);
4903 pSMB->DataOffset = cpu_to_le16(offset);
4907 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
4910 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
4911 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4912 pSMB->ClientUnixCap = cpu_to_le64(cap);
4914 inc_rfc1001_len(pSMB, byte_count);
4915 pSMB->ByteCount = cpu_to_le16(byte_count);
4917 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4918 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4920 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
4921 } else { /* decode response */
4922 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4924 rc = -EIO; /* bad smb */
4926 cifs_buf_release(pSMB);
4929 goto SETFSUnixRetry;
4937 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
4938 struct kstatfs *FSData)
4940 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
4941 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4942 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4943 FILE_SYSTEM_POSIX_INFO *response_data;
4945 int bytes_returned = 0;
4946 __u16 params, byte_count;
4948 cifs_dbg(FYI, "In QFSPosixInfo\n");
4950 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4955 params = 2; /* level */
4956 pSMB->TotalDataCount = 0;
4957 pSMB->DataCount = 0;
4958 pSMB->DataOffset = 0;
4959 pSMB->MaxParameterCount = cpu_to_le16(2);
4960 /* BB find exact max SMB PDU from sess structure BB */
4961 pSMB->MaxDataCount = cpu_to_le16(100);
4962 pSMB->MaxSetupCount = 0;
4966 pSMB->Reserved2 = 0;
4967 byte_count = params + 1 /* pad */ ;
4968 pSMB->ParameterCount = cpu_to_le16(params);
4969 pSMB->TotalParameterCount = pSMB->ParameterCount;
4970 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4971 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4972 pSMB->SetupCount = 1;
4973 pSMB->Reserved3 = 0;
4974 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4975 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4976 inc_rfc1001_len(pSMB, byte_count);
4977 pSMB->ByteCount = cpu_to_le16(byte_count);
4979 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4980 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4982 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
4983 } else { /* decode response */
4984 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4986 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4987 rc = -EIO; /* bad smb */
4989 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4991 (FILE_SYSTEM_POSIX_INFO
4992 *) (((char *) &pSMBr->hdr.Protocol) +
4995 le32_to_cpu(response_data->BlockSize);
4997 * much prefer larger but if server doesn't report
4998 * a valid size than 4K is a reasonable minimum
5000 if (FSData->f_bsize < 512)
5001 FSData->f_bsize = 4096;
5004 le64_to_cpu(response_data->TotalBlocks);
5006 le64_to_cpu(response_data->BlocksAvail);
5007 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5008 FSData->f_bavail = FSData->f_bfree;
5011 le64_to_cpu(response_data->UserBlocksAvail);
5013 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5015 le64_to_cpu(response_data->TotalFileNodes);
5016 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5018 le64_to_cpu(response_data->FreeFileNodes);
5021 cifs_buf_release(pSMB);
5031 * We can not use write of zero bytes trick to set file size due to need for
5032 * large file support. Also note that this SetPathInfo is preferred to
5033 * SetFileInfo based method in next routine which is only needed to work around
5034 * a sharing violation bugin Samba which this routine can run into.
5037 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5038 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5039 bool set_allocation, struct dentry *dentry)
5041 struct smb_com_transaction2_spi_req *pSMB = NULL;
5042 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5043 struct file_end_of_file_info *parm_data;
5046 int bytes_returned = 0;
5047 int remap = cifs_remap(cifs_sb);
5049 __u16 params, byte_count, data_count, param_offset, offset;
5051 cifs_dbg(FYI, "In SetEOF\n");
5053 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5058 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5060 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5061 PATH_MAX, cifs_sb->local_nls, remap);
5062 name_len++; /* trailing null */
5065 name_len = copy_path_name(pSMB->FileName, file_name);
5067 params = 6 + name_len;
5068 data_count = sizeof(struct file_end_of_file_info);
5069 pSMB->MaxParameterCount = cpu_to_le16(2);
5070 pSMB->MaxDataCount = cpu_to_le16(4100);
5071 pSMB->MaxSetupCount = 0;
5075 pSMB->Reserved2 = 0;
5076 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5077 InformationLevel) - 4;
5078 offset = param_offset + params;
5079 if (set_allocation) {
5080 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5081 pSMB->InformationLevel =
5082 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5084 pSMB->InformationLevel =
5085 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5086 } else /* Set File Size */ {
5087 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5088 pSMB->InformationLevel =
5089 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5091 pSMB->InformationLevel =
5092 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5096 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5098 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5099 pSMB->DataOffset = cpu_to_le16(offset);
5100 pSMB->SetupCount = 1;
5101 pSMB->Reserved3 = 0;
5102 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5103 byte_count = 3 /* pad */ + params + data_count;
5104 pSMB->DataCount = cpu_to_le16(data_count);
5105 pSMB->TotalDataCount = pSMB->DataCount;
5106 pSMB->ParameterCount = cpu_to_le16(params);
5107 pSMB->TotalParameterCount = pSMB->ParameterCount;
5108 pSMB->Reserved4 = 0;
5109 inc_rfc1001_len(pSMB, byte_count);
5110 parm_data->FileSize = cpu_to_le64(size);
5111 pSMB->ByteCount = cpu_to_le16(byte_count);
5112 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5113 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5115 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5117 cifs_buf_release(pSMB);
5126 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5127 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5129 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5130 struct file_end_of_file_info *parm_data;
5132 __u16 params, param_offset, offset, byte_count, count;
5134 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5136 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5141 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5142 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5145 pSMB->MaxSetupCount = 0;
5149 pSMB->Reserved2 = 0;
5150 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5151 offset = param_offset + params;
5153 count = sizeof(struct file_end_of_file_info);
5154 pSMB->MaxParameterCount = cpu_to_le16(2);
5155 /* BB find exact max SMB PDU from sess structure BB */
5156 pSMB->MaxDataCount = cpu_to_le16(1000);
5157 pSMB->SetupCount = 1;
5158 pSMB->Reserved3 = 0;
5159 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5160 byte_count = 3 /* pad */ + params + count;
5161 pSMB->DataCount = cpu_to_le16(count);
5162 pSMB->ParameterCount = cpu_to_le16(params);
5163 pSMB->TotalDataCount = pSMB->DataCount;
5164 pSMB->TotalParameterCount = pSMB->ParameterCount;
5165 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5166 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5168 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5169 pSMB->DataOffset = cpu_to_le16(offset);
5170 parm_data->FileSize = cpu_to_le64(size);
5171 pSMB->Fid = cfile->fid.netfid;
5172 if (set_allocation) {
5173 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5174 pSMB->InformationLevel =
5175 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5177 pSMB->InformationLevel =
5178 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5179 } else /* Set File Size */ {
5180 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5181 pSMB->InformationLevel =
5182 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5184 pSMB->InformationLevel =
5185 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5187 pSMB->Reserved4 = 0;
5188 inc_rfc1001_len(pSMB, byte_count);
5189 pSMB->ByteCount = cpu_to_le16(byte_count);
5190 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5191 cifs_small_buf_release(pSMB);
5193 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5197 /* Note: On -EAGAIN error only caller can retry on handle based calls
5198 since file handle passed in no longer valid */
5203 /* Some legacy servers such as NT4 require that the file times be set on
5204 an open handle, rather than by pathname - this is awkward due to
5205 potential access conflicts on the open, but it is unavoidable for these
5206 old servers since the only other choice is to go from 100 nanosecond DCE
5207 time and resort to the original setpathinfo level which takes the ancient
5208 DOS time format with 2 second granularity */
5210 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5211 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5213 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5216 __u16 params, param_offset, offset, byte_count, count;
5218 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5219 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5224 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5225 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5228 pSMB->MaxSetupCount = 0;
5232 pSMB->Reserved2 = 0;
5233 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5234 offset = param_offset + params;
5236 data_offset = (char *)pSMB +
5237 offsetof(struct smb_hdr, Protocol) + offset;
5239 count = sizeof(FILE_BASIC_INFO);
5240 pSMB->MaxParameterCount = cpu_to_le16(2);
5241 /* BB find max SMB PDU from sess */
5242 pSMB->MaxDataCount = cpu_to_le16(1000);
5243 pSMB->SetupCount = 1;
5244 pSMB->Reserved3 = 0;
5245 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5246 byte_count = 3 /* pad */ + params + count;
5247 pSMB->DataCount = cpu_to_le16(count);
5248 pSMB->ParameterCount = cpu_to_le16(params);
5249 pSMB->TotalDataCount = pSMB->DataCount;
5250 pSMB->TotalParameterCount = pSMB->ParameterCount;
5251 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5252 pSMB->DataOffset = cpu_to_le16(offset);
5254 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5255 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5257 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5258 pSMB->Reserved4 = 0;
5259 inc_rfc1001_len(pSMB, byte_count);
5260 pSMB->ByteCount = cpu_to_le16(byte_count);
5261 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5262 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5263 cifs_small_buf_release(pSMB);
5265 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5268 /* Note: On -EAGAIN error only caller can retry on handle based calls
5269 since file handle passed in no longer valid */
5275 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5276 bool delete_file, __u16 fid, __u32 pid_of_opener)
5278 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5281 __u16 params, param_offset, offset, byte_count, count;
5283 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5284 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5289 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5290 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5293 pSMB->MaxSetupCount = 0;
5297 pSMB->Reserved2 = 0;
5298 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5299 offset = param_offset + params;
5301 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5302 data_offset = (char *)(pSMB) + offset + 4;
5305 pSMB->MaxParameterCount = cpu_to_le16(2);
5306 /* BB find max SMB PDU from sess */
5307 pSMB->MaxDataCount = cpu_to_le16(1000);
5308 pSMB->SetupCount = 1;
5309 pSMB->Reserved3 = 0;
5310 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5311 byte_count = 3 /* pad */ + params + count;
5312 pSMB->DataCount = cpu_to_le16(count);
5313 pSMB->ParameterCount = cpu_to_le16(params);
5314 pSMB->TotalDataCount = pSMB->DataCount;
5315 pSMB->TotalParameterCount = pSMB->ParameterCount;
5316 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5317 pSMB->DataOffset = cpu_to_le16(offset);
5319 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5320 pSMB->Reserved4 = 0;
5321 inc_rfc1001_len(pSMB, byte_count);
5322 pSMB->ByteCount = cpu_to_le16(byte_count);
5323 *data_offset = delete_file ? 1 : 0;
5324 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5325 cifs_small_buf_release(pSMB);
5327 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5333 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5334 const char *fileName, const FILE_BASIC_INFO *data,
5335 const struct nls_table *nls_codepage,
5336 struct cifs_sb_info *cifs_sb)
5339 struct cifs_open_parms oparms;
5340 struct cifs_fid fid;
5343 oparms = (struct cifs_open_parms) {
5346 .desired_access = GENERIC_WRITE,
5347 .create_options = cifs_create_options(cifs_sb, 0),
5348 .disposition = FILE_OPEN,
5353 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5357 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5358 CIFSSMBClose(xid, tcon, fid.netfid);
5365 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5366 const char *fileName, const FILE_BASIC_INFO *data,
5367 const struct nls_table *nls_codepage,
5368 struct cifs_sb_info *cifs_sb)
5370 TRANSACTION2_SPI_REQ *pSMB = NULL;
5371 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5374 int bytes_returned = 0;
5376 __u16 params, param_offset, offset, byte_count, count;
5377 int remap = cifs_remap(cifs_sb);
5379 cifs_dbg(FYI, "In SetTimes\n");
5382 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5387 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5389 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5390 PATH_MAX, nls_codepage, remap);
5391 name_len++; /* trailing null */
5394 name_len = copy_path_name(pSMB->FileName, fileName);
5397 params = 6 + name_len;
5398 count = sizeof(FILE_BASIC_INFO);
5399 pSMB->MaxParameterCount = cpu_to_le16(2);
5400 /* BB find max SMB PDU from sess structure BB */
5401 pSMB->MaxDataCount = cpu_to_le16(1000);
5402 pSMB->MaxSetupCount = 0;
5406 pSMB->Reserved2 = 0;
5407 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5408 InformationLevel) - 4;
5409 offset = param_offset + params;
5410 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5411 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5412 pSMB->DataOffset = cpu_to_le16(offset);
5413 pSMB->SetupCount = 1;
5414 pSMB->Reserved3 = 0;
5415 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5416 byte_count = 3 /* pad */ + params + count;
5418 pSMB->DataCount = cpu_to_le16(count);
5419 pSMB->ParameterCount = cpu_to_le16(params);
5420 pSMB->TotalDataCount = pSMB->DataCount;
5421 pSMB->TotalParameterCount = pSMB->ParameterCount;
5422 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5423 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5425 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5426 pSMB->Reserved4 = 0;
5427 inc_rfc1001_len(pSMB, byte_count);
5428 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5429 pSMB->ByteCount = cpu_to_le16(byte_count);
5430 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5431 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5433 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5435 cifs_buf_release(pSMB);
5440 if (rc == -EOPNOTSUPP)
5441 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5442 nls_codepage, cifs_sb);
5448 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5449 const struct cifs_unix_set_info_args *args)
5451 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5452 u64 mode = args->mode;
5454 if (uid_valid(args->uid))
5455 uid = from_kuid(&init_user_ns, args->uid);
5456 if (gid_valid(args->gid))
5457 gid = from_kgid(&init_user_ns, args->gid);
5460 * Samba server ignores set of file size to zero due to bugs in some
5461 * older clients, but we should be precise - we use SetFileSize to
5462 * set file size and do not want to truncate file size to zero
5463 * accidentally as happened on one Samba server beta by putting
5464 * zero instead of -1 here
5466 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5467 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5468 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5469 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5470 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5471 data_offset->Uid = cpu_to_le64(uid);
5472 data_offset->Gid = cpu_to_le64(gid);
5473 /* better to leave device as zero when it is */
5474 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5475 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5476 data_offset->Permissions = cpu_to_le64(mode);
5479 data_offset->Type = cpu_to_le32(UNIX_FILE);
5480 else if (S_ISDIR(mode))
5481 data_offset->Type = cpu_to_le32(UNIX_DIR);
5482 else if (S_ISLNK(mode))
5483 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5484 else if (S_ISCHR(mode))
5485 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5486 else if (S_ISBLK(mode))
5487 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5488 else if (S_ISFIFO(mode))
5489 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5490 else if (S_ISSOCK(mode))
5491 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5495 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5496 const struct cifs_unix_set_info_args *args,
5497 u16 fid, u32 pid_of_opener)
5499 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5502 u16 params, param_offset, offset, byte_count, count;
5504 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5505 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5510 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5511 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5514 pSMB->MaxSetupCount = 0;
5518 pSMB->Reserved2 = 0;
5519 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5520 offset = param_offset + params;
5522 data_offset = (char *)pSMB +
5523 offsetof(struct smb_hdr, Protocol) + offset;
5525 count = sizeof(FILE_UNIX_BASIC_INFO);
5527 pSMB->MaxParameterCount = cpu_to_le16(2);
5528 /* BB find max SMB PDU from sess */
5529 pSMB->MaxDataCount = cpu_to_le16(1000);
5530 pSMB->SetupCount = 1;
5531 pSMB->Reserved3 = 0;
5532 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5533 byte_count = 3 /* pad */ + params + count;
5534 pSMB->DataCount = cpu_to_le16(count);
5535 pSMB->ParameterCount = cpu_to_le16(params);
5536 pSMB->TotalDataCount = pSMB->DataCount;
5537 pSMB->TotalParameterCount = pSMB->ParameterCount;
5538 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5539 pSMB->DataOffset = cpu_to_le16(offset);
5541 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5542 pSMB->Reserved4 = 0;
5543 inc_rfc1001_len(pSMB, byte_count);
5544 pSMB->ByteCount = cpu_to_le16(byte_count);
5546 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5548 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5549 cifs_small_buf_release(pSMB);
5551 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5554 /* Note: On -EAGAIN error only caller can retry on handle based calls
5555 since file handle passed in no longer valid */
5561 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5562 const char *file_name,
5563 const struct cifs_unix_set_info_args *args,
5564 const struct nls_table *nls_codepage, int remap)
5566 TRANSACTION2_SPI_REQ *pSMB = NULL;
5567 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5570 int bytes_returned = 0;
5571 FILE_UNIX_BASIC_INFO *data_offset;
5572 __u16 params, param_offset, offset, count, byte_count;
5574 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5576 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5581 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5583 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5584 PATH_MAX, nls_codepage, remap);
5585 name_len++; /* trailing null */
5588 name_len = copy_path_name(pSMB->FileName, file_name);
5591 params = 6 + name_len;
5592 count = sizeof(FILE_UNIX_BASIC_INFO);
5593 pSMB->MaxParameterCount = cpu_to_le16(2);
5594 /* BB find max SMB PDU from sess structure BB */
5595 pSMB->MaxDataCount = cpu_to_le16(1000);
5596 pSMB->MaxSetupCount = 0;
5600 pSMB->Reserved2 = 0;
5601 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5602 InformationLevel) - 4;
5603 offset = param_offset + params;
5604 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5605 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
5606 memset(data_offset, 0, count);
5607 pSMB->DataOffset = cpu_to_le16(offset);
5608 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5609 pSMB->SetupCount = 1;
5610 pSMB->Reserved3 = 0;
5611 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5612 byte_count = 3 /* pad */ + params + count;
5613 pSMB->ParameterCount = cpu_to_le16(params);
5614 pSMB->DataCount = cpu_to_le16(count);
5615 pSMB->TotalParameterCount = pSMB->ParameterCount;
5616 pSMB->TotalDataCount = pSMB->DataCount;
5617 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5618 pSMB->Reserved4 = 0;
5619 inc_rfc1001_len(pSMB, byte_count);
5621 cifs_fill_unix_set_info(data_offset, args);
5623 pSMB->ByteCount = cpu_to_le16(byte_count);
5624 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5625 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5627 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
5629 cifs_buf_release(pSMB);
5635 #ifdef CONFIG_CIFS_XATTR
5637 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
5638 * function used by listxattr and getxattr type calls. When ea_name is set,
5639 * it looks for that attribute name and stuffs that value into the EAData
5640 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
5641 * buffer. In both cases, the return value is either the length of the
5642 * resulting data or a negative error code. If EAData is a NULL pointer then
5643 * the data isn't copied to it, but the length is returned.
5646 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
5647 const unsigned char *searchName, const unsigned char *ea_name,
5648 char *EAData, size_t buf_size,
5649 struct cifs_sb_info *cifs_sb)
5651 /* BB assumes one setup word */
5652 TRANSACTION2_QPI_REQ *pSMB = NULL;
5653 TRANSACTION2_QPI_RSP *pSMBr = NULL;
5654 int remap = cifs_remap(cifs_sb);
5655 struct nls_table *nls_codepage = cifs_sb->local_nls;
5659 struct fealist *ea_response_data;
5660 struct fea *temp_fea;
5663 __u16 params, byte_count, data_offset;
5664 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
5666 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
5668 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5673 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5675 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
5676 PATH_MAX, nls_codepage, remap);
5677 list_len++; /* trailing null */
5680 list_len = copy_path_name(pSMB->FileName, searchName);
5683 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
5684 pSMB->TotalDataCount = 0;
5685 pSMB->MaxParameterCount = cpu_to_le16(2);
5686 /* BB find exact max SMB PDU from sess structure BB */
5687 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
5688 pSMB->MaxSetupCount = 0;
5692 pSMB->Reserved2 = 0;
5693 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5694 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5695 pSMB->DataCount = 0;
5696 pSMB->DataOffset = 0;
5697 pSMB->SetupCount = 1;
5698 pSMB->Reserved3 = 0;
5699 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
5700 byte_count = params + 1 /* pad */ ;
5701 pSMB->TotalParameterCount = cpu_to_le16(params);
5702 pSMB->ParameterCount = pSMB->TotalParameterCount;
5703 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5704 pSMB->Reserved4 = 0;
5705 inc_rfc1001_len(pSMB, byte_count);
5706 pSMB->ByteCount = cpu_to_le16(byte_count);
5708 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5709 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5711 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
5716 /* BB also check enough total bytes returned */
5717 /* BB we need to improve the validity checking
5718 of these trans2 responses */
5720 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5721 if (rc || get_bcc(&pSMBr->hdr) < 4) {
5722 rc = -EIO; /* bad smb */
5726 /* check that length of list is not more than bcc */
5727 /* check that each entry does not go beyond length
5729 /* check that each element of each entry does not
5730 go beyond end of list */
5731 /* validate_trans2_offsets() */
5732 /* BB check if start of smb + data_offset > &bcc+ bcc */
5734 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5735 ea_response_data = (struct fealist *)
5736 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5738 list_len = le32_to_cpu(ea_response_data->list_len);
5739 cifs_dbg(FYI, "ea length %d\n", list_len);
5740 if (list_len <= 8) {
5741 cifs_dbg(FYI, "empty EA list returned from server\n");
5742 /* didn't find the named attribute */
5748 /* make sure list_len doesn't go past end of SMB */
5749 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
5750 if ((char *)ea_response_data + list_len > end_of_smb) {
5751 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
5756 /* account for ea list len */
5758 temp_fea = &ea_response_data->list;
5759 temp_ptr = (char *)temp_fea;
5760 while (list_len > 0) {
5761 unsigned int name_len;
5766 /* make sure we can read name_len and value_len */
5768 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5773 name_len = temp_fea->name_len;
5774 value_len = le16_to_cpu(temp_fea->value_len);
5775 list_len -= name_len + 1 + value_len;
5777 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5783 if (ea_name_len == name_len &&
5784 memcmp(ea_name, temp_ptr, name_len) == 0) {
5785 temp_ptr += name_len + 1;
5789 if ((size_t)value_len > buf_size) {
5793 memcpy(EAData, temp_ptr, value_len);
5797 /* account for prefix user. and trailing null */
5798 rc += (5 + 1 + name_len);
5799 if (rc < (int) buf_size) {
5800 memcpy(EAData, "user.", 5);
5802 memcpy(EAData, temp_ptr, name_len);
5804 /* null terminate name */
5807 } else if (buf_size == 0) {
5808 /* skip copy - calc size only */
5810 /* stop before overrun buffer */
5815 temp_ptr += name_len + 1 + value_len;
5816 temp_fea = (struct fea *)temp_ptr;
5819 /* didn't find the named attribute */
5824 cifs_buf_release(pSMB);
5832 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
5833 const char *fileName, const char *ea_name, const void *ea_value,
5834 const __u16 ea_value_len, const struct nls_table *nls_codepage,
5835 struct cifs_sb_info *cifs_sb)
5837 struct smb_com_transaction2_spi_req *pSMB = NULL;
5838 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5839 struct fealist *parm_data;
5842 int bytes_returned = 0;
5843 __u16 params, param_offset, byte_count, offset, count;
5844 int remap = cifs_remap(cifs_sb);
5846 cifs_dbg(FYI, "In SetEA\n");
5848 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5853 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5855 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5856 PATH_MAX, nls_codepage, remap);
5857 name_len++; /* trailing null */
5860 name_len = copy_path_name(pSMB->FileName, fileName);
5863 params = 6 + name_len;
5865 /* done calculating parms using name_len of file name,
5866 now use name_len to calculate length of ea name
5867 we are going to create in the inode xattrs */
5868 if (ea_name == NULL)
5871 name_len = strnlen(ea_name, 255);
5873 count = sizeof(*parm_data) + 1 + ea_value_len + name_len;
5874 pSMB->MaxParameterCount = cpu_to_le16(2);
5875 /* BB find max SMB PDU from sess */
5876 pSMB->MaxDataCount = cpu_to_le16(1000);
5877 pSMB->MaxSetupCount = 0;
5881 pSMB->Reserved2 = 0;
5882 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5883 InformationLevel) - 4;
5884 offset = param_offset + params;
5885 pSMB->InformationLevel =
5886 cpu_to_le16(SMB_SET_FILE_EA);
5888 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
5889 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5890 pSMB->DataOffset = cpu_to_le16(offset);
5891 pSMB->SetupCount = 1;
5892 pSMB->Reserved3 = 0;
5893 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5894 byte_count = 3 /* pad */ + params + count;
5895 pSMB->DataCount = cpu_to_le16(count);
5896 parm_data->list_len = cpu_to_le32(count);
5897 parm_data->list.EA_flags = 0;
5898 /* we checked above that name len is less than 255 */
5899 parm_data->list.name_len = (__u8)name_len;
5900 /* EA names are always ASCII and NUL-terminated */
5901 strscpy(parm_data->list.name, ea_name ?: "", name_len + 1);
5902 parm_data->list.value_len = cpu_to_le16(ea_value_len);
5903 /* caller ensures that ea_value_len is less than 64K but
5904 we need to ensure that it fits within the smb */
5906 /*BB add length check to see if it would fit in
5907 negotiated SMB buffer size BB */
5908 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
5910 memcpy(parm_data->list.name + name_len + 1,
5911 ea_value, ea_value_len);
5913 pSMB->TotalDataCount = pSMB->DataCount;
5914 pSMB->ParameterCount = cpu_to_le16(params);
5915 pSMB->TotalParameterCount = pSMB->ParameterCount;
5916 pSMB->Reserved4 = 0;
5917 inc_rfc1001_len(pSMB, byte_count);
5918 pSMB->ByteCount = cpu_to_le16(byte_count);
5919 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5920 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5922 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
5924 cifs_buf_release(pSMB);