1 // SPDX-License-Identifier: LGPL-2.1
4 * Copyright (C) International Business Machines Corp., 2002,2010
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for constructing the SMB PDUs themselves
11 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
12 /* These are mostly routines that operate on a pathname, or on a tree id */
13 /* (mounted volume), but there are eight handle based routines which must be */
14 /* treated slightly differently for reconnection purposes since we never */
15 /* want to reuse a stale file handle and only the caller knows the file info */
18 #include <linux/kernel.h>
19 #include <linux/vfs.h>
20 #include <linux/slab.h>
21 #include <linux/posix_acl_xattr.h>
22 #include <linux/pagemap.h>
23 #include <linux/swap.h>
24 #include <linux/task_io_accounting_ops.h>
25 #include <linux/uaccess.h>
29 #include "cifsproto.h"
30 #include "cifs_unicode.h"
31 #include "cifs_debug.h"
33 #include "smbdirect.h"
34 #ifdef CONFIG_CIFS_DFS_UPCALL
35 #include "dfs_cache.h"
38 #ifdef CONFIG_CIFS_POSIX
43 {CIFS_PROT, "\2NT LM 0.12"},
44 {POSIX_PROT, "\2POSIX 2"},
52 {CIFS_PROT, "\2NT LM 0.12"},
57 /* define the number of elements in the cifs dialect array */
58 #ifdef CONFIG_CIFS_POSIX
59 #define CIFS_NUM_PROT 2
61 #define CIFS_NUM_PROT 1
62 #endif /* CIFS_POSIX */
65 /* reconnect the socket, tcon, and smb session if needed */
67 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
71 struct TCP_Server_Info *server;
72 struct nls_table *nls_codepage;
75 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
76 * tcp and smb session status done differently for those three - in the
86 * only tree disconnect, open, and write, (and ulogoff which does not
87 * have tcon) are allowed as we start umount
89 spin_lock(&tcon->tc_lock);
90 if (tcon->status == TID_EXITING) {
91 if (smb_command != SMB_COM_TREE_DISCONNECT) {
92 spin_unlock(&tcon->tc_lock);
93 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
98 spin_unlock(&tcon->tc_lock);
100 rc = cifs_wait_for_server_reconnect(server, tcon->retry);
104 spin_lock(&ses->chan_lock);
105 if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
106 spin_unlock(&ses->chan_lock);
109 spin_unlock(&ses->chan_lock);
111 nls_codepage = load_nls_default();
114 * Recheck after acquire mutex. If another thread is negotiating
115 * and the server never sends an answer the socket will be closed
116 * and tcpStatus set to reconnect.
118 spin_lock(&server->srv_lock);
119 if (server->tcpStatus == CifsNeedReconnect) {
120 spin_unlock(&server->srv_lock);
124 spin_unlock(&server->srv_lock);
127 * need to prevent multiple threads trying to simultaneously
128 * reconnect the same SMB session
130 spin_lock(&ses->chan_lock);
131 if (!cifs_chan_needs_reconnect(ses, server)) {
132 spin_unlock(&ses->chan_lock);
134 /* this means that we only need to tree connect */
135 if (tcon->need_reconnect)
136 goto skip_sess_setup;
141 spin_unlock(&ses->chan_lock);
143 mutex_lock(&ses->session_mutex);
144 rc = cifs_negotiate_protocol(0, ses, server);
146 rc = cifs_setup_session(0, ses, server, nls_codepage);
148 /* do we need to reconnect tcon? */
149 if (rc || !tcon->need_reconnect) {
150 mutex_unlock(&ses->session_mutex);
155 cifs_mark_open_files_invalid(tcon);
156 rc = cifs_tree_connect(0, tcon, nls_codepage);
157 mutex_unlock(&ses->session_mutex);
158 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
161 pr_warn_once("reconnect tcon failed rc = %d\n", rc);
165 atomic_inc(&tconInfoReconnectCount);
167 /* tell server Unix caps we support */
169 reset_cifs_unix_caps(0, tcon, NULL, NULL);
172 * Removed call to reopen open files here. It is safer (and faster) to
173 * reopen files one at a time as needed in read and write.
175 * FIXME: what about file locks? don't we need to reclaim them ASAP?
180 * Check if handle based operation so we know whether we can continue
181 * or not without returning to caller to reset file handle
183 switch (smb_command) {
184 case SMB_COM_READ_ANDX:
185 case SMB_COM_WRITE_ANDX:
187 case SMB_COM_FIND_CLOSE2:
188 case SMB_COM_LOCKING_ANDX:
192 unload_nls(nls_codepage);
196 /* Allocate and return pointer to an SMB request buffer, and set basic
197 SMB information in the SMB header. If the return code is zero, this
198 function must have filled in request_buf pointer */
200 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
205 rc = cifs_reconnect_tcon(tcon, smb_command);
209 *request_buf = cifs_small_buf_get();
210 if (*request_buf == NULL) {
211 /* BB should we add a retry in here if not a writepage? */
215 header_assemble((struct smb_hdr *) *request_buf, smb_command,
219 cifs_stats_inc(&tcon->num_smbs_sent);
225 small_smb_init_no_tc(const int smb_command, const int wct,
226 struct cifs_ses *ses, void **request_buf)
229 struct smb_hdr *buffer;
231 rc = small_smb_init(smb_command, wct, NULL, request_buf);
235 buffer = (struct smb_hdr *)*request_buf;
236 buffer->Mid = get_next_mid(ses->server);
237 if (ses->capabilities & CAP_UNICODE)
238 buffer->Flags2 |= SMBFLG2_UNICODE;
239 if (ses->capabilities & CAP_STATUS32)
240 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
242 /* uid, tid can stay at zero as set in header assemble */
244 /* BB add support for turning on the signing when
245 this function is used after 1st of session setup requests */
250 /* If the return code is zero, this function must fill in request_buf pointer */
252 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
253 void **request_buf, void **response_buf)
255 *request_buf = cifs_buf_get();
256 if (*request_buf == NULL) {
257 /* BB should we add a retry in here if not a writepage? */
260 /* Although the original thought was we needed the response buf for */
261 /* potential retries of smb operations it turns out we can determine */
262 /* from the mid flags when the request buffer can be resent without */
263 /* having to use a second distinct buffer for the response */
265 *response_buf = *request_buf;
267 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
271 cifs_stats_inc(&tcon->num_smbs_sent);
276 /* If the return code is zero, this function must fill in request_buf pointer */
278 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
279 void **request_buf, void **response_buf)
283 rc = cifs_reconnect_tcon(tcon, smb_command);
287 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
291 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
292 void **request_buf, void **response_buf)
294 spin_lock(&tcon->ses->chan_lock);
295 if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) ||
296 tcon->need_reconnect) {
297 spin_unlock(&tcon->ses->chan_lock);
300 spin_unlock(&tcon->ses->chan_lock);
302 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
305 static int validate_t2(struct smb_t2_rsp *pSMB)
307 unsigned int total_size;
309 /* check for plausible wct */
310 if (pSMB->hdr.WordCount < 10)
313 /* check for parm and data offset going beyond end of smb */
314 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
315 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
318 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
319 if (total_size >= 512)
322 /* check that bcc is at least as big as parms + data, and that it is
323 * less than negotiated smb buffer
325 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
326 if (total_size > get_bcc(&pSMB->hdr) ||
327 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
332 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
333 sizeof(struct smb_t2_rsp) + 16);
338 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
342 char *guid = pSMBr->u.extended_response.GUID;
343 struct TCP_Server_Info *server = ses->server;
345 count = get_bcc(&pSMBr->hdr);
346 if (count < SMB1_CLIENT_GUID_SIZE)
349 spin_lock(&cifs_tcp_ses_lock);
350 if (server->srv_count > 1) {
351 spin_unlock(&cifs_tcp_ses_lock);
352 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
353 cifs_dbg(FYI, "server UID changed\n");
354 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
357 spin_unlock(&cifs_tcp_ses_lock);
358 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
361 if (count == SMB1_CLIENT_GUID_SIZE) {
362 server->sec_ntlmssp = true;
364 count -= SMB1_CLIENT_GUID_SIZE;
365 rc = decode_negTokenInit(
366 pSMBr->u.extended_response.SecurityBlob, count, server);
375 should_set_ext_sec_flag(enum securityEnum sectype)
382 if (global_secflags &
383 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
392 CIFSSMBNegotiate(const unsigned int xid,
393 struct cifs_ses *ses,
394 struct TCP_Server_Info *server)
397 NEGOTIATE_RSP *pSMBr;
404 WARN(1, "%s: server is NULL!\n", __func__);
408 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
409 (void **) &pSMB, (void **) &pSMBr);
413 pSMB->hdr.Mid = get_next_mid(server);
414 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
416 if (should_set_ext_sec_flag(ses->sectype)) {
417 cifs_dbg(FYI, "Requesting extended security\n");
418 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
423 * We know that all the name entries in the protocols array
424 * are short (< 16 bytes anyway) and are NUL terminated.
426 for (i = 0; i < CIFS_NUM_PROT; i++) {
427 size_t len = strlen(protocols[i].name) + 1;
429 memcpy(&pSMB->DialectsArray[count], protocols[i].name, len);
432 inc_rfc1001_len(pSMB, count);
433 pSMB->ByteCount = cpu_to_le16(count);
435 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
436 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
440 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
441 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
442 /* Check wct = 1 error case */
443 if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
444 /* core returns wct = 1, but we do not ask for core - otherwise
445 small wct just comes when dialect index is -1 indicating we
446 could not negotiate a common dialect */
449 } else if (pSMBr->hdr.WordCount != 17) {
454 /* else wct == 17, NTLM or better */
456 server->sec_mode = pSMBr->SecurityMode;
457 if ((server->sec_mode & SECMODE_USER) == 0)
458 cifs_dbg(FYI, "share mode security\n");
460 /* one byte, so no need to convert this or EncryptionKeyLen from
462 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
464 set_credits(server, server->maxReq);
465 /* probably no need to store and check maxvcs */
466 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
467 /* set up max_read for readahead check */
468 server->max_read = server->maxBuf;
469 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
470 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
471 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
472 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
473 server->timeAdj *= 60;
475 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
476 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
477 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
478 CIFS_CRYPTO_KEY_SIZE);
479 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
480 server->capabilities & CAP_EXTENDED_SECURITY) {
481 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
482 rc = decode_ext_sec_blob(ses, pSMBr);
483 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
484 rc = -EIO; /* no crypt key only if plain text pwd */
486 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
487 server->capabilities &= ~CAP_EXTENDED_SECURITY;
491 rc = cifs_enable_signing(server, ses->sign);
493 cifs_buf_release(pSMB);
495 cifs_dbg(FYI, "negprot rc %d\n", rc);
500 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
502 struct smb_hdr *smb_buffer;
505 cifs_dbg(FYI, "In tree disconnect\n");
507 /* BB: do we need to check this? These should never be NULL. */
508 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
512 * No need to return error on this operation if tid invalidated and
513 * closed on server already e.g. due to tcp session crashing. Also,
514 * the tcon is no longer on the list, so no need to take lock before
517 spin_lock(&tcon->ses->chan_lock);
518 if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
519 spin_unlock(&tcon->ses->chan_lock);
522 spin_unlock(&tcon->ses->chan_lock);
524 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
525 (void **)&smb_buffer);
529 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
530 cifs_small_buf_release(smb_buffer);
532 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
534 /* No need to return error on this operation if tid invalidated and
535 closed on server already e.g. due to tcp session crashing */
543 * This is a no-op for now. We're not really interested in the reply, but
544 * rather in the fact that the server sent one and that server->lstrp
547 * FIXME: maybe we should consider checking that the reply matches request?
550 cifs_echo_callback(struct mid_q_entry *mid)
552 struct TCP_Server_Info *server = mid->callback_data;
553 struct cifs_credits credits = { .value = 1, .instance = 0 };
556 add_credits(server, &credits, CIFS_ECHO_OP);
560 CIFSSMBEcho(struct TCP_Server_Info *server)
565 struct smb_rqst rqst = { .rq_iov = iov,
568 cifs_dbg(FYI, "In echo request\n");
570 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
574 if (server->capabilities & CAP_UNICODE)
575 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
577 /* set up echo request */
578 smb->hdr.Tid = 0xffff;
579 smb->hdr.WordCount = 1;
580 put_unaligned_le16(1, &smb->EchoCount);
581 put_bcc(1, &smb->hdr);
583 inc_rfc1001_len(smb, 3);
586 iov[0].iov_base = smb;
587 iov[1].iov_len = get_rfc1002_length(smb);
588 iov[1].iov_base = (char *)smb + 4;
590 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
591 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
593 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
595 cifs_small_buf_release(smb);
601 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
603 LOGOFF_ANDX_REQ *pSMB;
606 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
609 * BB: do we need to check validity of ses and server? They should
610 * always be valid since we have an active reference. If not, that
611 * should probably be a BUG()
613 if (!ses || !ses->server)
616 mutex_lock(&ses->session_mutex);
617 spin_lock(&ses->chan_lock);
618 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
619 spin_unlock(&ses->chan_lock);
620 goto session_already_dead; /* no need to send SMBlogoff if uid
621 already closed due to reconnect */
623 spin_unlock(&ses->chan_lock);
625 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
627 mutex_unlock(&ses->session_mutex);
631 pSMB->hdr.Mid = get_next_mid(ses->server);
633 if (ses->server->sign)
634 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
636 pSMB->hdr.Uid = ses->Suid;
638 pSMB->AndXCommand = 0xFF;
639 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
640 cifs_small_buf_release(pSMB);
641 session_already_dead:
642 mutex_unlock(&ses->session_mutex);
644 /* if session dead then we do not need to do ulogoff,
645 since server closed smb session, no sense reporting
653 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
654 const char *fileName, __u16 type,
655 const struct nls_table *nls_codepage, int remap)
657 TRANSACTION2_SPI_REQ *pSMB = NULL;
658 TRANSACTION2_SPI_RSP *pSMBr = NULL;
659 struct unlink_psx_rq *pRqD;
662 int bytes_returned = 0;
663 __u16 params, param_offset, offset, byte_count;
665 cifs_dbg(FYI, "In POSIX delete\n");
667 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
672 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
674 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
675 PATH_MAX, nls_codepage, remap);
676 name_len++; /* trailing null */
679 name_len = copy_path_name(pSMB->FileName, fileName);
682 params = 6 + name_len;
683 pSMB->MaxParameterCount = cpu_to_le16(2);
684 pSMB->MaxDataCount = 0; /* BB double check this with jra */
685 pSMB->MaxSetupCount = 0;
690 param_offset = offsetof(struct smb_com_transaction2_spi_req,
691 InformationLevel) - 4;
692 offset = param_offset + params;
694 /* Setup pointer to Request Data (inode type).
695 * Note that SMB offsets are from the beginning of SMB which is 4 bytes
696 * in, after RFC1001 field
698 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
699 pRqD->type = cpu_to_le16(type);
700 pSMB->ParameterOffset = cpu_to_le16(param_offset);
701 pSMB->DataOffset = cpu_to_le16(offset);
702 pSMB->SetupCount = 1;
704 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
705 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
707 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
708 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
709 pSMB->ParameterCount = cpu_to_le16(params);
710 pSMB->TotalParameterCount = pSMB->ParameterCount;
711 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
713 inc_rfc1001_len(pSMB, byte_count);
714 pSMB->ByteCount = cpu_to_le16(byte_count);
715 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
716 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
718 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
719 cifs_buf_release(pSMB);
721 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
730 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
731 struct cifs_sb_info *cifs_sb)
733 DELETE_FILE_REQ *pSMB = NULL;
734 DELETE_FILE_RSP *pSMBr = NULL;
738 int remap = cifs_remap(cifs_sb);
741 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
746 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
747 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
748 PATH_MAX, cifs_sb->local_nls,
750 name_len++; /* trailing null */
753 name_len = copy_path_name(pSMB->fileName, name);
755 pSMB->SearchAttributes =
756 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
757 pSMB->BufferFormat = 0x04;
758 inc_rfc1001_len(pSMB, name_len + 1);
759 pSMB->ByteCount = cpu_to_le16(name_len + 1);
760 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
761 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
762 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
764 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
766 cifs_buf_release(pSMB);
774 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
775 struct cifs_sb_info *cifs_sb)
777 DELETE_DIRECTORY_REQ *pSMB = NULL;
778 DELETE_DIRECTORY_RSP *pSMBr = NULL;
782 int remap = cifs_remap(cifs_sb);
784 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
786 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
791 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
792 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
793 PATH_MAX, cifs_sb->local_nls,
795 name_len++; /* trailing null */
798 name_len = copy_path_name(pSMB->DirName, name);
801 pSMB->BufferFormat = 0x04;
802 inc_rfc1001_len(pSMB, name_len + 1);
803 pSMB->ByteCount = cpu_to_le16(name_len + 1);
804 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
805 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
806 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
808 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
810 cifs_buf_release(pSMB);
817 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
818 struct cifs_tcon *tcon, const char *name,
819 struct cifs_sb_info *cifs_sb)
822 CREATE_DIRECTORY_REQ *pSMB = NULL;
823 CREATE_DIRECTORY_RSP *pSMBr = NULL;
826 int remap = cifs_remap(cifs_sb);
828 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
830 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
835 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
836 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
837 PATH_MAX, cifs_sb->local_nls,
839 name_len++; /* trailing null */
842 name_len = copy_path_name(pSMB->DirName, name);
845 pSMB->BufferFormat = 0x04;
846 inc_rfc1001_len(pSMB, name_len + 1);
847 pSMB->ByteCount = cpu_to_le16(name_len + 1);
848 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
849 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
850 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
852 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
854 cifs_buf_release(pSMB);
861 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
862 __u32 posix_flags, __u64 mode, __u16 *netfid,
863 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
864 const char *name, const struct nls_table *nls_codepage,
867 TRANSACTION2_SPI_REQ *pSMB = NULL;
868 TRANSACTION2_SPI_RSP *pSMBr = NULL;
871 int bytes_returned = 0;
872 __u16 params, param_offset, offset, byte_count, count;
874 OPEN_PSX_RSP *psx_rsp;
876 cifs_dbg(FYI, "In POSIX Create\n");
878 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
883 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
885 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
886 PATH_MAX, nls_codepage, remap);
887 name_len++; /* trailing null */
890 name_len = copy_path_name(pSMB->FileName, name);
893 params = 6 + name_len;
894 count = sizeof(OPEN_PSX_REQ);
895 pSMB->MaxParameterCount = cpu_to_le16(2);
896 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
897 pSMB->MaxSetupCount = 0;
902 param_offset = offsetof(struct smb_com_transaction2_spi_req,
903 InformationLevel) - 4;
904 offset = param_offset + params;
905 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
906 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
907 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
908 pdata->Permissions = cpu_to_le64(mode);
909 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
910 pdata->OpenFlags = cpu_to_le32(*pOplock);
911 pSMB->ParameterOffset = cpu_to_le16(param_offset);
912 pSMB->DataOffset = cpu_to_le16(offset);
913 pSMB->SetupCount = 1;
915 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
916 byte_count = 3 /* pad */ + params + count;
918 pSMB->DataCount = cpu_to_le16(count);
919 pSMB->ParameterCount = cpu_to_le16(params);
920 pSMB->TotalDataCount = pSMB->DataCount;
921 pSMB->TotalParameterCount = pSMB->ParameterCount;
922 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
924 inc_rfc1001_len(pSMB, byte_count);
925 pSMB->ByteCount = cpu_to_le16(byte_count);
926 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
927 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
929 cifs_dbg(FYI, "Posix create returned %d\n", rc);
933 cifs_dbg(FYI, "copying inode info\n");
934 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
936 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
937 rc = -EIO; /* bad smb */
941 /* copy return information to pRetData */
942 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
943 + le16_to_cpu(pSMBr->t2.DataOffset));
945 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
947 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
948 /* Let caller know file was created so we can set the mode. */
949 /* Do we care about the CreateAction in any other cases? */
950 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
951 *pOplock |= CIFS_CREATE_ACTION;
952 /* check to make sure response data is there */
953 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
954 pRetData->Type = cpu_to_le32(-1); /* unknown */
955 cifs_dbg(NOISY, "unknown type\n");
957 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
958 + sizeof(FILE_UNIX_BASIC_INFO)) {
959 cifs_dbg(VFS, "Open response data too small\n");
960 pRetData->Type = cpu_to_le32(-1);
963 memcpy((char *) pRetData,
964 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
965 sizeof(FILE_UNIX_BASIC_INFO));
969 cifs_buf_release(pSMB);
971 if (posix_flags & SMB_O_DIRECTORY)
972 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
974 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
982 static __u16 convert_disposition(int disposition)
986 switch (disposition) {
988 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
991 ofun = SMBOPEN_OAPPEND;
994 ofun = SMBOPEN_OCREATE;
997 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1000 ofun = SMBOPEN_OTRUNC;
1002 case FILE_OVERWRITE_IF:
1003 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1006 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1007 ofun = SMBOPEN_OAPPEND; /* regular open */
1013 access_flags_to_smbopen_mode(const int access_flags)
1015 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1017 if (masked_flags == GENERIC_READ)
1018 return SMBOPEN_READ;
1019 else if (masked_flags == GENERIC_WRITE)
1020 return SMBOPEN_WRITE;
1022 /* just go for read/write */
1023 return SMBOPEN_READWRITE;
1027 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1028 const char *fileName, const int openDisposition,
1029 const int access_flags, const int create_options, __u16 *netfid,
1030 int *pOplock, FILE_ALL_INFO *pfile_info,
1031 const struct nls_table *nls_codepage, int remap)
1034 OPENX_REQ *pSMB = NULL;
1035 OPENX_RSP *pSMBr = NULL;
1041 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1046 pSMB->AndXCommand = 0xFF; /* none */
1048 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1049 count = 1; /* account for one byte pad to word boundary */
1051 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1052 fileName, PATH_MAX, nls_codepage, remap);
1053 name_len++; /* trailing null */
1056 count = 0; /* no pad */
1057 name_len = copy_path_name(pSMB->fileName, fileName);
1059 if (*pOplock & REQ_OPLOCK)
1060 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1061 else if (*pOplock & REQ_BATCHOPLOCK)
1062 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1064 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1065 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1066 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1067 /* set file as system file if special file such
1068 as fifo and server expecting SFU style and
1069 no Unix extensions */
1071 if (create_options & CREATE_OPTION_SPECIAL)
1072 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1073 else /* BB FIXME BB */
1074 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1076 if (create_options & CREATE_OPTION_READONLY)
1077 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1080 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1081 CREATE_OPTIONS_MASK); */
1082 /* BB FIXME END BB */
1084 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1085 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1087 inc_rfc1001_len(pSMB, count);
1089 pSMB->ByteCount = cpu_to_le16(count);
1090 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1091 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1092 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1094 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1096 /* BB verify if wct == 15 */
1098 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1100 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1101 /* Let caller know file was created so we can set the mode. */
1102 /* Do we care about the CreateAction in any other cases? */
1104 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1105 *pOplock |= CIFS_CREATE_ACTION; */
1109 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1110 pfile_info->LastAccessTime = 0; /* BB fixme */
1111 pfile_info->LastWriteTime = 0; /* BB fixme */
1112 pfile_info->ChangeTime = 0; /* BB fixme */
1113 pfile_info->Attributes =
1114 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1115 /* the file_info buf is endian converted by caller */
1116 pfile_info->AllocationSize =
1117 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1118 pfile_info->EndOfFile = pfile_info->AllocationSize;
1119 pfile_info->NumberOfLinks = cpu_to_le32(1);
1120 pfile_info->DeletePending = 0;
1124 cifs_buf_release(pSMB);
1131 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1135 OPEN_REQ *req = NULL;
1136 OPEN_RSP *rsp = NULL;
1140 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1141 struct cifs_tcon *tcon = oparms->tcon;
1142 int remap = cifs_remap(cifs_sb);
1143 const struct nls_table *nls = cifs_sb->local_nls;
1144 int create_options = oparms->create_options;
1145 int desired_access = oparms->desired_access;
1146 int disposition = oparms->disposition;
1147 const char *path = oparms->path;
1150 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1155 /* no commands go after this */
1156 req->AndXCommand = 0xFF;
1158 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1159 /* account for one byte pad to word boundary */
1161 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1162 path, PATH_MAX, nls, remap);
1166 req->NameLength = cpu_to_le16(name_len);
1168 /* BB improve check for buffer overruns BB */
1171 name_len = copy_path_name(req->fileName, path);
1172 req->NameLength = cpu_to_le16(name_len);
1175 if (*oplock & REQ_OPLOCK)
1176 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1177 else if (*oplock & REQ_BATCHOPLOCK)
1178 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1180 req->DesiredAccess = cpu_to_le32(desired_access);
1181 req->AllocationSize = 0;
1184 * Set file as system file if special file such as fifo and server
1185 * expecting SFU style and no Unix extensions.
1187 if (create_options & CREATE_OPTION_SPECIAL)
1188 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1190 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1193 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1194 * sensitive checks for other servers such as Samba.
1196 if (tcon->ses->capabilities & CAP_UNIX)
1197 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1199 if (create_options & CREATE_OPTION_READONLY)
1200 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1202 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1203 req->CreateDisposition = cpu_to_le32(disposition);
1204 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1206 /* BB Expirement with various impersonation levels and verify */
1207 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1208 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1211 inc_rfc1001_len(req, count);
1213 req->ByteCount = cpu_to_le16(count);
1214 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1215 (struct smb_hdr *)rsp, &bytes_returned, 0);
1216 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1218 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1219 cifs_buf_release(req);
1225 /* 1 byte no need to le_to_cpu */
1226 *oplock = rsp->OplockLevel;
1227 /* cifs fid stays in le */
1228 oparms->fid->netfid = rsp->Fid;
1229 oparms->fid->access = desired_access;
1231 /* Let caller know file was created so we can set the mode. */
1232 /* Do we care about the CreateAction in any other cases? */
1233 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1234 *oplock |= CIFS_CREATE_ACTION;
1237 /* copy commonly used attributes */
1238 memcpy(&buf->common_attributes,
1239 &rsp->common_attributes,
1240 sizeof(buf->common_attributes));
1241 /* the file_info buf is endian converted by caller */
1242 buf->AllocationSize = rsp->AllocationSize;
1243 buf->EndOfFile = rsp->EndOfFile;
1244 buf->NumberOfLinks = cpu_to_le32(1);
1245 buf->DeletePending = 0;
1248 cifs_buf_release(req);
1253 cifs_readv_callback(struct mid_q_entry *mid)
1255 struct cifs_readdata *rdata = mid->callback_data;
1256 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1257 struct TCP_Server_Info *server = tcon->ses->server;
1258 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1260 .rq_pages = rdata->pages,
1261 .rq_offset = rdata->page_offset,
1262 .rq_npages = rdata->nr_pages,
1263 .rq_pagesz = rdata->pagesz,
1264 .rq_tailsz = rdata->tailsz };
1265 struct cifs_credits credits = { .value = 1, .instance = 0 };
1267 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1268 __func__, mid->mid, mid->mid_state, rdata->result,
1271 switch (mid->mid_state) {
1272 case MID_RESPONSE_RECEIVED:
1273 /* result already set, check signature */
1277 rc = cifs_verify_signature(&rqst, server,
1278 mid->sequence_number);
1280 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1283 /* FIXME: should this be counted toward the initiating task? */
1284 task_io_account_read(rdata->got_bytes);
1285 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1287 case MID_REQUEST_SUBMITTED:
1288 case MID_RETRY_NEEDED:
1289 rdata->result = -EAGAIN;
1290 if (server->sign && rdata->got_bytes)
1291 /* reset bytes number since we can not check a sign */
1292 rdata->got_bytes = 0;
1293 /* FIXME: should this be counted toward the initiating task? */
1294 task_io_account_read(rdata->got_bytes);
1295 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1298 rdata->result = -EIO;
1301 queue_work(cifsiod_wq, &rdata->work);
1303 add_credits(server, &credits, 0);
1306 /* cifs_async_readv - send an async write, and set up mid to handle result */
1308 cifs_async_readv(struct cifs_readdata *rdata)
1311 READ_REQ *smb = NULL;
1313 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1314 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1317 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1318 __func__, rdata->offset, rdata->bytes);
1320 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1323 wct = 10; /* old style read */
1324 if ((rdata->offset >> 32) > 0) {
1325 /* can not handle this big offset for old */
1330 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1334 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1335 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1337 smb->AndXCommand = 0xFF; /* none */
1338 smb->Fid = rdata->cfile->fid.netfid;
1339 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1341 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1343 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1344 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1348 /* old style read */
1349 struct smb_com_readx_req *smbr =
1350 (struct smb_com_readx_req *)smb;
1351 smbr->ByteCount = 0;
1354 /* 4 for RFC1001 length + 1 for BCC */
1355 rdata->iov[0].iov_base = smb;
1356 rdata->iov[0].iov_len = 4;
1357 rdata->iov[1].iov_base = (char *)smb + 4;
1358 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1360 kref_get(&rdata->refcount);
1361 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1362 cifs_readv_callback, NULL, rdata, 0, NULL);
1365 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1367 kref_put(&rdata->refcount, cifs_readdata_release);
1369 cifs_small_buf_release(smb);
1374 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1375 unsigned int *nbytes, char **buf, int *pbuf_type)
1378 READ_REQ *pSMB = NULL;
1379 READ_RSP *pSMBr = NULL;
1380 char *pReadData = NULL;
1382 int resp_buf_type = 0;
1384 struct kvec rsp_iov;
1385 __u32 pid = io_parms->pid;
1386 __u16 netfid = io_parms->netfid;
1387 __u64 offset = io_parms->offset;
1388 struct cifs_tcon *tcon = io_parms->tcon;
1389 unsigned int count = io_parms->length;
1391 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1392 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1395 wct = 10; /* old style read */
1396 if ((offset >> 32) > 0) {
1397 /* can not handle this big offset for old */
1403 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1407 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1408 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1410 /* tcon and ses pointer are checked in smb_init */
1411 if (tcon->ses->server == NULL)
1412 return -ECONNABORTED;
1414 pSMB->AndXCommand = 0xFF; /* none */
1416 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1418 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1420 pSMB->Remaining = 0;
1421 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1422 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1424 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1426 /* old style read */
1427 struct smb_com_readx_req *pSMBW =
1428 (struct smb_com_readx_req *)pSMB;
1429 pSMBW->ByteCount = 0;
1432 iov[0].iov_base = (char *)pSMB;
1433 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1434 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1435 CIFS_LOG_ERROR, &rsp_iov);
1436 cifs_small_buf_release(pSMB);
1437 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1438 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1440 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1442 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1443 data_length = data_length << 16;
1444 data_length += le16_to_cpu(pSMBr->DataLength);
1445 *nbytes = data_length;
1447 /*check that DataLength would not go beyond end of SMB */
1448 if ((data_length > CIFSMaxBufSize)
1449 || (data_length > count)) {
1450 cifs_dbg(FYI, "bad length %d for count %d\n",
1451 data_length, count);
1455 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1456 le16_to_cpu(pSMBr->DataOffset);
1457 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1458 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1460 }*/ /* can not use copy_to_user when using page cache*/
1462 memcpy(*buf, pReadData, data_length);
1467 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1468 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1469 /* return buffer to caller to free */
1470 *buf = rsp_iov.iov_base;
1471 if (resp_buf_type == CIFS_SMALL_BUFFER)
1472 *pbuf_type = CIFS_SMALL_BUFFER;
1473 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1474 *pbuf_type = CIFS_LARGE_BUFFER;
1475 } /* else no valid buffer on return - leave as null */
1477 /* Note: On -EAGAIN error only caller can retry on handle based calls
1478 since file handle passed in no longer valid */
1484 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1485 unsigned int *nbytes, const char *buf)
1488 WRITE_REQ *pSMB = NULL;
1489 WRITE_RSP *pSMBr = NULL;
1490 int bytes_returned, wct;
1493 __u32 pid = io_parms->pid;
1494 __u16 netfid = io_parms->netfid;
1495 __u64 offset = io_parms->offset;
1496 struct cifs_tcon *tcon = io_parms->tcon;
1497 unsigned int count = io_parms->length;
1501 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1502 if (tcon->ses == NULL)
1503 return -ECONNABORTED;
1505 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1509 if ((offset >> 32) > 0) {
1510 /* can not handle big offset for old srv */
1515 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1520 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1521 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1523 /* tcon and ses pointer are checked in smb_init */
1524 if (tcon->ses->server == NULL)
1525 return -ECONNABORTED;
1527 pSMB->AndXCommand = 0xFF; /* none */
1529 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1531 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1533 pSMB->Reserved = 0xFFFFFFFF;
1534 pSMB->WriteMode = 0;
1535 pSMB->Remaining = 0;
1537 /* Can increase buffer size if buffer is big enough in some cases ie we
1538 can send more if LARGE_WRITE_X capability returned by the server and if
1539 our buffer is big enough or if we convert to iovecs on socket writes
1540 and eliminate the copy to the CIFS buffer */
1541 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1542 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1544 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1548 if (bytes_sent > count)
1551 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1553 memcpy(pSMB->Data, buf, bytes_sent);
1554 else if (count != 0) {
1556 cifs_buf_release(pSMB);
1558 } /* else setting file size with write of zero bytes */
1560 byte_count = bytes_sent + 1; /* pad */
1561 else /* wct == 12 */
1562 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1564 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1565 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1566 inc_rfc1001_len(pSMB, byte_count);
1569 pSMB->ByteCount = cpu_to_le16(byte_count);
1570 else { /* old style write has byte count 4 bytes earlier
1572 struct smb_com_writex_req *pSMBW =
1573 (struct smb_com_writex_req *)pSMB;
1574 pSMBW->ByteCount = cpu_to_le16(byte_count);
1577 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1578 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1579 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1581 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1583 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1584 *nbytes = (*nbytes) << 16;
1585 *nbytes += le16_to_cpu(pSMBr->Count);
1588 * Mask off high 16 bits when bytes written as returned by the
1589 * server is greater than bytes requested by the client. Some
1590 * OS/2 servers are known to set incorrect CountHigh values.
1592 if (*nbytes > count)
1596 cifs_buf_release(pSMB);
1598 /* Note: On -EAGAIN error only caller can retry on handle based calls
1599 since file handle passed in no longer valid */
1605 * Check the mid_state and signature on received buffer (if any), and queue the
1606 * workqueue completion task.
1609 cifs_writev_callback(struct mid_q_entry *mid)
1611 struct cifs_writedata *wdata = mid->callback_data;
1612 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1613 unsigned int written;
1614 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1615 struct cifs_credits credits = { .value = 1, .instance = 0 };
1617 switch (mid->mid_state) {
1618 case MID_RESPONSE_RECEIVED:
1619 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
1620 if (wdata->result != 0)
1623 written = le16_to_cpu(smb->CountHigh);
1625 written += le16_to_cpu(smb->Count);
1627 * Mask off high 16 bits when bytes written as returned
1628 * by the server is greater than bytes requested by the
1629 * client. OS/2 servers are known to set incorrect
1632 if (written > wdata->bytes)
1635 if (written < wdata->bytes)
1636 wdata->result = -ENOSPC;
1638 wdata->bytes = written;
1640 case MID_REQUEST_SUBMITTED:
1641 case MID_RETRY_NEEDED:
1642 wdata->result = -EAGAIN;
1645 wdata->result = -EIO;
1649 queue_work(cifsiod_wq, &wdata->work);
1651 add_credits(tcon->ses->server, &credits, 0);
1654 /* cifs_async_writev - send an async write, and set up mid to handle result */
1656 cifs_async_writev(struct cifs_writedata *wdata,
1657 void (*release)(struct kref *kref))
1660 WRITE_REQ *smb = NULL;
1662 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1664 struct smb_rqst rqst = { };
1666 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1670 if (wdata->offset >> 32 > 0) {
1671 /* can not handle big offset for old srv */
1676 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
1678 goto async_writev_out;
1680 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
1681 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
1683 smb->AndXCommand = 0xFF; /* none */
1684 smb->Fid = wdata->cfile->fid.netfid;
1685 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
1687 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
1688 smb->Reserved = 0xFFFFFFFF;
1693 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1695 /* 4 for RFC1001 length + 1 for BCC */
1697 iov[0].iov_base = smb;
1698 iov[1].iov_len = get_rfc1002_length(smb) + 1;
1699 iov[1].iov_base = (char *)smb + 4;
1703 rqst.rq_pages = wdata->pages;
1704 rqst.rq_offset = wdata->page_offset;
1705 rqst.rq_npages = wdata->nr_pages;
1706 rqst.rq_pagesz = wdata->pagesz;
1707 rqst.rq_tailsz = wdata->tailsz;
1709 cifs_dbg(FYI, "async write at %llu %u bytes\n",
1710 wdata->offset, wdata->bytes);
1712 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
1713 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
1716 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
1717 put_bcc(wdata->bytes + 1, &smb->hdr);
1720 struct smb_com_writex_req *smbw =
1721 (struct smb_com_writex_req *)smb;
1722 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
1723 put_bcc(wdata->bytes + 5, &smbw->hdr);
1724 iov[1].iov_len += 4; /* pad bigger by four bytes */
1727 kref_get(&wdata->refcount);
1728 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
1729 cifs_writev_callback, NULL, wdata, 0, NULL);
1732 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1734 kref_put(&wdata->refcount, release);
1737 cifs_small_buf_release(smb);
1742 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
1743 unsigned int *nbytes, struct kvec *iov, int n_vec)
1746 WRITE_REQ *pSMB = NULL;
1749 int resp_buf_type = 0;
1750 __u32 pid = io_parms->pid;
1751 __u16 netfid = io_parms->netfid;
1752 __u64 offset = io_parms->offset;
1753 struct cifs_tcon *tcon = io_parms->tcon;
1754 unsigned int count = io_parms->length;
1755 struct kvec rsp_iov;
1759 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
1761 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1765 if ((offset >> 32) > 0) {
1766 /* can not handle big offset for old srv */
1770 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
1774 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1775 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1777 /* tcon and ses pointer are checked in smb_init */
1778 if (tcon->ses->server == NULL)
1779 return -ECONNABORTED;
1781 pSMB->AndXCommand = 0xFF; /* none */
1783 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1785 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1786 pSMB->Reserved = 0xFFFFFFFF;
1787 pSMB->WriteMode = 0;
1788 pSMB->Remaining = 0;
1791 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1793 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1794 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1795 /* header + 1 byte pad */
1796 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
1798 inc_rfc1001_len(pSMB, count + 1);
1799 else /* wct == 12 */
1800 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
1802 pSMB->ByteCount = cpu_to_le16(count + 1);
1803 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1804 struct smb_com_writex_req *pSMBW =
1805 (struct smb_com_writex_req *)pSMB;
1806 pSMBW->ByteCount = cpu_to_le16(count + 5);
1808 iov[0].iov_base = pSMB;
1810 iov[0].iov_len = smb_hdr_len + 4;
1811 else /* wct == 12 pad bigger by four bytes */
1812 iov[0].iov_len = smb_hdr_len + 8;
1814 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
1816 cifs_small_buf_release(pSMB);
1817 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1819 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
1820 } else if (resp_buf_type == 0) {
1821 /* presumably this can not happen, but best to be safe */
1824 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
1825 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1826 *nbytes = (*nbytes) << 16;
1827 *nbytes += le16_to_cpu(pSMBr->Count);
1830 * Mask off high 16 bits when bytes written as returned by the
1831 * server is greater than bytes requested by the client. OS/2
1832 * servers are known to set incorrect CountHigh values.
1834 if (*nbytes > count)
1838 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1840 /* Note: On -EAGAIN error only caller can retry on handle based calls
1841 since file handle passed in no longer valid */
1846 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
1847 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
1848 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
1851 LOCK_REQ *pSMB = NULL;
1853 struct kvec rsp_iov;
1857 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
1858 num_lock, num_unlock);
1860 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1865 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
1866 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
1867 pSMB->LockType = lock_type;
1868 pSMB->AndXCommand = 0xFF; /* none */
1869 pSMB->Fid = netfid; /* netfid stays le */
1871 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1872 inc_rfc1001_len(pSMB, count);
1873 pSMB->ByteCount = cpu_to_le16(count);
1875 iov[0].iov_base = (char *)pSMB;
1876 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
1877 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1878 iov[1].iov_base = (char *)buf;
1879 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1881 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1882 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
1883 CIFS_NO_RSP_BUF, &rsp_iov);
1884 cifs_small_buf_release(pSMB);
1886 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
1892 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
1893 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
1894 const __u64 offset, const __u32 numUnlock,
1895 const __u32 numLock, const __u8 lockType,
1896 const bool waitFlag, const __u8 oplock_level)
1899 LOCK_REQ *pSMB = NULL;
1900 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
1905 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
1906 (int)waitFlag, numLock);
1907 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1912 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1913 /* no response expected */
1914 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
1916 } else if (waitFlag) {
1917 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1918 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
1923 pSMB->NumberOfLocks = cpu_to_le16(numLock);
1924 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
1925 pSMB->LockType = lockType;
1926 pSMB->OplockLevel = oplock_level;
1927 pSMB->AndXCommand = 0xFF; /* none */
1928 pSMB->Fid = smb_file_id; /* netfid stays le */
1930 if ((numLock != 0) || (numUnlock != 0)) {
1931 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
1932 /* BB where to store pid high? */
1933 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
1934 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
1935 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
1936 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
1937 count = sizeof(LOCKING_ANDX_RANGE);
1942 inc_rfc1001_len(pSMB, count);
1943 pSMB->ByteCount = cpu_to_le16(count);
1946 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1947 (struct smb_hdr *) pSMB, &bytes_returned);
1949 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
1950 cifs_small_buf_release(pSMB);
1951 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1953 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
1955 /* Note: On -EAGAIN error only caller can retry on handle based calls
1956 since file handle passed in no longer valid */
1961 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
1962 const __u16 smb_file_id, const __u32 netpid,
1963 const loff_t start_offset, const __u64 len,
1964 struct file_lock *pLockData, const __u16 lock_type,
1965 const bool waitFlag)
1967 struct smb_com_transaction2_sfi_req *pSMB = NULL;
1968 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
1969 struct cifs_posix_lock *parm_data;
1972 int bytes_returned = 0;
1973 int resp_buf_type = 0;
1974 __u16 params, param_offset, offset, byte_count, count;
1976 struct kvec rsp_iov;
1978 cifs_dbg(FYI, "Posix Lock\n");
1980 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
1985 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
1988 pSMB->MaxSetupCount = 0;
1991 pSMB->Reserved2 = 0;
1992 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
1993 offset = param_offset + params;
1995 count = sizeof(struct cifs_posix_lock);
1996 pSMB->MaxParameterCount = cpu_to_le16(2);
1997 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
1998 pSMB->SetupCount = 1;
1999 pSMB->Reserved3 = 0;
2001 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2003 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2004 byte_count = 3 /* pad */ + params + count;
2005 pSMB->DataCount = cpu_to_le16(count);
2006 pSMB->ParameterCount = cpu_to_le16(params);
2007 pSMB->TotalDataCount = pSMB->DataCount;
2008 pSMB->TotalParameterCount = pSMB->ParameterCount;
2009 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2010 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2011 parm_data = (struct cifs_posix_lock *)
2012 (((char *)pSMB) + offset + 4);
2014 parm_data->lock_type = cpu_to_le16(lock_type);
2016 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2017 parm_data->lock_flags = cpu_to_le16(1);
2018 pSMB->Timeout = cpu_to_le32(-1);
2022 parm_data->pid = cpu_to_le32(netpid);
2023 parm_data->start = cpu_to_le64(start_offset);
2024 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2026 pSMB->DataOffset = cpu_to_le16(offset);
2027 pSMB->Fid = smb_file_id;
2028 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2029 pSMB->Reserved4 = 0;
2030 inc_rfc1001_len(pSMB, byte_count);
2031 pSMB->ByteCount = cpu_to_le16(byte_count);
2033 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2034 (struct smb_hdr *) pSMBr, &bytes_returned);
2036 iov[0].iov_base = (char *)pSMB;
2037 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2038 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2039 &resp_buf_type, timeout, &rsp_iov);
2040 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2042 cifs_small_buf_release(pSMB);
2045 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2046 } else if (pLockData) {
2047 /* lock structure can be returned on get */
2050 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2052 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2053 rc = -EIO; /* bad smb */
2056 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2057 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2058 if (data_count < sizeof(struct cifs_posix_lock)) {
2062 parm_data = (struct cifs_posix_lock *)
2063 ((char *)&pSMBr->hdr.Protocol + data_offset);
2064 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2065 pLockData->fl_type = F_UNLCK;
2067 if (parm_data->lock_type ==
2068 cpu_to_le16(CIFS_RDLCK))
2069 pLockData->fl_type = F_RDLCK;
2070 else if (parm_data->lock_type ==
2071 cpu_to_le16(CIFS_WRLCK))
2072 pLockData->fl_type = F_WRLCK;
2074 pLockData->fl_start = le64_to_cpu(parm_data->start);
2075 pLockData->fl_end = pLockData->fl_start +
2076 (le64_to_cpu(parm_data->length) ?
2077 le64_to_cpu(parm_data->length) - 1 : 0);
2078 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2083 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2085 /* Note: On -EAGAIN error only caller can retry on handle based calls
2086 since file handle passed in no longer valid */
2093 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2096 CLOSE_REQ *pSMB = NULL;
2097 cifs_dbg(FYI, "In CIFSSMBClose\n");
2099 /* do not retry on dead session on close */
2100 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2106 pSMB->FileID = (__u16) smb_file_id;
2107 pSMB->LastWriteTime = 0xFFFFFFFF;
2108 pSMB->ByteCount = 0;
2109 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2110 cifs_small_buf_release(pSMB);
2111 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2114 /* EINTR is expected when user ctl-c to kill app */
2115 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2119 /* Since session is dead, file will be closed on server already */
2127 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2130 FLUSH_REQ *pSMB = NULL;
2131 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2133 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2137 pSMB->FileID = (__u16) smb_file_id;
2138 pSMB->ByteCount = 0;
2139 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2140 cifs_small_buf_release(pSMB);
2141 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2143 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2149 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2150 const char *from_name, const char *to_name,
2151 struct cifs_sb_info *cifs_sb)
2154 RENAME_REQ *pSMB = NULL;
2155 RENAME_RSP *pSMBr = NULL;
2157 int name_len, name_len2;
2159 int remap = cifs_remap(cifs_sb);
2161 cifs_dbg(FYI, "In CIFSSMBRename\n");
2163 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2168 pSMB->BufferFormat = 0x04;
2169 pSMB->SearchAttributes =
2170 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2173 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2174 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2175 from_name, PATH_MAX,
2176 cifs_sb->local_nls, remap);
2177 name_len++; /* trailing null */
2179 pSMB->OldFileName[name_len] = 0x04; /* pad */
2180 /* protocol requires ASCII signature byte on Unicode string */
2181 pSMB->OldFileName[name_len + 1] = 0x00;
2183 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2184 to_name, PATH_MAX, cifs_sb->local_nls,
2186 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2187 name_len2 *= 2; /* convert to bytes */
2189 name_len = copy_path_name(pSMB->OldFileName, from_name);
2190 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2191 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2192 name_len2++; /* signature byte */
2195 count = 1 /* 1st signature byte */ + name_len + name_len2;
2196 inc_rfc1001_len(pSMB, count);
2197 pSMB->ByteCount = cpu_to_le16(count);
2199 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2200 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2201 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2203 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2205 cifs_buf_release(pSMB);
2213 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2214 int netfid, const char *target_name,
2215 const struct nls_table *nls_codepage, int remap)
2217 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2218 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2219 struct set_file_rename *rename_info;
2221 char dummy_string[30];
2223 int bytes_returned = 0;
2225 __u16 params, param_offset, offset, count, byte_count;
2227 cifs_dbg(FYI, "Rename to File by handle\n");
2228 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2234 pSMB->MaxSetupCount = 0;
2238 pSMB->Reserved2 = 0;
2239 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2240 offset = param_offset + params;
2242 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2243 data_offset = (char *)(pSMB) + offset + 4;
2244 rename_info = (struct set_file_rename *) data_offset;
2245 pSMB->MaxParameterCount = cpu_to_le16(2);
2246 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2247 pSMB->SetupCount = 1;
2248 pSMB->Reserved3 = 0;
2249 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2250 byte_count = 3 /* pad */ + params;
2251 pSMB->ParameterCount = cpu_to_le16(params);
2252 pSMB->TotalParameterCount = pSMB->ParameterCount;
2253 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2254 pSMB->DataOffset = cpu_to_le16(offset);
2255 /* construct random name ".cifs_tmp<inodenum><mid>" */
2256 rename_info->overwrite = cpu_to_le32(1);
2257 rename_info->root_fid = 0;
2258 /* unicode only call */
2259 if (target_name == NULL) {
2260 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2262 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2263 dummy_string, 24, nls_codepage, remap);
2266 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2267 target_name, PATH_MAX, nls_codepage,
2270 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2271 count = sizeof(struct set_file_rename) + (2 * len_of_str);
2272 byte_count += count;
2273 pSMB->DataCount = cpu_to_le16(count);
2274 pSMB->TotalDataCount = pSMB->DataCount;
2276 pSMB->InformationLevel =
2277 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2278 pSMB->Reserved4 = 0;
2279 inc_rfc1001_len(pSMB, byte_count);
2280 pSMB->ByteCount = cpu_to_le16(byte_count);
2281 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2282 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2283 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2285 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2288 cifs_buf_release(pSMB);
2290 /* Note: On -EAGAIN error only caller can retry on handle based calls
2291 since file handle passed in no longer valid */
2297 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2298 const char *fromName, const __u16 target_tid, const char *toName,
2299 const int flags, const struct nls_table *nls_codepage, int remap)
2302 COPY_REQ *pSMB = NULL;
2303 COPY_RSP *pSMBr = NULL;
2305 int name_len, name_len2;
2308 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2310 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2315 pSMB->BufferFormat = 0x04;
2316 pSMB->Tid2 = target_tid;
2318 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2320 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2321 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2322 fromName, PATH_MAX, nls_codepage,
2324 name_len++; /* trailing null */
2326 pSMB->OldFileName[name_len] = 0x04; /* pad */
2327 /* protocol requires ASCII signature byte on Unicode string */
2328 pSMB->OldFileName[name_len + 1] = 0x00;
2330 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2331 toName, PATH_MAX, nls_codepage, remap);
2332 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2333 name_len2 *= 2; /* convert to bytes */
2335 name_len = copy_path_name(pSMB->OldFileName, fromName);
2336 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2337 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2338 name_len2++; /* signature byte */
2341 count = 1 /* 1st signature byte */ + name_len + name_len2;
2342 inc_rfc1001_len(pSMB, count);
2343 pSMB->ByteCount = cpu_to_le16(count);
2345 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2346 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2348 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2349 rc, le16_to_cpu(pSMBr->CopyCount));
2351 cifs_buf_release(pSMB);
2360 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2361 const char *fromName, const char *toName,
2362 const struct nls_table *nls_codepage, int remap)
2364 TRANSACTION2_SPI_REQ *pSMB = NULL;
2365 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2368 int name_len_target;
2370 int bytes_returned = 0;
2371 __u16 params, param_offset, offset, byte_count;
2373 cifs_dbg(FYI, "In Symlink Unix style\n");
2375 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2380 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2382 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2383 /* find define for this maxpathcomponent */
2384 PATH_MAX, nls_codepage, remap);
2385 name_len++; /* trailing null */
2389 name_len = copy_path_name(pSMB->FileName, fromName);
2391 params = 6 + name_len;
2392 pSMB->MaxSetupCount = 0;
2396 pSMB->Reserved2 = 0;
2397 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2398 InformationLevel) - 4;
2399 offset = param_offset + params;
2401 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2402 data_offset = (char *)pSMB + offset + 4;
2403 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2405 cifsConvertToUTF16((__le16 *) data_offset, toName,
2406 /* find define for this maxpathcomponent */
2407 PATH_MAX, nls_codepage, remap);
2408 name_len_target++; /* trailing null */
2409 name_len_target *= 2;
2411 name_len_target = copy_path_name(data_offset, toName);
2414 pSMB->MaxParameterCount = cpu_to_le16(2);
2415 /* BB find exact max on data count below from sess */
2416 pSMB->MaxDataCount = cpu_to_le16(1000);
2417 pSMB->SetupCount = 1;
2418 pSMB->Reserved3 = 0;
2419 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2420 byte_count = 3 /* pad */ + params + name_len_target;
2421 pSMB->DataCount = cpu_to_le16(name_len_target);
2422 pSMB->ParameterCount = cpu_to_le16(params);
2423 pSMB->TotalDataCount = pSMB->DataCount;
2424 pSMB->TotalParameterCount = pSMB->ParameterCount;
2425 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2426 pSMB->DataOffset = cpu_to_le16(offset);
2427 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2428 pSMB->Reserved4 = 0;
2429 inc_rfc1001_len(pSMB, byte_count);
2430 pSMB->ByteCount = cpu_to_le16(byte_count);
2431 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2432 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2433 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2435 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2438 cifs_buf_release(pSMB);
2441 goto createSymLinkRetry;
2447 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2448 const char *fromName, const char *toName,
2449 const struct nls_table *nls_codepage, int remap)
2451 TRANSACTION2_SPI_REQ *pSMB = NULL;
2452 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2455 int name_len_target;
2457 int bytes_returned = 0;
2458 __u16 params, param_offset, offset, byte_count;
2460 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2461 createHardLinkRetry:
2462 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2467 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2468 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2469 PATH_MAX, nls_codepage, remap);
2470 name_len++; /* trailing null */
2474 name_len = copy_path_name(pSMB->FileName, toName);
2476 params = 6 + name_len;
2477 pSMB->MaxSetupCount = 0;
2481 pSMB->Reserved2 = 0;
2482 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2483 InformationLevel) - 4;
2484 offset = param_offset + params;
2486 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2487 data_offset = (char *)pSMB + offset + 4;
2488 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2490 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2491 PATH_MAX, nls_codepage, remap);
2492 name_len_target++; /* trailing null */
2493 name_len_target *= 2;
2495 name_len_target = copy_path_name(data_offset, fromName);
2498 pSMB->MaxParameterCount = cpu_to_le16(2);
2499 /* BB find exact max on data count below from sess*/
2500 pSMB->MaxDataCount = cpu_to_le16(1000);
2501 pSMB->SetupCount = 1;
2502 pSMB->Reserved3 = 0;
2503 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2504 byte_count = 3 /* pad */ + params + name_len_target;
2505 pSMB->ParameterCount = cpu_to_le16(params);
2506 pSMB->TotalParameterCount = pSMB->ParameterCount;
2507 pSMB->DataCount = cpu_to_le16(name_len_target);
2508 pSMB->TotalDataCount = pSMB->DataCount;
2509 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2510 pSMB->DataOffset = cpu_to_le16(offset);
2511 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2512 pSMB->Reserved4 = 0;
2513 inc_rfc1001_len(pSMB, byte_count);
2514 pSMB->ByteCount = cpu_to_le16(byte_count);
2515 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2516 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2517 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2519 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2522 cifs_buf_release(pSMB);
2524 goto createHardLinkRetry;
2530 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2531 const char *from_name, const char *to_name,
2532 struct cifs_sb_info *cifs_sb)
2535 NT_RENAME_REQ *pSMB = NULL;
2536 RENAME_RSP *pSMBr = NULL;
2538 int name_len, name_len2;
2540 int remap = cifs_remap(cifs_sb);
2542 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2543 winCreateHardLinkRetry:
2545 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2550 pSMB->SearchAttributes =
2551 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2553 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2554 pSMB->ClusterCount = 0;
2556 pSMB->BufferFormat = 0x04;
2558 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2560 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2561 PATH_MAX, cifs_sb->local_nls, remap);
2562 name_len++; /* trailing null */
2565 /* protocol specifies ASCII buffer format (0x04) for unicode */
2566 pSMB->OldFileName[name_len] = 0x04;
2567 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2569 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2570 to_name, PATH_MAX, cifs_sb->local_nls,
2572 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2573 name_len2 *= 2; /* convert to bytes */
2575 name_len = copy_path_name(pSMB->OldFileName, from_name);
2576 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2577 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2578 name_len2++; /* signature byte */
2581 count = 1 /* string type byte */ + name_len + name_len2;
2582 inc_rfc1001_len(pSMB, count);
2583 pSMB->ByteCount = cpu_to_le16(count);
2585 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2586 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2587 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2589 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2591 cifs_buf_release(pSMB);
2593 goto winCreateHardLinkRetry;
2599 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2600 const unsigned char *searchName, char **symlinkinfo,
2601 const struct nls_table *nls_codepage, int remap)
2603 /* SMB_QUERY_FILE_UNIX_LINK */
2604 TRANSACTION2_QPI_REQ *pSMB = NULL;
2605 TRANSACTION2_QPI_RSP *pSMBr = NULL;
2609 __u16 params, byte_count;
2612 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
2615 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2620 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2622 cifsConvertToUTF16((__le16 *) pSMB->FileName,
2623 searchName, PATH_MAX, nls_codepage,
2625 name_len++; /* trailing null */
2628 name_len = copy_path_name(pSMB->FileName, searchName);
2631 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
2632 pSMB->TotalDataCount = 0;
2633 pSMB->MaxParameterCount = cpu_to_le16(2);
2634 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2635 pSMB->MaxSetupCount = 0;
2639 pSMB->Reserved2 = 0;
2640 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2641 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
2642 pSMB->DataCount = 0;
2643 pSMB->DataOffset = 0;
2644 pSMB->SetupCount = 1;
2645 pSMB->Reserved3 = 0;
2646 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2647 byte_count = params + 1 /* pad */ ;
2648 pSMB->TotalParameterCount = cpu_to_le16(params);
2649 pSMB->ParameterCount = pSMB->TotalParameterCount;
2650 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2651 pSMB->Reserved4 = 0;
2652 inc_rfc1001_len(pSMB, byte_count);
2653 pSMB->ByteCount = cpu_to_le16(byte_count);
2655 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2656 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2658 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
2660 /* decode response */
2662 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2663 /* BB also check enough total bytes returned */
2664 if (rc || get_bcc(&pSMBr->hdr) < 2)
2668 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2670 data_start = ((char *) &pSMBr->hdr.Protocol) +
2671 le16_to_cpu(pSMBr->t2.DataOffset);
2673 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2678 /* BB FIXME investigate remapping reserved chars here */
2679 *symlinkinfo = cifs_strndup_from_utf16(data_start,
2680 count, is_unicode, nls_codepage);
2685 cifs_buf_release(pSMB);
2687 goto querySymLinkRetry;
2692 * Recent Windows versions now create symlinks more frequently
2693 * and they use the "reparse point" mechanism below. We can of course
2694 * do symlinks nicely to Samba and other servers which support the
2695 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
2696 * "MF" symlinks optionally, but for recent Windows we really need to
2697 * reenable the code below and fix the cifs_symlink callers to handle this.
2698 * In the interim this code has been moved to its own config option so
2699 * it is not compiled in by default until callers fixed up and more tested.
2702 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2703 __u16 fid, char **symlinkinfo,
2704 const struct nls_table *nls_codepage)
2708 struct smb_com_transaction_ioctl_req *pSMB;
2709 struct smb_com_transaction_ioctl_rsp *pSMBr;
2711 unsigned int sub_len;
2713 struct reparse_symlink_data *reparse_buf;
2714 struct reparse_posix_data *posix_buf;
2715 __u32 data_offset, data_count;
2718 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
2719 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2724 pSMB->TotalParameterCount = 0 ;
2725 pSMB->TotalDataCount = 0;
2726 pSMB->MaxParameterCount = cpu_to_le32(2);
2727 /* BB find exact data count max from sess structure BB */
2728 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
2729 pSMB->MaxSetupCount = 4;
2731 pSMB->ParameterOffset = 0;
2732 pSMB->DataCount = 0;
2733 pSMB->DataOffset = 0;
2734 pSMB->SetupCount = 4;
2735 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2736 pSMB->ParameterCount = pSMB->TotalParameterCount;
2737 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
2738 pSMB->IsFsctl = 1; /* FSCTL */
2739 pSMB->IsRootFlag = 0;
2740 pSMB->Fid = fid; /* file handle always le */
2741 pSMB->ByteCount = 0;
2743 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2744 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2746 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
2750 data_offset = le32_to_cpu(pSMBr->DataOffset);
2751 data_count = le32_to_cpu(pSMBr->DataCount);
2752 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
2753 /* BB also check enough total bytes returned */
2754 rc = -EIO; /* bad smb */
2757 if (!data_count || (data_count > 2048)) {
2759 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
2762 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
2763 reparse_buf = (struct reparse_symlink_data *)
2764 ((char *)&pSMBr->hdr.Protocol + data_offset);
2765 if ((char *)reparse_buf >= end_of_smb) {
2769 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
2770 cifs_dbg(FYI, "NFS style reparse tag\n");
2771 posix_buf = (struct reparse_posix_data *)reparse_buf;
2773 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
2774 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
2775 le64_to_cpu(posix_buf->InodeType));
2780 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
2781 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
2782 cifs_dbg(FYI, "reparse buf beyond SMB\n");
2786 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
2787 sub_len, is_unicode, nls_codepage);
2789 } else if (reparse_buf->ReparseTag !=
2790 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
2795 /* Reparse tag is NTFS symlink */
2796 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
2797 reparse_buf->PathBuffer;
2798 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
2799 if (sub_start + sub_len > end_of_smb) {
2800 cifs_dbg(FYI, "reparse buf beyond SMB\n");
2804 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2809 /* BB FIXME investigate remapping reserved chars here */
2810 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
2815 cifs_buf_release(pSMB);
2818 * Note: On -EAGAIN error only caller can retry on handle based calls
2819 * since file handle passed in no longer valid.
2825 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
2830 struct smb_com_transaction_compr_ioctl_req *pSMB;
2831 struct smb_com_transaction_ioctl_rsp *pSMBr;
2833 cifs_dbg(FYI, "Set compression for %u\n", fid);
2834 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2839 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
2841 pSMB->TotalParameterCount = 0;
2842 pSMB->TotalDataCount = cpu_to_le32(2);
2843 pSMB->MaxParameterCount = 0;
2844 pSMB->MaxDataCount = 0;
2845 pSMB->MaxSetupCount = 4;
2847 pSMB->ParameterOffset = 0;
2848 pSMB->DataCount = cpu_to_le32(2);
2850 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
2851 compression_state) - 4); /* 84 */
2852 pSMB->SetupCount = 4;
2853 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2854 pSMB->ParameterCount = 0;
2855 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
2856 pSMB->IsFsctl = 1; /* FSCTL */
2857 pSMB->IsRootFlag = 0;
2858 pSMB->Fid = fid; /* file handle always le */
2859 /* 3 byte pad, followed by 2 byte compress state */
2860 pSMB->ByteCount = cpu_to_le16(5);
2861 inc_rfc1001_len(pSMB, 5);
2863 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2864 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2866 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
2868 cifs_buf_release(pSMB);
2871 * Note: On -EAGAIN error only caller can retry on handle based calls
2872 * since file handle passed in no longer valid.
2878 #ifdef CONFIG_CIFS_POSIX
2880 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
2881 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
2882 struct cifs_posix_ace *cifs_ace)
2884 /* u8 cifs fields do not need le conversion */
2885 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
2886 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
2887 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
2889 cifs_dbg(FYI, "perm %d tag %d id %d\n",
2890 ace->e_perm, ace->e_tag, ace->e_id);
2896 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
2897 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
2898 const int acl_type, const int size_of_data_area)
2903 struct cifs_posix_ace *pACE;
2904 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
2905 struct posix_acl_xattr_header *local_acl = (void *)trgt;
2907 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
2910 if (acl_type == ACL_TYPE_ACCESS) {
2911 count = le16_to_cpu(cifs_acl->access_entry_count);
2912 pACE = &cifs_acl->ace_array[0];
2913 size = sizeof(struct cifs_posix_acl);
2914 size += sizeof(struct cifs_posix_ace) * count;
2915 /* check if we would go beyond end of SMB */
2916 if (size_of_data_area < size) {
2917 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
2918 size_of_data_area, size);
2921 } else if (acl_type == ACL_TYPE_DEFAULT) {
2922 count = le16_to_cpu(cifs_acl->access_entry_count);
2923 size = sizeof(struct cifs_posix_acl);
2924 size += sizeof(struct cifs_posix_ace) * count;
2925 /* skip past access ACEs to get to default ACEs */
2926 pACE = &cifs_acl->ace_array[count];
2927 count = le16_to_cpu(cifs_acl->default_entry_count);
2928 size += sizeof(struct cifs_posix_ace) * count;
2929 /* check if we would go beyond end of SMB */
2930 if (size_of_data_area < size)
2937 size = posix_acl_xattr_size(count);
2938 if ((buflen == 0) || (local_acl == NULL)) {
2939 /* used to query ACL EA size */
2940 } else if (size > buflen) {
2942 } else /* buffer big enough */ {
2943 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
2945 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
2946 for (i = 0; i < count ; i++) {
2947 cifs_convert_ace(&ace[i], pACE);
2954 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
2955 const struct posix_acl_xattr_entry *local_ace)
2957 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
2958 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
2959 /* BB is there a better way to handle the large uid? */
2960 if (local_ace->e_id == cpu_to_le32(-1)) {
2961 /* Probably no need to le convert -1 on any arch but can not hurt */
2962 cifs_ace->cifs_uid = cpu_to_le64(-1);
2964 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
2966 cifs_dbg(FYI, "perm %d tag %d id %d\n",
2967 ace->e_perm, ace->e_tag, ace->e_id);
2971 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
2972 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
2973 const int buflen, const int acl_type)
2976 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
2977 struct posix_acl_xattr_header *local_acl = (void *)pACL;
2978 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
2982 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
2985 count = posix_acl_xattr_count((size_t)buflen);
2986 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
2987 count, buflen, le32_to_cpu(local_acl->a_version));
2988 if (le32_to_cpu(local_acl->a_version) != 2) {
2989 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
2990 le32_to_cpu(local_acl->a_version));
2993 cifs_acl->version = cpu_to_le16(1);
2994 if (acl_type == ACL_TYPE_ACCESS) {
2995 cifs_acl->access_entry_count = cpu_to_le16(count);
2996 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
2997 } else if (acl_type == ACL_TYPE_DEFAULT) {
2998 cifs_acl->default_entry_count = cpu_to_le16(count);
2999 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3001 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3004 for (i = 0; i < count; i++)
3005 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3007 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3008 rc += sizeof(struct cifs_posix_acl);
3009 /* BB add check to make sure ACL does not overflow SMB */
3015 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3016 const unsigned char *searchName,
3017 char *acl_inf, const int buflen, const int acl_type,
3018 const struct nls_table *nls_codepage, int remap)
3020 /* SMB_QUERY_POSIX_ACL */
3021 TRANSACTION2_QPI_REQ *pSMB = NULL;
3022 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3026 __u16 params, byte_count;
3028 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3031 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3036 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3038 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3039 searchName, PATH_MAX, nls_codepage,
3041 name_len++; /* trailing null */
3043 pSMB->FileName[name_len] = 0;
3044 pSMB->FileName[name_len+1] = 0;
3046 name_len = copy_path_name(pSMB->FileName, searchName);
3049 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3050 pSMB->TotalDataCount = 0;
3051 pSMB->MaxParameterCount = cpu_to_le16(2);
3052 /* BB find exact max data count below from sess structure BB */
3053 pSMB->MaxDataCount = cpu_to_le16(4000);
3054 pSMB->MaxSetupCount = 0;
3058 pSMB->Reserved2 = 0;
3059 pSMB->ParameterOffset = cpu_to_le16(
3060 offsetof(struct smb_com_transaction2_qpi_req,
3061 InformationLevel) - 4);
3062 pSMB->DataCount = 0;
3063 pSMB->DataOffset = 0;
3064 pSMB->SetupCount = 1;
3065 pSMB->Reserved3 = 0;
3066 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3067 byte_count = params + 1 /* pad */ ;
3068 pSMB->TotalParameterCount = cpu_to_le16(params);
3069 pSMB->ParameterCount = pSMB->TotalParameterCount;
3070 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3071 pSMB->Reserved4 = 0;
3072 inc_rfc1001_len(pSMB, byte_count);
3073 pSMB->ByteCount = cpu_to_le16(byte_count);
3075 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3076 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3077 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3079 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3081 /* decode response */
3083 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3084 /* BB also check enough total bytes returned */
3085 if (rc || get_bcc(&pSMBr->hdr) < 2)
3086 rc = -EIO; /* bad smb */
3088 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3089 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3090 rc = cifs_copy_posix_acl(acl_inf,
3091 (char *)&pSMBr->hdr.Protocol+data_offset,
3092 buflen, acl_type, count);
3095 cifs_buf_release(pSMB);
3102 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3103 const unsigned char *fileName,
3104 const char *local_acl, const int buflen,
3106 const struct nls_table *nls_codepage, int remap)
3108 struct smb_com_transaction2_spi_req *pSMB = NULL;
3109 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3113 int bytes_returned = 0;
3114 __u16 params, byte_count, data_count, param_offset, offset;
3116 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3118 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3122 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3124 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3125 PATH_MAX, nls_codepage, remap);
3126 name_len++; /* trailing null */
3129 name_len = copy_path_name(pSMB->FileName, fileName);
3131 params = 6 + name_len;
3132 pSMB->MaxParameterCount = cpu_to_le16(2);
3133 /* BB find max SMB size from sess */
3134 pSMB->MaxDataCount = cpu_to_le16(1000);
3135 pSMB->MaxSetupCount = 0;
3139 pSMB->Reserved2 = 0;
3140 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3141 InformationLevel) - 4;
3142 offset = param_offset + params;
3143 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3144 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3146 /* convert to on the wire format for POSIX ACL */
3147 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3149 if (data_count == 0) {
3151 goto setACLerrorExit;
3153 pSMB->DataOffset = cpu_to_le16(offset);
3154 pSMB->SetupCount = 1;
3155 pSMB->Reserved3 = 0;
3156 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3157 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3158 byte_count = 3 /* pad */ + params + data_count;
3159 pSMB->DataCount = cpu_to_le16(data_count);
3160 pSMB->TotalDataCount = pSMB->DataCount;
3161 pSMB->ParameterCount = cpu_to_le16(params);
3162 pSMB->TotalParameterCount = pSMB->ParameterCount;
3163 pSMB->Reserved4 = 0;
3164 inc_rfc1001_len(pSMB, byte_count);
3165 pSMB->ByteCount = cpu_to_le16(byte_count);
3166 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3167 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3169 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3172 cifs_buf_release(pSMB);
3179 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3180 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3183 struct smb_t2_qfi_req *pSMB = NULL;
3184 struct smb_t2_qfi_rsp *pSMBr = NULL;
3186 __u16 params, byte_count;
3188 cifs_dbg(FYI, "In GetExtAttr\n");
3193 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3198 params = 2 /* level */ + 2 /* fid */;
3199 pSMB->t2.TotalDataCount = 0;
3200 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3201 /* BB find exact max data count below from sess structure BB */
3202 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3203 pSMB->t2.MaxSetupCount = 0;
3204 pSMB->t2.Reserved = 0;
3206 pSMB->t2.Timeout = 0;
3207 pSMB->t2.Reserved2 = 0;
3208 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3210 pSMB->t2.DataCount = 0;
3211 pSMB->t2.DataOffset = 0;
3212 pSMB->t2.SetupCount = 1;
3213 pSMB->t2.Reserved3 = 0;
3214 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3215 byte_count = params + 1 /* pad */ ;
3216 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3217 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3218 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3221 inc_rfc1001_len(pSMB, byte_count);
3222 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3224 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3225 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3227 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3229 /* decode response */
3230 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3231 /* BB also check enough total bytes returned */
3232 if (rc || get_bcc(&pSMBr->hdr) < 2)
3233 /* If rc should we check for EOPNOSUPP and
3234 disable the srvino flag? or in caller? */
3235 rc = -EIO; /* bad smb */
3237 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3238 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3239 struct file_chattr_info *pfinfo;
3242 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3246 pfinfo = (struct file_chattr_info *)
3247 (data_offset + (char *) &pSMBr->hdr.Protocol);
3248 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3249 *pMask = le64_to_cpu(pfinfo->mask);
3253 cifs_buf_release(pSMB);
3255 goto GetExtAttrRetry;
3259 #endif /* CONFIG_POSIX */
3262 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3263 * all NT TRANSACTS that we init here have total parm and data under about 400
3264 * bytes (to fit in small cifs buffer size), which is the case so far, it
3265 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3266 * returned setup area) and MaxParameterCount (returned parms size) must be set
3270 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3271 const int parm_len, struct cifs_tcon *tcon,
3276 struct smb_com_ntransact_req *pSMB;
3278 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3282 *ret_buf = (void *)pSMB;
3284 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3285 pSMB->TotalDataCount = 0;
3286 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3287 pSMB->ParameterCount = pSMB->TotalParameterCount;
3288 pSMB->DataCount = pSMB->TotalDataCount;
3289 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3290 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3291 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3292 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3293 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3294 pSMB->SubCommand = cpu_to_le16(sub_command);
3299 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3300 __u32 *pparmlen, __u32 *pdatalen)
3303 __u32 data_count, data_offset, parm_count, parm_offset;
3304 struct smb_com_ntransact_rsp *pSMBr;
3313 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3315 bcc = get_bcc(&pSMBr->hdr);
3316 end_of_smb = 2 /* sizeof byte count */ + bcc +
3317 (char *)&pSMBr->ByteCount;
3319 data_offset = le32_to_cpu(pSMBr->DataOffset);
3320 data_count = le32_to_cpu(pSMBr->DataCount);
3321 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3322 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3324 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3325 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3327 /* should we also check that parm and data areas do not overlap? */
3328 if (*ppparm > end_of_smb) {
3329 cifs_dbg(FYI, "parms start after end of smb\n");
3331 } else if (parm_count + *ppparm > end_of_smb) {
3332 cifs_dbg(FYI, "parm end after end of smb\n");
3334 } else if (*ppdata > end_of_smb) {
3335 cifs_dbg(FYI, "data starts after end of smb\n");
3337 } else if (data_count + *ppdata > end_of_smb) {
3338 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3339 *ppdata, data_count, (data_count + *ppdata),
3342 } else if (parm_count + data_count > bcc) {
3343 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3346 *pdatalen = data_count;
3347 *pparmlen = parm_count;
3351 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3353 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3354 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3358 QUERY_SEC_DESC_REQ *pSMB;
3360 struct kvec rsp_iov;
3362 cifs_dbg(FYI, "GetCifsACL\n");
3367 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3368 8 /* parm len */, tcon, (void **) &pSMB);
3372 pSMB->MaxParameterCount = cpu_to_le32(4);
3373 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3374 pSMB->MaxSetupCount = 0;
3375 pSMB->Fid = fid; /* file handle always le */
3376 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3378 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3379 inc_rfc1001_len(pSMB, 11);
3380 iov[0].iov_base = (char *)pSMB;
3381 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3383 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3385 cifs_small_buf_release(pSMB);
3386 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3388 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3389 } else { /* decode response */
3393 struct smb_com_ntransact_rsp *pSMBr;
3396 /* validate_nttransact */
3397 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3398 &pdata, &parm_len, pbuflen);
3401 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3403 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3404 pSMBr, parm, *acl_inf);
3406 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3407 rc = -EIO; /* bad smb */
3412 /* BB check that data area is minimum length and as big as acl_len */
3414 acl_len = le32_to_cpu(*parm);
3415 if (acl_len != *pbuflen) {
3416 cifs_dbg(VFS, "acl length %d does not match %d\n",
3418 if (*pbuflen > acl_len)
3422 /* check if buffer is big enough for the acl
3423 header followed by the smallest SID */
3424 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3425 (*pbuflen >= 64 * 1024)) {
3426 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3430 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3431 if (*acl_inf == NULL) {
3438 free_rsp_buf(buf_type, rsp_iov.iov_base);
3443 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3444 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3446 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3448 int bytes_returned = 0;
3449 SET_SEC_DESC_REQ *pSMB = NULL;
3453 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3457 pSMB->MaxSetupCount = 0;
3461 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3462 data_count = acllen;
3463 data_offset = param_offset + param_count;
3464 byte_count = 3 /* pad */ + param_count;
3466 pSMB->DataCount = cpu_to_le32(data_count);
3467 pSMB->TotalDataCount = pSMB->DataCount;
3468 pSMB->MaxParameterCount = cpu_to_le32(4);
3469 pSMB->MaxDataCount = cpu_to_le32(16384);
3470 pSMB->ParameterCount = cpu_to_le32(param_count);
3471 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3472 pSMB->TotalParameterCount = pSMB->ParameterCount;
3473 pSMB->DataOffset = cpu_to_le32(data_offset);
3474 pSMB->SetupCount = 0;
3475 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3476 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3478 pSMB->Fid = fid; /* file handle always le */
3479 pSMB->Reserved2 = 0;
3480 pSMB->AclFlags = cpu_to_le32(aclflag);
3482 if (pntsd && acllen) {
3483 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3484 data_offset, pntsd, acllen);
3485 inc_rfc1001_len(pSMB, byte_count + data_count);
3487 inc_rfc1001_len(pSMB, byte_count);
3489 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3490 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3492 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3493 bytes_returned, rc);
3495 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3496 cifs_buf_release(pSMB);
3499 goto setCifsAclRetry;
3505 /* Legacy Query Path Information call for lookup to old servers such
3508 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3509 const char *search_name, FILE_ALL_INFO *data,
3510 const struct nls_table *nls_codepage, int remap)
3512 QUERY_INFORMATION_REQ *pSMB;
3513 QUERY_INFORMATION_RSP *pSMBr;
3518 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3520 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3525 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3527 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3528 search_name, PATH_MAX, nls_codepage,
3530 name_len++; /* trailing null */
3533 name_len = copy_path_name(pSMB->FileName, search_name);
3535 pSMB->BufferFormat = 0x04;
3536 name_len++; /* account for buffer type byte */
3537 inc_rfc1001_len(pSMB, (__u16)name_len);
3538 pSMB->ByteCount = cpu_to_le16(name_len);
3540 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3541 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3543 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3545 struct timespec64 ts;
3546 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3548 /* decode response */
3549 /* BB FIXME - add time zone adjustment BB */
3550 memset(data, 0, sizeof(FILE_ALL_INFO));
3553 /* decode time fields */
3554 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3555 data->LastWriteTime = data->ChangeTime;
3556 data->LastAccessTime = 0;
3557 data->AllocationSize =
3558 cpu_to_le64(le32_to_cpu(pSMBr->size));
3559 data->EndOfFile = data->AllocationSize;
3561 cpu_to_le32(le16_to_cpu(pSMBr->attr));
3563 rc = -EIO; /* bad buffer passed in */
3565 cifs_buf_release(pSMB);
3574 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3575 u16 netfid, FILE_ALL_INFO *pFindData)
3577 struct smb_t2_qfi_req *pSMB = NULL;
3578 struct smb_t2_qfi_rsp *pSMBr = NULL;
3581 __u16 params, byte_count;
3584 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3589 params = 2 /* level */ + 2 /* fid */;
3590 pSMB->t2.TotalDataCount = 0;
3591 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3592 /* BB find exact max data count below from sess structure BB */
3593 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3594 pSMB->t2.MaxSetupCount = 0;
3595 pSMB->t2.Reserved = 0;
3597 pSMB->t2.Timeout = 0;
3598 pSMB->t2.Reserved2 = 0;
3599 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3601 pSMB->t2.DataCount = 0;
3602 pSMB->t2.DataOffset = 0;
3603 pSMB->t2.SetupCount = 1;
3604 pSMB->t2.Reserved3 = 0;
3605 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3606 byte_count = params + 1 /* pad */ ;
3607 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3608 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3609 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3612 inc_rfc1001_len(pSMB, byte_count);
3613 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3615 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3616 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3618 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
3619 } else { /* decode response */
3620 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3622 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3624 else if (get_bcc(&pSMBr->hdr) < 40)
3625 rc = -EIO; /* bad smb */
3626 else if (pFindData) {
3627 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3628 memcpy((char *) pFindData,
3629 (char *) &pSMBr->hdr.Protocol +
3630 data_offset, sizeof(FILE_ALL_INFO));
3634 cifs_buf_release(pSMB);
3636 goto QFileInfoRetry;
3642 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3643 const char *search_name, FILE_ALL_INFO *data,
3644 int legacy /* old style infolevel */,
3645 const struct nls_table *nls_codepage, int remap)
3647 /* level 263 SMB_QUERY_FILE_ALL_INFO */
3648 TRANSACTION2_QPI_REQ *pSMB = NULL;
3649 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3653 __u16 params, byte_count;
3655 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3657 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3662 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3664 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3665 PATH_MAX, nls_codepage, remap);
3666 name_len++; /* trailing null */
3669 name_len = copy_path_name(pSMB->FileName, search_name);
3672 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3673 pSMB->TotalDataCount = 0;
3674 pSMB->MaxParameterCount = cpu_to_le16(2);
3675 /* BB find exact max SMB PDU from sess structure BB */
3676 pSMB->MaxDataCount = cpu_to_le16(4000);
3677 pSMB->MaxSetupCount = 0;
3681 pSMB->Reserved2 = 0;
3682 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3683 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3684 pSMB->DataCount = 0;
3685 pSMB->DataOffset = 0;
3686 pSMB->SetupCount = 1;
3687 pSMB->Reserved3 = 0;
3688 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3689 byte_count = params + 1 /* pad */ ;
3690 pSMB->TotalParameterCount = cpu_to_le16(params);
3691 pSMB->ParameterCount = pSMB->TotalParameterCount;
3693 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3695 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3696 pSMB->Reserved4 = 0;
3697 inc_rfc1001_len(pSMB, byte_count);
3698 pSMB->ByteCount = cpu_to_le16(byte_count);
3700 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3701 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3703 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3704 } else { /* decode response */
3705 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3707 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3709 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3710 rc = -EIO; /* bad smb */
3711 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3712 rc = -EIO; /* 24 or 26 expected but we do not read
3716 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3719 * On legacy responses we do not read the last field,
3720 * EAsize, fortunately since it varies by subdialect and
3721 * also note it differs on Set vs Get, ie two bytes or 4
3722 * bytes depending but we don't care here.
3725 size = sizeof(FILE_INFO_STANDARD);
3727 size = sizeof(FILE_ALL_INFO);
3728 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
3733 cifs_buf_release(pSMB);
3735 goto QPathInfoRetry;
3741 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3742 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3744 struct smb_t2_qfi_req *pSMB = NULL;
3745 struct smb_t2_qfi_rsp *pSMBr = NULL;
3748 __u16 params, byte_count;
3751 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3756 params = 2 /* level */ + 2 /* fid */;
3757 pSMB->t2.TotalDataCount = 0;
3758 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3759 /* BB find exact max data count below from sess structure BB */
3760 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3761 pSMB->t2.MaxSetupCount = 0;
3762 pSMB->t2.Reserved = 0;
3764 pSMB->t2.Timeout = 0;
3765 pSMB->t2.Reserved2 = 0;
3766 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3768 pSMB->t2.DataCount = 0;
3769 pSMB->t2.DataOffset = 0;
3770 pSMB->t2.SetupCount = 1;
3771 pSMB->t2.Reserved3 = 0;
3772 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3773 byte_count = params + 1 /* pad */ ;
3774 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3775 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3776 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3779 inc_rfc1001_len(pSMB, byte_count);
3780 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3782 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3783 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3785 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
3786 } else { /* decode response */
3787 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3789 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3790 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3791 rc = -EIO; /* bad smb */
3793 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3794 memcpy((char *) pFindData,
3795 (char *) &pSMBr->hdr.Protocol +
3797 sizeof(FILE_UNIX_BASIC_INFO));
3801 cifs_buf_release(pSMB);
3803 goto UnixQFileInfoRetry;
3809 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3810 const unsigned char *searchName,
3811 FILE_UNIX_BASIC_INFO *pFindData,
3812 const struct nls_table *nls_codepage, int remap)
3814 /* SMB_QUERY_FILE_UNIX_BASIC */
3815 TRANSACTION2_QPI_REQ *pSMB = NULL;
3816 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3818 int bytes_returned = 0;
3820 __u16 params, byte_count;
3822 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
3824 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3829 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3831 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3832 PATH_MAX, nls_codepage, remap);
3833 name_len++; /* trailing null */
3836 name_len = copy_path_name(pSMB->FileName, searchName);
3839 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3840 pSMB->TotalDataCount = 0;
3841 pSMB->MaxParameterCount = cpu_to_le16(2);
3842 /* BB find exact max SMB PDU from sess structure BB */
3843 pSMB->MaxDataCount = cpu_to_le16(4000);
3844 pSMB->MaxSetupCount = 0;
3848 pSMB->Reserved2 = 0;
3849 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3850 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3851 pSMB->DataCount = 0;
3852 pSMB->DataOffset = 0;
3853 pSMB->SetupCount = 1;
3854 pSMB->Reserved3 = 0;
3855 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3856 byte_count = params + 1 /* pad */ ;
3857 pSMB->TotalParameterCount = cpu_to_le16(params);
3858 pSMB->ParameterCount = pSMB->TotalParameterCount;
3859 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3860 pSMB->Reserved4 = 0;
3861 inc_rfc1001_len(pSMB, byte_count);
3862 pSMB->ByteCount = cpu_to_le16(byte_count);
3864 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3865 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3867 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
3868 } else { /* decode response */
3869 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3871 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3872 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3873 rc = -EIO; /* bad smb */
3875 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3876 memcpy((char *) pFindData,
3877 (char *) &pSMBr->hdr.Protocol +
3879 sizeof(FILE_UNIX_BASIC_INFO));
3882 cifs_buf_release(pSMB);
3884 goto UnixQPathInfoRetry;
3889 /* xid, tcon, searchName and codepage are input parms, rest are returned */
3891 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
3892 const char *searchName, struct cifs_sb_info *cifs_sb,
3893 __u16 *pnetfid, __u16 search_flags,
3894 struct cifs_search_info *psrch_inf, bool msearch)
3896 /* level 257 SMB_ */
3897 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
3898 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
3899 T2_FFIRST_RSP_PARMS *parms;
3901 int bytes_returned = 0;
3902 int name_len, remap;
3903 __u16 params, byte_count;
3904 struct nls_table *nls_codepage;
3906 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
3909 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3914 nls_codepage = cifs_sb->local_nls;
3915 remap = cifs_remap(cifs_sb);
3917 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3919 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3920 PATH_MAX, nls_codepage, remap);
3921 /* We can not add the asterik earlier in case
3922 it got remapped to 0xF03A as if it were part of the
3923 directory name instead of a wildcard */
3926 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
3927 pSMB->FileName[name_len+1] = 0;
3928 pSMB->FileName[name_len+2] = '*';
3929 pSMB->FileName[name_len+3] = 0;
3930 name_len += 4; /* now the trailing null */
3931 /* null terminate just in case */
3932 pSMB->FileName[name_len] = 0;
3933 pSMB->FileName[name_len+1] = 0;
3937 name_len = copy_path_name(pSMB->FileName, searchName);
3939 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
3940 name_len = PATH_MAX-2;
3941 /* overwrite nul byte */
3942 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
3943 pSMB->FileName[name_len] = '*';
3944 pSMB->FileName[name_len+1] = 0;
3949 params = 12 + name_len /* includes null */ ;
3950 pSMB->TotalDataCount = 0; /* no EAs */
3951 pSMB->MaxParameterCount = cpu_to_le16(10);
3952 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
3953 pSMB->MaxSetupCount = 0;
3957 pSMB->Reserved2 = 0;
3958 byte_count = params + 1 /* pad */ ;
3959 pSMB->TotalParameterCount = cpu_to_le16(params);
3960 pSMB->ParameterCount = pSMB->TotalParameterCount;
3961 pSMB->ParameterOffset = cpu_to_le16(
3962 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
3964 pSMB->DataCount = 0;
3965 pSMB->DataOffset = 0;
3966 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
3967 pSMB->Reserved3 = 0;
3968 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
3969 pSMB->SearchAttributes =
3970 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3972 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
3973 pSMB->SearchFlags = cpu_to_le16(search_flags);
3974 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
3976 /* BB what should we set StorageType to? Does it matter? BB */
3977 pSMB->SearchStorageType = 0;
3978 inc_rfc1001_len(pSMB, byte_count);
3979 pSMB->ByteCount = cpu_to_le16(byte_count);
3981 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3982 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3983 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
3985 if (rc) {/* BB add logic to retry regular search if Unix search
3986 rejected unexpectedly by server */
3987 /* BB Add code to handle unsupported level rc */
3988 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
3990 cifs_buf_release(pSMB);
3992 /* BB eventually could optimize out free and realloc of buf */
3995 goto findFirstRetry;
3996 } else { /* decode response */
3997 /* BB remember to free buffer if error BB */
3998 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4002 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4003 psrch_inf->unicode = true;
4005 psrch_inf->unicode = false;
4007 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4008 psrch_inf->smallBuf = false;
4009 psrch_inf->srch_entries_start =
4010 (char *) &pSMBr->hdr.Protocol +
4011 le16_to_cpu(pSMBr->t2.DataOffset);
4012 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4013 le16_to_cpu(pSMBr->t2.ParameterOffset));
4015 if (parms->EndofSearch)
4016 psrch_inf->endOfSearch = true;
4018 psrch_inf->endOfSearch = false;
4020 psrch_inf->entries_in_buffer =
4021 le16_to_cpu(parms->SearchCount);
4022 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4023 psrch_inf->entries_in_buffer;
4024 lnoff = le16_to_cpu(parms->LastNameOffset);
4025 if (CIFSMaxBufSize < lnoff) {
4026 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4027 psrch_inf->last_entry = NULL;
4031 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4035 *pnetfid = parms->SearchHandle;
4037 cifs_buf_release(pSMB);
4044 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4045 __u16 searchHandle, __u16 search_flags,
4046 struct cifs_search_info *psrch_inf)
4048 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4049 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4050 T2_FNEXT_RSP_PARMS *parms;
4051 char *response_data;
4054 unsigned int name_len;
4055 __u16 params, byte_count;
4057 cifs_dbg(FYI, "In FindNext\n");
4059 if (psrch_inf->endOfSearch)
4062 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4067 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4069 pSMB->TotalDataCount = 0; /* no EAs */
4070 pSMB->MaxParameterCount = cpu_to_le16(8);
4071 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4072 pSMB->MaxSetupCount = 0;
4076 pSMB->Reserved2 = 0;
4077 pSMB->ParameterOffset = cpu_to_le16(
4078 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4079 pSMB->DataCount = 0;
4080 pSMB->DataOffset = 0;
4081 pSMB->SetupCount = 1;
4082 pSMB->Reserved3 = 0;
4083 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4084 pSMB->SearchHandle = searchHandle; /* always kept as le */
4086 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4087 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4088 pSMB->ResumeKey = psrch_inf->resume_key;
4089 pSMB->SearchFlags = cpu_to_le16(search_flags);
4091 name_len = psrch_inf->resume_name_len;
4093 if (name_len < PATH_MAX) {
4094 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4095 byte_count += name_len;
4096 /* 14 byte parm len above enough for 2 byte null terminator */
4097 pSMB->ResumeFileName[name_len] = 0;
4098 pSMB->ResumeFileName[name_len+1] = 0;
4101 goto FNext2_err_exit;
4103 byte_count = params + 1 /* pad */ ;
4104 pSMB->TotalParameterCount = cpu_to_le16(params);
4105 pSMB->ParameterCount = pSMB->TotalParameterCount;
4106 inc_rfc1001_len(pSMB, byte_count);
4107 pSMB->ByteCount = cpu_to_le16(byte_count);
4109 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4110 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4111 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4114 psrch_inf->endOfSearch = true;
4115 cifs_buf_release(pSMB);
4116 rc = 0; /* search probably was closed at end of search*/
4118 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4119 } else { /* decode response */
4120 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4125 /* BB fixme add lock for file (srch_info) struct here */
4126 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4127 psrch_inf->unicode = true;
4129 psrch_inf->unicode = false;
4130 response_data = (char *) &pSMBr->hdr.Protocol +
4131 le16_to_cpu(pSMBr->t2.ParameterOffset);
4132 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4133 response_data = (char *)&pSMBr->hdr.Protocol +
4134 le16_to_cpu(pSMBr->t2.DataOffset);
4135 if (psrch_inf->smallBuf)
4136 cifs_small_buf_release(
4137 psrch_inf->ntwrk_buf_start);
4139 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4140 psrch_inf->srch_entries_start = response_data;
4141 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4142 psrch_inf->smallBuf = false;
4143 if (parms->EndofSearch)
4144 psrch_inf->endOfSearch = true;
4146 psrch_inf->endOfSearch = false;
4147 psrch_inf->entries_in_buffer =
4148 le16_to_cpu(parms->SearchCount);
4149 psrch_inf->index_of_last_entry +=
4150 psrch_inf->entries_in_buffer;
4151 lnoff = le16_to_cpu(parms->LastNameOffset);
4152 if (CIFSMaxBufSize < lnoff) {
4153 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4154 psrch_inf->last_entry = NULL;
4157 psrch_inf->last_entry =
4158 psrch_inf->srch_entries_start + lnoff;
4160 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4161 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4163 /* BB fixme add unlock here */
4168 /* BB On error, should we leave previous search buf (and count and
4169 last entry fields) intact or free the previous one? */
4171 /* Note: On -EAGAIN error only caller can retry on handle based calls
4172 since file handle passed in no longer valid */
4175 cifs_buf_release(pSMB);
4180 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4181 const __u16 searchHandle)
4184 FINDCLOSE_REQ *pSMB = NULL;
4186 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4187 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4189 /* no sense returning error if session restarted
4190 as file handle has been closed */
4196 pSMB->FileID = searchHandle;
4197 pSMB->ByteCount = 0;
4198 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4199 cifs_small_buf_release(pSMB);
4201 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4203 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4205 /* Since session is dead, search handle closed on server already */
4213 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4214 const char *search_name, __u64 *inode_number,
4215 const struct nls_table *nls_codepage, int remap)
4218 TRANSACTION2_QPI_REQ *pSMB = NULL;
4219 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4220 int name_len, bytes_returned;
4221 __u16 params, byte_count;
4223 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4227 GetInodeNumberRetry:
4228 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4233 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4235 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4236 search_name, PATH_MAX, nls_codepage,
4238 name_len++; /* trailing null */
4241 name_len = copy_path_name(pSMB->FileName, search_name);
4244 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4245 pSMB->TotalDataCount = 0;
4246 pSMB->MaxParameterCount = cpu_to_le16(2);
4247 /* BB find exact max data count below from sess structure BB */
4248 pSMB->MaxDataCount = cpu_to_le16(4000);
4249 pSMB->MaxSetupCount = 0;
4253 pSMB->Reserved2 = 0;
4254 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4255 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4256 pSMB->DataCount = 0;
4257 pSMB->DataOffset = 0;
4258 pSMB->SetupCount = 1;
4259 pSMB->Reserved3 = 0;
4260 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4261 byte_count = params + 1 /* pad */ ;
4262 pSMB->TotalParameterCount = cpu_to_le16(params);
4263 pSMB->ParameterCount = pSMB->TotalParameterCount;
4264 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4265 pSMB->Reserved4 = 0;
4266 inc_rfc1001_len(pSMB, byte_count);
4267 pSMB->ByteCount = cpu_to_le16(byte_count);
4269 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4270 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4272 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4274 /* decode response */
4275 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4276 /* BB also check enough total bytes returned */
4277 if (rc || get_bcc(&pSMBr->hdr) < 2)
4278 /* If rc should we check for EOPNOSUPP and
4279 disable the srvino flag? or in caller? */
4280 rc = -EIO; /* bad smb */
4282 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4283 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4284 struct file_internal_info *pfinfo;
4285 /* BB Do we need a cast or hash here ? */
4287 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4289 goto GetInodeNumOut;
4291 pfinfo = (struct file_internal_info *)
4292 (data_offset + (char *) &pSMBr->hdr.Protocol);
4293 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4297 cifs_buf_release(pSMB);
4299 goto GetInodeNumberRetry;
4304 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4305 const char *search_name, struct dfs_info3_param **target_nodes,
4306 unsigned int *num_of_nodes,
4307 const struct nls_table *nls_codepage, int remap)
4309 /* TRANS2_GET_DFS_REFERRAL */
4310 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4311 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4315 __u16 params, byte_count;
4317 *target_nodes = NULL;
4319 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4320 if (ses == NULL || ses->tcon_ipc == NULL)
4325 * Use smb_init_no_reconnect() instead of smb_init() as
4326 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4327 * causing an infinite recursion.
4329 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4330 (void **)&pSMB, (void **)&pSMBr);
4334 /* server pointer checked in called function,
4335 but should never be null here anyway */
4336 pSMB->hdr.Mid = get_next_mid(ses->server);
4337 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4338 pSMB->hdr.Uid = ses->Suid;
4339 if (ses->capabilities & CAP_STATUS32)
4340 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4341 if (ses->capabilities & CAP_DFS)
4342 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4344 if (ses->capabilities & CAP_UNICODE) {
4345 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4347 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4348 search_name, PATH_MAX, nls_codepage,
4350 name_len++; /* trailing null */
4352 } else { /* BB improve the check for buffer overruns BB */
4353 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4356 if (ses->server->sign)
4357 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4359 pSMB->hdr.Uid = ses->Suid;
4361 params = 2 /* level */ + name_len /*includes null */ ;
4362 pSMB->TotalDataCount = 0;
4363 pSMB->DataCount = 0;
4364 pSMB->DataOffset = 0;
4365 pSMB->MaxParameterCount = 0;
4366 /* BB find exact max SMB PDU from sess structure BB */
4367 pSMB->MaxDataCount = cpu_to_le16(4000);
4368 pSMB->MaxSetupCount = 0;
4372 pSMB->Reserved2 = 0;
4373 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4374 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4375 pSMB->SetupCount = 1;
4376 pSMB->Reserved3 = 0;
4377 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4378 byte_count = params + 3 /* pad */ ;
4379 pSMB->ParameterCount = cpu_to_le16(params);
4380 pSMB->TotalParameterCount = pSMB->ParameterCount;
4381 pSMB->MaxReferralLevel = cpu_to_le16(3);
4382 inc_rfc1001_len(pSMB, byte_count);
4383 pSMB->ByteCount = cpu_to_le16(byte_count);
4385 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4386 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4388 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4391 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4393 /* BB Also check if enough total bytes returned? */
4394 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4395 rc = -EIO; /* bad smb */
4399 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4400 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4402 /* parse returned result into more usable form */
4403 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4404 le16_to_cpu(pSMBr->t2.DataCount),
4405 num_of_nodes, target_nodes, nls_codepage,
4407 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4410 cifs_buf_release(pSMB);
4418 /* Query File System Info such as free space to old servers such as Win 9x */
4420 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4421 struct kstatfs *FSData)
4423 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4424 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4425 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4426 FILE_SYSTEM_ALLOC_INFO *response_data;
4428 int bytes_returned = 0;
4429 __u16 params, byte_count;
4431 cifs_dbg(FYI, "OldQFSInfo\n");
4433 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4438 params = 2; /* level */
4439 pSMB->TotalDataCount = 0;
4440 pSMB->MaxParameterCount = cpu_to_le16(2);
4441 pSMB->MaxDataCount = cpu_to_le16(1000);
4442 pSMB->MaxSetupCount = 0;
4446 pSMB->Reserved2 = 0;
4447 byte_count = params + 1 /* pad */ ;
4448 pSMB->TotalParameterCount = cpu_to_le16(params);
4449 pSMB->ParameterCount = pSMB->TotalParameterCount;
4450 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4451 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4452 pSMB->DataCount = 0;
4453 pSMB->DataOffset = 0;
4454 pSMB->SetupCount = 1;
4455 pSMB->Reserved3 = 0;
4456 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4457 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4458 inc_rfc1001_len(pSMB, byte_count);
4459 pSMB->ByteCount = cpu_to_le16(byte_count);
4461 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4462 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4464 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4465 } else { /* decode response */
4466 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4468 if (rc || get_bcc(&pSMBr->hdr) < 18)
4469 rc = -EIO; /* bad smb */
4471 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4472 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4473 get_bcc(&pSMBr->hdr), data_offset);
4475 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4476 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4478 le16_to_cpu(response_data->BytesPerSector) *
4479 le32_to_cpu(response_data->
4480 SectorsPerAllocationUnit);
4482 * much prefer larger but if server doesn't report
4483 * a valid size than 4K is a reasonable minimum
4485 if (FSData->f_bsize < 512)
4486 FSData->f_bsize = 4096;
4489 le32_to_cpu(response_data->TotalAllocationUnits);
4490 FSData->f_bfree = FSData->f_bavail =
4491 le32_to_cpu(response_data->FreeAllocationUnits);
4492 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4493 (unsigned long long)FSData->f_blocks,
4494 (unsigned long long)FSData->f_bfree,
4498 cifs_buf_release(pSMB);
4501 goto oldQFSInfoRetry;
4507 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4508 struct kstatfs *FSData)
4510 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4511 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4512 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4513 FILE_SYSTEM_INFO *response_data;
4515 int bytes_returned = 0;
4516 __u16 params, byte_count;
4518 cifs_dbg(FYI, "In QFSInfo\n");
4520 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4525 params = 2; /* level */
4526 pSMB->TotalDataCount = 0;
4527 pSMB->MaxParameterCount = cpu_to_le16(2);
4528 pSMB->MaxDataCount = cpu_to_le16(1000);
4529 pSMB->MaxSetupCount = 0;
4533 pSMB->Reserved2 = 0;
4534 byte_count = params + 1 /* pad */ ;
4535 pSMB->TotalParameterCount = cpu_to_le16(params);
4536 pSMB->ParameterCount = pSMB->TotalParameterCount;
4537 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4538 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4539 pSMB->DataCount = 0;
4540 pSMB->DataOffset = 0;
4541 pSMB->SetupCount = 1;
4542 pSMB->Reserved3 = 0;
4543 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4544 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4545 inc_rfc1001_len(pSMB, byte_count);
4546 pSMB->ByteCount = cpu_to_le16(byte_count);
4548 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4549 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4551 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4552 } else { /* decode response */
4553 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4555 if (rc || get_bcc(&pSMBr->hdr) < 24)
4556 rc = -EIO; /* bad smb */
4558 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4562 *) (((char *) &pSMBr->hdr.Protocol) +
4565 le32_to_cpu(response_data->BytesPerSector) *
4566 le32_to_cpu(response_data->
4567 SectorsPerAllocationUnit);
4569 * much prefer larger but if server doesn't report
4570 * a valid size than 4K is a reasonable minimum
4572 if (FSData->f_bsize < 512)
4573 FSData->f_bsize = 4096;
4576 le64_to_cpu(response_data->TotalAllocationUnits);
4577 FSData->f_bfree = FSData->f_bavail =
4578 le64_to_cpu(response_data->FreeAllocationUnits);
4579 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4580 (unsigned long long)FSData->f_blocks,
4581 (unsigned long long)FSData->f_bfree,
4585 cifs_buf_release(pSMB);
4594 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
4596 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
4597 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4598 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4599 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
4601 int bytes_returned = 0;
4602 __u16 params, byte_count;
4604 cifs_dbg(FYI, "In QFSAttributeInfo\n");
4606 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4611 params = 2; /* level */
4612 pSMB->TotalDataCount = 0;
4613 pSMB->MaxParameterCount = cpu_to_le16(2);
4614 /* BB find exact max SMB PDU from sess structure BB */
4615 pSMB->MaxDataCount = cpu_to_le16(1000);
4616 pSMB->MaxSetupCount = 0;
4620 pSMB->Reserved2 = 0;
4621 byte_count = params + 1 /* pad */ ;
4622 pSMB->TotalParameterCount = cpu_to_le16(params);
4623 pSMB->ParameterCount = pSMB->TotalParameterCount;
4624 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4625 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4626 pSMB->DataCount = 0;
4627 pSMB->DataOffset = 0;
4628 pSMB->SetupCount = 1;
4629 pSMB->Reserved3 = 0;
4630 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4631 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4632 inc_rfc1001_len(pSMB, byte_count);
4633 pSMB->ByteCount = cpu_to_le16(byte_count);
4635 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4636 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4638 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
4639 } else { /* decode response */
4640 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4642 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4643 /* BB also check if enough bytes returned */
4644 rc = -EIO; /* bad smb */
4646 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4648 (FILE_SYSTEM_ATTRIBUTE_INFO
4649 *) (((char *) &pSMBr->hdr.Protocol) +
4651 memcpy(&tcon->fsAttrInfo, response_data,
4652 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
4655 cifs_buf_release(pSMB);
4658 goto QFSAttributeRetry;
4664 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
4666 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4667 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4668 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4669 FILE_SYSTEM_DEVICE_INFO *response_data;
4671 int bytes_returned = 0;
4672 __u16 params, byte_count;
4674 cifs_dbg(FYI, "In QFSDeviceInfo\n");
4676 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4681 params = 2; /* level */
4682 pSMB->TotalDataCount = 0;
4683 pSMB->MaxParameterCount = cpu_to_le16(2);
4684 /* BB find exact max SMB PDU from sess structure BB */
4685 pSMB->MaxDataCount = cpu_to_le16(1000);
4686 pSMB->MaxSetupCount = 0;
4690 pSMB->Reserved2 = 0;
4691 byte_count = params + 1 /* pad */ ;
4692 pSMB->TotalParameterCount = cpu_to_le16(params);
4693 pSMB->ParameterCount = pSMB->TotalParameterCount;
4694 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4695 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4697 pSMB->DataCount = 0;
4698 pSMB->DataOffset = 0;
4699 pSMB->SetupCount = 1;
4700 pSMB->Reserved3 = 0;
4701 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4702 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4703 inc_rfc1001_len(pSMB, byte_count);
4704 pSMB->ByteCount = cpu_to_le16(byte_count);
4706 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4707 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4709 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
4710 } else { /* decode response */
4711 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4713 if (rc || get_bcc(&pSMBr->hdr) <
4714 sizeof(FILE_SYSTEM_DEVICE_INFO))
4715 rc = -EIO; /* bad smb */
4717 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4719 (FILE_SYSTEM_DEVICE_INFO *)
4720 (((char *) &pSMBr->hdr.Protocol) +
4722 memcpy(&tcon->fsDevInfo, response_data,
4723 sizeof(FILE_SYSTEM_DEVICE_INFO));
4726 cifs_buf_release(pSMB);
4729 goto QFSDeviceRetry;
4735 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
4737 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
4738 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4739 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4740 FILE_SYSTEM_UNIX_INFO *response_data;
4742 int bytes_returned = 0;
4743 __u16 params, byte_count;
4745 cifs_dbg(FYI, "In QFSUnixInfo\n");
4747 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4748 (void **) &pSMB, (void **) &pSMBr);
4752 params = 2; /* level */
4753 pSMB->TotalDataCount = 0;
4754 pSMB->DataCount = 0;
4755 pSMB->DataOffset = 0;
4756 pSMB->MaxParameterCount = cpu_to_le16(2);
4757 /* BB find exact max SMB PDU from sess structure BB */
4758 pSMB->MaxDataCount = cpu_to_le16(100);
4759 pSMB->MaxSetupCount = 0;
4763 pSMB->Reserved2 = 0;
4764 byte_count = params + 1 /* pad */ ;
4765 pSMB->ParameterCount = cpu_to_le16(params);
4766 pSMB->TotalParameterCount = pSMB->ParameterCount;
4767 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4768 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4769 pSMB->SetupCount = 1;
4770 pSMB->Reserved3 = 0;
4771 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4772 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4773 inc_rfc1001_len(pSMB, byte_count);
4774 pSMB->ByteCount = cpu_to_le16(byte_count);
4776 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4777 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4779 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
4780 } else { /* decode response */
4781 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4783 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4784 rc = -EIO; /* bad smb */
4786 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4788 (FILE_SYSTEM_UNIX_INFO
4789 *) (((char *) &pSMBr->hdr.Protocol) +
4791 memcpy(&tcon->fsUnixInfo, response_data,
4792 sizeof(FILE_SYSTEM_UNIX_INFO));
4795 cifs_buf_release(pSMB);
4805 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
4807 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
4808 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
4809 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
4811 int bytes_returned = 0;
4812 __u16 params, param_offset, offset, byte_count;
4814 cifs_dbg(FYI, "In SETFSUnixInfo\n");
4816 /* BB switch to small buf init to save memory */
4817 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4818 (void **) &pSMB, (void **) &pSMBr);
4822 params = 4; /* 2 bytes zero followed by info level. */
4823 pSMB->MaxSetupCount = 0;
4827 pSMB->Reserved2 = 0;
4828 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
4830 offset = param_offset + params;
4832 pSMB->MaxParameterCount = cpu_to_le16(4);
4833 /* BB find exact max SMB PDU from sess structure BB */
4834 pSMB->MaxDataCount = cpu_to_le16(100);
4835 pSMB->SetupCount = 1;
4836 pSMB->Reserved3 = 0;
4837 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
4838 byte_count = 1 /* pad */ + params + 12;
4840 pSMB->DataCount = cpu_to_le16(12);
4841 pSMB->ParameterCount = cpu_to_le16(params);
4842 pSMB->TotalDataCount = pSMB->DataCount;
4843 pSMB->TotalParameterCount = pSMB->ParameterCount;
4844 pSMB->ParameterOffset = cpu_to_le16(param_offset);
4845 pSMB->DataOffset = cpu_to_le16(offset);
4849 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
4852 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
4853 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4854 pSMB->ClientUnixCap = cpu_to_le64(cap);
4856 inc_rfc1001_len(pSMB, byte_count);
4857 pSMB->ByteCount = cpu_to_le16(byte_count);
4859 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4860 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4862 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
4863 } else { /* decode response */
4864 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4866 rc = -EIO; /* bad smb */
4868 cifs_buf_release(pSMB);
4871 goto SETFSUnixRetry;
4879 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
4880 struct kstatfs *FSData)
4882 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
4883 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4884 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4885 FILE_SYSTEM_POSIX_INFO *response_data;
4887 int bytes_returned = 0;
4888 __u16 params, byte_count;
4890 cifs_dbg(FYI, "In QFSPosixInfo\n");
4892 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4897 params = 2; /* level */
4898 pSMB->TotalDataCount = 0;
4899 pSMB->DataCount = 0;
4900 pSMB->DataOffset = 0;
4901 pSMB->MaxParameterCount = cpu_to_le16(2);
4902 /* BB find exact max SMB PDU from sess structure BB */
4903 pSMB->MaxDataCount = cpu_to_le16(100);
4904 pSMB->MaxSetupCount = 0;
4908 pSMB->Reserved2 = 0;
4909 byte_count = params + 1 /* pad */ ;
4910 pSMB->ParameterCount = cpu_to_le16(params);
4911 pSMB->TotalParameterCount = pSMB->ParameterCount;
4912 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4913 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4914 pSMB->SetupCount = 1;
4915 pSMB->Reserved3 = 0;
4916 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4917 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4918 inc_rfc1001_len(pSMB, byte_count);
4919 pSMB->ByteCount = cpu_to_le16(byte_count);
4921 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4922 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4924 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
4925 } else { /* decode response */
4926 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4928 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4929 rc = -EIO; /* bad smb */
4931 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4933 (FILE_SYSTEM_POSIX_INFO
4934 *) (((char *) &pSMBr->hdr.Protocol) +
4937 le32_to_cpu(response_data->BlockSize);
4939 * much prefer larger but if server doesn't report
4940 * a valid size than 4K is a reasonable minimum
4942 if (FSData->f_bsize < 512)
4943 FSData->f_bsize = 4096;
4946 le64_to_cpu(response_data->TotalBlocks);
4948 le64_to_cpu(response_data->BlocksAvail);
4949 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
4950 FSData->f_bavail = FSData->f_bfree;
4953 le64_to_cpu(response_data->UserBlocksAvail);
4955 if (response_data->TotalFileNodes != cpu_to_le64(-1))
4957 le64_to_cpu(response_data->TotalFileNodes);
4958 if (response_data->FreeFileNodes != cpu_to_le64(-1))
4960 le64_to_cpu(response_data->FreeFileNodes);
4963 cifs_buf_release(pSMB);
4973 * We can not use write of zero bytes trick to set file size due to need for
4974 * large file support. Also note that this SetPathInfo is preferred to
4975 * SetFileInfo based method in next routine which is only needed to work around
4976 * a sharing violation bugin Samba which this routine can run into.
4979 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
4980 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
4981 bool set_allocation)
4983 struct smb_com_transaction2_spi_req *pSMB = NULL;
4984 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
4985 struct file_end_of_file_info *parm_data;
4988 int bytes_returned = 0;
4989 int remap = cifs_remap(cifs_sb);
4991 __u16 params, byte_count, data_count, param_offset, offset;
4993 cifs_dbg(FYI, "In SetEOF\n");
4995 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5000 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5002 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5003 PATH_MAX, cifs_sb->local_nls, remap);
5004 name_len++; /* trailing null */
5007 name_len = copy_path_name(pSMB->FileName, file_name);
5009 params = 6 + name_len;
5010 data_count = sizeof(struct file_end_of_file_info);
5011 pSMB->MaxParameterCount = cpu_to_le16(2);
5012 pSMB->MaxDataCount = cpu_to_le16(4100);
5013 pSMB->MaxSetupCount = 0;
5017 pSMB->Reserved2 = 0;
5018 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5019 InformationLevel) - 4;
5020 offset = param_offset + params;
5021 if (set_allocation) {
5022 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5023 pSMB->InformationLevel =
5024 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5026 pSMB->InformationLevel =
5027 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5028 } else /* Set File Size */ {
5029 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5030 pSMB->InformationLevel =
5031 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5033 pSMB->InformationLevel =
5034 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5038 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5040 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5041 pSMB->DataOffset = cpu_to_le16(offset);
5042 pSMB->SetupCount = 1;
5043 pSMB->Reserved3 = 0;
5044 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5045 byte_count = 3 /* pad */ + params + data_count;
5046 pSMB->DataCount = cpu_to_le16(data_count);
5047 pSMB->TotalDataCount = pSMB->DataCount;
5048 pSMB->ParameterCount = cpu_to_le16(params);
5049 pSMB->TotalParameterCount = pSMB->ParameterCount;
5050 pSMB->Reserved4 = 0;
5051 inc_rfc1001_len(pSMB, byte_count);
5052 parm_data->FileSize = cpu_to_le64(size);
5053 pSMB->ByteCount = cpu_to_le16(byte_count);
5054 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5055 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5057 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5059 cifs_buf_release(pSMB);
5068 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5069 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5071 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5072 struct file_end_of_file_info *parm_data;
5074 __u16 params, param_offset, offset, byte_count, count;
5076 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5078 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5083 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5084 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5087 pSMB->MaxSetupCount = 0;
5091 pSMB->Reserved2 = 0;
5092 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5093 offset = param_offset + params;
5095 count = sizeof(struct file_end_of_file_info);
5096 pSMB->MaxParameterCount = cpu_to_le16(2);
5097 /* BB find exact max SMB PDU from sess structure BB */
5098 pSMB->MaxDataCount = cpu_to_le16(1000);
5099 pSMB->SetupCount = 1;
5100 pSMB->Reserved3 = 0;
5101 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5102 byte_count = 3 /* pad */ + params + count;
5103 pSMB->DataCount = cpu_to_le16(count);
5104 pSMB->ParameterCount = cpu_to_le16(params);
5105 pSMB->TotalDataCount = pSMB->DataCount;
5106 pSMB->TotalParameterCount = pSMB->ParameterCount;
5107 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5108 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5110 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5111 pSMB->DataOffset = cpu_to_le16(offset);
5112 parm_data->FileSize = cpu_to_le64(size);
5113 pSMB->Fid = cfile->fid.netfid;
5114 if (set_allocation) {
5115 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5116 pSMB->InformationLevel =
5117 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5119 pSMB->InformationLevel =
5120 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5121 } else /* Set File Size */ {
5122 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5123 pSMB->InformationLevel =
5124 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5126 pSMB->InformationLevel =
5127 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5129 pSMB->Reserved4 = 0;
5130 inc_rfc1001_len(pSMB, byte_count);
5131 pSMB->ByteCount = cpu_to_le16(byte_count);
5132 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5133 cifs_small_buf_release(pSMB);
5135 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5139 /* Note: On -EAGAIN error only caller can retry on handle based calls
5140 since file handle passed in no longer valid */
5145 /* Some legacy servers such as NT4 require that the file times be set on
5146 an open handle, rather than by pathname - this is awkward due to
5147 potential access conflicts on the open, but it is unavoidable for these
5148 old servers since the only other choice is to go from 100 nanosecond DCE
5149 time and resort to the original setpathinfo level which takes the ancient
5150 DOS time format with 2 second granularity */
5152 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5153 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5155 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5158 __u16 params, param_offset, offset, byte_count, count;
5160 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5161 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5166 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5167 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5170 pSMB->MaxSetupCount = 0;
5174 pSMB->Reserved2 = 0;
5175 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5176 offset = param_offset + params;
5178 data_offset = (char *)pSMB +
5179 offsetof(struct smb_hdr, Protocol) + offset;
5181 count = sizeof(FILE_BASIC_INFO);
5182 pSMB->MaxParameterCount = cpu_to_le16(2);
5183 /* BB find max SMB PDU from sess */
5184 pSMB->MaxDataCount = cpu_to_le16(1000);
5185 pSMB->SetupCount = 1;
5186 pSMB->Reserved3 = 0;
5187 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5188 byte_count = 3 /* pad */ + params + count;
5189 pSMB->DataCount = cpu_to_le16(count);
5190 pSMB->ParameterCount = cpu_to_le16(params);
5191 pSMB->TotalDataCount = pSMB->DataCount;
5192 pSMB->TotalParameterCount = pSMB->ParameterCount;
5193 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5194 pSMB->DataOffset = cpu_to_le16(offset);
5196 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5197 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5199 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5200 pSMB->Reserved4 = 0;
5201 inc_rfc1001_len(pSMB, byte_count);
5202 pSMB->ByteCount = cpu_to_le16(byte_count);
5203 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5204 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5205 cifs_small_buf_release(pSMB);
5207 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5210 /* Note: On -EAGAIN error only caller can retry on handle based calls
5211 since file handle passed in no longer valid */
5217 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5218 bool delete_file, __u16 fid, __u32 pid_of_opener)
5220 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5223 __u16 params, param_offset, offset, byte_count, count;
5225 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5226 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5231 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5232 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5235 pSMB->MaxSetupCount = 0;
5239 pSMB->Reserved2 = 0;
5240 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5241 offset = param_offset + params;
5243 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5244 data_offset = (char *)(pSMB) + offset + 4;
5247 pSMB->MaxParameterCount = cpu_to_le16(2);
5248 /* BB find max SMB PDU from sess */
5249 pSMB->MaxDataCount = cpu_to_le16(1000);
5250 pSMB->SetupCount = 1;
5251 pSMB->Reserved3 = 0;
5252 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5253 byte_count = 3 /* pad */ + params + count;
5254 pSMB->DataCount = cpu_to_le16(count);
5255 pSMB->ParameterCount = cpu_to_le16(params);
5256 pSMB->TotalDataCount = pSMB->DataCount;
5257 pSMB->TotalParameterCount = pSMB->ParameterCount;
5258 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5259 pSMB->DataOffset = cpu_to_le16(offset);
5261 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5262 pSMB->Reserved4 = 0;
5263 inc_rfc1001_len(pSMB, byte_count);
5264 pSMB->ByteCount = cpu_to_le16(byte_count);
5265 *data_offset = delete_file ? 1 : 0;
5266 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5267 cifs_small_buf_release(pSMB);
5269 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5275 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5276 const char *fileName, const FILE_BASIC_INFO *data,
5277 const struct nls_table *nls_codepage,
5278 struct cifs_sb_info *cifs_sb)
5281 struct cifs_open_parms oparms;
5282 struct cifs_fid fid;
5285 oparms = (struct cifs_open_parms) {
5288 .desired_access = GENERIC_WRITE,
5289 .create_options = cifs_create_options(cifs_sb, 0),
5290 .disposition = FILE_OPEN,
5295 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5299 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5300 CIFSSMBClose(xid, tcon, fid.netfid);
5307 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5308 const char *fileName, const FILE_BASIC_INFO *data,
5309 const struct nls_table *nls_codepage,
5310 struct cifs_sb_info *cifs_sb)
5312 TRANSACTION2_SPI_REQ *pSMB = NULL;
5313 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5316 int bytes_returned = 0;
5318 __u16 params, param_offset, offset, byte_count, count;
5319 int remap = cifs_remap(cifs_sb);
5321 cifs_dbg(FYI, "In SetTimes\n");
5324 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5329 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5331 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5332 PATH_MAX, nls_codepage, remap);
5333 name_len++; /* trailing null */
5336 name_len = copy_path_name(pSMB->FileName, fileName);
5339 params = 6 + name_len;
5340 count = sizeof(FILE_BASIC_INFO);
5341 pSMB->MaxParameterCount = cpu_to_le16(2);
5342 /* BB find max SMB PDU from sess structure BB */
5343 pSMB->MaxDataCount = cpu_to_le16(1000);
5344 pSMB->MaxSetupCount = 0;
5348 pSMB->Reserved2 = 0;
5349 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5350 InformationLevel) - 4;
5351 offset = param_offset + params;
5352 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5353 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5354 pSMB->DataOffset = cpu_to_le16(offset);
5355 pSMB->SetupCount = 1;
5356 pSMB->Reserved3 = 0;
5357 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5358 byte_count = 3 /* pad */ + params + count;
5360 pSMB->DataCount = cpu_to_le16(count);
5361 pSMB->ParameterCount = cpu_to_le16(params);
5362 pSMB->TotalDataCount = pSMB->DataCount;
5363 pSMB->TotalParameterCount = pSMB->ParameterCount;
5364 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5365 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5367 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5368 pSMB->Reserved4 = 0;
5369 inc_rfc1001_len(pSMB, byte_count);
5370 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5371 pSMB->ByteCount = cpu_to_le16(byte_count);
5372 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5373 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5375 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5377 cifs_buf_release(pSMB);
5382 if (rc == -EOPNOTSUPP)
5383 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5384 nls_codepage, cifs_sb);
5390 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5391 const struct cifs_unix_set_info_args *args)
5393 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5394 u64 mode = args->mode;
5396 if (uid_valid(args->uid))
5397 uid = from_kuid(&init_user_ns, args->uid);
5398 if (gid_valid(args->gid))
5399 gid = from_kgid(&init_user_ns, args->gid);
5402 * Samba server ignores set of file size to zero due to bugs in some
5403 * older clients, but we should be precise - we use SetFileSize to
5404 * set file size and do not want to truncate file size to zero
5405 * accidentally as happened on one Samba server beta by putting
5406 * zero instead of -1 here
5408 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5409 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5410 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5411 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5412 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5413 data_offset->Uid = cpu_to_le64(uid);
5414 data_offset->Gid = cpu_to_le64(gid);
5415 /* better to leave device as zero when it is */
5416 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5417 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5418 data_offset->Permissions = cpu_to_le64(mode);
5421 data_offset->Type = cpu_to_le32(UNIX_FILE);
5422 else if (S_ISDIR(mode))
5423 data_offset->Type = cpu_to_le32(UNIX_DIR);
5424 else if (S_ISLNK(mode))
5425 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5426 else if (S_ISCHR(mode))
5427 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5428 else if (S_ISBLK(mode))
5429 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5430 else if (S_ISFIFO(mode))
5431 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5432 else if (S_ISSOCK(mode))
5433 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5437 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5438 const struct cifs_unix_set_info_args *args,
5439 u16 fid, u32 pid_of_opener)
5441 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5444 u16 params, param_offset, offset, byte_count, count;
5446 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5447 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5452 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5453 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5456 pSMB->MaxSetupCount = 0;
5460 pSMB->Reserved2 = 0;
5461 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5462 offset = param_offset + params;
5464 data_offset = (char *)pSMB +
5465 offsetof(struct smb_hdr, Protocol) + offset;
5467 count = sizeof(FILE_UNIX_BASIC_INFO);
5469 pSMB->MaxParameterCount = cpu_to_le16(2);
5470 /* BB find max SMB PDU from sess */
5471 pSMB->MaxDataCount = cpu_to_le16(1000);
5472 pSMB->SetupCount = 1;
5473 pSMB->Reserved3 = 0;
5474 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5475 byte_count = 3 /* pad */ + params + count;
5476 pSMB->DataCount = cpu_to_le16(count);
5477 pSMB->ParameterCount = cpu_to_le16(params);
5478 pSMB->TotalDataCount = pSMB->DataCount;
5479 pSMB->TotalParameterCount = pSMB->ParameterCount;
5480 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5481 pSMB->DataOffset = cpu_to_le16(offset);
5483 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5484 pSMB->Reserved4 = 0;
5485 inc_rfc1001_len(pSMB, byte_count);
5486 pSMB->ByteCount = cpu_to_le16(byte_count);
5488 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5490 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5491 cifs_small_buf_release(pSMB);
5493 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5496 /* Note: On -EAGAIN error only caller can retry on handle based calls
5497 since file handle passed in no longer valid */
5503 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5504 const char *file_name,
5505 const struct cifs_unix_set_info_args *args,
5506 const struct nls_table *nls_codepage, int remap)
5508 TRANSACTION2_SPI_REQ *pSMB = NULL;
5509 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5512 int bytes_returned = 0;
5513 FILE_UNIX_BASIC_INFO *data_offset;
5514 __u16 params, param_offset, offset, count, byte_count;
5516 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5518 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5523 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5525 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5526 PATH_MAX, nls_codepage, remap);
5527 name_len++; /* trailing null */
5530 name_len = copy_path_name(pSMB->FileName, file_name);
5533 params = 6 + name_len;
5534 count = sizeof(FILE_UNIX_BASIC_INFO);
5535 pSMB->MaxParameterCount = cpu_to_le16(2);
5536 /* BB find max SMB PDU from sess structure BB */
5537 pSMB->MaxDataCount = cpu_to_le16(1000);
5538 pSMB->MaxSetupCount = 0;
5542 pSMB->Reserved2 = 0;
5543 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5544 InformationLevel) - 4;
5545 offset = param_offset + params;
5546 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5547 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
5548 memset(data_offset, 0, count);
5549 pSMB->DataOffset = cpu_to_le16(offset);
5550 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5551 pSMB->SetupCount = 1;
5552 pSMB->Reserved3 = 0;
5553 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5554 byte_count = 3 /* pad */ + params + count;
5555 pSMB->ParameterCount = cpu_to_le16(params);
5556 pSMB->DataCount = cpu_to_le16(count);
5557 pSMB->TotalParameterCount = pSMB->ParameterCount;
5558 pSMB->TotalDataCount = pSMB->DataCount;
5559 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5560 pSMB->Reserved4 = 0;
5561 inc_rfc1001_len(pSMB, byte_count);
5563 cifs_fill_unix_set_info(data_offset, args);
5565 pSMB->ByteCount = cpu_to_le16(byte_count);
5566 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5567 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5569 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
5571 cifs_buf_release(pSMB);
5577 #ifdef CONFIG_CIFS_XATTR
5579 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
5580 * function used by listxattr and getxattr type calls. When ea_name is set,
5581 * it looks for that attribute name and stuffs that value into the EAData
5582 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
5583 * buffer. In both cases, the return value is either the length of the
5584 * resulting data or a negative error code. If EAData is a NULL pointer then
5585 * the data isn't copied to it, but the length is returned.
5588 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
5589 const unsigned char *searchName, const unsigned char *ea_name,
5590 char *EAData, size_t buf_size,
5591 struct cifs_sb_info *cifs_sb)
5593 /* BB assumes one setup word */
5594 TRANSACTION2_QPI_REQ *pSMB = NULL;
5595 TRANSACTION2_QPI_RSP *pSMBr = NULL;
5596 int remap = cifs_remap(cifs_sb);
5597 struct nls_table *nls_codepage = cifs_sb->local_nls;
5601 struct fealist *ea_response_data;
5602 struct fea *temp_fea;
5605 __u16 params, byte_count, data_offset;
5606 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
5608 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
5610 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5615 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5617 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
5618 PATH_MAX, nls_codepage, remap);
5619 list_len++; /* trailing null */
5622 list_len = copy_path_name(pSMB->FileName, searchName);
5625 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
5626 pSMB->TotalDataCount = 0;
5627 pSMB->MaxParameterCount = cpu_to_le16(2);
5628 /* BB find exact max SMB PDU from sess structure BB */
5629 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
5630 pSMB->MaxSetupCount = 0;
5634 pSMB->Reserved2 = 0;
5635 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5636 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5637 pSMB->DataCount = 0;
5638 pSMB->DataOffset = 0;
5639 pSMB->SetupCount = 1;
5640 pSMB->Reserved3 = 0;
5641 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
5642 byte_count = params + 1 /* pad */ ;
5643 pSMB->TotalParameterCount = cpu_to_le16(params);
5644 pSMB->ParameterCount = pSMB->TotalParameterCount;
5645 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5646 pSMB->Reserved4 = 0;
5647 inc_rfc1001_len(pSMB, byte_count);
5648 pSMB->ByteCount = cpu_to_le16(byte_count);
5650 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5651 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5653 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
5658 /* BB also check enough total bytes returned */
5659 /* BB we need to improve the validity checking
5660 of these trans2 responses */
5662 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5663 if (rc || get_bcc(&pSMBr->hdr) < 4) {
5664 rc = -EIO; /* bad smb */
5668 /* check that length of list is not more than bcc */
5669 /* check that each entry does not go beyond length
5671 /* check that each element of each entry does not
5672 go beyond end of list */
5673 /* validate_trans2_offsets() */
5674 /* BB check if start of smb + data_offset > &bcc+ bcc */
5676 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5677 ea_response_data = (struct fealist *)
5678 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5680 list_len = le32_to_cpu(ea_response_data->list_len);
5681 cifs_dbg(FYI, "ea length %d\n", list_len);
5682 if (list_len <= 8) {
5683 cifs_dbg(FYI, "empty EA list returned from server\n");
5684 /* didn't find the named attribute */
5690 /* make sure list_len doesn't go past end of SMB */
5691 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
5692 if ((char *)ea_response_data + list_len > end_of_smb) {
5693 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
5698 /* account for ea list len */
5700 temp_fea = ea_response_data->list;
5701 temp_ptr = (char *)temp_fea;
5702 while (list_len > 0) {
5703 unsigned int name_len;
5708 /* make sure we can read name_len and value_len */
5710 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5715 name_len = temp_fea->name_len;
5716 value_len = le16_to_cpu(temp_fea->value_len);
5717 list_len -= name_len + 1 + value_len;
5719 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5725 if (ea_name_len == name_len &&
5726 memcmp(ea_name, temp_ptr, name_len) == 0) {
5727 temp_ptr += name_len + 1;
5731 if ((size_t)value_len > buf_size) {
5735 memcpy(EAData, temp_ptr, value_len);
5739 /* account for prefix user. and trailing null */
5740 rc += (5 + 1 + name_len);
5741 if (rc < (int) buf_size) {
5742 memcpy(EAData, "user.", 5);
5744 memcpy(EAData, temp_ptr, name_len);
5746 /* null terminate name */
5749 } else if (buf_size == 0) {
5750 /* skip copy - calc size only */
5752 /* stop before overrun buffer */
5757 temp_ptr += name_len + 1 + value_len;
5758 temp_fea = (struct fea *)temp_ptr;
5761 /* didn't find the named attribute */
5766 cifs_buf_release(pSMB);
5774 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
5775 const char *fileName, const char *ea_name, const void *ea_value,
5776 const __u16 ea_value_len, const struct nls_table *nls_codepage,
5777 struct cifs_sb_info *cifs_sb)
5779 struct smb_com_transaction2_spi_req *pSMB = NULL;
5780 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5781 struct fealist *parm_data;
5784 int bytes_returned = 0;
5785 __u16 params, param_offset, byte_count, offset, count;
5786 int remap = cifs_remap(cifs_sb);
5788 cifs_dbg(FYI, "In SetEA\n");
5790 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5795 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5797 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5798 PATH_MAX, nls_codepage, remap);
5799 name_len++; /* trailing null */
5802 name_len = copy_path_name(pSMB->FileName, fileName);
5805 params = 6 + name_len;
5807 /* done calculating parms using name_len of file name,
5808 now use name_len to calculate length of ea name
5809 we are going to create in the inode xattrs */
5810 if (ea_name == NULL)
5813 name_len = strnlen(ea_name, 255);
5815 count = sizeof(*parm_data) + ea_value_len + name_len;
5816 pSMB->MaxParameterCount = cpu_to_le16(2);
5817 /* BB find max SMB PDU from sess */
5818 pSMB->MaxDataCount = cpu_to_le16(1000);
5819 pSMB->MaxSetupCount = 0;
5823 pSMB->Reserved2 = 0;
5824 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5825 InformationLevel) - 4;
5826 offset = param_offset + params;
5827 pSMB->InformationLevel =
5828 cpu_to_le16(SMB_SET_FILE_EA);
5830 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
5831 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5832 pSMB->DataOffset = cpu_to_le16(offset);
5833 pSMB->SetupCount = 1;
5834 pSMB->Reserved3 = 0;
5835 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5836 byte_count = 3 /* pad */ + params + count;
5837 pSMB->DataCount = cpu_to_le16(count);
5838 parm_data->list_len = cpu_to_le32(count);
5839 parm_data->list[0].EA_flags = 0;
5840 /* we checked above that name len is less than 255 */
5841 parm_data->list[0].name_len = (__u8)name_len;
5842 /* EA names are always ASCII */
5844 strncpy(parm_data->list[0].name, ea_name, name_len);
5845 parm_data->list[0].name[name_len] = 0;
5846 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
5847 /* caller ensures that ea_value_len is less than 64K but
5848 we need to ensure that it fits within the smb */
5850 /*BB add length check to see if it would fit in
5851 negotiated SMB buffer size BB */
5852 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
5854 memcpy(parm_data->list[0].name+name_len+1,
5855 ea_value, ea_value_len);
5857 pSMB->TotalDataCount = pSMB->DataCount;
5858 pSMB->ParameterCount = cpu_to_le16(params);
5859 pSMB->TotalParameterCount = pSMB->ParameterCount;
5860 pSMB->Reserved4 = 0;
5861 inc_rfc1001_len(pSMB, byte_count);
5862 pSMB->ByteCount = cpu_to_le16(byte_count);
5863 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5864 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5866 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
5868 cifs_buf_release(pSMB);