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 from CreationTime to Attributes */
1238 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1239 /* the file_info buf is endian converted by caller */
1240 buf->AllocationSize = rsp->AllocationSize;
1241 buf->EndOfFile = rsp->EndOfFile;
1242 buf->NumberOfLinks = cpu_to_le32(1);
1243 buf->DeletePending = 0;
1246 cifs_buf_release(req);
1251 cifs_readv_callback(struct mid_q_entry *mid)
1253 struct cifs_readdata *rdata = mid->callback_data;
1254 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1255 struct TCP_Server_Info *server = tcon->ses->server;
1256 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1258 .rq_pages = rdata->pages,
1259 .rq_offset = rdata->page_offset,
1260 .rq_npages = rdata->nr_pages,
1261 .rq_pagesz = rdata->pagesz,
1262 .rq_tailsz = rdata->tailsz };
1263 struct cifs_credits credits = { .value = 1, .instance = 0 };
1265 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1266 __func__, mid->mid, mid->mid_state, rdata->result,
1269 switch (mid->mid_state) {
1270 case MID_RESPONSE_RECEIVED:
1271 /* result already set, check signature */
1275 rc = cifs_verify_signature(&rqst, server,
1276 mid->sequence_number);
1278 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1281 /* FIXME: should this be counted toward the initiating task? */
1282 task_io_account_read(rdata->got_bytes);
1283 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1285 case MID_REQUEST_SUBMITTED:
1286 case MID_RETRY_NEEDED:
1287 rdata->result = -EAGAIN;
1288 if (server->sign && rdata->got_bytes)
1289 /* reset bytes number since we can not check a sign */
1290 rdata->got_bytes = 0;
1291 /* FIXME: should this be counted toward the initiating task? */
1292 task_io_account_read(rdata->got_bytes);
1293 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1296 rdata->result = -EIO;
1299 queue_work(cifsiod_wq, &rdata->work);
1301 add_credits(server, &credits, 0);
1304 /* cifs_async_readv - send an async write, and set up mid to handle result */
1306 cifs_async_readv(struct cifs_readdata *rdata)
1309 READ_REQ *smb = NULL;
1311 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1312 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1315 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1316 __func__, rdata->offset, rdata->bytes);
1318 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1321 wct = 10; /* old style read */
1322 if ((rdata->offset >> 32) > 0) {
1323 /* can not handle this big offset for old */
1328 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1332 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1333 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1335 smb->AndXCommand = 0xFF; /* none */
1336 smb->Fid = rdata->cfile->fid.netfid;
1337 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1339 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1341 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1342 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1346 /* old style read */
1347 struct smb_com_readx_req *smbr =
1348 (struct smb_com_readx_req *)smb;
1349 smbr->ByteCount = 0;
1352 /* 4 for RFC1001 length + 1 for BCC */
1353 rdata->iov[0].iov_base = smb;
1354 rdata->iov[0].iov_len = 4;
1355 rdata->iov[1].iov_base = (char *)smb + 4;
1356 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1358 kref_get(&rdata->refcount);
1359 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1360 cifs_readv_callback, NULL, rdata, 0, NULL);
1363 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1365 kref_put(&rdata->refcount, cifs_readdata_release);
1367 cifs_small_buf_release(smb);
1372 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1373 unsigned int *nbytes, char **buf, int *pbuf_type)
1376 READ_REQ *pSMB = NULL;
1377 READ_RSP *pSMBr = NULL;
1378 char *pReadData = NULL;
1380 int resp_buf_type = 0;
1382 struct kvec rsp_iov;
1383 __u32 pid = io_parms->pid;
1384 __u16 netfid = io_parms->netfid;
1385 __u64 offset = io_parms->offset;
1386 struct cifs_tcon *tcon = io_parms->tcon;
1387 unsigned int count = io_parms->length;
1389 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1390 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1393 wct = 10; /* old style read */
1394 if ((offset >> 32) > 0) {
1395 /* can not handle this big offset for old */
1401 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1405 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1406 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1408 /* tcon and ses pointer are checked in smb_init */
1409 if (tcon->ses->server == NULL)
1410 return -ECONNABORTED;
1412 pSMB->AndXCommand = 0xFF; /* none */
1414 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1416 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1418 pSMB->Remaining = 0;
1419 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1420 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1422 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1424 /* old style read */
1425 struct smb_com_readx_req *pSMBW =
1426 (struct smb_com_readx_req *)pSMB;
1427 pSMBW->ByteCount = 0;
1430 iov[0].iov_base = (char *)pSMB;
1431 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1432 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1433 CIFS_LOG_ERROR, &rsp_iov);
1434 cifs_small_buf_release(pSMB);
1435 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1436 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1438 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1440 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1441 data_length = data_length << 16;
1442 data_length += le16_to_cpu(pSMBr->DataLength);
1443 *nbytes = data_length;
1445 /*check that DataLength would not go beyond end of SMB */
1446 if ((data_length > CIFSMaxBufSize)
1447 || (data_length > count)) {
1448 cifs_dbg(FYI, "bad length %d for count %d\n",
1449 data_length, count);
1453 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1454 le16_to_cpu(pSMBr->DataOffset);
1455 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1456 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1458 }*/ /* can not use copy_to_user when using page cache*/
1460 memcpy(*buf, pReadData, data_length);
1465 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1466 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1467 /* return buffer to caller to free */
1468 *buf = rsp_iov.iov_base;
1469 if (resp_buf_type == CIFS_SMALL_BUFFER)
1470 *pbuf_type = CIFS_SMALL_BUFFER;
1471 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1472 *pbuf_type = CIFS_LARGE_BUFFER;
1473 } /* else no valid buffer on return - leave as null */
1475 /* Note: On -EAGAIN error only caller can retry on handle based calls
1476 since file handle passed in no longer valid */
1482 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1483 unsigned int *nbytes, const char *buf)
1486 WRITE_REQ *pSMB = NULL;
1487 WRITE_RSP *pSMBr = NULL;
1488 int bytes_returned, wct;
1491 __u32 pid = io_parms->pid;
1492 __u16 netfid = io_parms->netfid;
1493 __u64 offset = io_parms->offset;
1494 struct cifs_tcon *tcon = io_parms->tcon;
1495 unsigned int count = io_parms->length;
1499 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1500 if (tcon->ses == NULL)
1501 return -ECONNABORTED;
1503 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1507 if ((offset >> 32) > 0) {
1508 /* can not handle big offset for old srv */
1513 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1518 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1519 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1521 /* tcon and ses pointer are checked in smb_init */
1522 if (tcon->ses->server == NULL)
1523 return -ECONNABORTED;
1525 pSMB->AndXCommand = 0xFF; /* none */
1527 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1529 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1531 pSMB->Reserved = 0xFFFFFFFF;
1532 pSMB->WriteMode = 0;
1533 pSMB->Remaining = 0;
1535 /* Can increase buffer size if buffer is big enough in some cases ie we
1536 can send more if LARGE_WRITE_X capability returned by the server and if
1537 our buffer is big enough or if we convert to iovecs on socket writes
1538 and eliminate the copy to the CIFS buffer */
1539 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1540 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1542 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1546 if (bytes_sent > count)
1549 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1551 memcpy(pSMB->Data, buf, bytes_sent);
1552 else if (count != 0) {
1554 cifs_buf_release(pSMB);
1556 } /* else setting file size with write of zero bytes */
1558 byte_count = bytes_sent + 1; /* pad */
1559 else /* wct == 12 */
1560 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1562 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1563 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1564 inc_rfc1001_len(pSMB, byte_count);
1567 pSMB->ByteCount = cpu_to_le16(byte_count);
1568 else { /* old style write has byte count 4 bytes earlier
1570 struct smb_com_writex_req *pSMBW =
1571 (struct smb_com_writex_req *)pSMB;
1572 pSMBW->ByteCount = cpu_to_le16(byte_count);
1575 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1576 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1577 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1579 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1581 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1582 *nbytes = (*nbytes) << 16;
1583 *nbytes += le16_to_cpu(pSMBr->Count);
1586 * Mask off high 16 bits when bytes written as returned by the
1587 * server is greater than bytes requested by the client. Some
1588 * OS/2 servers are known to set incorrect CountHigh values.
1590 if (*nbytes > count)
1594 cifs_buf_release(pSMB);
1596 /* Note: On -EAGAIN error only caller can retry on handle based calls
1597 since file handle passed in no longer valid */
1603 * Check the mid_state and signature on received buffer (if any), and queue the
1604 * workqueue completion task.
1607 cifs_writev_callback(struct mid_q_entry *mid)
1609 struct cifs_writedata *wdata = mid->callback_data;
1610 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1611 unsigned int written;
1612 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1613 struct cifs_credits credits = { .value = 1, .instance = 0 };
1615 switch (mid->mid_state) {
1616 case MID_RESPONSE_RECEIVED:
1617 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
1618 if (wdata->result != 0)
1621 written = le16_to_cpu(smb->CountHigh);
1623 written += le16_to_cpu(smb->Count);
1625 * Mask off high 16 bits when bytes written as returned
1626 * by the server is greater than bytes requested by the
1627 * client. OS/2 servers are known to set incorrect
1630 if (written > wdata->bytes)
1633 if (written < wdata->bytes)
1634 wdata->result = -ENOSPC;
1636 wdata->bytes = written;
1638 case MID_REQUEST_SUBMITTED:
1639 case MID_RETRY_NEEDED:
1640 wdata->result = -EAGAIN;
1643 wdata->result = -EIO;
1647 queue_work(cifsiod_wq, &wdata->work);
1649 add_credits(tcon->ses->server, &credits, 0);
1652 /* cifs_async_writev - send an async write, and set up mid to handle result */
1654 cifs_async_writev(struct cifs_writedata *wdata,
1655 void (*release)(struct kref *kref))
1658 WRITE_REQ *smb = NULL;
1660 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1662 struct smb_rqst rqst = { };
1664 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1668 if (wdata->offset >> 32 > 0) {
1669 /* can not handle big offset for old srv */
1674 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
1676 goto async_writev_out;
1678 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
1679 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
1681 smb->AndXCommand = 0xFF; /* none */
1682 smb->Fid = wdata->cfile->fid.netfid;
1683 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
1685 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
1686 smb->Reserved = 0xFFFFFFFF;
1691 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1693 /* 4 for RFC1001 length + 1 for BCC */
1695 iov[0].iov_base = smb;
1696 iov[1].iov_len = get_rfc1002_length(smb) + 1;
1697 iov[1].iov_base = (char *)smb + 4;
1701 rqst.rq_pages = wdata->pages;
1702 rqst.rq_offset = wdata->page_offset;
1703 rqst.rq_npages = wdata->nr_pages;
1704 rqst.rq_pagesz = wdata->pagesz;
1705 rqst.rq_tailsz = wdata->tailsz;
1707 cifs_dbg(FYI, "async write at %llu %u bytes\n",
1708 wdata->offset, wdata->bytes);
1710 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
1711 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
1714 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
1715 put_bcc(wdata->bytes + 1, &smb->hdr);
1718 struct smb_com_writex_req *smbw =
1719 (struct smb_com_writex_req *)smb;
1720 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
1721 put_bcc(wdata->bytes + 5, &smbw->hdr);
1722 iov[1].iov_len += 4; /* pad bigger by four bytes */
1725 kref_get(&wdata->refcount);
1726 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
1727 cifs_writev_callback, NULL, wdata, 0, NULL);
1730 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1732 kref_put(&wdata->refcount, release);
1735 cifs_small_buf_release(smb);
1740 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
1741 unsigned int *nbytes, struct kvec *iov, int n_vec)
1744 WRITE_REQ *pSMB = NULL;
1747 int resp_buf_type = 0;
1748 __u32 pid = io_parms->pid;
1749 __u16 netfid = io_parms->netfid;
1750 __u64 offset = io_parms->offset;
1751 struct cifs_tcon *tcon = io_parms->tcon;
1752 unsigned int count = io_parms->length;
1753 struct kvec rsp_iov;
1757 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
1759 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1763 if ((offset >> 32) > 0) {
1764 /* can not handle big offset for old srv */
1768 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
1772 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1773 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1775 /* tcon and ses pointer are checked in smb_init */
1776 if (tcon->ses->server == NULL)
1777 return -ECONNABORTED;
1779 pSMB->AndXCommand = 0xFF; /* none */
1781 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1783 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1784 pSMB->Reserved = 0xFFFFFFFF;
1785 pSMB->WriteMode = 0;
1786 pSMB->Remaining = 0;
1789 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1791 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1792 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1793 /* header + 1 byte pad */
1794 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
1796 inc_rfc1001_len(pSMB, count + 1);
1797 else /* wct == 12 */
1798 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
1800 pSMB->ByteCount = cpu_to_le16(count + 1);
1801 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1802 struct smb_com_writex_req *pSMBW =
1803 (struct smb_com_writex_req *)pSMB;
1804 pSMBW->ByteCount = cpu_to_le16(count + 5);
1806 iov[0].iov_base = pSMB;
1808 iov[0].iov_len = smb_hdr_len + 4;
1809 else /* wct == 12 pad bigger by four bytes */
1810 iov[0].iov_len = smb_hdr_len + 8;
1812 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
1814 cifs_small_buf_release(pSMB);
1815 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1817 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
1818 } else if (resp_buf_type == 0) {
1819 /* presumably this can not happen, but best to be safe */
1822 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
1823 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1824 *nbytes = (*nbytes) << 16;
1825 *nbytes += le16_to_cpu(pSMBr->Count);
1828 * Mask off high 16 bits when bytes written as returned by the
1829 * server is greater than bytes requested by the client. OS/2
1830 * servers are known to set incorrect CountHigh values.
1832 if (*nbytes > count)
1836 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1838 /* Note: On -EAGAIN error only caller can retry on handle based calls
1839 since file handle passed in no longer valid */
1844 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
1845 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
1846 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
1849 LOCK_REQ *pSMB = NULL;
1851 struct kvec rsp_iov;
1855 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
1856 num_lock, num_unlock);
1858 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1863 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
1864 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
1865 pSMB->LockType = lock_type;
1866 pSMB->AndXCommand = 0xFF; /* none */
1867 pSMB->Fid = netfid; /* netfid stays le */
1869 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1870 inc_rfc1001_len(pSMB, count);
1871 pSMB->ByteCount = cpu_to_le16(count);
1873 iov[0].iov_base = (char *)pSMB;
1874 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
1875 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1876 iov[1].iov_base = (char *)buf;
1877 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1879 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1880 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
1881 CIFS_NO_RSP_BUF, &rsp_iov);
1882 cifs_small_buf_release(pSMB);
1884 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
1890 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
1891 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
1892 const __u64 offset, const __u32 numUnlock,
1893 const __u32 numLock, const __u8 lockType,
1894 const bool waitFlag, const __u8 oplock_level)
1897 LOCK_REQ *pSMB = NULL;
1898 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
1903 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
1904 (int)waitFlag, numLock);
1905 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1910 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1911 /* no response expected */
1912 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
1914 } else if (waitFlag) {
1915 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1916 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
1921 pSMB->NumberOfLocks = cpu_to_le16(numLock);
1922 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
1923 pSMB->LockType = lockType;
1924 pSMB->OplockLevel = oplock_level;
1925 pSMB->AndXCommand = 0xFF; /* none */
1926 pSMB->Fid = smb_file_id; /* netfid stays le */
1928 if ((numLock != 0) || (numUnlock != 0)) {
1929 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
1930 /* BB where to store pid high? */
1931 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
1932 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
1933 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
1934 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
1935 count = sizeof(LOCKING_ANDX_RANGE);
1940 inc_rfc1001_len(pSMB, count);
1941 pSMB->ByteCount = cpu_to_le16(count);
1944 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1945 (struct smb_hdr *) pSMB, &bytes_returned);
1947 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
1948 cifs_small_buf_release(pSMB);
1949 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1951 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
1953 /* Note: On -EAGAIN error only caller can retry on handle based calls
1954 since file handle passed in no longer valid */
1959 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
1960 const __u16 smb_file_id, const __u32 netpid,
1961 const loff_t start_offset, const __u64 len,
1962 struct file_lock *pLockData, const __u16 lock_type,
1963 const bool waitFlag)
1965 struct smb_com_transaction2_sfi_req *pSMB = NULL;
1966 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
1967 struct cifs_posix_lock *parm_data;
1970 int bytes_returned = 0;
1971 int resp_buf_type = 0;
1972 __u16 params, param_offset, offset, byte_count, count;
1974 struct kvec rsp_iov;
1976 cifs_dbg(FYI, "Posix Lock\n");
1978 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
1983 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
1986 pSMB->MaxSetupCount = 0;
1989 pSMB->Reserved2 = 0;
1990 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
1991 offset = param_offset + params;
1993 count = sizeof(struct cifs_posix_lock);
1994 pSMB->MaxParameterCount = cpu_to_le16(2);
1995 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
1996 pSMB->SetupCount = 1;
1997 pSMB->Reserved3 = 0;
1999 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2001 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2002 byte_count = 3 /* pad */ + params + count;
2003 pSMB->DataCount = cpu_to_le16(count);
2004 pSMB->ParameterCount = cpu_to_le16(params);
2005 pSMB->TotalDataCount = pSMB->DataCount;
2006 pSMB->TotalParameterCount = pSMB->ParameterCount;
2007 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2008 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2009 parm_data = (struct cifs_posix_lock *)
2010 (((char *)pSMB) + offset + 4);
2012 parm_data->lock_type = cpu_to_le16(lock_type);
2014 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2015 parm_data->lock_flags = cpu_to_le16(1);
2016 pSMB->Timeout = cpu_to_le32(-1);
2020 parm_data->pid = cpu_to_le32(netpid);
2021 parm_data->start = cpu_to_le64(start_offset);
2022 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2024 pSMB->DataOffset = cpu_to_le16(offset);
2025 pSMB->Fid = smb_file_id;
2026 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2027 pSMB->Reserved4 = 0;
2028 inc_rfc1001_len(pSMB, byte_count);
2029 pSMB->ByteCount = cpu_to_le16(byte_count);
2031 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2032 (struct smb_hdr *) pSMBr, &bytes_returned);
2034 iov[0].iov_base = (char *)pSMB;
2035 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2036 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2037 &resp_buf_type, timeout, &rsp_iov);
2038 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2040 cifs_small_buf_release(pSMB);
2043 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2044 } else if (pLockData) {
2045 /* lock structure can be returned on get */
2048 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2050 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2051 rc = -EIO; /* bad smb */
2054 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2055 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2056 if (data_count < sizeof(struct cifs_posix_lock)) {
2060 parm_data = (struct cifs_posix_lock *)
2061 ((char *)&pSMBr->hdr.Protocol + data_offset);
2062 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2063 pLockData->fl_type = F_UNLCK;
2065 if (parm_data->lock_type ==
2066 cpu_to_le16(CIFS_RDLCK))
2067 pLockData->fl_type = F_RDLCK;
2068 else if (parm_data->lock_type ==
2069 cpu_to_le16(CIFS_WRLCK))
2070 pLockData->fl_type = F_WRLCK;
2072 pLockData->fl_start = le64_to_cpu(parm_data->start);
2073 pLockData->fl_end = pLockData->fl_start +
2074 (le64_to_cpu(parm_data->length) ?
2075 le64_to_cpu(parm_data->length) - 1 : 0);
2076 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2081 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2083 /* Note: On -EAGAIN error only caller can retry on handle based calls
2084 since file handle passed in no longer valid */
2091 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2094 CLOSE_REQ *pSMB = NULL;
2095 cifs_dbg(FYI, "In CIFSSMBClose\n");
2097 /* do not retry on dead session on close */
2098 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2104 pSMB->FileID = (__u16) smb_file_id;
2105 pSMB->LastWriteTime = 0xFFFFFFFF;
2106 pSMB->ByteCount = 0;
2107 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2108 cifs_small_buf_release(pSMB);
2109 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2112 /* EINTR is expected when user ctl-c to kill app */
2113 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2117 /* Since session is dead, file will be closed on server already */
2125 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2128 FLUSH_REQ *pSMB = NULL;
2129 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2131 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2135 pSMB->FileID = (__u16) smb_file_id;
2136 pSMB->ByteCount = 0;
2137 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2138 cifs_small_buf_release(pSMB);
2139 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2141 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2147 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2148 const char *from_name, const char *to_name,
2149 struct cifs_sb_info *cifs_sb)
2152 RENAME_REQ *pSMB = NULL;
2153 RENAME_RSP *pSMBr = NULL;
2155 int name_len, name_len2;
2157 int remap = cifs_remap(cifs_sb);
2159 cifs_dbg(FYI, "In CIFSSMBRename\n");
2161 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2166 pSMB->BufferFormat = 0x04;
2167 pSMB->SearchAttributes =
2168 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2171 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2172 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2173 from_name, PATH_MAX,
2174 cifs_sb->local_nls, remap);
2175 name_len++; /* trailing null */
2177 pSMB->OldFileName[name_len] = 0x04; /* pad */
2178 /* protocol requires ASCII signature byte on Unicode string */
2179 pSMB->OldFileName[name_len + 1] = 0x00;
2181 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2182 to_name, PATH_MAX, cifs_sb->local_nls,
2184 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2185 name_len2 *= 2; /* convert to bytes */
2187 name_len = copy_path_name(pSMB->OldFileName, from_name);
2188 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2189 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2190 name_len2++; /* signature byte */
2193 count = 1 /* 1st signature byte */ + name_len + name_len2;
2194 inc_rfc1001_len(pSMB, count);
2195 pSMB->ByteCount = cpu_to_le16(count);
2197 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2198 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2199 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2201 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2203 cifs_buf_release(pSMB);
2211 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2212 int netfid, const char *target_name,
2213 const struct nls_table *nls_codepage, int remap)
2215 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2216 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2217 struct set_file_rename *rename_info;
2219 char dummy_string[30];
2221 int bytes_returned = 0;
2223 __u16 params, param_offset, offset, count, byte_count;
2225 cifs_dbg(FYI, "Rename to File by handle\n");
2226 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2232 pSMB->MaxSetupCount = 0;
2236 pSMB->Reserved2 = 0;
2237 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2238 offset = param_offset + params;
2240 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2241 data_offset = (char *)(pSMB) + offset + 4;
2242 rename_info = (struct set_file_rename *) data_offset;
2243 pSMB->MaxParameterCount = cpu_to_le16(2);
2244 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2245 pSMB->SetupCount = 1;
2246 pSMB->Reserved3 = 0;
2247 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2248 byte_count = 3 /* pad */ + params;
2249 pSMB->ParameterCount = cpu_to_le16(params);
2250 pSMB->TotalParameterCount = pSMB->ParameterCount;
2251 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2252 pSMB->DataOffset = cpu_to_le16(offset);
2253 /* construct random name ".cifs_tmp<inodenum><mid>" */
2254 rename_info->overwrite = cpu_to_le32(1);
2255 rename_info->root_fid = 0;
2256 /* unicode only call */
2257 if (target_name == NULL) {
2258 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2260 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2261 dummy_string, 24, nls_codepage, remap);
2264 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2265 target_name, PATH_MAX, nls_codepage,
2268 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2269 count = sizeof(struct set_file_rename) + (2 * len_of_str);
2270 byte_count += count;
2271 pSMB->DataCount = cpu_to_le16(count);
2272 pSMB->TotalDataCount = pSMB->DataCount;
2274 pSMB->InformationLevel =
2275 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2276 pSMB->Reserved4 = 0;
2277 inc_rfc1001_len(pSMB, byte_count);
2278 pSMB->ByteCount = cpu_to_le16(byte_count);
2279 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2280 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2281 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2283 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2286 cifs_buf_release(pSMB);
2288 /* Note: On -EAGAIN error only caller can retry on handle based calls
2289 since file handle passed in no longer valid */
2295 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2296 const char *fromName, const __u16 target_tid, const char *toName,
2297 const int flags, const struct nls_table *nls_codepage, int remap)
2300 COPY_REQ *pSMB = NULL;
2301 COPY_RSP *pSMBr = NULL;
2303 int name_len, name_len2;
2306 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2308 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2313 pSMB->BufferFormat = 0x04;
2314 pSMB->Tid2 = target_tid;
2316 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2318 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2319 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2320 fromName, PATH_MAX, nls_codepage,
2322 name_len++; /* trailing null */
2324 pSMB->OldFileName[name_len] = 0x04; /* pad */
2325 /* protocol requires ASCII signature byte on Unicode string */
2326 pSMB->OldFileName[name_len + 1] = 0x00;
2328 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2329 toName, PATH_MAX, nls_codepage, remap);
2330 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2331 name_len2 *= 2; /* convert to bytes */
2333 name_len = copy_path_name(pSMB->OldFileName, fromName);
2334 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2335 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2336 name_len2++; /* signature byte */
2339 count = 1 /* 1st signature byte */ + name_len + name_len2;
2340 inc_rfc1001_len(pSMB, count);
2341 pSMB->ByteCount = cpu_to_le16(count);
2343 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2344 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2346 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2347 rc, le16_to_cpu(pSMBr->CopyCount));
2349 cifs_buf_release(pSMB);
2358 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2359 const char *fromName, const char *toName,
2360 const struct nls_table *nls_codepage, int remap)
2362 TRANSACTION2_SPI_REQ *pSMB = NULL;
2363 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2366 int name_len_target;
2368 int bytes_returned = 0;
2369 __u16 params, param_offset, offset, byte_count;
2371 cifs_dbg(FYI, "In Symlink Unix style\n");
2373 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2378 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2380 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2381 /* find define for this maxpathcomponent */
2382 PATH_MAX, nls_codepage, remap);
2383 name_len++; /* trailing null */
2387 name_len = copy_path_name(pSMB->FileName, fromName);
2389 params = 6 + name_len;
2390 pSMB->MaxSetupCount = 0;
2394 pSMB->Reserved2 = 0;
2395 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2396 InformationLevel) - 4;
2397 offset = param_offset + params;
2399 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2400 data_offset = (char *)pSMB + offset + 4;
2401 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2403 cifsConvertToUTF16((__le16 *) data_offset, toName,
2404 /* find define for this maxpathcomponent */
2405 PATH_MAX, nls_codepage, remap);
2406 name_len_target++; /* trailing null */
2407 name_len_target *= 2;
2409 name_len_target = copy_path_name(data_offset, toName);
2412 pSMB->MaxParameterCount = cpu_to_le16(2);
2413 /* BB find exact max on data count below from sess */
2414 pSMB->MaxDataCount = cpu_to_le16(1000);
2415 pSMB->SetupCount = 1;
2416 pSMB->Reserved3 = 0;
2417 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2418 byte_count = 3 /* pad */ + params + name_len_target;
2419 pSMB->DataCount = cpu_to_le16(name_len_target);
2420 pSMB->ParameterCount = cpu_to_le16(params);
2421 pSMB->TotalDataCount = pSMB->DataCount;
2422 pSMB->TotalParameterCount = pSMB->ParameterCount;
2423 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2424 pSMB->DataOffset = cpu_to_le16(offset);
2425 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2426 pSMB->Reserved4 = 0;
2427 inc_rfc1001_len(pSMB, byte_count);
2428 pSMB->ByteCount = cpu_to_le16(byte_count);
2429 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2430 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2431 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2433 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2436 cifs_buf_release(pSMB);
2439 goto createSymLinkRetry;
2445 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2446 const char *fromName, const char *toName,
2447 const struct nls_table *nls_codepage, int remap)
2449 TRANSACTION2_SPI_REQ *pSMB = NULL;
2450 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2453 int name_len_target;
2455 int bytes_returned = 0;
2456 __u16 params, param_offset, offset, byte_count;
2458 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2459 createHardLinkRetry:
2460 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2465 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2466 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2467 PATH_MAX, nls_codepage, remap);
2468 name_len++; /* trailing null */
2472 name_len = copy_path_name(pSMB->FileName, toName);
2474 params = 6 + name_len;
2475 pSMB->MaxSetupCount = 0;
2479 pSMB->Reserved2 = 0;
2480 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2481 InformationLevel) - 4;
2482 offset = param_offset + params;
2484 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2485 data_offset = (char *)pSMB + offset + 4;
2486 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2488 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2489 PATH_MAX, nls_codepage, remap);
2490 name_len_target++; /* trailing null */
2491 name_len_target *= 2;
2493 name_len_target = copy_path_name(data_offset, fromName);
2496 pSMB->MaxParameterCount = cpu_to_le16(2);
2497 /* BB find exact max on data count below from sess*/
2498 pSMB->MaxDataCount = cpu_to_le16(1000);
2499 pSMB->SetupCount = 1;
2500 pSMB->Reserved3 = 0;
2501 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2502 byte_count = 3 /* pad */ + params + name_len_target;
2503 pSMB->ParameterCount = cpu_to_le16(params);
2504 pSMB->TotalParameterCount = pSMB->ParameterCount;
2505 pSMB->DataCount = cpu_to_le16(name_len_target);
2506 pSMB->TotalDataCount = pSMB->DataCount;
2507 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2508 pSMB->DataOffset = cpu_to_le16(offset);
2509 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2510 pSMB->Reserved4 = 0;
2511 inc_rfc1001_len(pSMB, byte_count);
2512 pSMB->ByteCount = cpu_to_le16(byte_count);
2513 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2514 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2515 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2517 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2520 cifs_buf_release(pSMB);
2522 goto createHardLinkRetry;
2528 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2529 const char *from_name, const char *to_name,
2530 struct cifs_sb_info *cifs_sb)
2533 NT_RENAME_REQ *pSMB = NULL;
2534 RENAME_RSP *pSMBr = NULL;
2536 int name_len, name_len2;
2538 int remap = cifs_remap(cifs_sb);
2540 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2541 winCreateHardLinkRetry:
2543 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2548 pSMB->SearchAttributes =
2549 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2551 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2552 pSMB->ClusterCount = 0;
2554 pSMB->BufferFormat = 0x04;
2556 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2558 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2559 PATH_MAX, cifs_sb->local_nls, remap);
2560 name_len++; /* trailing null */
2563 /* protocol specifies ASCII buffer format (0x04) for unicode */
2564 pSMB->OldFileName[name_len] = 0x04;
2565 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2567 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2568 to_name, PATH_MAX, cifs_sb->local_nls,
2570 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2571 name_len2 *= 2; /* convert to bytes */
2573 name_len = copy_path_name(pSMB->OldFileName, from_name);
2574 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2575 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2576 name_len2++; /* signature byte */
2579 count = 1 /* string type byte */ + name_len + name_len2;
2580 inc_rfc1001_len(pSMB, count);
2581 pSMB->ByteCount = cpu_to_le16(count);
2583 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2584 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2585 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2587 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2589 cifs_buf_release(pSMB);
2591 goto winCreateHardLinkRetry;
2597 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2598 const unsigned char *searchName, char **symlinkinfo,
2599 const struct nls_table *nls_codepage, int remap)
2601 /* SMB_QUERY_FILE_UNIX_LINK */
2602 TRANSACTION2_QPI_REQ *pSMB = NULL;
2603 TRANSACTION2_QPI_RSP *pSMBr = NULL;
2607 __u16 params, byte_count;
2610 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
2613 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2618 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2620 cifsConvertToUTF16((__le16 *) pSMB->FileName,
2621 searchName, PATH_MAX, nls_codepage,
2623 name_len++; /* trailing null */
2626 name_len = copy_path_name(pSMB->FileName, searchName);
2629 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
2630 pSMB->TotalDataCount = 0;
2631 pSMB->MaxParameterCount = cpu_to_le16(2);
2632 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2633 pSMB->MaxSetupCount = 0;
2637 pSMB->Reserved2 = 0;
2638 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2639 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
2640 pSMB->DataCount = 0;
2641 pSMB->DataOffset = 0;
2642 pSMB->SetupCount = 1;
2643 pSMB->Reserved3 = 0;
2644 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2645 byte_count = params + 1 /* pad */ ;
2646 pSMB->TotalParameterCount = cpu_to_le16(params);
2647 pSMB->ParameterCount = pSMB->TotalParameterCount;
2648 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2649 pSMB->Reserved4 = 0;
2650 inc_rfc1001_len(pSMB, byte_count);
2651 pSMB->ByteCount = cpu_to_le16(byte_count);
2653 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2654 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2656 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
2658 /* decode response */
2660 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2661 /* BB also check enough total bytes returned */
2662 if (rc || get_bcc(&pSMBr->hdr) < 2)
2666 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2668 data_start = ((char *) &pSMBr->hdr.Protocol) +
2669 le16_to_cpu(pSMBr->t2.DataOffset);
2671 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2676 /* BB FIXME investigate remapping reserved chars here */
2677 *symlinkinfo = cifs_strndup_from_utf16(data_start,
2678 count, is_unicode, nls_codepage);
2683 cifs_buf_release(pSMB);
2685 goto querySymLinkRetry;
2690 * Recent Windows versions now create symlinks more frequently
2691 * and they use the "reparse point" mechanism below. We can of course
2692 * do symlinks nicely to Samba and other servers which support the
2693 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
2694 * "MF" symlinks optionally, but for recent Windows we really need to
2695 * reenable the code below and fix the cifs_symlink callers to handle this.
2696 * In the interim this code has been moved to its own config option so
2697 * it is not compiled in by default until callers fixed up and more tested.
2700 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2701 __u16 fid, char **symlinkinfo,
2702 const struct nls_table *nls_codepage)
2706 struct smb_com_transaction_ioctl_req *pSMB;
2707 struct smb_com_transaction_ioctl_rsp *pSMBr;
2709 unsigned int sub_len;
2711 struct reparse_symlink_data *reparse_buf;
2712 struct reparse_posix_data *posix_buf;
2713 __u32 data_offset, data_count;
2716 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
2717 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2722 pSMB->TotalParameterCount = 0 ;
2723 pSMB->TotalDataCount = 0;
2724 pSMB->MaxParameterCount = cpu_to_le32(2);
2725 /* BB find exact data count max from sess structure BB */
2726 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
2727 pSMB->MaxSetupCount = 4;
2729 pSMB->ParameterOffset = 0;
2730 pSMB->DataCount = 0;
2731 pSMB->DataOffset = 0;
2732 pSMB->SetupCount = 4;
2733 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2734 pSMB->ParameterCount = pSMB->TotalParameterCount;
2735 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
2736 pSMB->IsFsctl = 1; /* FSCTL */
2737 pSMB->IsRootFlag = 0;
2738 pSMB->Fid = fid; /* file handle always le */
2739 pSMB->ByteCount = 0;
2741 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2742 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2744 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
2748 data_offset = le32_to_cpu(pSMBr->DataOffset);
2749 data_count = le32_to_cpu(pSMBr->DataCount);
2750 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
2751 /* BB also check enough total bytes returned */
2752 rc = -EIO; /* bad smb */
2755 if (!data_count || (data_count > 2048)) {
2757 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
2760 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
2761 reparse_buf = (struct reparse_symlink_data *)
2762 ((char *)&pSMBr->hdr.Protocol + data_offset);
2763 if ((char *)reparse_buf >= end_of_smb) {
2767 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
2768 cifs_dbg(FYI, "NFS style reparse tag\n");
2769 posix_buf = (struct reparse_posix_data *)reparse_buf;
2771 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
2772 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
2773 le64_to_cpu(posix_buf->InodeType));
2778 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
2779 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
2780 cifs_dbg(FYI, "reparse buf beyond SMB\n");
2784 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
2785 sub_len, is_unicode, nls_codepage);
2787 } else if (reparse_buf->ReparseTag !=
2788 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
2793 /* Reparse tag is NTFS symlink */
2794 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
2795 reparse_buf->PathBuffer;
2796 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
2797 if (sub_start + sub_len > end_of_smb) {
2798 cifs_dbg(FYI, "reparse buf beyond SMB\n");
2802 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2807 /* BB FIXME investigate remapping reserved chars here */
2808 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
2813 cifs_buf_release(pSMB);
2816 * Note: On -EAGAIN error only caller can retry on handle based calls
2817 * since file handle passed in no longer valid.
2823 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
2828 struct smb_com_transaction_compr_ioctl_req *pSMB;
2829 struct smb_com_transaction_ioctl_rsp *pSMBr;
2831 cifs_dbg(FYI, "Set compression for %u\n", fid);
2832 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2837 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
2839 pSMB->TotalParameterCount = 0;
2840 pSMB->TotalDataCount = cpu_to_le32(2);
2841 pSMB->MaxParameterCount = 0;
2842 pSMB->MaxDataCount = 0;
2843 pSMB->MaxSetupCount = 4;
2845 pSMB->ParameterOffset = 0;
2846 pSMB->DataCount = cpu_to_le32(2);
2848 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
2849 compression_state) - 4); /* 84 */
2850 pSMB->SetupCount = 4;
2851 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2852 pSMB->ParameterCount = 0;
2853 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
2854 pSMB->IsFsctl = 1; /* FSCTL */
2855 pSMB->IsRootFlag = 0;
2856 pSMB->Fid = fid; /* file handle always le */
2857 /* 3 byte pad, followed by 2 byte compress state */
2858 pSMB->ByteCount = cpu_to_le16(5);
2859 inc_rfc1001_len(pSMB, 5);
2861 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2862 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2864 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
2866 cifs_buf_release(pSMB);
2869 * Note: On -EAGAIN error only caller can retry on handle based calls
2870 * since file handle passed in no longer valid.
2876 #ifdef CONFIG_CIFS_POSIX
2878 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
2879 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
2880 struct cifs_posix_ace *cifs_ace)
2882 /* u8 cifs fields do not need le conversion */
2883 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
2884 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
2885 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
2887 cifs_dbg(FYI, "perm %d tag %d id %d\n",
2888 ace->e_perm, ace->e_tag, ace->e_id);
2894 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
2895 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
2896 const int acl_type, const int size_of_data_area)
2901 struct cifs_posix_ace *pACE;
2902 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
2903 struct posix_acl_xattr_header *local_acl = (void *)trgt;
2905 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
2908 if (acl_type == ACL_TYPE_ACCESS) {
2909 count = le16_to_cpu(cifs_acl->access_entry_count);
2910 pACE = &cifs_acl->ace_array[0];
2911 size = sizeof(struct cifs_posix_acl);
2912 size += sizeof(struct cifs_posix_ace) * count;
2913 /* check if we would go beyond end of SMB */
2914 if (size_of_data_area < size) {
2915 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
2916 size_of_data_area, size);
2919 } else if (acl_type == ACL_TYPE_DEFAULT) {
2920 count = le16_to_cpu(cifs_acl->access_entry_count);
2921 size = sizeof(struct cifs_posix_acl);
2922 size += sizeof(struct cifs_posix_ace) * count;
2923 /* skip past access ACEs to get to default ACEs */
2924 pACE = &cifs_acl->ace_array[count];
2925 count = le16_to_cpu(cifs_acl->default_entry_count);
2926 size += sizeof(struct cifs_posix_ace) * count;
2927 /* check if we would go beyond end of SMB */
2928 if (size_of_data_area < size)
2935 size = posix_acl_xattr_size(count);
2936 if ((buflen == 0) || (local_acl == NULL)) {
2937 /* used to query ACL EA size */
2938 } else if (size > buflen) {
2940 } else /* buffer big enough */ {
2941 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
2943 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
2944 for (i = 0; i < count ; i++) {
2945 cifs_convert_ace(&ace[i], pACE);
2952 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
2953 const struct posix_acl_xattr_entry *local_ace)
2955 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
2956 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
2957 /* BB is there a better way to handle the large uid? */
2958 if (local_ace->e_id == cpu_to_le32(-1)) {
2959 /* Probably no need to le convert -1 on any arch but can not hurt */
2960 cifs_ace->cifs_uid = cpu_to_le64(-1);
2962 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
2964 cifs_dbg(FYI, "perm %d tag %d id %d\n",
2965 ace->e_perm, ace->e_tag, ace->e_id);
2969 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
2970 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
2971 const int buflen, const int acl_type)
2974 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
2975 struct posix_acl_xattr_header *local_acl = (void *)pACL;
2976 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
2980 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
2983 count = posix_acl_xattr_count((size_t)buflen);
2984 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
2985 count, buflen, le32_to_cpu(local_acl->a_version));
2986 if (le32_to_cpu(local_acl->a_version) != 2) {
2987 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
2988 le32_to_cpu(local_acl->a_version));
2991 cifs_acl->version = cpu_to_le16(1);
2992 if (acl_type == ACL_TYPE_ACCESS) {
2993 cifs_acl->access_entry_count = cpu_to_le16(count);
2994 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
2995 } else if (acl_type == ACL_TYPE_DEFAULT) {
2996 cifs_acl->default_entry_count = cpu_to_le16(count);
2997 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
2999 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3002 for (i = 0; i < count; i++)
3003 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3005 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3006 rc += sizeof(struct cifs_posix_acl);
3007 /* BB add check to make sure ACL does not overflow SMB */
3013 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3014 const unsigned char *searchName,
3015 char *acl_inf, const int buflen, const int acl_type,
3016 const struct nls_table *nls_codepage, int remap)
3018 /* SMB_QUERY_POSIX_ACL */
3019 TRANSACTION2_QPI_REQ *pSMB = NULL;
3020 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3024 __u16 params, byte_count;
3026 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3029 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3034 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3036 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3037 searchName, PATH_MAX, nls_codepage,
3039 name_len++; /* trailing null */
3041 pSMB->FileName[name_len] = 0;
3042 pSMB->FileName[name_len+1] = 0;
3044 name_len = copy_path_name(pSMB->FileName, searchName);
3047 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3048 pSMB->TotalDataCount = 0;
3049 pSMB->MaxParameterCount = cpu_to_le16(2);
3050 /* BB find exact max data count below from sess structure BB */
3051 pSMB->MaxDataCount = cpu_to_le16(4000);
3052 pSMB->MaxSetupCount = 0;
3056 pSMB->Reserved2 = 0;
3057 pSMB->ParameterOffset = cpu_to_le16(
3058 offsetof(struct smb_com_transaction2_qpi_req,
3059 InformationLevel) - 4);
3060 pSMB->DataCount = 0;
3061 pSMB->DataOffset = 0;
3062 pSMB->SetupCount = 1;
3063 pSMB->Reserved3 = 0;
3064 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3065 byte_count = params + 1 /* pad */ ;
3066 pSMB->TotalParameterCount = cpu_to_le16(params);
3067 pSMB->ParameterCount = pSMB->TotalParameterCount;
3068 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3069 pSMB->Reserved4 = 0;
3070 inc_rfc1001_len(pSMB, byte_count);
3071 pSMB->ByteCount = cpu_to_le16(byte_count);
3073 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3074 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3075 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3077 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3079 /* decode response */
3081 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3082 /* BB also check enough total bytes returned */
3083 if (rc || get_bcc(&pSMBr->hdr) < 2)
3084 rc = -EIO; /* bad smb */
3086 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3087 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3088 rc = cifs_copy_posix_acl(acl_inf,
3089 (char *)&pSMBr->hdr.Protocol+data_offset,
3090 buflen, acl_type, count);
3093 cifs_buf_release(pSMB);
3100 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3101 const unsigned char *fileName,
3102 const char *local_acl, const int buflen,
3104 const struct nls_table *nls_codepage, int remap)
3106 struct smb_com_transaction2_spi_req *pSMB = NULL;
3107 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3111 int bytes_returned = 0;
3112 __u16 params, byte_count, data_count, param_offset, offset;
3114 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3116 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3120 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3122 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3123 PATH_MAX, nls_codepage, remap);
3124 name_len++; /* trailing null */
3127 name_len = copy_path_name(pSMB->FileName, fileName);
3129 params = 6 + name_len;
3130 pSMB->MaxParameterCount = cpu_to_le16(2);
3131 /* BB find max SMB size from sess */
3132 pSMB->MaxDataCount = cpu_to_le16(1000);
3133 pSMB->MaxSetupCount = 0;
3137 pSMB->Reserved2 = 0;
3138 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3139 InformationLevel) - 4;
3140 offset = param_offset + params;
3141 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3142 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3144 /* convert to on the wire format for POSIX ACL */
3145 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3147 if (data_count == 0) {
3149 goto setACLerrorExit;
3151 pSMB->DataOffset = cpu_to_le16(offset);
3152 pSMB->SetupCount = 1;
3153 pSMB->Reserved3 = 0;
3154 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3155 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3156 byte_count = 3 /* pad */ + params + data_count;
3157 pSMB->DataCount = cpu_to_le16(data_count);
3158 pSMB->TotalDataCount = pSMB->DataCount;
3159 pSMB->ParameterCount = cpu_to_le16(params);
3160 pSMB->TotalParameterCount = pSMB->ParameterCount;
3161 pSMB->Reserved4 = 0;
3162 inc_rfc1001_len(pSMB, byte_count);
3163 pSMB->ByteCount = cpu_to_le16(byte_count);
3164 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3165 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3167 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3170 cifs_buf_release(pSMB);
3177 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3178 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3181 struct smb_t2_qfi_req *pSMB = NULL;
3182 struct smb_t2_qfi_rsp *pSMBr = NULL;
3184 __u16 params, byte_count;
3186 cifs_dbg(FYI, "In GetExtAttr\n");
3191 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3196 params = 2 /* level */ + 2 /* fid */;
3197 pSMB->t2.TotalDataCount = 0;
3198 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3199 /* BB find exact max data count below from sess structure BB */
3200 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3201 pSMB->t2.MaxSetupCount = 0;
3202 pSMB->t2.Reserved = 0;
3204 pSMB->t2.Timeout = 0;
3205 pSMB->t2.Reserved2 = 0;
3206 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3208 pSMB->t2.DataCount = 0;
3209 pSMB->t2.DataOffset = 0;
3210 pSMB->t2.SetupCount = 1;
3211 pSMB->t2.Reserved3 = 0;
3212 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3213 byte_count = params + 1 /* pad */ ;
3214 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3215 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3216 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3219 inc_rfc1001_len(pSMB, byte_count);
3220 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3222 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3223 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3225 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3227 /* decode response */
3228 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3229 /* BB also check enough total bytes returned */
3230 if (rc || get_bcc(&pSMBr->hdr) < 2)
3231 /* If rc should we check for EOPNOSUPP and
3232 disable the srvino flag? or in caller? */
3233 rc = -EIO; /* bad smb */
3235 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3236 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3237 struct file_chattr_info *pfinfo;
3240 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3244 pfinfo = (struct file_chattr_info *)
3245 (data_offset + (char *) &pSMBr->hdr.Protocol);
3246 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3247 *pMask = le64_to_cpu(pfinfo->mask);
3251 cifs_buf_release(pSMB);
3253 goto GetExtAttrRetry;
3257 #endif /* CONFIG_POSIX */
3260 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3261 * all NT TRANSACTS that we init here have total parm and data under about 400
3262 * bytes (to fit in small cifs buffer size), which is the case so far, it
3263 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3264 * returned setup area) and MaxParameterCount (returned parms size) must be set
3268 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3269 const int parm_len, struct cifs_tcon *tcon,
3274 struct smb_com_ntransact_req *pSMB;
3276 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3280 *ret_buf = (void *)pSMB;
3282 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3283 pSMB->TotalDataCount = 0;
3284 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3285 pSMB->ParameterCount = pSMB->TotalParameterCount;
3286 pSMB->DataCount = pSMB->TotalDataCount;
3287 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3288 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3289 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3290 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3291 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3292 pSMB->SubCommand = cpu_to_le16(sub_command);
3297 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3298 __u32 *pparmlen, __u32 *pdatalen)
3301 __u32 data_count, data_offset, parm_count, parm_offset;
3302 struct smb_com_ntransact_rsp *pSMBr;
3311 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3313 bcc = get_bcc(&pSMBr->hdr);
3314 end_of_smb = 2 /* sizeof byte count */ + bcc +
3315 (char *)&pSMBr->ByteCount;
3317 data_offset = le32_to_cpu(pSMBr->DataOffset);
3318 data_count = le32_to_cpu(pSMBr->DataCount);
3319 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3320 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3322 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3323 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3325 /* should we also check that parm and data areas do not overlap? */
3326 if (*ppparm > end_of_smb) {
3327 cifs_dbg(FYI, "parms start after end of smb\n");
3329 } else if (parm_count + *ppparm > end_of_smb) {
3330 cifs_dbg(FYI, "parm end after end of smb\n");
3332 } else if (*ppdata > end_of_smb) {
3333 cifs_dbg(FYI, "data starts after end of smb\n");
3335 } else if (data_count + *ppdata > end_of_smb) {
3336 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3337 *ppdata, data_count, (data_count + *ppdata),
3340 } else if (parm_count + data_count > bcc) {
3341 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3344 *pdatalen = data_count;
3345 *pparmlen = parm_count;
3349 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3351 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3352 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3356 QUERY_SEC_DESC_REQ *pSMB;
3358 struct kvec rsp_iov;
3360 cifs_dbg(FYI, "GetCifsACL\n");
3365 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3366 8 /* parm len */, tcon, (void **) &pSMB);
3370 pSMB->MaxParameterCount = cpu_to_le32(4);
3371 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3372 pSMB->MaxSetupCount = 0;
3373 pSMB->Fid = fid; /* file handle always le */
3374 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3376 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3377 inc_rfc1001_len(pSMB, 11);
3378 iov[0].iov_base = (char *)pSMB;
3379 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3381 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3383 cifs_small_buf_release(pSMB);
3384 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3386 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3387 } else { /* decode response */
3391 struct smb_com_ntransact_rsp *pSMBr;
3394 /* validate_nttransact */
3395 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3396 &pdata, &parm_len, pbuflen);
3399 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3401 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3402 pSMBr, parm, *acl_inf);
3404 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3405 rc = -EIO; /* bad smb */
3410 /* BB check that data area is minimum length and as big as acl_len */
3412 acl_len = le32_to_cpu(*parm);
3413 if (acl_len != *pbuflen) {
3414 cifs_dbg(VFS, "acl length %d does not match %d\n",
3416 if (*pbuflen > acl_len)
3420 /* check if buffer is big enough for the acl
3421 header followed by the smallest SID */
3422 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3423 (*pbuflen >= 64 * 1024)) {
3424 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3428 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3429 if (*acl_inf == NULL) {
3436 free_rsp_buf(buf_type, rsp_iov.iov_base);
3441 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3442 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3444 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3446 int bytes_returned = 0;
3447 SET_SEC_DESC_REQ *pSMB = NULL;
3451 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3455 pSMB->MaxSetupCount = 0;
3459 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3460 data_count = acllen;
3461 data_offset = param_offset + param_count;
3462 byte_count = 3 /* pad */ + param_count;
3464 pSMB->DataCount = cpu_to_le32(data_count);
3465 pSMB->TotalDataCount = pSMB->DataCount;
3466 pSMB->MaxParameterCount = cpu_to_le32(4);
3467 pSMB->MaxDataCount = cpu_to_le32(16384);
3468 pSMB->ParameterCount = cpu_to_le32(param_count);
3469 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3470 pSMB->TotalParameterCount = pSMB->ParameterCount;
3471 pSMB->DataOffset = cpu_to_le32(data_offset);
3472 pSMB->SetupCount = 0;
3473 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3474 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3476 pSMB->Fid = fid; /* file handle always le */
3477 pSMB->Reserved2 = 0;
3478 pSMB->AclFlags = cpu_to_le32(aclflag);
3480 if (pntsd && acllen) {
3481 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3482 data_offset, pntsd, acllen);
3483 inc_rfc1001_len(pSMB, byte_count + data_count);
3485 inc_rfc1001_len(pSMB, byte_count);
3487 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3488 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3490 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3491 bytes_returned, rc);
3493 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3494 cifs_buf_release(pSMB);
3497 goto setCifsAclRetry;
3503 /* Legacy Query Path Information call for lookup to old servers such
3506 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3507 const char *search_name, FILE_ALL_INFO *data,
3508 const struct nls_table *nls_codepage, int remap)
3510 QUERY_INFORMATION_REQ *pSMB;
3511 QUERY_INFORMATION_RSP *pSMBr;
3516 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3518 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3523 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3525 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3526 search_name, PATH_MAX, nls_codepage,
3528 name_len++; /* trailing null */
3531 name_len = copy_path_name(pSMB->FileName, search_name);
3533 pSMB->BufferFormat = 0x04;
3534 name_len++; /* account for buffer type byte */
3535 inc_rfc1001_len(pSMB, (__u16)name_len);
3536 pSMB->ByteCount = cpu_to_le16(name_len);
3538 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3539 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3541 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3543 struct timespec64 ts;
3544 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3546 /* decode response */
3547 /* BB FIXME - add time zone adjustment BB */
3548 memset(data, 0, sizeof(FILE_ALL_INFO));
3551 /* decode time fields */
3552 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3553 data->LastWriteTime = data->ChangeTime;
3554 data->LastAccessTime = 0;
3555 data->AllocationSize =
3556 cpu_to_le64(le32_to_cpu(pSMBr->size));
3557 data->EndOfFile = data->AllocationSize;
3559 cpu_to_le32(le16_to_cpu(pSMBr->attr));
3561 rc = -EIO; /* bad buffer passed in */
3563 cifs_buf_release(pSMB);
3572 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3573 u16 netfid, FILE_ALL_INFO *pFindData)
3575 struct smb_t2_qfi_req *pSMB = NULL;
3576 struct smb_t2_qfi_rsp *pSMBr = NULL;
3579 __u16 params, byte_count;
3582 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3587 params = 2 /* level */ + 2 /* fid */;
3588 pSMB->t2.TotalDataCount = 0;
3589 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3590 /* BB find exact max data count below from sess structure BB */
3591 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3592 pSMB->t2.MaxSetupCount = 0;
3593 pSMB->t2.Reserved = 0;
3595 pSMB->t2.Timeout = 0;
3596 pSMB->t2.Reserved2 = 0;
3597 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3599 pSMB->t2.DataCount = 0;
3600 pSMB->t2.DataOffset = 0;
3601 pSMB->t2.SetupCount = 1;
3602 pSMB->t2.Reserved3 = 0;
3603 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3604 byte_count = params + 1 /* pad */ ;
3605 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3606 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3607 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3610 inc_rfc1001_len(pSMB, byte_count);
3611 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3613 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3614 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3616 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
3617 } else { /* decode response */
3618 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3620 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3622 else if (get_bcc(&pSMBr->hdr) < 40)
3623 rc = -EIO; /* bad smb */
3624 else if (pFindData) {
3625 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3626 memcpy((char *) pFindData,
3627 (char *) &pSMBr->hdr.Protocol +
3628 data_offset, sizeof(FILE_ALL_INFO));
3632 cifs_buf_release(pSMB);
3634 goto QFileInfoRetry;
3640 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3641 const char *search_name, FILE_ALL_INFO *data,
3642 int legacy /* old style infolevel */,
3643 const struct nls_table *nls_codepage, int remap)
3645 /* level 263 SMB_QUERY_FILE_ALL_INFO */
3646 TRANSACTION2_QPI_REQ *pSMB = NULL;
3647 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3651 __u16 params, byte_count;
3653 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3655 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3660 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3662 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3663 PATH_MAX, nls_codepage, remap);
3664 name_len++; /* trailing null */
3667 name_len = copy_path_name(pSMB->FileName, search_name);
3670 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3671 pSMB->TotalDataCount = 0;
3672 pSMB->MaxParameterCount = cpu_to_le16(2);
3673 /* BB find exact max SMB PDU from sess structure BB */
3674 pSMB->MaxDataCount = cpu_to_le16(4000);
3675 pSMB->MaxSetupCount = 0;
3679 pSMB->Reserved2 = 0;
3680 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3681 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3682 pSMB->DataCount = 0;
3683 pSMB->DataOffset = 0;
3684 pSMB->SetupCount = 1;
3685 pSMB->Reserved3 = 0;
3686 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3687 byte_count = params + 1 /* pad */ ;
3688 pSMB->TotalParameterCount = cpu_to_le16(params);
3689 pSMB->ParameterCount = pSMB->TotalParameterCount;
3691 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3693 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3694 pSMB->Reserved4 = 0;
3695 inc_rfc1001_len(pSMB, byte_count);
3696 pSMB->ByteCount = cpu_to_le16(byte_count);
3698 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3699 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3701 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3702 } else { /* decode response */
3703 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3705 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3707 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3708 rc = -EIO; /* bad smb */
3709 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3710 rc = -EIO; /* 24 or 26 expected but we do not read
3714 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3717 * On legacy responses we do not read the last field,
3718 * EAsize, fortunately since it varies by subdialect and
3719 * also note it differs on Set vs Get, ie two bytes or 4
3720 * bytes depending but we don't care here.
3723 size = sizeof(FILE_INFO_STANDARD);
3725 size = sizeof(FILE_ALL_INFO);
3726 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
3731 cifs_buf_release(pSMB);
3733 goto QPathInfoRetry;
3739 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3740 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3742 struct smb_t2_qfi_req *pSMB = NULL;
3743 struct smb_t2_qfi_rsp *pSMBr = NULL;
3746 __u16 params, byte_count;
3749 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3754 params = 2 /* level */ + 2 /* fid */;
3755 pSMB->t2.TotalDataCount = 0;
3756 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3757 /* BB find exact max data count below from sess structure BB */
3758 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3759 pSMB->t2.MaxSetupCount = 0;
3760 pSMB->t2.Reserved = 0;
3762 pSMB->t2.Timeout = 0;
3763 pSMB->t2.Reserved2 = 0;
3764 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3766 pSMB->t2.DataCount = 0;
3767 pSMB->t2.DataOffset = 0;
3768 pSMB->t2.SetupCount = 1;
3769 pSMB->t2.Reserved3 = 0;
3770 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3771 byte_count = params + 1 /* pad */ ;
3772 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3773 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3774 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3777 inc_rfc1001_len(pSMB, byte_count);
3778 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3780 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3781 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3783 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
3784 } else { /* decode response */
3785 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3787 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3788 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3789 rc = -EIO; /* bad smb */
3791 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3792 memcpy((char *) pFindData,
3793 (char *) &pSMBr->hdr.Protocol +
3795 sizeof(FILE_UNIX_BASIC_INFO));
3799 cifs_buf_release(pSMB);
3801 goto UnixQFileInfoRetry;
3807 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3808 const unsigned char *searchName,
3809 FILE_UNIX_BASIC_INFO *pFindData,
3810 const struct nls_table *nls_codepage, int remap)
3812 /* SMB_QUERY_FILE_UNIX_BASIC */
3813 TRANSACTION2_QPI_REQ *pSMB = NULL;
3814 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3816 int bytes_returned = 0;
3818 __u16 params, byte_count;
3820 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
3822 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3827 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3829 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3830 PATH_MAX, nls_codepage, remap);
3831 name_len++; /* trailing null */
3834 name_len = copy_path_name(pSMB->FileName, searchName);
3837 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3838 pSMB->TotalDataCount = 0;
3839 pSMB->MaxParameterCount = cpu_to_le16(2);
3840 /* BB find exact max SMB PDU from sess structure BB */
3841 pSMB->MaxDataCount = cpu_to_le16(4000);
3842 pSMB->MaxSetupCount = 0;
3846 pSMB->Reserved2 = 0;
3847 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3848 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3849 pSMB->DataCount = 0;
3850 pSMB->DataOffset = 0;
3851 pSMB->SetupCount = 1;
3852 pSMB->Reserved3 = 0;
3853 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3854 byte_count = params + 1 /* pad */ ;
3855 pSMB->TotalParameterCount = cpu_to_le16(params);
3856 pSMB->ParameterCount = pSMB->TotalParameterCount;
3857 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3858 pSMB->Reserved4 = 0;
3859 inc_rfc1001_len(pSMB, byte_count);
3860 pSMB->ByteCount = cpu_to_le16(byte_count);
3862 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3863 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3865 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
3866 } else { /* decode response */
3867 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3869 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3870 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3871 rc = -EIO; /* bad smb */
3873 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3874 memcpy((char *) pFindData,
3875 (char *) &pSMBr->hdr.Protocol +
3877 sizeof(FILE_UNIX_BASIC_INFO));
3880 cifs_buf_release(pSMB);
3882 goto UnixQPathInfoRetry;
3887 /* xid, tcon, searchName and codepage are input parms, rest are returned */
3889 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
3890 const char *searchName, struct cifs_sb_info *cifs_sb,
3891 __u16 *pnetfid, __u16 search_flags,
3892 struct cifs_search_info *psrch_inf, bool msearch)
3894 /* level 257 SMB_ */
3895 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
3896 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
3897 T2_FFIRST_RSP_PARMS *parms;
3899 int bytes_returned = 0;
3900 int name_len, remap;
3901 __u16 params, byte_count;
3902 struct nls_table *nls_codepage;
3904 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
3907 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3912 nls_codepage = cifs_sb->local_nls;
3913 remap = cifs_remap(cifs_sb);
3915 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3917 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3918 PATH_MAX, nls_codepage, remap);
3919 /* We can not add the asterik earlier in case
3920 it got remapped to 0xF03A as if it were part of the
3921 directory name instead of a wildcard */
3924 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
3925 pSMB->FileName[name_len+1] = 0;
3926 pSMB->FileName[name_len+2] = '*';
3927 pSMB->FileName[name_len+3] = 0;
3928 name_len += 4; /* now the trailing null */
3929 /* null terminate just in case */
3930 pSMB->FileName[name_len] = 0;
3931 pSMB->FileName[name_len+1] = 0;
3935 name_len = copy_path_name(pSMB->FileName, searchName);
3937 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
3938 name_len = PATH_MAX-2;
3939 /* overwrite nul byte */
3940 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
3941 pSMB->FileName[name_len] = '*';
3942 pSMB->FileName[name_len+1] = 0;
3947 params = 12 + name_len /* includes null */ ;
3948 pSMB->TotalDataCount = 0; /* no EAs */
3949 pSMB->MaxParameterCount = cpu_to_le16(10);
3950 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
3951 pSMB->MaxSetupCount = 0;
3955 pSMB->Reserved2 = 0;
3956 byte_count = params + 1 /* pad */ ;
3957 pSMB->TotalParameterCount = cpu_to_le16(params);
3958 pSMB->ParameterCount = pSMB->TotalParameterCount;
3959 pSMB->ParameterOffset = cpu_to_le16(
3960 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
3962 pSMB->DataCount = 0;
3963 pSMB->DataOffset = 0;
3964 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
3965 pSMB->Reserved3 = 0;
3966 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
3967 pSMB->SearchAttributes =
3968 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3970 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
3971 pSMB->SearchFlags = cpu_to_le16(search_flags);
3972 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
3974 /* BB what should we set StorageType to? Does it matter? BB */
3975 pSMB->SearchStorageType = 0;
3976 inc_rfc1001_len(pSMB, byte_count);
3977 pSMB->ByteCount = cpu_to_le16(byte_count);
3979 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3980 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3981 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
3983 if (rc) {/* BB add logic to retry regular search if Unix search
3984 rejected unexpectedly by server */
3985 /* BB Add code to handle unsupported level rc */
3986 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
3988 cifs_buf_release(pSMB);
3990 /* BB eventually could optimize out free and realloc of buf */
3993 goto findFirstRetry;
3994 } else { /* decode response */
3995 /* BB remember to free buffer if error BB */
3996 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4000 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4001 psrch_inf->unicode = true;
4003 psrch_inf->unicode = false;
4005 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4006 psrch_inf->smallBuf = false;
4007 psrch_inf->srch_entries_start =
4008 (char *) &pSMBr->hdr.Protocol +
4009 le16_to_cpu(pSMBr->t2.DataOffset);
4010 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4011 le16_to_cpu(pSMBr->t2.ParameterOffset));
4013 if (parms->EndofSearch)
4014 psrch_inf->endOfSearch = true;
4016 psrch_inf->endOfSearch = false;
4018 psrch_inf->entries_in_buffer =
4019 le16_to_cpu(parms->SearchCount);
4020 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4021 psrch_inf->entries_in_buffer;
4022 lnoff = le16_to_cpu(parms->LastNameOffset);
4023 if (CIFSMaxBufSize < lnoff) {
4024 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4025 psrch_inf->last_entry = NULL;
4029 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4033 *pnetfid = parms->SearchHandle;
4035 cifs_buf_release(pSMB);
4042 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4043 __u16 searchHandle, __u16 search_flags,
4044 struct cifs_search_info *psrch_inf)
4046 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4047 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4048 T2_FNEXT_RSP_PARMS *parms;
4049 char *response_data;
4052 unsigned int name_len;
4053 __u16 params, byte_count;
4055 cifs_dbg(FYI, "In FindNext\n");
4057 if (psrch_inf->endOfSearch)
4060 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4065 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4067 pSMB->TotalDataCount = 0; /* no EAs */
4068 pSMB->MaxParameterCount = cpu_to_le16(8);
4069 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4070 pSMB->MaxSetupCount = 0;
4074 pSMB->Reserved2 = 0;
4075 pSMB->ParameterOffset = cpu_to_le16(
4076 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4077 pSMB->DataCount = 0;
4078 pSMB->DataOffset = 0;
4079 pSMB->SetupCount = 1;
4080 pSMB->Reserved3 = 0;
4081 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4082 pSMB->SearchHandle = searchHandle; /* always kept as le */
4084 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4085 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4086 pSMB->ResumeKey = psrch_inf->resume_key;
4087 pSMB->SearchFlags = cpu_to_le16(search_flags);
4089 name_len = psrch_inf->resume_name_len;
4091 if (name_len < PATH_MAX) {
4092 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4093 byte_count += name_len;
4094 /* 14 byte parm len above enough for 2 byte null terminator */
4095 pSMB->ResumeFileName[name_len] = 0;
4096 pSMB->ResumeFileName[name_len+1] = 0;
4099 goto FNext2_err_exit;
4101 byte_count = params + 1 /* pad */ ;
4102 pSMB->TotalParameterCount = cpu_to_le16(params);
4103 pSMB->ParameterCount = pSMB->TotalParameterCount;
4104 inc_rfc1001_len(pSMB, byte_count);
4105 pSMB->ByteCount = cpu_to_le16(byte_count);
4107 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4108 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4109 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4112 psrch_inf->endOfSearch = true;
4113 cifs_buf_release(pSMB);
4114 rc = 0; /* search probably was closed at end of search*/
4116 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4117 } else { /* decode response */
4118 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4123 /* BB fixme add lock for file (srch_info) struct here */
4124 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4125 psrch_inf->unicode = true;
4127 psrch_inf->unicode = false;
4128 response_data = (char *) &pSMBr->hdr.Protocol +
4129 le16_to_cpu(pSMBr->t2.ParameterOffset);
4130 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4131 response_data = (char *)&pSMBr->hdr.Protocol +
4132 le16_to_cpu(pSMBr->t2.DataOffset);
4133 if (psrch_inf->smallBuf)
4134 cifs_small_buf_release(
4135 psrch_inf->ntwrk_buf_start);
4137 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4138 psrch_inf->srch_entries_start = response_data;
4139 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4140 psrch_inf->smallBuf = false;
4141 if (parms->EndofSearch)
4142 psrch_inf->endOfSearch = true;
4144 psrch_inf->endOfSearch = false;
4145 psrch_inf->entries_in_buffer =
4146 le16_to_cpu(parms->SearchCount);
4147 psrch_inf->index_of_last_entry +=
4148 psrch_inf->entries_in_buffer;
4149 lnoff = le16_to_cpu(parms->LastNameOffset);
4150 if (CIFSMaxBufSize < lnoff) {
4151 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4152 psrch_inf->last_entry = NULL;
4155 psrch_inf->last_entry =
4156 psrch_inf->srch_entries_start + lnoff;
4158 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4159 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4161 /* BB fixme add unlock here */
4166 /* BB On error, should we leave previous search buf (and count and
4167 last entry fields) intact or free the previous one? */
4169 /* Note: On -EAGAIN error only caller can retry on handle based calls
4170 since file handle passed in no longer valid */
4173 cifs_buf_release(pSMB);
4178 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4179 const __u16 searchHandle)
4182 FINDCLOSE_REQ *pSMB = NULL;
4184 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4185 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4187 /* no sense returning error if session restarted
4188 as file handle has been closed */
4194 pSMB->FileID = searchHandle;
4195 pSMB->ByteCount = 0;
4196 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4197 cifs_small_buf_release(pSMB);
4199 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4201 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4203 /* Since session is dead, search handle closed on server already */
4211 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4212 const char *search_name, __u64 *inode_number,
4213 const struct nls_table *nls_codepage, int remap)
4216 TRANSACTION2_QPI_REQ *pSMB = NULL;
4217 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4218 int name_len, bytes_returned;
4219 __u16 params, byte_count;
4221 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4225 GetInodeNumberRetry:
4226 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4231 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4233 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4234 search_name, PATH_MAX, nls_codepage,
4236 name_len++; /* trailing null */
4239 name_len = copy_path_name(pSMB->FileName, search_name);
4242 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4243 pSMB->TotalDataCount = 0;
4244 pSMB->MaxParameterCount = cpu_to_le16(2);
4245 /* BB find exact max data count below from sess structure BB */
4246 pSMB->MaxDataCount = cpu_to_le16(4000);
4247 pSMB->MaxSetupCount = 0;
4251 pSMB->Reserved2 = 0;
4252 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4253 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4254 pSMB->DataCount = 0;
4255 pSMB->DataOffset = 0;
4256 pSMB->SetupCount = 1;
4257 pSMB->Reserved3 = 0;
4258 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4259 byte_count = params + 1 /* pad */ ;
4260 pSMB->TotalParameterCount = cpu_to_le16(params);
4261 pSMB->ParameterCount = pSMB->TotalParameterCount;
4262 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4263 pSMB->Reserved4 = 0;
4264 inc_rfc1001_len(pSMB, byte_count);
4265 pSMB->ByteCount = cpu_to_le16(byte_count);
4267 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4268 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4270 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4272 /* decode response */
4273 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4274 /* BB also check enough total bytes returned */
4275 if (rc || get_bcc(&pSMBr->hdr) < 2)
4276 /* If rc should we check for EOPNOSUPP and
4277 disable the srvino flag? or in caller? */
4278 rc = -EIO; /* bad smb */
4280 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4281 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4282 struct file_internal_info *pfinfo;
4283 /* BB Do we need a cast or hash here ? */
4285 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4287 goto GetInodeNumOut;
4289 pfinfo = (struct file_internal_info *)
4290 (data_offset + (char *) &pSMBr->hdr.Protocol);
4291 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4295 cifs_buf_release(pSMB);
4297 goto GetInodeNumberRetry;
4302 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4303 const char *search_name, struct dfs_info3_param **target_nodes,
4304 unsigned int *num_of_nodes,
4305 const struct nls_table *nls_codepage, int remap)
4307 /* TRANS2_GET_DFS_REFERRAL */
4308 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4309 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4313 __u16 params, byte_count;
4315 *target_nodes = NULL;
4317 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4318 if (ses == NULL || ses->tcon_ipc == NULL)
4323 * Use smb_init_no_reconnect() instead of smb_init() as
4324 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4325 * causing an infinite recursion.
4327 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4328 (void **)&pSMB, (void **)&pSMBr);
4332 /* server pointer checked in called function,
4333 but should never be null here anyway */
4334 pSMB->hdr.Mid = get_next_mid(ses->server);
4335 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4336 pSMB->hdr.Uid = ses->Suid;
4337 if (ses->capabilities & CAP_STATUS32)
4338 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4339 if (ses->capabilities & CAP_DFS)
4340 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4342 if (ses->capabilities & CAP_UNICODE) {
4343 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4345 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4346 search_name, PATH_MAX, nls_codepage,
4348 name_len++; /* trailing null */
4350 } else { /* BB improve the check for buffer overruns BB */
4351 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4354 if (ses->server->sign)
4355 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4357 pSMB->hdr.Uid = ses->Suid;
4359 params = 2 /* level */ + name_len /*includes null */ ;
4360 pSMB->TotalDataCount = 0;
4361 pSMB->DataCount = 0;
4362 pSMB->DataOffset = 0;
4363 pSMB->MaxParameterCount = 0;
4364 /* BB find exact max SMB PDU from sess structure BB */
4365 pSMB->MaxDataCount = cpu_to_le16(4000);
4366 pSMB->MaxSetupCount = 0;
4370 pSMB->Reserved2 = 0;
4371 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4372 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4373 pSMB->SetupCount = 1;
4374 pSMB->Reserved3 = 0;
4375 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4376 byte_count = params + 3 /* pad */ ;
4377 pSMB->ParameterCount = cpu_to_le16(params);
4378 pSMB->TotalParameterCount = pSMB->ParameterCount;
4379 pSMB->MaxReferralLevel = cpu_to_le16(3);
4380 inc_rfc1001_len(pSMB, byte_count);
4381 pSMB->ByteCount = cpu_to_le16(byte_count);
4383 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4384 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4386 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4389 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4391 /* BB Also check if enough total bytes returned? */
4392 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4393 rc = -EIO; /* bad smb */
4397 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4398 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4400 /* parse returned result into more usable form */
4401 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4402 le16_to_cpu(pSMBr->t2.DataCount),
4403 num_of_nodes, target_nodes, nls_codepage,
4405 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4408 cifs_buf_release(pSMB);
4416 /* Query File System Info such as free space to old servers such as Win 9x */
4418 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4419 struct kstatfs *FSData)
4421 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4422 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4423 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4424 FILE_SYSTEM_ALLOC_INFO *response_data;
4426 int bytes_returned = 0;
4427 __u16 params, byte_count;
4429 cifs_dbg(FYI, "OldQFSInfo\n");
4431 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4436 params = 2; /* level */
4437 pSMB->TotalDataCount = 0;
4438 pSMB->MaxParameterCount = cpu_to_le16(2);
4439 pSMB->MaxDataCount = cpu_to_le16(1000);
4440 pSMB->MaxSetupCount = 0;
4444 pSMB->Reserved2 = 0;
4445 byte_count = params + 1 /* pad */ ;
4446 pSMB->TotalParameterCount = cpu_to_le16(params);
4447 pSMB->ParameterCount = pSMB->TotalParameterCount;
4448 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4449 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4450 pSMB->DataCount = 0;
4451 pSMB->DataOffset = 0;
4452 pSMB->SetupCount = 1;
4453 pSMB->Reserved3 = 0;
4454 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4455 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4456 inc_rfc1001_len(pSMB, byte_count);
4457 pSMB->ByteCount = cpu_to_le16(byte_count);
4459 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4460 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4462 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4463 } else { /* decode response */
4464 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4466 if (rc || get_bcc(&pSMBr->hdr) < 18)
4467 rc = -EIO; /* bad smb */
4469 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4470 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4471 get_bcc(&pSMBr->hdr), data_offset);
4473 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4474 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4476 le16_to_cpu(response_data->BytesPerSector) *
4477 le32_to_cpu(response_data->
4478 SectorsPerAllocationUnit);
4480 * much prefer larger but if server doesn't report
4481 * a valid size than 4K is a reasonable minimum
4483 if (FSData->f_bsize < 512)
4484 FSData->f_bsize = 4096;
4487 le32_to_cpu(response_data->TotalAllocationUnits);
4488 FSData->f_bfree = FSData->f_bavail =
4489 le32_to_cpu(response_data->FreeAllocationUnits);
4490 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4491 (unsigned long long)FSData->f_blocks,
4492 (unsigned long long)FSData->f_bfree,
4496 cifs_buf_release(pSMB);
4499 goto oldQFSInfoRetry;
4505 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4506 struct kstatfs *FSData)
4508 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4509 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4510 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4511 FILE_SYSTEM_INFO *response_data;
4513 int bytes_returned = 0;
4514 __u16 params, byte_count;
4516 cifs_dbg(FYI, "In QFSInfo\n");
4518 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4523 params = 2; /* level */
4524 pSMB->TotalDataCount = 0;
4525 pSMB->MaxParameterCount = cpu_to_le16(2);
4526 pSMB->MaxDataCount = cpu_to_le16(1000);
4527 pSMB->MaxSetupCount = 0;
4531 pSMB->Reserved2 = 0;
4532 byte_count = params + 1 /* pad */ ;
4533 pSMB->TotalParameterCount = cpu_to_le16(params);
4534 pSMB->ParameterCount = pSMB->TotalParameterCount;
4535 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4536 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4537 pSMB->DataCount = 0;
4538 pSMB->DataOffset = 0;
4539 pSMB->SetupCount = 1;
4540 pSMB->Reserved3 = 0;
4541 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4542 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4543 inc_rfc1001_len(pSMB, byte_count);
4544 pSMB->ByteCount = cpu_to_le16(byte_count);
4546 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4547 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4549 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4550 } else { /* decode response */
4551 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4553 if (rc || get_bcc(&pSMBr->hdr) < 24)
4554 rc = -EIO; /* bad smb */
4556 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4560 *) (((char *) &pSMBr->hdr.Protocol) +
4563 le32_to_cpu(response_data->BytesPerSector) *
4564 le32_to_cpu(response_data->
4565 SectorsPerAllocationUnit);
4567 * much prefer larger but if server doesn't report
4568 * a valid size than 4K is a reasonable minimum
4570 if (FSData->f_bsize < 512)
4571 FSData->f_bsize = 4096;
4574 le64_to_cpu(response_data->TotalAllocationUnits);
4575 FSData->f_bfree = FSData->f_bavail =
4576 le64_to_cpu(response_data->FreeAllocationUnits);
4577 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4578 (unsigned long long)FSData->f_blocks,
4579 (unsigned long long)FSData->f_bfree,
4583 cifs_buf_release(pSMB);
4592 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
4594 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
4595 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4596 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4597 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
4599 int bytes_returned = 0;
4600 __u16 params, byte_count;
4602 cifs_dbg(FYI, "In QFSAttributeInfo\n");
4604 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4609 params = 2; /* level */
4610 pSMB->TotalDataCount = 0;
4611 pSMB->MaxParameterCount = cpu_to_le16(2);
4612 /* BB find exact max SMB PDU from sess structure BB */
4613 pSMB->MaxDataCount = cpu_to_le16(1000);
4614 pSMB->MaxSetupCount = 0;
4618 pSMB->Reserved2 = 0;
4619 byte_count = params + 1 /* pad */ ;
4620 pSMB->TotalParameterCount = cpu_to_le16(params);
4621 pSMB->ParameterCount = pSMB->TotalParameterCount;
4622 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4623 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4624 pSMB->DataCount = 0;
4625 pSMB->DataOffset = 0;
4626 pSMB->SetupCount = 1;
4627 pSMB->Reserved3 = 0;
4628 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4629 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4630 inc_rfc1001_len(pSMB, byte_count);
4631 pSMB->ByteCount = cpu_to_le16(byte_count);
4633 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4634 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4636 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
4637 } else { /* decode response */
4638 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4640 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4641 /* BB also check if enough bytes returned */
4642 rc = -EIO; /* bad smb */
4644 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4646 (FILE_SYSTEM_ATTRIBUTE_INFO
4647 *) (((char *) &pSMBr->hdr.Protocol) +
4649 memcpy(&tcon->fsAttrInfo, response_data,
4650 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
4653 cifs_buf_release(pSMB);
4656 goto QFSAttributeRetry;
4662 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
4664 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4665 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4666 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4667 FILE_SYSTEM_DEVICE_INFO *response_data;
4669 int bytes_returned = 0;
4670 __u16 params, byte_count;
4672 cifs_dbg(FYI, "In QFSDeviceInfo\n");
4674 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4679 params = 2; /* level */
4680 pSMB->TotalDataCount = 0;
4681 pSMB->MaxParameterCount = cpu_to_le16(2);
4682 /* BB find exact max SMB PDU from sess structure BB */
4683 pSMB->MaxDataCount = cpu_to_le16(1000);
4684 pSMB->MaxSetupCount = 0;
4688 pSMB->Reserved2 = 0;
4689 byte_count = params + 1 /* pad */ ;
4690 pSMB->TotalParameterCount = cpu_to_le16(params);
4691 pSMB->ParameterCount = pSMB->TotalParameterCount;
4692 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4693 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4695 pSMB->DataCount = 0;
4696 pSMB->DataOffset = 0;
4697 pSMB->SetupCount = 1;
4698 pSMB->Reserved3 = 0;
4699 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4700 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4701 inc_rfc1001_len(pSMB, byte_count);
4702 pSMB->ByteCount = cpu_to_le16(byte_count);
4704 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4705 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4707 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
4708 } else { /* decode response */
4709 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4711 if (rc || get_bcc(&pSMBr->hdr) <
4712 sizeof(FILE_SYSTEM_DEVICE_INFO))
4713 rc = -EIO; /* bad smb */
4715 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4717 (FILE_SYSTEM_DEVICE_INFO *)
4718 (((char *) &pSMBr->hdr.Protocol) +
4720 memcpy(&tcon->fsDevInfo, response_data,
4721 sizeof(FILE_SYSTEM_DEVICE_INFO));
4724 cifs_buf_release(pSMB);
4727 goto QFSDeviceRetry;
4733 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
4735 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
4736 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4737 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4738 FILE_SYSTEM_UNIX_INFO *response_data;
4740 int bytes_returned = 0;
4741 __u16 params, byte_count;
4743 cifs_dbg(FYI, "In QFSUnixInfo\n");
4745 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4746 (void **) &pSMB, (void **) &pSMBr);
4750 params = 2; /* level */
4751 pSMB->TotalDataCount = 0;
4752 pSMB->DataCount = 0;
4753 pSMB->DataOffset = 0;
4754 pSMB->MaxParameterCount = cpu_to_le16(2);
4755 /* BB find exact max SMB PDU from sess structure BB */
4756 pSMB->MaxDataCount = cpu_to_le16(100);
4757 pSMB->MaxSetupCount = 0;
4761 pSMB->Reserved2 = 0;
4762 byte_count = params + 1 /* pad */ ;
4763 pSMB->ParameterCount = cpu_to_le16(params);
4764 pSMB->TotalParameterCount = pSMB->ParameterCount;
4765 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4766 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4767 pSMB->SetupCount = 1;
4768 pSMB->Reserved3 = 0;
4769 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4770 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4771 inc_rfc1001_len(pSMB, byte_count);
4772 pSMB->ByteCount = cpu_to_le16(byte_count);
4774 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4775 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4777 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
4778 } else { /* decode response */
4779 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4781 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4782 rc = -EIO; /* bad smb */
4784 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4786 (FILE_SYSTEM_UNIX_INFO
4787 *) (((char *) &pSMBr->hdr.Protocol) +
4789 memcpy(&tcon->fsUnixInfo, response_data,
4790 sizeof(FILE_SYSTEM_UNIX_INFO));
4793 cifs_buf_release(pSMB);
4803 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
4805 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
4806 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
4807 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
4809 int bytes_returned = 0;
4810 __u16 params, param_offset, offset, byte_count;
4812 cifs_dbg(FYI, "In SETFSUnixInfo\n");
4814 /* BB switch to small buf init to save memory */
4815 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4816 (void **) &pSMB, (void **) &pSMBr);
4820 params = 4; /* 2 bytes zero followed by info level. */
4821 pSMB->MaxSetupCount = 0;
4825 pSMB->Reserved2 = 0;
4826 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
4828 offset = param_offset + params;
4830 pSMB->MaxParameterCount = cpu_to_le16(4);
4831 /* BB find exact max SMB PDU from sess structure BB */
4832 pSMB->MaxDataCount = cpu_to_le16(100);
4833 pSMB->SetupCount = 1;
4834 pSMB->Reserved3 = 0;
4835 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
4836 byte_count = 1 /* pad */ + params + 12;
4838 pSMB->DataCount = cpu_to_le16(12);
4839 pSMB->ParameterCount = cpu_to_le16(params);
4840 pSMB->TotalDataCount = pSMB->DataCount;
4841 pSMB->TotalParameterCount = pSMB->ParameterCount;
4842 pSMB->ParameterOffset = cpu_to_le16(param_offset);
4843 pSMB->DataOffset = cpu_to_le16(offset);
4847 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
4850 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
4851 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4852 pSMB->ClientUnixCap = cpu_to_le64(cap);
4854 inc_rfc1001_len(pSMB, byte_count);
4855 pSMB->ByteCount = cpu_to_le16(byte_count);
4857 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4858 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4860 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
4861 } else { /* decode response */
4862 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4864 rc = -EIO; /* bad smb */
4866 cifs_buf_release(pSMB);
4869 goto SETFSUnixRetry;
4877 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
4878 struct kstatfs *FSData)
4880 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
4881 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4882 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4883 FILE_SYSTEM_POSIX_INFO *response_data;
4885 int bytes_returned = 0;
4886 __u16 params, byte_count;
4888 cifs_dbg(FYI, "In QFSPosixInfo\n");
4890 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4895 params = 2; /* level */
4896 pSMB->TotalDataCount = 0;
4897 pSMB->DataCount = 0;
4898 pSMB->DataOffset = 0;
4899 pSMB->MaxParameterCount = cpu_to_le16(2);
4900 /* BB find exact max SMB PDU from sess structure BB */
4901 pSMB->MaxDataCount = cpu_to_le16(100);
4902 pSMB->MaxSetupCount = 0;
4906 pSMB->Reserved2 = 0;
4907 byte_count = params + 1 /* pad */ ;
4908 pSMB->ParameterCount = cpu_to_le16(params);
4909 pSMB->TotalParameterCount = pSMB->ParameterCount;
4910 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4911 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4912 pSMB->SetupCount = 1;
4913 pSMB->Reserved3 = 0;
4914 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4915 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4916 inc_rfc1001_len(pSMB, byte_count);
4917 pSMB->ByteCount = cpu_to_le16(byte_count);
4919 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4920 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4922 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
4923 } else { /* decode response */
4924 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4926 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4927 rc = -EIO; /* bad smb */
4929 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4931 (FILE_SYSTEM_POSIX_INFO
4932 *) (((char *) &pSMBr->hdr.Protocol) +
4935 le32_to_cpu(response_data->BlockSize);
4937 * much prefer larger but if server doesn't report
4938 * a valid size than 4K is a reasonable minimum
4940 if (FSData->f_bsize < 512)
4941 FSData->f_bsize = 4096;
4944 le64_to_cpu(response_data->TotalBlocks);
4946 le64_to_cpu(response_data->BlocksAvail);
4947 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
4948 FSData->f_bavail = FSData->f_bfree;
4951 le64_to_cpu(response_data->UserBlocksAvail);
4953 if (response_data->TotalFileNodes != cpu_to_le64(-1))
4955 le64_to_cpu(response_data->TotalFileNodes);
4956 if (response_data->FreeFileNodes != cpu_to_le64(-1))
4958 le64_to_cpu(response_data->FreeFileNodes);
4961 cifs_buf_release(pSMB);
4971 * We can not use write of zero bytes trick to set file size due to need for
4972 * large file support. Also note that this SetPathInfo is preferred to
4973 * SetFileInfo based method in next routine which is only needed to work around
4974 * a sharing violation bugin Samba which this routine can run into.
4977 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
4978 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
4979 bool set_allocation)
4981 struct smb_com_transaction2_spi_req *pSMB = NULL;
4982 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
4983 struct file_end_of_file_info *parm_data;
4986 int bytes_returned = 0;
4987 int remap = cifs_remap(cifs_sb);
4989 __u16 params, byte_count, data_count, param_offset, offset;
4991 cifs_dbg(FYI, "In SetEOF\n");
4993 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4998 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5000 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5001 PATH_MAX, cifs_sb->local_nls, remap);
5002 name_len++; /* trailing null */
5005 name_len = copy_path_name(pSMB->FileName, file_name);
5007 params = 6 + name_len;
5008 data_count = sizeof(struct file_end_of_file_info);
5009 pSMB->MaxParameterCount = cpu_to_le16(2);
5010 pSMB->MaxDataCount = cpu_to_le16(4100);
5011 pSMB->MaxSetupCount = 0;
5015 pSMB->Reserved2 = 0;
5016 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5017 InformationLevel) - 4;
5018 offset = param_offset + params;
5019 if (set_allocation) {
5020 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5021 pSMB->InformationLevel =
5022 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5024 pSMB->InformationLevel =
5025 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5026 } else /* Set File Size */ {
5027 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5028 pSMB->InformationLevel =
5029 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5031 pSMB->InformationLevel =
5032 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5036 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5038 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5039 pSMB->DataOffset = cpu_to_le16(offset);
5040 pSMB->SetupCount = 1;
5041 pSMB->Reserved3 = 0;
5042 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5043 byte_count = 3 /* pad */ + params + data_count;
5044 pSMB->DataCount = cpu_to_le16(data_count);
5045 pSMB->TotalDataCount = pSMB->DataCount;
5046 pSMB->ParameterCount = cpu_to_le16(params);
5047 pSMB->TotalParameterCount = pSMB->ParameterCount;
5048 pSMB->Reserved4 = 0;
5049 inc_rfc1001_len(pSMB, byte_count);
5050 parm_data->FileSize = cpu_to_le64(size);
5051 pSMB->ByteCount = cpu_to_le16(byte_count);
5052 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5053 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5055 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5057 cifs_buf_release(pSMB);
5066 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5067 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5069 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5070 struct file_end_of_file_info *parm_data;
5072 __u16 params, param_offset, offset, byte_count, count;
5074 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5076 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5081 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5082 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5085 pSMB->MaxSetupCount = 0;
5089 pSMB->Reserved2 = 0;
5090 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5091 offset = param_offset + params;
5093 count = sizeof(struct file_end_of_file_info);
5094 pSMB->MaxParameterCount = cpu_to_le16(2);
5095 /* BB find exact max SMB PDU from sess structure BB */
5096 pSMB->MaxDataCount = cpu_to_le16(1000);
5097 pSMB->SetupCount = 1;
5098 pSMB->Reserved3 = 0;
5099 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5100 byte_count = 3 /* pad */ + params + count;
5101 pSMB->DataCount = cpu_to_le16(count);
5102 pSMB->ParameterCount = cpu_to_le16(params);
5103 pSMB->TotalDataCount = pSMB->DataCount;
5104 pSMB->TotalParameterCount = pSMB->ParameterCount;
5105 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5106 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5108 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5109 pSMB->DataOffset = cpu_to_le16(offset);
5110 parm_data->FileSize = cpu_to_le64(size);
5111 pSMB->Fid = cfile->fid.netfid;
5112 if (set_allocation) {
5113 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5114 pSMB->InformationLevel =
5115 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5117 pSMB->InformationLevel =
5118 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5119 } else /* Set File Size */ {
5120 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5121 pSMB->InformationLevel =
5122 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5124 pSMB->InformationLevel =
5125 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5127 pSMB->Reserved4 = 0;
5128 inc_rfc1001_len(pSMB, byte_count);
5129 pSMB->ByteCount = cpu_to_le16(byte_count);
5130 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5131 cifs_small_buf_release(pSMB);
5133 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5137 /* Note: On -EAGAIN error only caller can retry on handle based calls
5138 since file handle passed in no longer valid */
5143 /* Some legacy servers such as NT4 require that the file times be set on
5144 an open handle, rather than by pathname - this is awkward due to
5145 potential access conflicts on the open, but it is unavoidable for these
5146 old servers since the only other choice is to go from 100 nanosecond DCE
5147 time and resort to the original setpathinfo level which takes the ancient
5148 DOS time format with 2 second granularity */
5150 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5151 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5153 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5156 __u16 params, param_offset, offset, byte_count, count;
5158 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5159 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5164 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5165 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5168 pSMB->MaxSetupCount = 0;
5172 pSMB->Reserved2 = 0;
5173 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5174 offset = param_offset + params;
5176 data_offset = (char *)pSMB +
5177 offsetof(struct smb_hdr, Protocol) + offset;
5179 count = sizeof(FILE_BASIC_INFO);
5180 pSMB->MaxParameterCount = cpu_to_le16(2);
5181 /* BB find max SMB PDU from sess */
5182 pSMB->MaxDataCount = cpu_to_le16(1000);
5183 pSMB->SetupCount = 1;
5184 pSMB->Reserved3 = 0;
5185 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5186 byte_count = 3 /* pad */ + params + count;
5187 pSMB->DataCount = cpu_to_le16(count);
5188 pSMB->ParameterCount = cpu_to_le16(params);
5189 pSMB->TotalDataCount = pSMB->DataCount;
5190 pSMB->TotalParameterCount = pSMB->ParameterCount;
5191 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5192 pSMB->DataOffset = cpu_to_le16(offset);
5194 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5195 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5197 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5198 pSMB->Reserved4 = 0;
5199 inc_rfc1001_len(pSMB, byte_count);
5200 pSMB->ByteCount = cpu_to_le16(byte_count);
5201 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5202 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5203 cifs_small_buf_release(pSMB);
5205 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5208 /* Note: On -EAGAIN error only caller can retry on handle based calls
5209 since file handle passed in no longer valid */
5215 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5216 bool delete_file, __u16 fid, __u32 pid_of_opener)
5218 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5221 __u16 params, param_offset, offset, byte_count, count;
5223 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5224 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5229 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5230 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5233 pSMB->MaxSetupCount = 0;
5237 pSMB->Reserved2 = 0;
5238 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5239 offset = param_offset + params;
5241 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5242 data_offset = (char *)(pSMB) + offset + 4;
5245 pSMB->MaxParameterCount = cpu_to_le16(2);
5246 /* BB find max SMB PDU from sess */
5247 pSMB->MaxDataCount = cpu_to_le16(1000);
5248 pSMB->SetupCount = 1;
5249 pSMB->Reserved3 = 0;
5250 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5251 byte_count = 3 /* pad */ + params + count;
5252 pSMB->DataCount = cpu_to_le16(count);
5253 pSMB->ParameterCount = cpu_to_le16(params);
5254 pSMB->TotalDataCount = pSMB->DataCount;
5255 pSMB->TotalParameterCount = pSMB->ParameterCount;
5256 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5257 pSMB->DataOffset = cpu_to_le16(offset);
5259 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5260 pSMB->Reserved4 = 0;
5261 inc_rfc1001_len(pSMB, byte_count);
5262 pSMB->ByteCount = cpu_to_le16(byte_count);
5263 *data_offset = delete_file ? 1 : 0;
5264 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5265 cifs_small_buf_release(pSMB);
5267 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5273 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5274 const char *fileName, const FILE_BASIC_INFO *data,
5275 const struct nls_table *nls_codepage,
5276 struct cifs_sb_info *cifs_sb)
5279 struct cifs_open_parms oparms;
5280 struct cifs_fid fid;
5283 oparms = (struct cifs_open_parms) {
5286 .desired_access = GENERIC_WRITE,
5287 .create_options = cifs_create_options(cifs_sb, 0),
5288 .disposition = FILE_OPEN,
5293 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5297 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5298 CIFSSMBClose(xid, tcon, fid.netfid);
5305 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5306 const char *fileName, const FILE_BASIC_INFO *data,
5307 const struct nls_table *nls_codepage,
5308 struct cifs_sb_info *cifs_sb)
5310 TRANSACTION2_SPI_REQ *pSMB = NULL;
5311 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5314 int bytes_returned = 0;
5316 __u16 params, param_offset, offset, byte_count, count;
5317 int remap = cifs_remap(cifs_sb);
5319 cifs_dbg(FYI, "In SetTimes\n");
5322 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5327 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5329 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5330 PATH_MAX, nls_codepage, remap);
5331 name_len++; /* trailing null */
5334 name_len = copy_path_name(pSMB->FileName, fileName);
5337 params = 6 + name_len;
5338 count = sizeof(FILE_BASIC_INFO);
5339 pSMB->MaxParameterCount = cpu_to_le16(2);
5340 /* BB find max SMB PDU from sess structure BB */
5341 pSMB->MaxDataCount = cpu_to_le16(1000);
5342 pSMB->MaxSetupCount = 0;
5346 pSMB->Reserved2 = 0;
5347 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5348 InformationLevel) - 4;
5349 offset = param_offset + params;
5350 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5351 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5352 pSMB->DataOffset = cpu_to_le16(offset);
5353 pSMB->SetupCount = 1;
5354 pSMB->Reserved3 = 0;
5355 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5356 byte_count = 3 /* pad */ + params + count;
5358 pSMB->DataCount = cpu_to_le16(count);
5359 pSMB->ParameterCount = cpu_to_le16(params);
5360 pSMB->TotalDataCount = pSMB->DataCount;
5361 pSMB->TotalParameterCount = pSMB->ParameterCount;
5362 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5363 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5365 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5366 pSMB->Reserved4 = 0;
5367 inc_rfc1001_len(pSMB, byte_count);
5368 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5369 pSMB->ByteCount = cpu_to_le16(byte_count);
5370 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5371 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5373 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5375 cifs_buf_release(pSMB);
5380 if (rc == -EOPNOTSUPP)
5381 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5382 nls_codepage, cifs_sb);
5388 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5389 const struct cifs_unix_set_info_args *args)
5391 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5392 u64 mode = args->mode;
5394 if (uid_valid(args->uid))
5395 uid = from_kuid(&init_user_ns, args->uid);
5396 if (gid_valid(args->gid))
5397 gid = from_kgid(&init_user_ns, args->gid);
5400 * Samba server ignores set of file size to zero due to bugs in some
5401 * older clients, but we should be precise - we use SetFileSize to
5402 * set file size and do not want to truncate file size to zero
5403 * accidentally as happened on one Samba server beta by putting
5404 * zero instead of -1 here
5406 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5407 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5408 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5409 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5410 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5411 data_offset->Uid = cpu_to_le64(uid);
5412 data_offset->Gid = cpu_to_le64(gid);
5413 /* better to leave device as zero when it is */
5414 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5415 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5416 data_offset->Permissions = cpu_to_le64(mode);
5419 data_offset->Type = cpu_to_le32(UNIX_FILE);
5420 else if (S_ISDIR(mode))
5421 data_offset->Type = cpu_to_le32(UNIX_DIR);
5422 else if (S_ISLNK(mode))
5423 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5424 else if (S_ISCHR(mode))
5425 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5426 else if (S_ISBLK(mode))
5427 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5428 else if (S_ISFIFO(mode))
5429 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5430 else if (S_ISSOCK(mode))
5431 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5435 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5436 const struct cifs_unix_set_info_args *args,
5437 u16 fid, u32 pid_of_opener)
5439 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5442 u16 params, param_offset, offset, byte_count, count;
5444 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5445 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5450 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5451 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5454 pSMB->MaxSetupCount = 0;
5458 pSMB->Reserved2 = 0;
5459 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5460 offset = param_offset + params;
5462 data_offset = (char *)pSMB +
5463 offsetof(struct smb_hdr, Protocol) + offset;
5465 count = sizeof(FILE_UNIX_BASIC_INFO);
5467 pSMB->MaxParameterCount = cpu_to_le16(2);
5468 /* BB find max SMB PDU from sess */
5469 pSMB->MaxDataCount = cpu_to_le16(1000);
5470 pSMB->SetupCount = 1;
5471 pSMB->Reserved3 = 0;
5472 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5473 byte_count = 3 /* pad */ + params + count;
5474 pSMB->DataCount = cpu_to_le16(count);
5475 pSMB->ParameterCount = cpu_to_le16(params);
5476 pSMB->TotalDataCount = pSMB->DataCount;
5477 pSMB->TotalParameterCount = pSMB->ParameterCount;
5478 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5479 pSMB->DataOffset = cpu_to_le16(offset);
5481 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5482 pSMB->Reserved4 = 0;
5483 inc_rfc1001_len(pSMB, byte_count);
5484 pSMB->ByteCount = cpu_to_le16(byte_count);
5486 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5488 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5489 cifs_small_buf_release(pSMB);
5491 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5494 /* Note: On -EAGAIN error only caller can retry on handle based calls
5495 since file handle passed in no longer valid */
5501 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5502 const char *file_name,
5503 const struct cifs_unix_set_info_args *args,
5504 const struct nls_table *nls_codepage, int remap)
5506 TRANSACTION2_SPI_REQ *pSMB = NULL;
5507 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5510 int bytes_returned = 0;
5511 FILE_UNIX_BASIC_INFO *data_offset;
5512 __u16 params, param_offset, offset, count, byte_count;
5514 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5516 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5521 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5523 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5524 PATH_MAX, nls_codepage, remap);
5525 name_len++; /* trailing null */
5528 name_len = copy_path_name(pSMB->FileName, file_name);
5531 params = 6 + name_len;
5532 count = sizeof(FILE_UNIX_BASIC_INFO);
5533 pSMB->MaxParameterCount = cpu_to_le16(2);
5534 /* BB find max SMB PDU from sess structure BB */
5535 pSMB->MaxDataCount = cpu_to_le16(1000);
5536 pSMB->MaxSetupCount = 0;
5540 pSMB->Reserved2 = 0;
5541 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5542 InformationLevel) - 4;
5543 offset = param_offset + params;
5544 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5545 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
5546 memset(data_offset, 0, count);
5547 pSMB->DataOffset = cpu_to_le16(offset);
5548 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5549 pSMB->SetupCount = 1;
5550 pSMB->Reserved3 = 0;
5551 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5552 byte_count = 3 /* pad */ + params + count;
5553 pSMB->ParameterCount = cpu_to_le16(params);
5554 pSMB->DataCount = cpu_to_le16(count);
5555 pSMB->TotalParameterCount = pSMB->ParameterCount;
5556 pSMB->TotalDataCount = pSMB->DataCount;
5557 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5558 pSMB->Reserved4 = 0;
5559 inc_rfc1001_len(pSMB, byte_count);
5561 cifs_fill_unix_set_info(data_offset, args);
5563 pSMB->ByteCount = cpu_to_le16(byte_count);
5564 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5565 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5567 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
5569 cifs_buf_release(pSMB);
5575 #ifdef CONFIG_CIFS_XATTR
5577 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
5578 * function used by listxattr and getxattr type calls. When ea_name is set,
5579 * it looks for that attribute name and stuffs that value into the EAData
5580 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
5581 * buffer. In both cases, the return value is either the length of the
5582 * resulting data or a negative error code. If EAData is a NULL pointer then
5583 * the data isn't copied to it, but the length is returned.
5586 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
5587 const unsigned char *searchName, const unsigned char *ea_name,
5588 char *EAData, size_t buf_size,
5589 struct cifs_sb_info *cifs_sb)
5591 /* BB assumes one setup word */
5592 TRANSACTION2_QPI_REQ *pSMB = NULL;
5593 TRANSACTION2_QPI_RSP *pSMBr = NULL;
5594 int remap = cifs_remap(cifs_sb);
5595 struct nls_table *nls_codepage = cifs_sb->local_nls;
5599 struct fealist *ea_response_data;
5600 struct fea *temp_fea;
5603 __u16 params, byte_count, data_offset;
5604 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
5606 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
5608 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5613 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5615 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
5616 PATH_MAX, nls_codepage, remap);
5617 list_len++; /* trailing null */
5620 list_len = copy_path_name(pSMB->FileName, searchName);
5623 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
5624 pSMB->TotalDataCount = 0;
5625 pSMB->MaxParameterCount = cpu_to_le16(2);
5626 /* BB find exact max SMB PDU from sess structure BB */
5627 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
5628 pSMB->MaxSetupCount = 0;
5632 pSMB->Reserved2 = 0;
5633 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5634 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5635 pSMB->DataCount = 0;
5636 pSMB->DataOffset = 0;
5637 pSMB->SetupCount = 1;
5638 pSMB->Reserved3 = 0;
5639 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
5640 byte_count = params + 1 /* pad */ ;
5641 pSMB->TotalParameterCount = cpu_to_le16(params);
5642 pSMB->ParameterCount = pSMB->TotalParameterCount;
5643 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5644 pSMB->Reserved4 = 0;
5645 inc_rfc1001_len(pSMB, byte_count);
5646 pSMB->ByteCount = cpu_to_le16(byte_count);
5648 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5649 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5651 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
5656 /* BB also check enough total bytes returned */
5657 /* BB we need to improve the validity checking
5658 of these trans2 responses */
5660 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5661 if (rc || get_bcc(&pSMBr->hdr) < 4) {
5662 rc = -EIO; /* bad smb */
5666 /* check that length of list is not more than bcc */
5667 /* check that each entry does not go beyond length
5669 /* check that each element of each entry does not
5670 go beyond end of list */
5671 /* validate_trans2_offsets() */
5672 /* BB check if start of smb + data_offset > &bcc+ bcc */
5674 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5675 ea_response_data = (struct fealist *)
5676 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5678 list_len = le32_to_cpu(ea_response_data->list_len);
5679 cifs_dbg(FYI, "ea length %d\n", list_len);
5680 if (list_len <= 8) {
5681 cifs_dbg(FYI, "empty EA list returned from server\n");
5682 /* didn't find the named attribute */
5688 /* make sure list_len doesn't go past end of SMB */
5689 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
5690 if ((char *)ea_response_data + list_len > end_of_smb) {
5691 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
5696 /* account for ea list len */
5698 temp_fea = ea_response_data->list;
5699 temp_ptr = (char *)temp_fea;
5700 while (list_len > 0) {
5701 unsigned int name_len;
5706 /* make sure we can read name_len and value_len */
5708 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5713 name_len = temp_fea->name_len;
5714 value_len = le16_to_cpu(temp_fea->value_len);
5715 list_len -= name_len + 1 + value_len;
5717 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5723 if (ea_name_len == name_len &&
5724 memcmp(ea_name, temp_ptr, name_len) == 0) {
5725 temp_ptr += name_len + 1;
5729 if ((size_t)value_len > buf_size) {
5733 memcpy(EAData, temp_ptr, value_len);
5737 /* account for prefix user. and trailing null */
5738 rc += (5 + 1 + name_len);
5739 if (rc < (int) buf_size) {
5740 memcpy(EAData, "user.", 5);
5742 memcpy(EAData, temp_ptr, name_len);
5744 /* null terminate name */
5747 } else if (buf_size == 0) {
5748 /* skip copy - calc size only */
5750 /* stop before overrun buffer */
5755 temp_ptr += name_len + 1 + value_len;
5756 temp_fea = (struct fea *)temp_ptr;
5759 /* didn't find the named attribute */
5764 cifs_buf_release(pSMB);
5772 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
5773 const char *fileName, const char *ea_name, const void *ea_value,
5774 const __u16 ea_value_len, const struct nls_table *nls_codepage,
5775 struct cifs_sb_info *cifs_sb)
5777 struct smb_com_transaction2_spi_req *pSMB = NULL;
5778 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5779 struct fealist *parm_data;
5782 int bytes_returned = 0;
5783 __u16 params, param_offset, byte_count, offset, count;
5784 int remap = cifs_remap(cifs_sb);
5786 cifs_dbg(FYI, "In SetEA\n");
5788 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5793 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5795 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5796 PATH_MAX, nls_codepage, remap);
5797 name_len++; /* trailing null */
5800 name_len = copy_path_name(pSMB->FileName, fileName);
5803 params = 6 + name_len;
5805 /* done calculating parms using name_len of file name,
5806 now use name_len to calculate length of ea name
5807 we are going to create in the inode xattrs */
5808 if (ea_name == NULL)
5811 name_len = strnlen(ea_name, 255);
5813 count = sizeof(*parm_data) + ea_value_len + name_len;
5814 pSMB->MaxParameterCount = cpu_to_le16(2);
5815 /* BB find max SMB PDU from sess */
5816 pSMB->MaxDataCount = cpu_to_le16(1000);
5817 pSMB->MaxSetupCount = 0;
5821 pSMB->Reserved2 = 0;
5822 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5823 InformationLevel) - 4;
5824 offset = param_offset + params;
5825 pSMB->InformationLevel =
5826 cpu_to_le16(SMB_SET_FILE_EA);
5828 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
5829 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5830 pSMB->DataOffset = cpu_to_le16(offset);
5831 pSMB->SetupCount = 1;
5832 pSMB->Reserved3 = 0;
5833 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5834 byte_count = 3 /* pad */ + params + count;
5835 pSMB->DataCount = cpu_to_le16(count);
5836 parm_data->list_len = cpu_to_le32(count);
5837 parm_data->list[0].EA_flags = 0;
5838 /* we checked above that name len is less than 255 */
5839 parm_data->list[0].name_len = (__u8)name_len;
5840 /* EA names are always ASCII */
5842 strncpy(parm_data->list[0].name, ea_name, name_len);
5843 parm_data->list[0].name[name_len] = 0;
5844 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
5845 /* caller ensures that ea_value_len is less than 64K but
5846 we need to ensure that it fits within the smb */
5848 /*BB add length check to see if it would fit in
5849 negotiated SMB buffer size BB */
5850 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
5852 memcpy(parm_data->list[0].name+name_len+1,
5853 ea_value, ea_value_len);
5855 pSMB->TotalDataCount = pSMB->DataCount;
5856 pSMB->ParameterCount = cpu_to_le16(params);
5857 pSMB->TotalParameterCount = pSMB->ParameterCount;
5858 pSMB->Reserved4 = 0;
5859 inc_rfc1001_len(pSMB, byte_count);
5860 pSMB->ByteCount = cpu_to_le16(byte_count);
5861 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5862 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5864 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
5866 cifs_buf_release(pSMB);