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/filelock.h>
19 #include <linux/kernel.h>
20 #include <linux/vfs.h>
21 #include <linux/slab.h>
22 #include <linux/posix_acl_xattr.h>
23 #include <linux/pagemap.h>
24 #include <linux/swap.h>
25 #include <linux/task_io_accounting_ops.h>
26 #include <linux/uaccess.h>
31 #include "cifsproto.h"
32 #include "cifs_unicode.h"
33 #include "cifs_debug.h"
35 #include "smbdirect.h"
36 #ifdef CONFIG_CIFS_DFS_UPCALL
37 #include "dfs_cache.h"
40 #ifdef CONFIG_CIFS_POSIX
45 {CIFS_PROT, "\2NT LM 0.12"},
46 {POSIX_PROT, "\2POSIX 2"},
54 {CIFS_PROT, "\2NT LM 0.12"},
59 /* define the number of elements in the cifs dialect array */
60 #ifdef CONFIG_CIFS_POSIX
61 #define CIFS_NUM_PROT 2
63 #define CIFS_NUM_PROT 1
64 #endif /* CIFS_POSIX */
67 /* reconnect the socket, tcon, and smb session if needed */
69 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
73 struct TCP_Server_Info *server;
74 struct nls_table *nls_codepage;
77 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
78 * tcp and smb session status done differently for those three - in the
88 * only tree disconnect, open, and write, (and ulogoff which does not
89 * have tcon) are allowed as we start umount
91 spin_lock(&tcon->tc_lock);
92 if (tcon->status == TID_EXITING) {
93 if (smb_command != SMB_COM_TREE_DISCONNECT) {
94 spin_unlock(&tcon->tc_lock);
95 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
100 spin_unlock(&tcon->tc_lock);
102 rc = cifs_wait_for_server_reconnect(server, tcon->retry);
106 spin_lock(&ses->chan_lock);
107 if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
108 spin_unlock(&ses->chan_lock);
111 spin_unlock(&ses->chan_lock);
113 nls_codepage = load_nls_default();
116 * Recheck after acquire mutex. If another thread is negotiating
117 * and the server never sends an answer the socket will be closed
118 * and tcpStatus set to reconnect.
120 spin_lock(&server->srv_lock);
121 if (server->tcpStatus == CifsNeedReconnect) {
122 spin_unlock(&server->srv_lock);
126 spin_unlock(&server->srv_lock);
129 * need to prevent multiple threads trying to simultaneously
130 * reconnect the same SMB session
132 spin_lock(&ses->chan_lock);
133 if (!cifs_chan_needs_reconnect(ses, server)) {
134 spin_unlock(&ses->chan_lock);
136 /* this means that we only need to tree connect */
137 if (tcon->need_reconnect)
138 goto skip_sess_setup;
143 spin_unlock(&ses->chan_lock);
145 mutex_lock(&ses->session_mutex);
146 rc = cifs_negotiate_protocol(0, ses, server);
148 rc = cifs_setup_session(0, ses, server, nls_codepage);
150 /* do we need to reconnect tcon? */
151 if (rc || !tcon->need_reconnect) {
152 mutex_unlock(&ses->session_mutex);
157 cifs_mark_open_files_invalid(tcon);
158 rc = cifs_tree_connect(0, tcon, nls_codepage);
159 mutex_unlock(&ses->session_mutex);
160 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
163 pr_warn_once("reconnect tcon failed rc = %d\n", rc);
167 atomic_inc(&tconInfoReconnectCount);
169 /* tell server Unix caps we support */
171 reset_cifs_unix_caps(0, tcon, NULL, NULL);
174 * Removed call to reopen open files here. It is safer (and faster) to
175 * reopen files one at a time as needed in read and write.
177 * FIXME: what about file locks? don't we need to reclaim them ASAP?
182 * Check if handle based operation so we know whether we can continue
183 * or not without returning to caller to reset file handle
185 switch (smb_command) {
186 case SMB_COM_READ_ANDX:
187 case SMB_COM_WRITE_ANDX:
189 case SMB_COM_FIND_CLOSE2:
190 case SMB_COM_LOCKING_ANDX:
194 unload_nls(nls_codepage);
198 /* Allocate and return pointer to an SMB request buffer, and set basic
199 SMB information in the SMB header. If the return code is zero, this
200 function must have filled in request_buf pointer */
202 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
207 rc = cifs_reconnect_tcon(tcon, smb_command);
211 *request_buf = cifs_small_buf_get();
212 if (*request_buf == NULL) {
213 /* BB should we add a retry in here if not a writepage? */
217 header_assemble((struct smb_hdr *) *request_buf, smb_command,
221 cifs_stats_inc(&tcon->num_smbs_sent);
227 small_smb_init_no_tc(const int smb_command, const int wct,
228 struct cifs_ses *ses, void **request_buf)
231 struct smb_hdr *buffer;
233 rc = small_smb_init(smb_command, wct, NULL, request_buf);
237 buffer = (struct smb_hdr *)*request_buf;
238 buffer->Mid = get_next_mid(ses->server);
239 if (ses->capabilities & CAP_UNICODE)
240 buffer->Flags2 |= SMBFLG2_UNICODE;
241 if (ses->capabilities & CAP_STATUS32)
242 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
244 /* uid, tid can stay at zero as set in header assemble */
246 /* BB add support for turning on the signing when
247 this function is used after 1st of session setup requests */
252 /* If the return code is zero, this function must fill in request_buf pointer */
254 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
255 void **request_buf, void **response_buf)
257 *request_buf = cifs_buf_get();
258 if (*request_buf == NULL) {
259 /* BB should we add a retry in here if not a writepage? */
262 /* Although the original thought was we needed the response buf for */
263 /* potential retries of smb operations it turns out we can determine */
264 /* from the mid flags when the request buffer can be resent without */
265 /* having to use a second distinct buffer for the response */
267 *response_buf = *request_buf;
269 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
273 cifs_stats_inc(&tcon->num_smbs_sent);
278 /* If the return code is zero, this function must fill in request_buf pointer */
280 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
281 void **request_buf, void **response_buf)
285 rc = cifs_reconnect_tcon(tcon, smb_command);
289 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
293 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
294 void **request_buf, void **response_buf)
296 spin_lock(&tcon->ses->chan_lock);
297 if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) ||
298 tcon->need_reconnect) {
299 spin_unlock(&tcon->ses->chan_lock);
302 spin_unlock(&tcon->ses->chan_lock);
304 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
307 static int validate_t2(struct smb_t2_rsp *pSMB)
309 unsigned int total_size;
311 /* check for plausible wct */
312 if (pSMB->hdr.WordCount < 10)
315 /* check for parm and data offset going beyond end of smb */
316 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
317 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
320 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
321 if (total_size >= 512)
324 /* check that bcc is at least as big as parms + data, and that it is
325 * less than negotiated smb buffer
327 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
328 if (total_size > get_bcc(&pSMB->hdr) ||
329 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
334 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
335 sizeof(struct smb_t2_rsp) + 16);
340 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
344 char *guid = pSMBr->u.extended_response.GUID;
345 struct TCP_Server_Info *server = ses->server;
347 count = get_bcc(&pSMBr->hdr);
348 if (count < SMB1_CLIENT_GUID_SIZE)
351 spin_lock(&cifs_tcp_ses_lock);
352 if (server->srv_count > 1) {
353 spin_unlock(&cifs_tcp_ses_lock);
354 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
355 cifs_dbg(FYI, "server UID changed\n");
356 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
359 spin_unlock(&cifs_tcp_ses_lock);
360 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
363 if (count == SMB1_CLIENT_GUID_SIZE) {
364 server->sec_ntlmssp = true;
366 count -= SMB1_CLIENT_GUID_SIZE;
367 rc = decode_negTokenInit(
368 pSMBr->u.extended_response.SecurityBlob, count, server);
377 should_set_ext_sec_flag(enum securityEnum sectype)
384 if (global_secflags &
385 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
394 CIFSSMBNegotiate(const unsigned int xid,
395 struct cifs_ses *ses,
396 struct TCP_Server_Info *server)
399 NEGOTIATE_RSP *pSMBr;
406 WARN(1, "%s: server is NULL!\n", __func__);
410 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
411 (void **) &pSMB, (void **) &pSMBr);
415 pSMB->hdr.Mid = get_next_mid(server);
416 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
418 if (should_set_ext_sec_flag(ses->sectype)) {
419 cifs_dbg(FYI, "Requesting extended security\n");
420 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
425 * We know that all the name entries in the protocols array
426 * are short (< 16 bytes anyway) and are NUL terminated.
428 for (i = 0; i < CIFS_NUM_PROT; i++) {
429 size_t len = strlen(protocols[i].name) + 1;
431 memcpy(&pSMB->DialectsArray[count], protocols[i].name, len);
434 inc_rfc1001_len(pSMB, count);
435 pSMB->ByteCount = cpu_to_le16(count);
437 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
438 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
442 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
443 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
444 /* Check wct = 1 error case */
445 if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
446 /* core returns wct = 1, but we do not ask for core - otherwise
447 small wct just comes when dialect index is -1 indicating we
448 could not negotiate a common dialect */
451 } else if (pSMBr->hdr.WordCount != 17) {
456 /* else wct == 17, NTLM or better */
458 server->sec_mode = pSMBr->SecurityMode;
459 if ((server->sec_mode & SECMODE_USER) == 0)
460 cifs_dbg(FYI, "share mode security\n");
462 /* one byte, so no need to convert this or EncryptionKeyLen from
464 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
466 set_credits(server, server->maxReq);
467 /* probably no need to store and check maxvcs */
468 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
469 /* set up max_read for readahead check */
470 server->max_read = server->maxBuf;
471 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
472 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
473 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
474 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
475 server->timeAdj *= 60;
477 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
478 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
479 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
480 CIFS_CRYPTO_KEY_SIZE);
481 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
482 server->capabilities & CAP_EXTENDED_SECURITY) {
483 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
484 rc = decode_ext_sec_blob(ses, pSMBr);
485 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
486 rc = -EIO; /* no crypt key only if plain text pwd */
488 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
489 server->capabilities &= ~CAP_EXTENDED_SECURITY;
493 rc = cifs_enable_signing(server, ses->sign);
495 cifs_buf_release(pSMB);
497 cifs_dbg(FYI, "negprot rc %d\n", rc);
502 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
504 struct smb_hdr *smb_buffer;
507 cifs_dbg(FYI, "In tree disconnect\n");
509 /* BB: do we need to check this? These should never be NULL. */
510 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
514 * No need to return error on this operation if tid invalidated and
515 * closed on server already e.g. due to tcp session crashing. Also,
516 * the tcon is no longer on the list, so no need to take lock before
519 spin_lock(&tcon->ses->chan_lock);
520 if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
521 spin_unlock(&tcon->ses->chan_lock);
524 spin_unlock(&tcon->ses->chan_lock);
526 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
527 (void **)&smb_buffer);
531 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
532 cifs_small_buf_release(smb_buffer);
534 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
536 /* No need to return error on this operation if tid invalidated and
537 closed on server already e.g. due to tcp session crashing */
545 * This is a no-op for now. We're not really interested in the reply, but
546 * rather in the fact that the server sent one and that server->lstrp
549 * FIXME: maybe we should consider checking that the reply matches request?
552 cifs_echo_callback(struct mid_q_entry *mid)
554 struct TCP_Server_Info *server = mid->callback_data;
555 struct cifs_credits credits = { .value = 1, .instance = 0 };
558 add_credits(server, &credits, CIFS_ECHO_OP);
562 CIFSSMBEcho(struct TCP_Server_Info *server)
567 struct smb_rqst rqst = { .rq_iov = iov,
570 cifs_dbg(FYI, "In echo request\n");
572 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
576 if (server->capabilities & CAP_UNICODE)
577 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
579 /* set up echo request */
580 smb->hdr.Tid = 0xffff;
581 smb->hdr.WordCount = 1;
582 put_unaligned_le16(1, &smb->EchoCount);
583 put_bcc(1, &smb->hdr);
585 inc_rfc1001_len(smb, 3);
588 iov[0].iov_base = smb;
589 iov[1].iov_len = get_rfc1002_length(smb);
590 iov[1].iov_base = (char *)smb + 4;
592 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
593 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
595 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
597 cifs_small_buf_release(smb);
603 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
605 LOGOFF_ANDX_REQ *pSMB;
608 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
611 * BB: do we need to check validity of ses and server? They should
612 * always be valid since we have an active reference. If not, that
613 * should probably be a BUG()
615 if (!ses || !ses->server)
618 mutex_lock(&ses->session_mutex);
619 spin_lock(&ses->chan_lock);
620 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
621 spin_unlock(&ses->chan_lock);
622 goto session_already_dead; /* no need to send SMBlogoff if uid
623 already closed due to reconnect */
625 spin_unlock(&ses->chan_lock);
627 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
629 mutex_unlock(&ses->session_mutex);
633 pSMB->hdr.Mid = get_next_mid(ses->server);
635 if (ses->server->sign)
636 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
638 pSMB->hdr.Uid = ses->Suid;
640 pSMB->AndXCommand = 0xFF;
641 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
642 cifs_small_buf_release(pSMB);
643 session_already_dead:
644 mutex_unlock(&ses->session_mutex);
646 /* if session dead then we do not need to do ulogoff,
647 since server closed smb session, no sense reporting
655 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
656 const char *fileName, __u16 type,
657 const struct nls_table *nls_codepage, int remap)
659 TRANSACTION2_SPI_REQ *pSMB = NULL;
660 TRANSACTION2_SPI_RSP *pSMBr = NULL;
661 struct unlink_psx_rq *pRqD;
664 int bytes_returned = 0;
665 __u16 params, param_offset, offset, byte_count;
667 cifs_dbg(FYI, "In POSIX delete\n");
669 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
674 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
676 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
677 PATH_MAX, nls_codepage, remap);
678 name_len++; /* trailing null */
681 name_len = copy_path_name(pSMB->FileName, fileName);
684 params = 6 + name_len;
685 pSMB->MaxParameterCount = cpu_to_le16(2);
686 pSMB->MaxDataCount = 0; /* BB double check this with jra */
687 pSMB->MaxSetupCount = 0;
692 param_offset = offsetof(struct smb_com_transaction2_spi_req,
693 InformationLevel) - 4;
694 offset = param_offset + params;
696 /* Setup pointer to Request Data (inode type).
697 * Note that SMB offsets are from the beginning of SMB which is 4 bytes
698 * in, after RFC1001 field
700 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
701 pRqD->type = cpu_to_le16(type);
702 pSMB->ParameterOffset = cpu_to_le16(param_offset);
703 pSMB->DataOffset = cpu_to_le16(offset);
704 pSMB->SetupCount = 1;
706 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
707 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
709 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
710 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
711 pSMB->ParameterCount = cpu_to_le16(params);
712 pSMB->TotalParameterCount = pSMB->ParameterCount;
713 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
715 inc_rfc1001_len(pSMB, byte_count);
716 pSMB->ByteCount = cpu_to_le16(byte_count);
717 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
718 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
720 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
721 cifs_buf_release(pSMB);
723 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
732 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
733 struct cifs_sb_info *cifs_sb)
735 DELETE_FILE_REQ *pSMB = NULL;
736 DELETE_FILE_RSP *pSMBr = NULL;
740 int remap = cifs_remap(cifs_sb);
743 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
748 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
749 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
750 PATH_MAX, cifs_sb->local_nls,
752 name_len++; /* trailing null */
755 name_len = copy_path_name(pSMB->fileName, name);
757 pSMB->SearchAttributes =
758 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
759 pSMB->BufferFormat = 0x04;
760 inc_rfc1001_len(pSMB, name_len + 1);
761 pSMB->ByteCount = cpu_to_le16(name_len + 1);
762 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
763 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
764 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
766 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
768 cifs_buf_release(pSMB);
776 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
777 struct cifs_sb_info *cifs_sb)
779 DELETE_DIRECTORY_REQ *pSMB = NULL;
780 DELETE_DIRECTORY_RSP *pSMBr = NULL;
784 int remap = cifs_remap(cifs_sb);
786 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
788 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
793 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
794 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
795 PATH_MAX, cifs_sb->local_nls,
797 name_len++; /* trailing null */
800 name_len = copy_path_name(pSMB->DirName, name);
803 pSMB->BufferFormat = 0x04;
804 inc_rfc1001_len(pSMB, name_len + 1);
805 pSMB->ByteCount = cpu_to_le16(name_len + 1);
806 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
807 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
808 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
810 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
812 cifs_buf_release(pSMB);
819 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
820 struct cifs_tcon *tcon, const char *name,
821 struct cifs_sb_info *cifs_sb)
824 CREATE_DIRECTORY_REQ *pSMB = NULL;
825 CREATE_DIRECTORY_RSP *pSMBr = NULL;
828 int remap = cifs_remap(cifs_sb);
830 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
832 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
837 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
838 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
839 PATH_MAX, cifs_sb->local_nls,
841 name_len++; /* trailing null */
844 name_len = copy_path_name(pSMB->DirName, name);
847 pSMB->BufferFormat = 0x04;
848 inc_rfc1001_len(pSMB, name_len + 1);
849 pSMB->ByteCount = cpu_to_le16(name_len + 1);
850 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
851 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
852 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
854 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
856 cifs_buf_release(pSMB);
863 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
864 __u32 posix_flags, __u64 mode, __u16 *netfid,
865 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
866 const char *name, const struct nls_table *nls_codepage,
869 TRANSACTION2_SPI_REQ *pSMB = NULL;
870 TRANSACTION2_SPI_RSP *pSMBr = NULL;
873 int bytes_returned = 0;
874 __u16 params, param_offset, offset, byte_count, count;
876 OPEN_PSX_RSP *psx_rsp;
878 cifs_dbg(FYI, "In POSIX Create\n");
880 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
885 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
887 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
888 PATH_MAX, nls_codepage, remap);
889 name_len++; /* trailing null */
892 name_len = copy_path_name(pSMB->FileName, name);
895 params = 6 + name_len;
896 count = sizeof(OPEN_PSX_REQ);
897 pSMB->MaxParameterCount = cpu_to_le16(2);
898 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
899 pSMB->MaxSetupCount = 0;
904 param_offset = offsetof(struct smb_com_transaction2_spi_req,
905 InformationLevel) - 4;
906 offset = param_offset + params;
907 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
908 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
909 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
910 pdata->Permissions = cpu_to_le64(mode);
911 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
912 pdata->OpenFlags = cpu_to_le32(*pOplock);
913 pSMB->ParameterOffset = cpu_to_le16(param_offset);
914 pSMB->DataOffset = cpu_to_le16(offset);
915 pSMB->SetupCount = 1;
917 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
918 byte_count = 3 /* pad */ + params + count;
920 pSMB->DataCount = cpu_to_le16(count);
921 pSMB->ParameterCount = cpu_to_le16(params);
922 pSMB->TotalDataCount = pSMB->DataCount;
923 pSMB->TotalParameterCount = pSMB->ParameterCount;
924 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
926 inc_rfc1001_len(pSMB, byte_count);
927 pSMB->ByteCount = cpu_to_le16(byte_count);
928 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
929 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
931 cifs_dbg(FYI, "Posix create returned %d\n", rc);
935 cifs_dbg(FYI, "copying inode info\n");
936 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
938 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
939 rc = -EIO; /* bad smb */
943 /* copy return information to pRetData */
944 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
945 + le16_to_cpu(pSMBr->t2.DataOffset));
947 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
949 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
950 /* Let caller know file was created so we can set the mode. */
951 /* Do we care about the CreateAction in any other cases? */
952 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
953 *pOplock |= CIFS_CREATE_ACTION;
954 /* check to make sure response data is there */
955 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
956 pRetData->Type = cpu_to_le32(-1); /* unknown */
957 cifs_dbg(NOISY, "unknown type\n");
959 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
960 + sizeof(FILE_UNIX_BASIC_INFO)) {
961 cifs_dbg(VFS, "Open response data too small\n");
962 pRetData->Type = cpu_to_le32(-1);
965 memcpy((char *) pRetData,
966 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
967 sizeof(FILE_UNIX_BASIC_INFO));
971 cifs_buf_release(pSMB);
973 if (posix_flags & SMB_O_DIRECTORY)
974 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
976 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
984 static __u16 convert_disposition(int disposition)
988 switch (disposition) {
990 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
993 ofun = SMBOPEN_OAPPEND;
996 ofun = SMBOPEN_OCREATE;
999 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1001 case FILE_OVERWRITE:
1002 ofun = SMBOPEN_OTRUNC;
1004 case FILE_OVERWRITE_IF:
1005 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1008 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1009 ofun = SMBOPEN_OAPPEND; /* regular open */
1015 access_flags_to_smbopen_mode(const int access_flags)
1017 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1019 if (masked_flags == GENERIC_READ)
1020 return SMBOPEN_READ;
1021 else if (masked_flags == GENERIC_WRITE)
1022 return SMBOPEN_WRITE;
1024 /* just go for read/write */
1025 return SMBOPEN_READWRITE;
1029 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1030 const char *fileName, const int openDisposition,
1031 const int access_flags, const int create_options, __u16 *netfid,
1032 int *pOplock, FILE_ALL_INFO *pfile_info,
1033 const struct nls_table *nls_codepage, int remap)
1036 OPENX_REQ *pSMB = NULL;
1037 OPENX_RSP *pSMBr = NULL;
1043 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1048 pSMB->AndXCommand = 0xFF; /* none */
1050 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1051 count = 1; /* account for one byte pad to word boundary */
1053 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1054 fileName, PATH_MAX, nls_codepage, remap);
1055 name_len++; /* trailing null */
1058 count = 0; /* no pad */
1059 name_len = copy_path_name(pSMB->fileName, fileName);
1061 if (*pOplock & REQ_OPLOCK)
1062 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1063 else if (*pOplock & REQ_BATCHOPLOCK)
1064 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1066 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1067 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1068 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1069 /* set file as system file if special file such
1070 as fifo and server expecting SFU style and
1071 no Unix extensions */
1073 if (create_options & CREATE_OPTION_SPECIAL)
1074 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1075 else /* BB FIXME BB */
1076 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1078 if (create_options & CREATE_OPTION_READONLY)
1079 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1082 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1083 CREATE_OPTIONS_MASK); */
1084 /* BB FIXME END BB */
1086 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1087 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1089 inc_rfc1001_len(pSMB, count);
1091 pSMB->ByteCount = cpu_to_le16(count);
1092 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1093 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1094 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1096 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1098 /* BB verify if wct == 15 */
1100 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1102 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1103 /* Let caller know file was created so we can set the mode. */
1104 /* Do we care about the CreateAction in any other cases? */
1106 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1107 *pOplock |= CIFS_CREATE_ACTION; */
1111 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1112 pfile_info->LastAccessTime = 0; /* BB fixme */
1113 pfile_info->LastWriteTime = 0; /* BB fixme */
1114 pfile_info->ChangeTime = 0; /* BB fixme */
1115 pfile_info->Attributes =
1116 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1117 /* the file_info buf is endian converted by caller */
1118 pfile_info->AllocationSize =
1119 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1120 pfile_info->EndOfFile = pfile_info->AllocationSize;
1121 pfile_info->NumberOfLinks = cpu_to_le32(1);
1122 pfile_info->DeletePending = 0;
1126 cifs_buf_release(pSMB);
1133 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1137 OPEN_REQ *req = NULL;
1138 OPEN_RSP *rsp = NULL;
1142 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1143 struct cifs_tcon *tcon = oparms->tcon;
1144 int remap = cifs_remap(cifs_sb);
1145 const struct nls_table *nls = cifs_sb->local_nls;
1146 int create_options = oparms->create_options;
1147 int desired_access = oparms->desired_access;
1148 int disposition = oparms->disposition;
1149 const char *path = oparms->path;
1152 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1157 /* no commands go after this */
1158 req->AndXCommand = 0xFF;
1160 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1161 /* account for one byte pad to word boundary */
1163 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1164 path, PATH_MAX, nls, remap);
1168 req->NameLength = cpu_to_le16(name_len);
1170 /* BB improve check for buffer overruns BB */
1173 name_len = copy_path_name(req->fileName, path);
1174 req->NameLength = cpu_to_le16(name_len);
1177 if (*oplock & REQ_OPLOCK)
1178 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1179 else if (*oplock & REQ_BATCHOPLOCK)
1180 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1182 req->DesiredAccess = cpu_to_le32(desired_access);
1183 req->AllocationSize = 0;
1186 * Set file as system file if special file such as fifo and server
1187 * expecting SFU style and no Unix extensions.
1189 if (create_options & CREATE_OPTION_SPECIAL)
1190 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1192 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1195 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1196 * sensitive checks for other servers such as Samba.
1198 if (tcon->ses->capabilities & CAP_UNIX)
1199 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1201 if (create_options & CREATE_OPTION_READONLY)
1202 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1204 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1205 req->CreateDisposition = cpu_to_le32(disposition);
1206 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1208 /* BB Expirement with various impersonation levels and verify */
1209 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1210 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1213 inc_rfc1001_len(req, count);
1215 req->ByteCount = cpu_to_le16(count);
1216 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1217 (struct smb_hdr *)rsp, &bytes_returned, 0);
1218 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1220 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1221 cifs_buf_release(req);
1227 /* 1 byte no need to le_to_cpu */
1228 *oplock = rsp->OplockLevel;
1229 /* cifs fid stays in le */
1230 oparms->fid->netfid = rsp->Fid;
1231 oparms->fid->access = desired_access;
1233 /* Let caller know file was created so we can set the mode. */
1234 /* Do we care about the CreateAction in any other cases? */
1235 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1236 *oplock |= CIFS_CREATE_ACTION;
1239 /* copy from CreationTime to Attributes */
1240 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1241 /* the file_info buf is endian converted by caller */
1242 buf->AllocationSize = rsp->AllocationSize;
1243 buf->EndOfFile = rsp->EndOfFile;
1244 buf->NumberOfLinks = cpu_to_le32(1);
1245 buf->DeletePending = 0;
1248 cifs_buf_release(req);
1253 cifs_readv_callback(struct mid_q_entry *mid)
1255 struct cifs_readdata *rdata = mid->callback_data;
1256 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1257 struct TCP_Server_Info *server = tcon->ses->server;
1258 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1260 .rq_iter_size = iov_iter_count(&rdata->iter),
1261 .rq_iter = rdata->iter };
1262 struct cifs_credits credits = { .value = 1, .instance = 0 };
1264 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1265 __func__, mid->mid, mid->mid_state, rdata->result,
1268 switch (mid->mid_state) {
1269 case MID_RESPONSE_RECEIVED:
1270 /* result already set, check signature */
1274 rc = cifs_verify_signature(&rqst, server,
1275 mid->sequence_number);
1277 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1280 /* FIXME: should this be counted toward the initiating task? */
1281 task_io_account_read(rdata->got_bytes);
1282 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1284 case MID_REQUEST_SUBMITTED:
1285 case MID_RETRY_NEEDED:
1286 rdata->result = -EAGAIN;
1287 if (server->sign && rdata->got_bytes)
1288 /* reset bytes number since we can not check a sign */
1289 rdata->got_bytes = 0;
1290 /* FIXME: should this be counted toward the initiating task? */
1291 task_io_account_read(rdata->got_bytes);
1292 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1295 rdata->result = -EIO;
1298 queue_work(cifsiod_wq, &rdata->work);
1300 add_credits(server, &credits, 0);
1303 /* cifs_async_readv - send an async write, and set up mid to handle result */
1305 cifs_async_readv(struct cifs_readdata *rdata)
1308 READ_REQ *smb = NULL;
1310 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1311 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1314 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1315 __func__, rdata->offset, rdata->bytes);
1317 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1320 wct = 10; /* old style read */
1321 if ((rdata->offset >> 32) > 0) {
1322 /* can not handle this big offset for old */
1327 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1331 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1332 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1334 smb->AndXCommand = 0xFF; /* none */
1335 smb->Fid = rdata->cfile->fid.netfid;
1336 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1338 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1340 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1341 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1345 /* old style read */
1346 struct smb_com_readx_req *smbr =
1347 (struct smb_com_readx_req *)smb;
1348 smbr->ByteCount = 0;
1351 /* 4 for RFC1001 length + 1 for BCC */
1352 rdata->iov[0].iov_base = smb;
1353 rdata->iov[0].iov_len = 4;
1354 rdata->iov[1].iov_base = (char *)smb + 4;
1355 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1357 kref_get(&rdata->refcount);
1358 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1359 cifs_readv_callback, NULL, rdata, 0, NULL);
1362 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1364 kref_put(&rdata->refcount, cifs_readdata_release);
1366 cifs_small_buf_release(smb);
1371 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1372 unsigned int *nbytes, char **buf, int *pbuf_type)
1375 READ_REQ *pSMB = NULL;
1376 READ_RSP *pSMBr = NULL;
1377 char *pReadData = NULL;
1379 int resp_buf_type = 0;
1381 struct kvec rsp_iov;
1382 __u32 pid = io_parms->pid;
1383 __u16 netfid = io_parms->netfid;
1384 __u64 offset = io_parms->offset;
1385 struct cifs_tcon *tcon = io_parms->tcon;
1386 unsigned int count = io_parms->length;
1388 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1389 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1392 wct = 10; /* old style read */
1393 if ((offset >> 32) > 0) {
1394 /* can not handle this big offset for old */
1400 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1404 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1405 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1407 /* tcon and ses pointer are checked in smb_init */
1408 if (tcon->ses->server == NULL)
1409 return -ECONNABORTED;
1411 pSMB->AndXCommand = 0xFF; /* none */
1413 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1415 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1417 pSMB->Remaining = 0;
1418 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1419 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1421 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1423 /* old style read */
1424 struct smb_com_readx_req *pSMBW =
1425 (struct smb_com_readx_req *)pSMB;
1426 pSMBW->ByteCount = 0;
1429 iov[0].iov_base = (char *)pSMB;
1430 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1431 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1432 CIFS_LOG_ERROR, &rsp_iov);
1433 cifs_small_buf_release(pSMB);
1434 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1435 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1437 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1439 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1440 data_length = data_length << 16;
1441 data_length += le16_to_cpu(pSMBr->DataLength);
1442 *nbytes = data_length;
1444 /*check that DataLength would not go beyond end of SMB */
1445 if ((data_length > CIFSMaxBufSize)
1446 || (data_length > count)) {
1447 cifs_dbg(FYI, "bad length %d for count %d\n",
1448 data_length, count);
1452 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1453 le16_to_cpu(pSMBr->DataOffset);
1454 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1455 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1457 }*/ /* can not use copy_to_user when using page cache*/
1459 memcpy(*buf, pReadData, data_length);
1464 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1465 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1466 /* return buffer to caller to free */
1467 *buf = rsp_iov.iov_base;
1468 if (resp_buf_type == CIFS_SMALL_BUFFER)
1469 *pbuf_type = CIFS_SMALL_BUFFER;
1470 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1471 *pbuf_type = CIFS_LARGE_BUFFER;
1472 } /* else no valid buffer on return - leave as null */
1474 /* Note: On -EAGAIN error only caller can retry on handle based calls
1475 since file handle passed in no longer valid */
1481 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1482 unsigned int *nbytes, const char *buf)
1485 WRITE_REQ *pSMB = NULL;
1486 WRITE_RSP *pSMBr = NULL;
1487 int bytes_returned, wct;
1490 __u32 pid = io_parms->pid;
1491 __u16 netfid = io_parms->netfid;
1492 __u64 offset = io_parms->offset;
1493 struct cifs_tcon *tcon = io_parms->tcon;
1494 unsigned int count = io_parms->length;
1498 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1499 if (tcon->ses == NULL)
1500 return -ECONNABORTED;
1502 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1506 if ((offset >> 32) > 0) {
1507 /* can not handle big offset for old srv */
1512 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1517 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1518 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1520 /* tcon and ses pointer are checked in smb_init */
1521 if (tcon->ses->server == NULL)
1522 return -ECONNABORTED;
1524 pSMB->AndXCommand = 0xFF; /* none */
1526 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1528 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1530 pSMB->Reserved = 0xFFFFFFFF;
1531 pSMB->WriteMode = 0;
1532 pSMB->Remaining = 0;
1534 /* Can increase buffer size if buffer is big enough in some cases ie we
1535 can send more if LARGE_WRITE_X capability returned by the server and if
1536 our buffer is big enough or if we convert to iovecs on socket writes
1537 and eliminate the copy to the CIFS buffer */
1538 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1539 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1541 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1545 if (bytes_sent > count)
1548 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1550 memcpy(pSMB->Data, buf, bytes_sent);
1551 else if (count != 0) {
1553 cifs_buf_release(pSMB);
1555 } /* else setting file size with write of zero bytes */
1557 byte_count = bytes_sent + 1; /* pad */
1558 else /* wct == 12 */
1559 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1561 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1562 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1563 inc_rfc1001_len(pSMB, byte_count);
1566 pSMB->ByteCount = cpu_to_le16(byte_count);
1567 else { /* old style write has byte count 4 bytes earlier
1569 struct smb_com_writex_req *pSMBW =
1570 (struct smb_com_writex_req *)pSMB;
1571 pSMBW->ByteCount = cpu_to_le16(byte_count);
1574 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1575 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1576 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1578 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1580 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1581 *nbytes = (*nbytes) << 16;
1582 *nbytes += le16_to_cpu(pSMBr->Count);
1585 * Mask off high 16 bits when bytes written as returned by the
1586 * server is greater than bytes requested by the client. Some
1587 * OS/2 servers are known to set incorrect CountHigh values.
1589 if (*nbytes > count)
1593 cifs_buf_release(pSMB);
1595 /* Note: On -EAGAIN error only caller can retry on handle based calls
1596 since file handle passed in no longer valid */
1602 * Check the mid_state and signature on received buffer (if any), and queue the
1603 * workqueue completion task.
1606 cifs_writev_callback(struct mid_q_entry *mid)
1608 struct cifs_writedata *wdata = mid->callback_data;
1609 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1610 unsigned int written;
1611 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1612 struct cifs_credits credits = { .value = 1, .instance = 0 };
1614 switch (mid->mid_state) {
1615 case MID_RESPONSE_RECEIVED:
1616 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
1617 if (wdata->result != 0)
1620 written = le16_to_cpu(smb->CountHigh);
1622 written += le16_to_cpu(smb->Count);
1624 * Mask off high 16 bits when bytes written as returned
1625 * by the server is greater than bytes requested by the
1626 * client. OS/2 servers are known to set incorrect
1629 if (written > wdata->bytes)
1632 if (written < wdata->bytes)
1633 wdata->result = -ENOSPC;
1635 wdata->bytes = written;
1637 case MID_REQUEST_SUBMITTED:
1638 case MID_RETRY_NEEDED:
1639 wdata->result = -EAGAIN;
1642 wdata->result = -EIO;
1646 queue_work(cifsiod_wq, &wdata->work);
1648 add_credits(tcon->ses->server, &credits, 0);
1651 /* cifs_async_writev - send an async write, and set up mid to handle result */
1653 cifs_async_writev(struct cifs_writedata *wdata,
1654 void (*release)(struct kref *kref))
1657 WRITE_REQ *smb = NULL;
1659 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1661 struct smb_rqst rqst = { };
1663 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1667 if (wdata->offset >> 32 > 0) {
1668 /* can not handle big offset for old srv */
1673 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
1675 goto async_writev_out;
1677 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
1678 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
1680 smb->AndXCommand = 0xFF; /* none */
1681 smb->Fid = wdata->cfile->fid.netfid;
1682 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
1684 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
1685 smb->Reserved = 0xFFFFFFFF;
1690 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1692 /* 4 for RFC1001 length + 1 for BCC */
1694 iov[0].iov_base = smb;
1695 iov[1].iov_len = get_rfc1002_length(smb) + 1;
1696 iov[1].iov_base = (char *)smb + 4;
1700 rqst.rq_iter = wdata->iter;
1701 rqst.rq_iter_size = iov_iter_count(&wdata->iter);
1703 cifs_dbg(FYI, "async write at %llu %u bytes\n",
1704 wdata->offset, wdata->bytes);
1706 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
1707 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
1710 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
1711 put_bcc(wdata->bytes + 1, &smb->hdr);
1714 struct smb_com_writex_req *smbw =
1715 (struct smb_com_writex_req *)smb;
1716 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
1717 put_bcc(wdata->bytes + 5, &smbw->hdr);
1718 iov[1].iov_len += 4; /* pad bigger by four bytes */
1721 kref_get(&wdata->refcount);
1722 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
1723 cifs_writev_callback, NULL, wdata, 0, NULL);
1726 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1728 kref_put(&wdata->refcount, release);
1731 cifs_small_buf_release(smb);
1736 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
1737 unsigned int *nbytes, struct kvec *iov, int n_vec)
1740 WRITE_REQ *pSMB = NULL;
1743 int resp_buf_type = 0;
1744 __u32 pid = io_parms->pid;
1745 __u16 netfid = io_parms->netfid;
1746 __u64 offset = io_parms->offset;
1747 struct cifs_tcon *tcon = io_parms->tcon;
1748 unsigned int count = io_parms->length;
1749 struct kvec rsp_iov;
1753 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
1755 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1759 if ((offset >> 32) > 0) {
1760 /* can not handle big offset for old srv */
1764 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
1768 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1769 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1771 /* tcon and ses pointer are checked in smb_init */
1772 if (tcon->ses->server == NULL)
1773 return -ECONNABORTED;
1775 pSMB->AndXCommand = 0xFF; /* none */
1777 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1779 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1780 pSMB->Reserved = 0xFFFFFFFF;
1781 pSMB->WriteMode = 0;
1782 pSMB->Remaining = 0;
1785 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1787 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1788 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1789 /* header + 1 byte pad */
1790 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
1792 inc_rfc1001_len(pSMB, count + 1);
1793 else /* wct == 12 */
1794 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
1796 pSMB->ByteCount = cpu_to_le16(count + 1);
1797 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1798 struct smb_com_writex_req *pSMBW =
1799 (struct smb_com_writex_req *)pSMB;
1800 pSMBW->ByteCount = cpu_to_le16(count + 5);
1802 iov[0].iov_base = pSMB;
1804 iov[0].iov_len = smb_hdr_len + 4;
1805 else /* wct == 12 pad bigger by four bytes */
1806 iov[0].iov_len = smb_hdr_len + 8;
1808 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
1810 cifs_small_buf_release(pSMB);
1811 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1813 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
1814 } else if (resp_buf_type == 0) {
1815 /* presumably this can not happen, but best to be safe */
1818 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
1819 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1820 *nbytes = (*nbytes) << 16;
1821 *nbytes += le16_to_cpu(pSMBr->Count);
1824 * Mask off high 16 bits when bytes written as returned by the
1825 * server is greater than bytes requested by the client. OS/2
1826 * servers are known to set incorrect CountHigh values.
1828 if (*nbytes > count)
1832 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1834 /* Note: On -EAGAIN error only caller can retry on handle based calls
1835 since file handle passed in no longer valid */
1840 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
1841 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
1842 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
1845 LOCK_REQ *pSMB = NULL;
1847 struct kvec rsp_iov;
1851 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
1852 num_lock, num_unlock);
1854 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1859 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
1860 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
1861 pSMB->LockType = lock_type;
1862 pSMB->AndXCommand = 0xFF; /* none */
1863 pSMB->Fid = netfid; /* netfid stays le */
1865 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1866 inc_rfc1001_len(pSMB, count);
1867 pSMB->ByteCount = cpu_to_le16(count);
1869 iov[0].iov_base = (char *)pSMB;
1870 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
1871 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1872 iov[1].iov_base = (char *)buf;
1873 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1875 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1876 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
1877 CIFS_NO_RSP_BUF, &rsp_iov);
1878 cifs_small_buf_release(pSMB);
1880 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
1886 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
1887 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
1888 const __u64 offset, const __u32 numUnlock,
1889 const __u32 numLock, const __u8 lockType,
1890 const bool waitFlag, const __u8 oplock_level)
1893 LOCK_REQ *pSMB = NULL;
1894 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
1899 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
1900 (int)waitFlag, numLock);
1901 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1906 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1907 /* no response expected */
1908 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
1910 } else if (waitFlag) {
1911 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1912 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
1917 pSMB->NumberOfLocks = cpu_to_le16(numLock);
1918 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
1919 pSMB->LockType = lockType;
1920 pSMB->OplockLevel = oplock_level;
1921 pSMB->AndXCommand = 0xFF; /* none */
1922 pSMB->Fid = smb_file_id; /* netfid stays le */
1924 if ((numLock != 0) || (numUnlock != 0)) {
1925 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
1926 /* BB where to store pid high? */
1927 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
1928 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
1929 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
1930 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
1931 count = sizeof(LOCKING_ANDX_RANGE);
1936 inc_rfc1001_len(pSMB, count);
1937 pSMB->ByteCount = cpu_to_le16(count);
1940 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1941 (struct smb_hdr *) pSMB, &bytes_returned);
1943 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
1944 cifs_small_buf_release(pSMB);
1945 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1947 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
1949 /* Note: On -EAGAIN error only caller can retry on handle based calls
1950 since file handle passed in no longer valid */
1955 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
1956 const __u16 smb_file_id, const __u32 netpid,
1957 const loff_t start_offset, const __u64 len,
1958 struct file_lock *pLockData, const __u16 lock_type,
1959 const bool waitFlag)
1961 struct smb_com_transaction2_sfi_req *pSMB = NULL;
1962 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
1963 struct cifs_posix_lock *parm_data;
1966 int bytes_returned = 0;
1967 int resp_buf_type = 0;
1968 __u16 params, param_offset, offset, byte_count, count;
1970 struct kvec rsp_iov;
1972 cifs_dbg(FYI, "Posix Lock\n");
1974 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
1979 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
1982 pSMB->MaxSetupCount = 0;
1985 pSMB->Reserved2 = 0;
1986 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
1987 offset = param_offset + params;
1989 count = sizeof(struct cifs_posix_lock);
1990 pSMB->MaxParameterCount = cpu_to_le16(2);
1991 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
1992 pSMB->SetupCount = 1;
1993 pSMB->Reserved3 = 0;
1995 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
1997 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
1998 byte_count = 3 /* pad */ + params + count;
1999 pSMB->DataCount = cpu_to_le16(count);
2000 pSMB->ParameterCount = cpu_to_le16(params);
2001 pSMB->TotalDataCount = pSMB->DataCount;
2002 pSMB->TotalParameterCount = pSMB->ParameterCount;
2003 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2004 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2005 parm_data = (struct cifs_posix_lock *)
2006 (((char *)pSMB) + offset + 4);
2008 parm_data->lock_type = cpu_to_le16(lock_type);
2010 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2011 parm_data->lock_flags = cpu_to_le16(1);
2012 pSMB->Timeout = cpu_to_le32(-1);
2016 parm_data->pid = cpu_to_le32(netpid);
2017 parm_data->start = cpu_to_le64(start_offset);
2018 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2020 pSMB->DataOffset = cpu_to_le16(offset);
2021 pSMB->Fid = smb_file_id;
2022 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2023 pSMB->Reserved4 = 0;
2024 inc_rfc1001_len(pSMB, byte_count);
2025 pSMB->ByteCount = cpu_to_le16(byte_count);
2027 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2028 (struct smb_hdr *) pSMBr, &bytes_returned);
2030 iov[0].iov_base = (char *)pSMB;
2031 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2032 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2033 &resp_buf_type, timeout, &rsp_iov);
2034 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2036 cifs_small_buf_release(pSMB);
2039 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2040 } else if (pLockData) {
2041 /* lock structure can be returned on get */
2044 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2046 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2047 rc = -EIO; /* bad smb */
2050 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2051 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2052 if (data_count < sizeof(struct cifs_posix_lock)) {
2056 parm_data = (struct cifs_posix_lock *)
2057 ((char *)&pSMBr->hdr.Protocol + data_offset);
2058 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2059 pLockData->fl_type = F_UNLCK;
2061 if (parm_data->lock_type ==
2062 cpu_to_le16(CIFS_RDLCK))
2063 pLockData->fl_type = F_RDLCK;
2064 else if (parm_data->lock_type ==
2065 cpu_to_le16(CIFS_WRLCK))
2066 pLockData->fl_type = F_WRLCK;
2068 pLockData->fl_start = le64_to_cpu(parm_data->start);
2069 pLockData->fl_end = pLockData->fl_start +
2070 (le64_to_cpu(parm_data->length) ?
2071 le64_to_cpu(parm_data->length) - 1 : 0);
2072 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2077 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2079 /* Note: On -EAGAIN error only caller can retry on handle based calls
2080 since file handle passed in no longer valid */
2087 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2090 CLOSE_REQ *pSMB = NULL;
2091 cifs_dbg(FYI, "In CIFSSMBClose\n");
2093 /* do not retry on dead session on close */
2094 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2100 pSMB->FileID = (__u16) smb_file_id;
2101 pSMB->LastWriteTime = 0xFFFFFFFF;
2102 pSMB->ByteCount = 0;
2103 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2104 cifs_small_buf_release(pSMB);
2105 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2108 /* EINTR is expected when user ctl-c to kill app */
2109 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2113 /* Since session is dead, file will be closed on server already */
2121 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2124 FLUSH_REQ *pSMB = NULL;
2125 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2127 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2131 pSMB->FileID = (__u16) smb_file_id;
2132 pSMB->ByteCount = 0;
2133 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2134 cifs_small_buf_release(pSMB);
2135 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2137 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2143 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2144 const char *from_name, const char *to_name,
2145 struct cifs_sb_info *cifs_sb)
2148 RENAME_REQ *pSMB = NULL;
2149 RENAME_RSP *pSMBr = NULL;
2151 int name_len, name_len2;
2153 int remap = cifs_remap(cifs_sb);
2155 cifs_dbg(FYI, "In CIFSSMBRename\n");
2157 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2162 pSMB->BufferFormat = 0x04;
2163 pSMB->SearchAttributes =
2164 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2167 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2168 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2169 from_name, PATH_MAX,
2170 cifs_sb->local_nls, remap);
2171 name_len++; /* trailing null */
2173 pSMB->OldFileName[name_len] = 0x04; /* pad */
2174 /* protocol requires ASCII signature byte on Unicode string */
2175 pSMB->OldFileName[name_len + 1] = 0x00;
2177 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2178 to_name, PATH_MAX, cifs_sb->local_nls,
2180 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2181 name_len2 *= 2; /* convert to bytes */
2183 name_len = copy_path_name(pSMB->OldFileName, from_name);
2184 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2185 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2186 name_len2++; /* signature byte */
2189 count = 1 /* 1st signature byte */ + name_len + name_len2;
2190 inc_rfc1001_len(pSMB, count);
2191 pSMB->ByteCount = cpu_to_le16(count);
2193 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2194 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2195 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2197 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2199 cifs_buf_release(pSMB);
2207 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2208 int netfid, const char *target_name,
2209 const struct nls_table *nls_codepage, int remap)
2211 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2212 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2213 struct set_file_rename *rename_info;
2215 char dummy_string[30];
2217 int bytes_returned = 0;
2219 __u16 params, param_offset, offset, count, byte_count;
2221 cifs_dbg(FYI, "Rename to File by handle\n");
2222 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2228 pSMB->MaxSetupCount = 0;
2232 pSMB->Reserved2 = 0;
2233 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2234 offset = param_offset + params;
2236 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2237 data_offset = (char *)(pSMB) + offset + 4;
2238 rename_info = (struct set_file_rename *) data_offset;
2239 pSMB->MaxParameterCount = cpu_to_le16(2);
2240 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2241 pSMB->SetupCount = 1;
2242 pSMB->Reserved3 = 0;
2243 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2244 byte_count = 3 /* pad */ + params;
2245 pSMB->ParameterCount = cpu_to_le16(params);
2246 pSMB->TotalParameterCount = pSMB->ParameterCount;
2247 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2248 pSMB->DataOffset = cpu_to_le16(offset);
2249 /* construct random name ".cifs_tmp<inodenum><mid>" */
2250 rename_info->overwrite = cpu_to_le32(1);
2251 rename_info->root_fid = 0;
2252 /* unicode only call */
2253 if (target_name == NULL) {
2254 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2256 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2257 dummy_string, 24, nls_codepage, remap);
2260 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2261 target_name, PATH_MAX, nls_codepage,
2264 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2265 count = sizeof(struct set_file_rename) + (2 * len_of_str);
2266 byte_count += count;
2267 pSMB->DataCount = cpu_to_le16(count);
2268 pSMB->TotalDataCount = pSMB->DataCount;
2270 pSMB->InformationLevel =
2271 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2272 pSMB->Reserved4 = 0;
2273 inc_rfc1001_len(pSMB, byte_count);
2274 pSMB->ByteCount = cpu_to_le16(byte_count);
2275 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2276 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2277 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2279 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2282 cifs_buf_release(pSMB);
2284 /* Note: On -EAGAIN error only caller can retry on handle based calls
2285 since file handle passed in no longer valid */
2291 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2292 const char *fromName, const __u16 target_tid, const char *toName,
2293 const int flags, const struct nls_table *nls_codepage, int remap)
2296 COPY_REQ *pSMB = NULL;
2297 COPY_RSP *pSMBr = NULL;
2299 int name_len, name_len2;
2302 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2304 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2309 pSMB->BufferFormat = 0x04;
2310 pSMB->Tid2 = target_tid;
2312 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2314 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2315 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2316 fromName, PATH_MAX, nls_codepage,
2318 name_len++; /* trailing null */
2320 pSMB->OldFileName[name_len] = 0x04; /* pad */
2321 /* protocol requires ASCII signature byte on Unicode string */
2322 pSMB->OldFileName[name_len + 1] = 0x00;
2324 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2325 toName, PATH_MAX, nls_codepage, remap);
2326 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2327 name_len2 *= 2; /* convert to bytes */
2329 name_len = copy_path_name(pSMB->OldFileName, fromName);
2330 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2331 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2332 name_len2++; /* signature byte */
2335 count = 1 /* 1st signature byte */ + name_len + name_len2;
2336 inc_rfc1001_len(pSMB, count);
2337 pSMB->ByteCount = cpu_to_le16(count);
2339 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2340 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2342 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2343 rc, le16_to_cpu(pSMBr->CopyCount));
2345 cifs_buf_release(pSMB);
2354 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2355 const char *fromName, const char *toName,
2356 const struct nls_table *nls_codepage, int remap)
2358 TRANSACTION2_SPI_REQ *pSMB = NULL;
2359 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2362 int name_len_target;
2364 int bytes_returned = 0;
2365 __u16 params, param_offset, offset, byte_count;
2367 cifs_dbg(FYI, "In Symlink Unix style\n");
2369 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2374 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2376 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2377 /* find define for this maxpathcomponent */
2378 PATH_MAX, nls_codepage, remap);
2379 name_len++; /* trailing null */
2383 name_len = copy_path_name(pSMB->FileName, fromName);
2385 params = 6 + name_len;
2386 pSMB->MaxSetupCount = 0;
2390 pSMB->Reserved2 = 0;
2391 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2392 InformationLevel) - 4;
2393 offset = param_offset + params;
2395 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2396 data_offset = (char *)pSMB + offset + 4;
2397 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2399 cifsConvertToUTF16((__le16 *) data_offset, toName,
2400 /* find define for this maxpathcomponent */
2401 PATH_MAX, nls_codepage, remap);
2402 name_len_target++; /* trailing null */
2403 name_len_target *= 2;
2405 name_len_target = copy_path_name(data_offset, toName);
2408 pSMB->MaxParameterCount = cpu_to_le16(2);
2409 /* BB find exact max on data count below from sess */
2410 pSMB->MaxDataCount = cpu_to_le16(1000);
2411 pSMB->SetupCount = 1;
2412 pSMB->Reserved3 = 0;
2413 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2414 byte_count = 3 /* pad */ + params + name_len_target;
2415 pSMB->DataCount = cpu_to_le16(name_len_target);
2416 pSMB->ParameterCount = cpu_to_le16(params);
2417 pSMB->TotalDataCount = pSMB->DataCount;
2418 pSMB->TotalParameterCount = pSMB->ParameterCount;
2419 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2420 pSMB->DataOffset = cpu_to_le16(offset);
2421 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2422 pSMB->Reserved4 = 0;
2423 inc_rfc1001_len(pSMB, byte_count);
2424 pSMB->ByteCount = cpu_to_le16(byte_count);
2425 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2426 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2427 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2429 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2432 cifs_buf_release(pSMB);
2435 goto createSymLinkRetry;
2441 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2442 const char *fromName, const char *toName,
2443 const struct nls_table *nls_codepage, int remap)
2445 TRANSACTION2_SPI_REQ *pSMB = NULL;
2446 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2449 int name_len_target;
2451 int bytes_returned = 0;
2452 __u16 params, param_offset, offset, byte_count;
2454 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2455 createHardLinkRetry:
2456 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2461 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2462 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2463 PATH_MAX, nls_codepage, remap);
2464 name_len++; /* trailing null */
2468 name_len = copy_path_name(pSMB->FileName, toName);
2470 params = 6 + name_len;
2471 pSMB->MaxSetupCount = 0;
2475 pSMB->Reserved2 = 0;
2476 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2477 InformationLevel) - 4;
2478 offset = param_offset + params;
2480 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2481 data_offset = (char *)pSMB + offset + 4;
2482 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2484 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2485 PATH_MAX, nls_codepage, remap);
2486 name_len_target++; /* trailing null */
2487 name_len_target *= 2;
2489 name_len_target = copy_path_name(data_offset, fromName);
2492 pSMB->MaxParameterCount = cpu_to_le16(2);
2493 /* BB find exact max on data count below from sess*/
2494 pSMB->MaxDataCount = cpu_to_le16(1000);
2495 pSMB->SetupCount = 1;
2496 pSMB->Reserved3 = 0;
2497 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2498 byte_count = 3 /* pad */ + params + name_len_target;
2499 pSMB->ParameterCount = cpu_to_le16(params);
2500 pSMB->TotalParameterCount = pSMB->ParameterCount;
2501 pSMB->DataCount = cpu_to_le16(name_len_target);
2502 pSMB->TotalDataCount = pSMB->DataCount;
2503 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2504 pSMB->DataOffset = cpu_to_le16(offset);
2505 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2506 pSMB->Reserved4 = 0;
2507 inc_rfc1001_len(pSMB, byte_count);
2508 pSMB->ByteCount = cpu_to_le16(byte_count);
2509 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2510 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2511 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2513 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2516 cifs_buf_release(pSMB);
2518 goto createHardLinkRetry;
2524 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2525 const char *from_name, const char *to_name,
2526 struct cifs_sb_info *cifs_sb)
2529 NT_RENAME_REQ *pSMB = NULL;
2530 RENAME_RSP *pSMBr = NULL;
2532 int name_len, name_len2;
2534 int remap = cifs_remap(cifs_sb);
2536 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2537 winCreateHardLinkRetry:
2539 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2544 pSMB->SearchAttributes =
2545 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2547 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2548 pSMB->ClusterCount = 0;
2550 pSMB->BufferFormat = 0x04;
2552 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2554 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2555 PATH_MAX, cifs_sb->local_nls, remap);
2556 name_len++; /* trailing null */
2559 /* protocol specifies ASCII buffer format (0x04) for unicode */
2560 pSMB->OldFileName[name_len] = 0x04;
2561 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2563 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2564 to_name, PATH_MAX, cifs_sb->local_nls,
2566 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2567 name_len2 *= 2; /* convert to bytes */
2569 name_len = copy_path_name(pSMB->OldFileName, from_name);
2570 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2571 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2572 name_len2++; /* signature byte */
2575 count = 1 /* string type byte */ + name_len + name_len2;
2576 inc_rfc1001_len(pSMB, count);
2577 pSMB->ByteCount = cpu_to_le16(count);
2579 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2580 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2581 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2583 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2585 cifs_buf_release(pSMB);
2587 goto winCreateHardLinkRetry;
2593 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2594 const unsigned char *searchName, char **symlinkinfo,
2595 const struct nls_table *nls_codepage, int remap)
2597 /* SMB_QUERY_FILE_UNIX_LINK */
2598 TRANSACTION2_QPI_REQ *pSMB = NULL;
2599 TRANSACTION2_QPI_RSP *pSMBr = NULL;
2603 __u16 params, byte_count;
2606 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
2609 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2614 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2616 cifsConvertToUTF16((__le16 *) pSMB->FileName,
2617 searchName, PATH_MAX, nls_codepage,
2619 name_len++; /* trailing null */
2622 name_len = copy_path_name(pSMB->FileName, searchName);
2625 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
2626 pSMB->TotalDataCount = 0;
2627 pSMB->MaxParameterCount = cpu_to_le16(2);
2628 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2629 pSMB->MaxSetupCount = 0;
2633 pSMB->Reserved2 = 0;
2634 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2635 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
2636 pSMB->DataCount = 0;
2637 pSMB->DataOffset = 0;
2638 pSMB->SetupCount = 1;
2639 pSMB->Reserved3 = 0;
2640 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2641 byte_count = params + 1 /* pad */ ;
2642 pSMB->TotalParameterCount = cpu_to_le16(params);
2643 pSMB->ParameterCount = pSMB->TotalParameterCount;
2644 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2645 pSMB->Reserved4 = 0;
2646 inc_rfc1001_len(pSMB, byte_count);
2647 pSMB->ByteCount = cpu_to_le16(byte_count);
2649 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2650 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2652 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
2654 /* decode response */
2656 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2657 /* BB also check enough total bytes returned */
2658 if (rc || get_bcc(&pSMBr->hdr) < 2)
2662 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2664 data_start = ((char *) &pSMBr->hdr.Protocol) +
2665 le16_to_cpu(pSMBr->t2.DataOffset);
2667 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2672 /* BB FIXME investigate remapping reserved chars here */
2673 *symlinkinfo = cifs_strndup_from_utf16(data_start,
2674 count, is_unicode, nls_codepage);
2679 cifs_buf_release(pSMB);
2681 goto querySymLinkRetry;
2686 * Recent Windows versions now create symlinks more frequently
2687 * and they use the "reparse point" mechanism below. We can of course
2688 * do symlinks nicely to Samba and other servers which support the
2689 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
2690 * "MF" symlinks optionally, but for recent Windows we really need to
2691 * reenable the code below and fix the cifs_symlink callers to handle this.
2692 * In the interim this code has been moved to its own config option so
2693 * it is not compiled in by default until callers fixed up and more tested.
2696 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2697 __u16 fid, char **symlinkinfo,
2698 const struct nls_table *nls_codepage)
2702 struct smb_com_transaction_ioctl_req *pSMB;
2703 struct smb_com_transaction_ioctl_rsp *pSMBr;
2705 unsigned int sub_len;
2707 struct reparse_symlink_data *reparse_buf;
2708 struct reparse_posix_data *posix_buf;
2709 __u32 data_offset, data_count;
2712 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
2713 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2718 pSMB->TotalParameterCount = 0 ;
2719 pSMB->TotalDataCount = 0;
2720 pSMB->MaxParameterCount = cpu_to_le32(2);
2721 /* BB find exact data count max from sess structure BB */
2722 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
2723 pSMB->MaxSetupCount = 4;
2725 pSMB->ParameterOffset = 0;
2726 pSMB->DataCount = 0;
2727 pSMB->DataOffset = 0;
2728 pSMB->SetupCount = 4;
2729 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2730 pSMB->ParameterCount = pSMB->TotalParameterCount;
2731 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
2732 pSMB->IsFsctl = 1; /* FSCTL */
2733 pSMB->IsRootFlag = 0;
2734 pSMB->Fid = fid; /* file handle always le */
2735 pSMB->ByteCount = 0;
2737 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2738 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2740 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
2744 data_offset = le32_to_cpu(pSMBr->DataOffset);
2745 data_count = le32_to_cpu(pSMBr->DataCount);
2746 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
2747 /* BB also check enough total bytes returned */
2748 rc = -EIO; /* bad smb */
2751 if (!data_count || (data_count > 2048)) {
2753 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
2756 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
2757 reparse_buf = (struct reparse_symlink_data *)
2758 ((char *)&pSMBr->hdr.Protocol + data_offset);
2759 if ((char *)reparse_buf >= end_of_smb) {
2763 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
2764 cifs_dbg(FYI, "NFS style reparse tag\n");
2765 posix_buf = (struct reparse_posix_data *)reparse_buf;
2767 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
2768 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
2769 le64_to_cpu(posix_buf->InodeType));
2774 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
2775 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
2776 cifs_dbg(FYI, "reparse buf beyond SMB\n");
2780 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
2781 sub_len, is_unicode, nls_codepage);
2783 } else if (reparse_buf->ReparseTag !=
2784 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
2789 /* Reparse tag is NTFS symlink */
2790 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
2791 reparse_buf->PathBuffer;
2792 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
2793 if (sub_start + sub_len > end_of_smb) {
2794 cifs_dbg(FYI, "reparse buf beyond SMB\n");
2798 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2803 /* BB FIXME investigate remapping reserved chars here */
2804 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
2809 cifs_buf_release(pSMB);
2812 * Note: On -EAGAIN error only caller can retry on handle based calls
2813 * since file handle passed in no longer valid.
2819 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
2824 struct smb_com_transaction_compr_ioctl_req *pSMB;
2825 struct smb_com_transaction_ioctl_rsp *pSMBr;
2827 cifs_dbg(FYI, "Set compression for %u\n", fid);
2828 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2833 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
2835 pSMB->TotalParameterCount = 0;
2836 pSMB->TotalDataCount = cpu_to_le32(2);
2837 pSMB->MaxParameterCount = 0;
2838 pSMB->MaxDataCount = 0;
2839 pSMB->MaxSetupCount = 4;
2841 pSMB->ParameterOffset = 0;
2842 pSMB->DataCount = cpu_to_le32(2);
2844 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
2845 compression_state) - 4); /* 84 */
2846 pSMB->SetupCount = 4;
2847 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2848 pSMB->ParameterCount = 0;
2849 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
2850 pSMB->IsFsctl = 1; /* FSCTL */
2851 pSMB->IsRootFlag = 0;
2852 pSMB->Fid = fid; /* file handle always le */
2853 /* 3 byte pad, followed by 2 byte compress state */
2854 pSMB->ByteCount = cpu_to_le16(5);
2855 inc_rfc1001_len(pSMB, 5);
2857 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2858 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2860 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
2862 cifs_buf_release(pSMB);
2865 * Note: On -EAGAIN error only caller can retry on handle based calls
2866 * since file handle passed in no longer valid.
2872 #ifdef CONFIG_CIFS_POSIX
2874 #ifdef CONFIG_FS_POSIX_ACL
2876 * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format
2877 * @ace: POSIX ACL entry to store converted ACL into
2878 * @cifs_ace: ACL in cifs format
2880 * Convert an Access Control Entry from wire format to local POSIX xattr
2883 * Note that the @cifs_uid member is used to store both {g,u}id_t.
2885 static void cifs_init_posix_acl(struct posix_acl_entry *ace,
2886 struct cifs_posix_ace *cifs_ace)
2888 /* u8 cifs fields do not need le conversion */
2889 ace->e_perm = cifs_ace->cifs_e_perm;
2890 ace->e_tag = cifs_ace->cifs_e_tag;
2892 switch (ace->e_tag) {
2894 ace->e_uid = make_kuid(&init_user_ns,
2895 le64_to_cpu(cifs_ace->cifs_uid));
2898 ace->e_gid = make_kgid(&init_user_ns,
2899 le64_to_cpu(cifs_ace->cifs_uid));
2906 * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format
2907 * @acl: ACLs returned in POSIX ACL format
2908 * @src: ACLs in cifs format
2909 * @acl_type: type of POSIX ACL requested
2910 * @size_of_data_area: size of SMB we got
2912 * This function converts ACLs from cifs format to POSIX ACL format.
2913 * If @acl is NULL then the size of the buffer required to store POSIX ACLs in
2914 * their uapi format is returned.
2916 static int cifs_to_posix_acl(struct posix_acl **acl, char *src,
2917 const int acl_type, const int size_of_data_area)
2921 struct cifs_posix_ace *pACE;
2922 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
2923 struct posix_acl *kacl = NULL;
2924 struct posix_acl_entry *pa, *pe;
2926 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
2929 if (acl_type == ACL_TYPE_ACCESS) {
2930 count = le16_to_cpu(cifs_acl->access_entry_count);
2931 pACE = &cifs_acl->ace_array[0];
2932 size = sizeof(struct cifs_posix_acl);
2933 size += sizeof(struct cifs_posix_ace) * count;
2934 /* check if we would go beyond end of SMB */
2935 if (size_of_data_area < size) {
2936 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
2937 size_of_data_area, size);
2940 } else if (acl_type == ACL_TYPE_DEFAULT) {
2941 count = le16_to_cpu(cifs_acl->access_entry_count);
2942 size = sizeof(struct cifs_posix_acl);
2943 size += sizeof(struct cifs_posix_ace) * count;
2944 /* skip past access ACEs to get to default ACEs */
2945 pACE = &cifs_acl->ace_array[count];
2946 count = le16_to_cpu(cifs_acl->default_entry_count);
2947 size += sizeof(struct cifs_posix_ace) * count;
2948 /* check if we would go beyond end of SMB */
2949 if (size_of_data_area < size)
2956 /* Allocate number of POSIX ACLs to store in VFS format. */
2957 kacl = posix_acl_alloc(count, GFP_NOFS);
2961 FOREACH_ACL_ENTRY(pa, kacl, pe) {
2962 cifs_init_posix_acl(pa, pACE);
2971 * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format
2972 * @cifs_ace: the cifs ACL entry to store into
2973 * @local_ace: the POSIX ACL entry to convert
2975 static void cifs_init_ace(struct cifs_posix_ace *cifs_ace,
2976 const struct posix_acl_entry *local_ace)
2978 cifs_ace->cifs_e_perm = local_ace->e_perm;
2979 cifs_ace->cifs_e_tag = local_ace->e_tag;
2981 switch (local_ace->e_tag) {
2983 cifs_ace->cifs_uid =
2984 cpu_to_le64(from_kuid(&init_user_ns, local_ace->e_uid));
2987 cifs_ace->cifs_uid =
2988 cpu_to_le64(from_kgid(&init_user_ns, local_ace->e_gid));
2991 cifs_ace->cifs_uid = cpu_to_le64(-1);
2996 * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format
2997 * @parm_data: ACLs in cifs format to conver to
2998 * @acl: ACLs in POSIX ACL format to convert from
2999 * @acl_type: the type of POSIX ACLs stored in @acl
3001 * Return: the number cifs ACL entries after conversion
3003 static __u16 posix_acl_to_cifs(char *parm_data, const struct posix_acl *acl,
3007 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3008 const struct posix_acl_entry *pa, *pe;
3012 if ((acl == NULL) || (cifs_acl == NULL))
3015 count = acl->a_count;
3016 cifs_dbg(FYI, "setting acl with %d entries\n", count);
3019 * Note that the uapi POSIX ACL version is verified by the VFS and is
3020 * independent of the cifs ACL version. Changing the POSIX ACL version
3021 * is a uapi change and if it's changed we will pass down the POSIX ACL
3022 * version in struct posix_acl from the VFS. For now there's really
3023 * only one that all filesystems know how to deal with.
3025 cifs_acl->version = cpu_to_le16(1);
3026 if (acl_type == ACL_TYPE_ACCESS) {
3027 cifs_acl->access_entry_count = cpu_to_le16(count);
3028 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3029 } else if (acl_type == ACL_TYPE_DEFAULT) {
3030 cifs_acl->default_entry_count = cpu_to_le16(count);
3031 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3033 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3036 FOREACH_ACL_ENTRY(pa, acl, pe) {
3037 cifs_init_ace(&cifs_acl->ace_array[i++], pa);
3040 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3041 rc += sizeof(struct cifs_posix_acl);
3042 /* BB add check to make sure ACL does not overflow SMB */
3047 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3048 const unsigned char *searchName, struct posix_acl **acl,
3049 const int acl_type, const struct nls_table *nls_codepage,
3052 /* SMB_QUERY_POSIX_ACL */
3053 TRANSACTION2_QPI_REQ *pSMB = NULL;
3054 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3058 __u16 params, byte_count;
3060 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3063 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3068 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3070 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3071 searchName, PATH_MAX, nls_codepage,
3073 name_len++; /* trailing null */
3075 pSMB->FileName[name_len] = 0;
3076 pSMB->FileName[name_len+1] = 0;
3078 name_len = copy_path_name(pSMB->FileName, searchName);
3081 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3082 pSMB->TotalDataCount = 0;
3083 pSMB->MaxParameterCount = cpu_to_le16(2);
3084 /* BB find exact max data count below from sess structure BB */
3085 pSMB->MaxDataCount = cpu_to_le16(4000);
3086 pSMB->MaxSetupCount = 0;
3090 pSMB->Reserved2 = 0;
3091 pSMB->ParameterOffset = cpu_to_le16(
3092 offsetof(struct smb_com_transaction2_qpi_req,
3093 InformationLevel) - 4);
3094 pSMB->DataCount = 0;
3095 pSMB->DataOffset = 0;
3096 pSMB->SetupCount = 1;
3097 pSMB->Reserved3 = 0;
3098 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3099 byte_count = params + 1 /* pad */ ;
3100 pSMB->TotalParameterCount = cpu_to_le16(params);
3101 pSMB->ParameterCount = pSMB->TotalParameterCount;
3102 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3103 pSMB->Reserved4 = 0;
3104 inc_rfc1001_len(pSMB, byte_count);
3105 pSMB->ByteCount = cpu_to_le16(byte_count);
3107 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3108 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3109 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3111 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3113 /* decode response */
3115 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3116 /* BB also check enough total bytes returned */
3117 if (rc || get_bcc(&pSMBr->hdr) < 2)
3118 rc = -EIO; /* bad smb */
3120 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3121 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3122 rc = cifs_to_posix_acl(acl,
3123 (char *)&pSMBr->hdr.Protocol+data_offset,
3127 cifs_buf_release(pSMB);
3129 * The else branch after SendReceive() doesn't return EAGAIN so if we
3130 * allocated @acl in cifs_to_posix_acl() we are guaranteed to return
3131 * here and don't leak POSIX ACLs.
3138 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3139 const unsigned char *fileName, const struct posix_acl *acl,
3140 const int acl_type, const struct nls_table *nls_codepage,
3143 struct smb_com_transaction2_spi_req *pSMB = NULL;
3144 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3148 int bytes_returned = 0;
3149 __u16 params, byte_count, data_count, param_offset, offset;
3151 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3153 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3157 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3159 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3160 PATH_MAX, nls_codepage, remap);
3161 name_len++; /* trailing null */
3164 name_len = copy_path_name(pSMB->FileName, fileName);
3166 params = 6 + name_len;
3167 pSMB->MaxParameterCount = cpu_to_le16(2);
3168 /* BB find max SMB size from sess */
3169 pSMB->MaxDataCount = cpu_to_le16(1000);
3170 pSMB->MaxSetupCount = 0;
3174 pSMB->Reserved2 = 0;
3175 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3176 InformationLevel) - 4;
3177 offset = param_offset + params;
3178 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3179 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3181 /* convert to on the wire format for POSIX ACL */
3182 data_count = posix_acl_to_cifs(parm_data, acl, acl_type);
3184 if (data_count == 0) {
3186 goto setACLerrorExit;
3188 pSMB->DataOffset = cpu_to_le16(offset);
3189 pSMB->SetupCount = 1;
3190 pSMB->Reserved3 = 0;
3191 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3192 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3193 byte_count = 3 /* pad */ + params + data_count;
3194 pSMB->DataCount = cpu_to_le16(data_count);
3195 pSMB->TotalDataCount = pSMB->DataCount;
3196 pSMB->ParameterCount = cpu_to_le16(params);
3197 pSMB->TotalParameterCount = pSMB->ParameterCount;
3198 pSMB->Reserved4 = 0;
3199 inc_rfc1001_len(pSMB, byte_count);
3200 pSMB->ByteCount = cpu_to_le16(byte_count);
3201 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3202 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3204 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3207 cifs_buf_release(pSMB);
3213 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3214 const unsigned char *searchName, struct posix_acl **acl,
3215 const int acl_type, const struct nls_table *nls_codepage,
3221 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3222 const unsigned char *fileName, const struct posix_acl *acl,
3223 const int acl_type, const struct nls_table *nls_codepage,
3228 #endif /* CONFIG_FS_POSIX_ACL */
3231 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3232 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3235 struct smb_t2_qfi_req *pSMB = NULL;
3236 struct smb_t2_qfi_rsp *pSMBr = NULL;
3238 __u16 params, byte_count;
3240 cifs_dbg(FYI, "In GetExtAttr\n");
3245 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3250 params = 2 /* level */ + 2 /* fid */;
3251 pSMB->t2.TotalDataCount = 0;
3252 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3253 /* BB find exact max data count below from sess structure BB */
3254 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3255 pSMB->t2.MaxSetupCount = 0;
3256 pSMB->t2.Reserved = 0;
3258 pSMB->t2.Timeout = 0;
3259 pSMB->t2.Reserved2 = 0;
3260 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3262 pSMB->t2.DataCount = 0;
3263 pSMB->t2.DataOffset = 0;
3264 pSMB->t2.SetupCount = 1;
3265 pSMB->t2.Reserved3 = 0;
3266 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3267 byte_count = params + 1 /* pad */ ;
3268 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3269 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3270 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3273 inc_rfc1001_len(pSMB, byte_count);
3274 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3276 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3277 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3279 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3281 /* decode response */
3282 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3283 /* BB also check enough total bytes returned */
3284 if (rc || get_bcc(&pSMBr->hdr) < 2)
3285 /* If rc should we check for EOPNOSUPP and
3286 disable the srvino flag? or in caller? */
3287 rc = -EIO; /* bad smb */
3289 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3290 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3291 struct file_chattr_info *pfinfo;
3294 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3298 pfinfo = (struct file_chattr_info *)
3299 (data_offset + (char *) &pSMBr->hdr.Protocol);
3300 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3301 *pMask = le64_to_cpu(pfinfo->mask);
3305 cifs_buf_release(pSMB);
3307 goto GetExtAttrRetry;
3311 #endif /* CONFIG_POSIX */
3314 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3315 * all NT TRANSACTS that we init here have total parm and data under about 400
3316 * bytes (to fit in small cifs buffer size), which is the case so far, it
3317 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3318 * returned setup area) and MaxParameterCount (returned parms size) must be set
3322 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3323 const int parm_len, struct cifs_tcon *tcon,
3328 struct smb_com_ntransact_req *pSMB;
3330 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3334 *ret_buf = (void *)pSMB;
3336 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3337 pSMB->TotalDataCount = 0;
3338 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3339 pSMB->ParameterCount = pSMB->TotalParameterCount;
3340 pSMB->DataCount = pSMB->TotalDataCount;
3341 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3342 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3343 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3344 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3345 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3346 pSMB->SubCommand = cpu_to_le16(sub_command);
3351 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3352 __u32 *pparmlen, __u32 *pdatalen)
3355 __u32 data_count, data_offset, parm_count, parm_offset;
3356 struct smb_com_ntransact_rsp *pSMBr;
3365 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3367 bcc = get_bcc(&pSMBr->hdr);
3368 end_of_smb = 2 /* sizeof byte count */ + bcc +
3369 (char *)&pSMBr->ByteCount;
3371 data_offset = le32_to_cpu(pSMBr->DataOffset);
3372 data_count = le32_to_cpu(pSMBr->DataCount);
3373 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3374 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3376 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3377 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3379 /* should we also check that parm and data areas do not overlap? */
3380 if (*ppparm > end_of_smb) {
3381 cifs_dbg(FYI, "parms start after end of smb\n");
3383 } else if (parm_count + *ppparm > end_of_smb) {
3384 cifs_dbg(FYI, "parm end after end of smb\n");
3386 } else if (*ppdata > end_of_smb) {
3387 cifs_dbg(FYI, "data starts after end of smb\n");
3389 } else if (data_count + *ppdata > end_of_smb) {
3390 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3391 *ppdata, data_count, (data_count + *ppdata),
3394 } else if (parm_count + data_count > bcc) {
3395 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3398 *pdatalen = data_count;
3399 *pparmlen = parm_count;
3403 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3405 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3406 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3410 QUERY_SEC_DESC_REQ *pSMB;
3412 struct kvec rsp_iov;
3414 cifs_dbg(FYI, "GetCifsACL\n");
3419 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3420 8 /* parm len */, tcon, (void **) &pSMB);
3424 pSMB->MaxParameterCount = cpu_to_le32(4);
3425 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3426 pSMB->MaxSetupCount = 0;
3427 pSMB->Fid = fid; /* file handle always le */
3428 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3430 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3431 inc_rfc1001_len(pSMB, 11);
3432 iov[0].iov_base = (char *)pSMB;
3433 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3435 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3437 cifs_small_buf_release(pSMB);
3438 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3440 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3441 } else { /* decode response */
3445 struct smb_com_ntransact_rsp *pSMBr;
3448 /* validate_nttransact */
3449 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3450 &pdata, &parm_len, pbuflen);
3453 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3455 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3456 pSMBr, parm, *acl_inf);
3458 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3459 rc = -EIO; /* bad smb */
3464 /* BB check that data area is minimum length and as big as acl_len */
3466 acl_len = le32_to_cpu(*parm);
3467 if (acl_len != *pbuflen) {
3468 cifs_dbg(VFS, "acl length %d does not match %d\n",
3470 if (*pbuflen > acl_len)
3474 /* check if buffer is big enough for the acl
3475 header followed by the smallest SID */
3476 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3477 (*pbuflen >= 64 * 1024)) {
3478 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3482 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3483 if (*acl_inf == NULL) {
3490 free_rsp_buf(buf_type, rsp_iov.iov_base);
3495 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3496 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3498 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3500 int bytes_returned = 0;
3501 SET_SEC_DESC_REQ *pSMB = NULL;
3505 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3509 pSMB->MaxSetupCount = 0;
3513 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3514 data_count = acllen;
3515 data_offset = param_offset + param_count;
3516 byte_count = 3 /* pad */ + param_count;
3518 pSMB->DataCount = cpu_to_le32(data_count);
3519 pSMB->TotalDataCount = pSMB->DataCount;
3520 pSMB->MaxParameterCount = cpu_to_le32(4);
3521 pSMB->MaxDataCount = cpu_to_le32(16384);
3522 pSMB->ParameterCount = cpu_to_le32(param_count);
3523 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3524 pSMB->TotalParameterCount = pSMB->ParameterCount;
3525 pSMB->DataOffset = cpu_to_le32(data_offset);
3526 pSMB->SetupCount = 0;
3527 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3528 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3530 pSMB->Fid = fid; /* file handle always le */
3531 pSMB->Reserved2 = 0;
3532 pSMB->AclFlags = cpu_to_le32(aclflag);
3534 if (pntsd && acllen) {
3535 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3536 data_offset, pntsd, acllen);
3537 inc_rfc1001_len(pSMB, byte_count + data_count);
3539 inc_rfc1001_len(pSMB, byte_count);
3541 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3542 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3544 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3545 bytes_returned, rc);
3547 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3548 cifs_buf_release(pSMB);
3551 goto setCifsAclRetry;
3557 /* Legacy Query Path Information call for lookup to old servers such
3560 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3561 const char *search_name, FILE_ALL_INFO *data,
3562 const struct nls_table *nls_codepage, int remap)
3564 QUERY_INFORMATION_REQ *pSMB;
3565 QUERY_INFORMATION_RSP *pSMBr;
3570 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3572 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3577 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3579 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3580 search_name, PATH_MAX, nls_codepage,
3582 name_len++; /* trailing null */
3585 name_len = copy_path_name(pSMB->FileName, search_name);
3587 pSMB->BufferFormat = 0x04;
3588 name_len++; /* account for buffer type byte */
3589 inc_rfc1001_len(pSMB, (__u16)name_len);
3590 pSMB->ByteCount = cpu_to_le16(name_len);
3592 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3593 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3595 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3597 struct timespec64 ts;
3598 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3600 /* decode response */
3601 /* BB FIXME - add time zone adjustment BB */
3602 memset(data, 0, sizeof(FILE_ALL_INFO));
3605 /* decode time fields */
3606 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3607 data->LastWriteTime = data->ChangeTime;
3608 data->LastAccessTime = 0;
3609 data->AllocationSize =
3610 cpu_to_le64(le32_to_cpu(pSMBr->size));
3611 data->EndOfFile = data->AllocationSize;
3613 cpu_to_le32(le16_to_cpu(pSMBr->attr));
3615 rc = -EIO; /* bad buffer passed in */
3617 cifs_buf_release(pSMB);
3626 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3627 u16 netfid, FILE_ALL_INFO *pFindData)
3629 struct smb_t2_qfi_req *pSMB = NULL;
3630 struct smb_t2_qfi_rsp *pSMBr = NULL;
3633 __u16 params, byte_count;
3636 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3641 params = 2 /* level */ + 2 /* fid */;
3642 pSMB->t2.TotalDataCount = 0;
3643 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3644 /* BB find exact max data count below from sess structure BB */
3645 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3646 pSMB->t2.MaxSetupCount = 0;
3647 pSMB->t2.Reserved = 0;
3649 pSMB->t2.Timeout = 0;
3650 pSMB->t2.Reserved2 = 0;
3651 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3653 pSMB->t2.DataCount = 0;
3654 pSMB->t2.DataOffset = 0;
3655 pSMB->t2.SetupCount = 1;
3656 pSMB->t2.Reserved3 = 0;
3657 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3658 byte_count = params + 1 /* pad */ ;
3659 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3660 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3661 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3664 inc_rfc1001_len(pSMB, byte_count);
3665 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3667 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3668 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3670 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
3671 } else { /* decode response */
3672 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3674 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3676 else if (get_bcc(&pSMBr->hdr) < 40)
3677 rc = -EIO; /* bad smb */
3678 else if (pFindData) {
3679 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3680 memcpy((char *) pFindData,
3681 (char *) &pSMBr->hdr.Protocol +
3682 data_offset, sizeof(FILE_ALL_INFO));
3686 cifs_buf_release(pSMB);
3688 goto QFileInfoRetry;
3694 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3695 const char *search_name, FILE_ALL_INFO *data,
3696 int legacy /* old style infolevel */,
3697 const struct nls_table *nls_codepage, int remap)
3699 /* level 263 SMB_QUERY_FILE_ALL_INFO */
3700 TRANSACTION2_QPI_REQ *pSMB = NULL;
3701 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3705 __u16 params, byte_count;
3707 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3709 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3714 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3716 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3717 PATH_MAX, nls_codepage, remap);
3718 name_len++; /* trailing null */
3721 name_len = copy_path_name(pSMB->FileName, search_name);
3724 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3725 pSMB->TotalDataCount = 0;
3726 pSMB->MaxParameterCount = cpu_to_le16(2);
3727 /* BB find exact max SMB PDU from sess structure BB */
3728 pSMB->MaxDataCount = cpu_to_le16(4000);
3729 pSMB->MaxSetupCount = 0;
3733 pSMB->Reserved2 = 0;
3734 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3735 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3736 pSMB->DataCount = 0;
3737 pSMB->DataOffset = 0;
3738 pSMB->SetupCount = 1;
3739 pSMB->Reserved3 = 0;
3740 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3741 byte_count = params + 1 /* pad */ ;
3742 pSMB->TotalParameterCount = cpu_to_le16(params);
3743 pSMB->ParameterCount = pSMB->TotalParameterCount;
3745 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3747 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3748 pSMB->Reserved4 = 0;
3749 inc_rfc1001_len(pSMB, byte_count);
3750 pSMB->ByteCount = cpu_to_le16(byte_count);
3752 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3753 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3755 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3756 } else { /* decode response */
3757 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3759 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3761 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3762 rc = -EIO; /* bad smb */
3763 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3764 rc = -EIO; /* 24 or 26 expected but we do not read
3768 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3771 * On legacy responses we do not read the last field,
3772 * EAsize, fortunately since it varies by subdialect and
3773 * also note it differs on Set vs Get, ie two bytes or 4
3774 * bytes depending but we don't care here.
3777 size = sizeof(FILE_INFO_STANDARD);
3779 size = sizeof(FILE_ALL_INFO);
3780 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
3785 cifs_buf_release(pSMB);
3787 goto QPathInfoRetry;
3793 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3794 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3796 struct smb_t2_qfi_req *pSMB = NULL;
3797 struct smb_t2_qfi_rsp *pSMBr = NULL;
3800 __u16 params, byte_count;
3803 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3808 params = 2 /* level */ + 2 /* fid */;
3809 pSMB->t2.TotalDataCount = 0;
3810 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3811 /* BB find exact max data count below from sess structure BB */
3812 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3813 pSMB->t2.MaxSetupCount = 0;
3814 pSMB->t2.Reserved = 0;
3816 pSMB->t2.Timeout = 0;
3817 pSMB->t2.Reserved2 = 0;
3818 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3820 pSMB->t2.DataCount = 0;
3821 pSMB->t2.DataOffset = 0;
3822 pSMB->t2.SetupCount = 1;
3823 pSMB->t2.Reserved3 = 0;
3824 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3825 byte_count = params + 1 /* pad */ ;
3826 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3827 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3828 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3831 inc_rfc1001_len(pSMB, byte_count);
3832 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3834 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3835 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3837 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
3838 } else { /* decode response */
3839 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3841 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3842 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3843 rc = -EIO; /* bad smb */
3845 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3846 memcpy((char *) pFindData,
3847 (char *) &pSMBr->hdr.Protocol +
3849 sizeof(FILE_UNIX_BASIC_INFO));
3853 cifs_buf_release(pSMB);
3855 goto UnixQFileInfoRetry;
3861 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3862 const unsigned char *searchName,
3863 FILE_UNIX_BASIC_INFO *pFindData,
3864 const struct nls_table *nls_codepage, int remap)
3866 /* SMB_QUERY_FILE_UNIX_BASIC */
3867 TRANSACTION2_QPI_REQ *pSMB = NULL;
3868 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3870 int bytes_returned = 0;
3872 __u16 params, byte_count;
3874 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
3876 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3881 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3883 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3884 PATH_MAX, nls_codepage, remap);
3885 name_len++; /* trailing null */
3888 name_len = copy_path_name(pSMB->FileName, searchName);
3891 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3892 pSMB->TotalDataCount = 0;
3893 pSMB->MaxParameterCount = cpu_to_le16(2);
3894 /* BB find exact max SMB PDU from sess structure BB */
3895 pSMB->MaxDataCount = cpu_to_le16(4000);
3896 pSMB->MaxSetupCount = 0;
3900 pSMB->Reserved2 = 0;
3901 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3902 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3903 pSMB->DataCount = 0;
3904 pSMB->DataOffset = 0;
3905 pSMB->SetupCount = 1;
3906 pSMB->Reserved3 = 0;
3907 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3908 byte_count = params + 1 /* pad */ ;
3909 pSMB->TotalParameterCount = cpu_to_le16(params);
3910 pSMB->ParameterCount = pSMB->TotalParameterCount;
3911 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3912 pSMB->Reserved4 = 0;
3913 inc_rfc1001_len(pSMB, byte_count);
3914 pSMB->ByteCount = cpu_to_le16(byte_count);
3916 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3917 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3919 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
3920 } else { /* decode response */
3921 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3923 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3924 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3925 rc = -EIO; /* bad smb */
3927 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3928 memcpy((char *) pFindData,
3929 (char *) &pSMBr->hdr.Protocol +
3931 sizeof(FILE_UNIX_BASIC_INFO));
3934 cifs_buf_release(pSMB);
3936 goto UnixQPathInfoRetry;
3941 /* xid, tcon, searchName and codepage are input parms, rest are returned */
3943 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
3944 const char *searchName, struct cifs_sb_info *cifs_sb,
3945 __u16 *pnetfid, __u16 search_flags,
3946 struct cifs_search_info *psrch_inf, bool msearch)
3948 /* level 257 SMB_ */
3949 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
3950 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
3951 T2_FFIRST_RSP_PARMS *parms;
3953 int bytes_returned = 0;
3954 int name_len, remap;
3955 __u16 params, byte_count;
3956 struct nls_table *nls_codepage;
3958 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
3961 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3966 nls_codepage = cifs_sb->local_nls;
3967 remap = cifs_remap(cifs_sb);
3969 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3971 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3972 PATH_MAX, nls_codepage, remap);
3973 /* We can not add the asterik earlier in case
3974 it got remapped to 0xF03A as if it were part of the
3975 directory name instead of a wildcard */
3978 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
3979 pSMB->FileName[name_len+1] = 0;
3980 pSMB->FileName[name_len+2] = '*';
3981 pSMB->FileName[name_len+3] = 0;
3982 name_len += 4; /* now the trailing null */
3983 /* null terminate just in case */
3984 pSMB->FileName[name_len] = 0;
3985 pSMB->FileName[name_len+1] = 0;
3989 name_len = copy_path_name(pSMB->FileName, searchName);
3991 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
3992 name_len = PATH_MAX-2;
3993 /* overwrite nul byte */
3994 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
3995 pSMB->FileName[name_len] = '*';
3996 pSMB->FileName[name_len+1] = 0;
4001 params = 12 + name_len /* includes null */ ;
4002 pSMB->TotalDataCount = 0; /* no EAs */
4003 pSMB->MaxParameterCount = cpu_to_le16(10);
4004 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4005 pSMB->MaxSetupCount = 0;
4009 pSMB->Reserved2 = 0;
4010 byte_count = params + 1 /* pad */ ;
4011 pSMB->TotalParameterCount = cpu_to_le16(params);
4012 pSMB->ParameterCount = pSMB->TotalParameterCount;
4013 pSMB->ParameterOffset = cpu_to_le16(
4014 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4016 pSMB->DataCount = 0;
4017 pSMB->DataOffset = 0;
4018 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4019 pSMB->Reserved3 = 0;
4020 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4021 pSMB->SearchAttributes =
4022 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4024 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4025 pSMB->SearchFlags = cpu_to_le16(search_flags);
4026 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4028 /* BB what should we set StorageType to? Does it matter? BB */
4029 pSMB->SearchStorageType = 0;
4030 inc_rfc1001_len(pSMB, byte_count);
4031 pSMB->ByteCount = cpu_to_le16(byte_count);
4033 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4034 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4035 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4037 if (rc) {/* BB add logic to retry regular search if Unix search
4038 rejected unexpectedly by server */
4039 /* BB Add code to handle unsupported level rc */
4040 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4042 cifs_buf_release(pSMB);
4044 /* BB eventually could optimize out free and realloc of buf */
4047 goto findFirstRetry;
4048 } else { /* decode response */
4049 /* BB remember to free buffer if error BB */
4050 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4054 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4055 psrch_inf->unicode = true;
4057 psrch_inf->unicode = false;
4059 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4060 psrch_inf->smallBuf = false;
4061 psrch_inf->srch_entries_start =
4062 (char *) &pSMBr->hdr.Protocol +
4063 le16_to_cpu(pSMBr->t2.DataOffset);
4064 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4065 le16_to_cpu(pSMBr->t2.ParameterOffset));
4067 if (parms->EndofSearch)
4068 psrch_inf->endOfSearch = true;
4070 psrch_inf->endOfSearch = false;
4072 psrch_inf->entries_in_buffer =
4073 le16_to_cpu(parms->SearchCount);
4074 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4075 psrch_inf->entries_in_buffer;
4076 lnoff = le16_to_cpu(parms->LastNameOffset);
4077 if (CIFSMaxBufSize < lnoff) {
4078 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4079 psrch_inf->last_entry = NULL;
4083 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4087 *pnetfid = parms->SearchHandle;
4089 cifs_buf_release(pSMB);
4096 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4097 __u16 searchHandle, __u16 search_flags,
4098 struct cifs_search_info *psrch_inf)
4100 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4101 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4102 T2_FNEXT_RSP_PARMS *parms;
4103 char *response_data;
4106 unsigned int name_len;
4107 __u16 params, byte_count;
4109 cifs_dbg(FYI, "In FindNext\n");
4111 if (psrch_inf->endOfSearch)
4114 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4119 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4121 pSMB->TotalDataCount = 0; /* no EAs */
4122 pSMB->MaxParameterCount = cpu_to_le16(8);
4123 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4124 pSMB->MaxSetupCount = 0;
4128 pSMB->Reserved2 = 0;
4129 pSMB->ParameterOffset = cpu_to_le16(
4130 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4131 pSMB->DataCount = 0;
4132 pSMB->DataOffset = 0;
4133 pSMB->SetupCount = 1;
4134 pSMB->Reserved3 = 0;
4135 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4136 pSMB->SearchHandle = searchHandle; /* always kept as le */
4138 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4139 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4140 pSMB->ResumeKey = psrch_inf->resume_key;
4141 pSMB->SearchFlags = cpu_to_le16(search_flags);
4143 name_len = psrch_inf->resume_name_len;
4145 if (name_len < PATH_MAX) {
4146 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4147 byte_count += name_len;
4148 /* 14 byte parm len above enough for 2 byte null terminator */
4149 pSMB->ResumeFileName[name_len] = 0;
4150 pSMB->ResumeFileName[name_len+1] = 0;
4153 goto FNext2_err_exit;
4155 byte_count = params + 1 /* pad */ ;
4156 pSMB->TotalParameterCount = cpu_to_le16(params);
4157 pSMB->ParameterCount = pSMB->TotalParameterCount;
4158 inc_rfc1001_len(pSMB, byte_count);
4159 pSMB->ByteCount = cpu_to_le16(byte_count);
4161 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4162 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4163 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4166 psrch_inf->endOfSearch = true;
4167 cifs_buf_release(pSMB);
4168 rc = 0; /* search probably was closed at end of search*/
4170 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4171 } else { /* decode response */
4172 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4177 /* BB fixme add lock for file (srch_info) struct here */
4178 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4179 psrch_inf->unicode = true;
4181 psrch_inf->unicode = false;
4182 response_data = (char *) &pSMBr->hdr.Protocol +
4183 le16_to_cpu(pSMBr->t2.ParameterOffset);
4184 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4185 response_data = (char *)&pSMBr->hdr.Protocol +
4186 le16_to_cpu(pSMBr->t2.DataOffset);
4187 if (psrch_inf->smallBuf)
4188 cifs_small_buf_release(
4189 psrch_inf->ntwrk_buf_start);
4191 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4192 psrch_inf->srch_entries_start = response_data;
4193 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4194 psrch_inf->smallBuf = false;
4195 if (parms->EndofSearch)
4196 psrch_inf->endOfSearch = true;
4198 psrch_inf->endOfSearch = false;
4199 psrch_inf->entries_in_buffer =
4200 le16_to_cpu(parms->SearchCount);
4201 psrch_inf->index_of_last_entry +=
4202 psrch_inf->entries_in_buffer;
4203 lnoff = le16_to_cpu(parms->LastNameOffset);
4204 if (CIFSMaxBufSize < lnoff) {
4205 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4206 psrch_inf->last_entry = NULL;
4209 psrch_inf->last_entry =
4210 psrch_inf->srch_entries_start + lnoff;
4212 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4213 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4215 /* BB fixme add unlock here */
4220 /* BB On error, should we leave previous search buf (and count and
4221 last entry fields) intact or free the previous one? */
4223 /* Note: On -EAGAIN error only caller can retry on handle based calls
4224 since file handle passed in no longer valid */
4227 cifs_buf_release(pSMB);
4232 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4233 const __u16 searchHandle)
4236 FINDCLOSE_REQ *pSMB = NULL;
4238 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4239 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4241 /* no sense returning error if session restarted
4242 as file handle has been closed */
4248 pSMB->FileID = searchHandle;
4249 pSMB->ByteCount = 0;
4250 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4251 cifs_small_buf_release(pSMB);
4253 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4255 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4257 /* Since session is dead, search handle closed on server already */
4265 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4266 const char *search_name, __u64 *inode_number,
4267 const struct nls_table *nls_codepage, int remap)
4270 TRANSACTION2_QPI_REQ *pSMB = NULL;
4271 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4272 int name_len, bytes_returned;
4273 __u16 params, byte_count;
4275 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4279 GetInodeNumberRetry:
4280 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4285 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4287 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4288 search_name, PATH_MAX, nls_codepage,
4290 name_len++; /* trailing null */
4293 name_len = copy_path_name(pSMB->FileName, search_name);
4296 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4297 pSMB->TotalDataCount = 0;
4298 pSMB->MaxParameterCount = cpu_to_le16(2);
4299 /* BB find exact max data count below from sess structure BB */
4300 pSMB->MaxDataCount = cpu_to_le16(4000);
4301 pSMB->MaxSetupCount = 0;
4305 pSMB->Reserved2 = 0;
4306 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4307 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4308 pSMB->DataCount = 0;
4309 pSMB->DataOffset = 0;
4310 pSMB->SetupCount = 1;
4311 pSMB->Reserved3 = 0;
4312 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4313 byte_count = params + 1 /* pad */ ;
4314 pSMB->TotalParameterCount = cpu_to_le16(params);
4315 pSMB->ParameterCount = pSMB->TotalParameterCount;
4316 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4317 pSMB->Reserved4 = 0;
4318 inc_rfc1001_len(pSMB, byte_count);
4319 pSMB->ByteCount = cpu_to_le16(byte_count);
4321 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4322 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4324 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4326 /* decode response */
4327 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4328 /* BB also check enough total bytes returned */
4329 if (rc || get_bcc(&pSMBr->hdr) < 2)
4330 /* If rc should we check for EOPNOSUPP and
4331 disable the srvino flag? or in caller? */
4332 rc = -EIO; /* bad smb */
4334 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4335 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4336 struct file_internal_info *pfinfo;
4337 /* BB Do we need a cast or hash here ? */
4339 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4341 goto GetInodeNumOut;
4343 pfinfo = (struct file_internal_info *)
4344 (data_offset + (char *) &pSMBr->hdr.Protocol);
4345 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4349 cifs_buf_release(pSMB);
4351 goto GetInodeNumberRetry;
4356 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4357 const char *search_name, struct dfs_info3_param **target_nodes,
4358 unsigned int *num_of_nodes,
4359 const struct nls_table *nls_codepage, int remap)
4361 /* TRANS2_GET_DFS_REFERRAL */
4362 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4363 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4367 __u16 params, byte_count;
4369 *target_nodes = NULL;
4371 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4372 if (ses == NULL || ses->tcon_ipc == NULL)
4376 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4381 /* server pointer checked in called function,
4382 but should never be null here anyway */
4383 pSMB->hdr.Mid = get_next_mid(ses->server);
4384 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4385 pSMB->hdr.Uid = ses->Suid;
4386 if (ses->capabilities & CAP_STATUS32)
4387 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4388 if (ses->capabilities & CAP_DFS)
4389 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4391 if (ses->capabilities & CAP_UNICODE) {
4392 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4394 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4395 search_name, PATH_MAX, nls_codepage,
4397 name_len++; /* trailing null */
4399 } else { /* BB improve the check for buffer overruns BB */
4400 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4403 if (ses->server->sign)
4404 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4406 pSMB->hdr.Uid = ses->Suid;
4408 params = 2 /* level */ + name_len /*includes null */ ;
4409 pSMB->TotalDataCount = 0;
4410 pSMB->DataCount = 0;
4411 pSMB->DataOffset = 0;
4412 pSMB->MaxParameterCount = 0;
4413 /* BB find exact max SMB PDU from sess structure BB */
4414 pSMB->MaxDataCount = cpu_to_le16(4000);
4415 pSMB->MaxSetupCount = 0;
4419 pSMB->Reserved2 = 0;
4420 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4421 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4422 pSMB->SetupCount = 1;
4423 pSMB->Reserved3 = 0;
4424 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4425 byte_count = params + 3 /* pad */ ;
4426 pSMB->ParameterCount = cpu_to_le16(params);
4427 pSMB->TotalParameterCount = pSMB->ParameterCount;
4428 pSMB->MaxReferralLevel = cpu_to_le16(3);
4429 inc_rfc1001_len(pSMB, byte_count);
4430 pSMB->ByteCount = cpu_to_le16(byte_count);
4432 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4433 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4435 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4438 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4440 /* BB Also check if enough total bytes returned? */
4441 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4442 rc = -EIO; /* bad smb */
4446 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4447 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4449 /* parse returned result into more usable form */
4450 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4451 le16_to_cpu(pSMBr->t2.DataCount),
4452 num_of_nodes, target_nodes, nls_codepage,
4454 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4457 cifs_buf_release(pSMB);
4465 /* Query File System Info such as free space to old servers such as Win 9x */
4467 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4468 struct kstatfs *FSData)
4470 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4471 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4472 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4473 FILE_SYSTEM_ALLOC_INFO *response_data;
4475 int bytes_returned = 0;
4476 __u16 params, byte_count;
4478 cifs_dbg(FYI, "OldQFSInfo\n");
4480 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4485 params = 2; /* level */
4486 pSMB->TotalDataCount = 0;
4487 pSMB->MaxParameterCount = cpu_to_le16(2);
4488 pSMB->MaxDataCount = cpu_to_le16(1000);
4489 pSMB->MaxSetupCount = 0;
4493 pSMB->Reserved2 = 0;
4494 byte_count = params + 1 /* pad */ ;
4495 pSMB->TotalParameterCount = cpu_to_le16(params);
4496 pSMB->ParameterCount = pSMB->TotalParameterCount;
4497 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4498 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4499 pSMB->DataCount = 0;
4500 pSMB->DataOffset = 0;
4501 pSMB->SetupCount = 1;
4502 pSMB->Reserved3 = 0;
4503 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4504 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4505 inc_rfc1001_len(pSMB, byte_count);
4506 pSMB->ByteCount = cpu_to_le16(byte_count);
4508 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4509 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4511 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4512 } else { /* decode response */
4513 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4515 if (rc || get_bcc(&pSMBr->hdr) < 18)
4516 rc = -EIO; /* bad smb */
4518 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4519 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4520 get_bcc(&pSMBr->hdr), data_offset);
4522 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4523 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4525 le16_to_cpu(response_data->BytesPerSector) *
4526 le32_to_cpu(response_data->
4527 SectorsPerAllocationUnit);
4529 * much prefer larger but if server doesn't report
4530 * a valid size than 4K is a reasonable minimum
4532 if (FSData->f_bsize < 512)
4533 FSData->f_bsize = 4096;
4536 le32_to_cpu(response_data->TotalAllocationUnits);
4537 FSData->f_bfree = FSData->f_bavail =
4538 le32_to_cpu(response_data->FreeAllocationUnits);
4539 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4540 (unsigned long long)FSData->f_blocks,
4541 (unsigned long long)FSData->f_bfree,
4545 cifs_buf_release(pSMB);
4548 goto oldQFSInfoRetry;
4554 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4555 struct kstatfs *FSData)
4557 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4558 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4559 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4560 FILE_SYSTEM_INFO *response_data;
4562 int bytes_returned = 0;
4563 __u16 params, byte_count;
4565 cifs_dbg(FYI, "In QFSInfo\n");
4567 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4572 params = 2; /* level */
4573 pSMB->TotalDataCount = 0;
4574 pSMB->MaxParameterCount = cpu_to_le16(2);
4575 pSMB->MaxDataCount = cpu_to_le16(1000);
4576 pSMB->MaxSetupCount = 0;
4580 pSMB->Reserved2 = 0;
4581 byte_count = params + 1 /* pad */ ;
4582 pSMB->TotalParameterCount = cpu_to_le16(params);
4583 pSMB->ParameterCount = pSMB->TotalParameterCount;
4584 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4585 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4586 pSMB->DataCount = 0;
4587 pSMB->DataOffset = 0;
4588 pSMB->SetupCount = 1;
4589 pSMB->Reserved3 = 0;
4590 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4591 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4592 inc_rfc1001_len(pSMB, byte_count);
4593 pSMB->ByteCount = cpu_to_le16(byte_count);
4595 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4596 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4598 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4599 } else { /* decode response */
4600 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4602 if (rc || get_bcc(&pSMBr->hdr) < 24)
4603 rc = -EIO; /* bad smb */
4605 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4609 *) (((char *) &pSMBr->hdr.Protocol) +
4612 le32_to_cpu(response_data->BytesPerSector) *
4613 le32_to_cpu(response_data->
4614 SectorsPerAllocationUnit);
4616 * much prefer larger but if server doesn't report
4617 * a valid size than 4K is a reasonable minimum
4619 if (FSData->f_bsize < 512)
4620 FSData->f_bsize = 4096;
4623 le64_to_cpu(response_data->TotalAllocationUnits);
4624 FSData->f_bfree = FSData->f_bavail =
4625 le64_to_cpu(response_data->FreeAllocationUnits);
4626 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4627 (unsigned long long)FSData->f_blocks,
4628 (unsigned long long)FSData->f_bfree,
4632 cifs_buf_release(pSMB);
4641 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
4643 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
4644 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4645 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4646 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
4648 int bytes_returned = 0;
4649 __u16 params, byte_count;
4651 cifs_dbg(FYI, "In QFSAttributeInfo\n");
4653 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4658 params = 2; /* level */
4659 pSMB->TotalDataCount = 0;
4660 pSMB->MaxParameterCount = cpu_to_le16(2);
4661 /* BB find exact max SMB PDU from sess structure BB */
4662 pSMB->MaxDataCount = cpu_to_le16(1000);
4663 pSMB->MaxSetupCount = 0;
4667 pSMB->Reserved2 = 0;
4668 byte_count = params + 1 /* pad */ ;
4669 pSMB->TotalParameterCount = cpu_to_le16(params);
4670 pSMB->ParameterCount = pSMB->TotalParameterCount;
4671 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4672 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4673 pSMB->DataCount = 0;
4674 pSMB->DataOffset = 0;
4675 pSMB->SetupCount = 1;
4676 pSMB->Reserved3 = 0;
4677 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4678 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4679 inc_rfc1001_len(pSMB, byte_count);
4680 pSMB->ByteCount = cpu_to_le16(byte_count);
4682 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4683 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4685 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
4686 } else { /* decode response */
4687 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4689 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4690 /* BB also check if enough bytes returned */
4691 rc = -EIO; /* bad smb */
4693 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4695 (FILE_SYSTEM_ATTRIBUTE_INFO
4696 *) (((char *) &pSMBr->hdr.Protocol) +
4698 memcpy(&tcon->fsAttrInfo, response_data,
4699 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
4702 cifs_buf_release(pSMB);
4705 goto QFSAttributeRetry;
4711 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
4713 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4714 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4715 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4716 FILE_SYSTEM_DEVICE_INFO *response_data;
4718 int bytes_returned = 0;
4719 __u16 params, byte_count;
4721 cifs_dbg(FYI, "In QFSDeviceInfo\n");
4723 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4728 params = 2; /* level */
4729 pSMB->TotalDataCount = 0;
4730 pSMB->MaxParameterCount = cpu_to_le16(2);
4731 /* BB find exact max SMB PDU from sess structure BB */
4732 pSMB->MaxDataCount = cpu_to_le16(1000);
4733 pSMB->MaxSetupCount = 0;
4737 pSMB->Reserved2 = 0;
4738 byte_count = params + 1 /* pad */ ;
4739 pSMB->TotalParameterCount = cpu_to_le16(params);
4740 pSMB->ParameterCount = pSMB->TotalParameterCount;
4741 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4742 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4744 pSMB->DataCount = 0;
4745 pSMB->DataOffset = 0;
4746 pSMB->SetupCount = 1;
4747 pSMB->Reserved3 = 0;
4748 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4749 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4750 inc_rfc1001_len(pSMB, byte_count);
4751 pSMB->ByteCount = cpu_to_le16(byte_count);
4753 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4754 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4756 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
4757 } else { /* decode response */
4758 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4760 if (rc || get_bcc(&pSMBr->hdr) <
4761 sizeof(FILE_SYSTEM_DEVICE_INFO))
4762 rc = -EIO; /* bad smb */
4764 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4766 (FILE_SYSTEM_DEVICE_INFO *)
4767 (((char *) &pSMBr->hdr.Protocol) +
4769 memcpy(&tcon->fsDevInfo, response_data,
4770 sizeof(FILE_SYSTEM_DEVICE_INFO));
4773 cifs_buf_release(pSMB);
4776 goto QFSDeviceRetry;
4782 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
4784 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
4785 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4786 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4787 FILE_SYSTEM_UNIX_INFO *response_data;
4789 int bytes_returned = 0;
4790 __u16 params, byte_count;
4792 cifs_dbg(FYI, "In QFSUnixInfo\n");
4794 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4795 (void **) &pSMB, (void **) &pSMBr);
4799 params = 2; /* level */
4800 pSMB->TotalDataCount = 0;
4801 pSMB->DataCount = 0;
4802 pSMB->DataOffset = 0;
4803 pSMB->MaxParameterCount = cpu_to_le16(2);
4804 /* BB find exact max SMB PDU from sess structure BB */
4805 pSMB->MaxDataCount = cpu_to_le16(100);
4806 pSMB->MaxSetupCount = 0;
4810 pSMB->Reserved2 = 0;
4811 byte_count = params + 1 /* pad */ ;
4812 pSMB->ParameterCount = cpu_to_le16(params);
4813 pSMB->TotalParameterCount = pSMB->ParameterCount;
4814 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4815 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4816 pSMB->SetupCount = 1;
4817 pSMB->Reserved3 = 0;
4818 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4819 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4820 inc_rfc1001_len(pSMB, byte_count);
4821 pSMB->ByteCount = cpu_to_le16(byte_count);
4823 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4824 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4826 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
4827 } else { /* decode response */
4828 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4830 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4831 rc = -EIO; /* bad smb */
4833 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4835 (FILE_SYSTEM_UNIX_INFO
4836 *) (((char *) &pSMBr->hdr.Protocol) +
4838 memcpy(&tcon->fsUnixInfo, response_data,
4839 sizeof(FILE_SYSTEM_UNIX_INFO));
4842 cifs_buf_release(pSMB);
4852 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
4854 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
4855 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
4856 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
4858 int bytes_returned = 0;
4859 __u16 params, param_offset, offset, byte_count;
4861 cifs_dbg(FYI, "In SETFSUnixInfo\n");
4863 /* BB switch to small buf init to save memory */
4864 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4865 (void **) &pSMB, (void **) &pSMBr);
4869 params = 4; /* 2 bytes zero followed by info level. */
4870 pSMB->MaxSetupCount = 0;
4874 pSMB->Reserved2 = 0;
4875 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
4877 offset = param_offset + params;
4879 pSMB->MaxParameterCount = cpu_to_le16(4);
4880 /* BB find exact max SMB PDU from sess structure BB */
4881 pSMB->MaxDataCount = cpu_to_le16(100);
4882 pSMB->SetupCount = 1;
4883 pSMB->Reserved3 = 0;
4884 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
4885 byte_count = 1 /* pad */ + params + 12;
4887 pSMB->DataCount = cpu_to_le16(12);
4888 pSMB->ParameterCount = cpu_to_le16(params);
4889 pSMB->TotalDataCount = pSMB->DataCount;
4890 pSMB->TotalParameterCount = pSMB->ParameterCount;
4891 pSMB->ParameterOffset = cpu_to_le16(param_offset);
4892 pSMB->DataOffset = cpu_to_le16(offset);
4896 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
4899 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
4900 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4901 pSMB->ClientUnixCap = cpu_to_le64(cap);
4903 inc_rfc1001_len(pSMB, byte_count);
4904 pSMB->ByteCount = cpu_to_le16(byte_count);
4906 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4907 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4909 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
4910 } else { /* decode response */
4911 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4913 rc = -EIO; /* bad smb */
4915 cifs_buf_release(pSMB);
4918 goto SETFSUnixRetry;
4926 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
4927 struct kstatfs *FSData)
4929 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
4930 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4931 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4932 FILE_SYSTEM_POSIX_INFO *response_data;
4934 int bytes_returned = 0;
4935 __u16 params, byte_count;
4937 cifs_dbg(FYI, "In QFSPosixInfo\n");
4939 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4944 params = 2; /* level */
4945 pSMB->TotalDataCount = 0;
4946 pSMB->DataCount = 0;
4947 pSMB->DataOffset = 0;
4948 pSMB->MaxParameterCount = cpu_to_le16(2);
4949 /* BB find exact max SMB PDU from sess structure BB */
4950 pSMB->MaxDataCount = cpu_to_le16(100);
4951 pSMB->MaxSetupCount = 0;
4955 pSMB->Reserved2 = 0;
4956 byte_count = params + 1 /* pad */ ;
4957 pSMB->ParameterCount = cpu_to_le16(params);
4958 pSMB->TotalParameterCount = pSMB->ParameterCount;
4959 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4960 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4961 pSMB->SetupCount = 1;
4962 pSMB->Reserved3 = 0;
4963 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4964 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4965 inc_rfc1001_len(pSMB, byte_count);
4966 pSMB->ByteCount = cpu_to_le16(byte_count);
4968 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4969 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4971 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
4972 } else { /* decode response */
4973 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4975 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4976 rc = -EIO; /* bad smb */
4978 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4980 (FILE_SYSTEM_POSIX_INFO
4981 *) (((char *) &pSMBr->hdr.Protocol) +
4984 le32_to_cpu(response_data->BlockSize);
4986 * much prefer larger but if server doesn't report
4987 * a valid size than 4K is a reasonable minimum
4989 if (FSData->f_bsize < 512)
4990 FSData->f_bsize = 4096;
4993 le64_to_cpu(response_data->TotalBlocks);
4995 le64_to_cpu(response_data->BlocksAvail);
4996 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
4997 FSData->f_bavail = FSData->f_bfree;
5000 le64_to_cpu(response_data->UserBlocksAvail);
5002 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5004 le64_to_cpu(response_data->TotalFileNodes);
5005 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5007 le64_to_cpu(response_data->FreeFileNodes);
5010 cifs_buf_release(pSMB);
5020 * We can not use write of zero bytes trick to set file size due to need for
5021 * large file support. Also note that this SetPathInfo is preferred to
5022 * SetFileInfo based method in next routine which is only needed to work around
5023 * a sharing violation bugin Samba which this routine can run into.
5026 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5027 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5028 bool set_allocation)
5030 struct smb_com_transaction2_spi_req *pSMB = NULL;
5031 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5032 struct file_end_of_file_info *parm_data;
5035 int bytes_returned = 0;
5036 int remap = cifs_remap(cifs_sb);
5038 __u16 params, byte_count, data_count, param_offset, offset;
5040 cifs_dbg(FYI, "In SetEOF\n");
5042 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5047 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5049 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5050 PATH_MAX, cifs_sb->local_nls, remap);
5051 name_len++; /* trailing null */
5054 name_len = copy_path_name(pSMB->FileName, file_name);
5056 params = 6 + name_len;
5057 data_count = sizeof(struct file_end_of_file_info);
5058 pSMB->MaxParameterCount = cpu_to_le16(2);
5059 pSMB->MaxDataCount = cpu_to_le16(4100);
5060 pSMB->MaxSetupCount = 0;
5064 pSMB->Reserved2 = 0;
5065 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5066 InformationLevel) - 4;
5067 offset = param_offset + params;
5068 if (set_allocation) {
5069 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5070 pSMB->InformationLevel =
5071 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5073 pSMB->InformationLevel =
5074 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5075 } else /* Set File Size */ {
5076 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5077 pSMB->InformationLevel =
5078 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5080 pSMB->InformationLevel =
5081 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5085 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5087 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5088 pSMB->DataOffset = cpu_to_le16(offset);
5089 pSMB->SetupCount = 1;
5090 pSMB->Reserved3 = 0;
5091 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5092 byte_count = 3 /* pad */ + params + data_count;
5093 pSMB->DataCount = cpu_to_le16(data_count);
5094 pSMB->TotalDataCount = pSMB->DataCount;
5095 pSMB->ParameterCount = cpu_to_le16(params);
5096 pSMB->TotalParameterCount = pSMB->ParameterCount;
5097 pSMB->Reserved4 = 0;
5098 inc_rfc1001_len(pSMB, byte_count);
5099 parm_data->FileSize = cpu_to_le64(size);
5100 pSMB->ByteCount = cpu_to_le16(byte_count);
5101 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5102 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5104 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5106 cifs_buf_release(pSMB);
5115 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5116 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5118 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5119 struct file_end_of_file_info *parm_data;
5121 __u16 params, param_offset, offset, byte_count, count;
5123 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5125 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5130 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5131 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5134 pSMB->MaxSetupCount = 0;
5138 pSMB->Reserved2 = 0;
5139 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5140 offset = param_offset + params;
5142 count = sizeof(struct file_end_of_file_info);
5143 pSMB->MaxParameterCount = cpu_to_le16(2);
5144 /* BB find exact max SMB PDU from sess structure BB */
5145 pSMB->MaxDataCount = cpu_to_le16(1000);
5146 pSMB->SetupCount = 1;
5147 pSMB->Reserved3 = 0;
5148 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5149 byte_count = 3 /* pad */ + params + count;
5150 pSMB->DataCount = cpu_to_le16(count);
5151 pSMB->ParameterCount = cpu_to_le16(params);
5152 pSMB->TotalDataCount = pSMB->DataCount;
5153 pSMB->TotalParameterCount = pSMB->ParameterCount;
5154 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5155 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5157 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5158 pSMB->DataOffset = cpu_to_le16(offset);
5159 parm_data->FileSize = cpu_to_le64(size);
5160 pSMB->Fid = cfile->fid.netfid;
5161 if (set_allocation) {
5162 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5163 pSMB->InformationLevel =
5164 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5166 pSMB->InformationLevel =
5167 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5168 } else /* Set File Size */ {
5169 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5170 pSMB->InformationLevel =
5171 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5173 pSMB->InformationLevel =
5174 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5176 pSMB->Reserved4 = 0;
5177 inc_rfc1001_len(pSMB, byte_count);
5178 pSMB->ByteCount = cpu_to_le16(byte_count);
5179 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5180 cifs_small_buf_release(pSMB);
5182 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5186 /* Note: On -EAGAIN error only caller can retry on handle based calls
5187 since file handle passed in no longer valid */
5192 /* Some legacy servers such as NT4 require that the file times be set on
5193 an open handle, rather than by pathname - this is awkward due to
5194 potential access conflicts on the open, but it is unavoidable for these
5195 old servers since the only other choice is to go from 100 nanosecond DCE
5196 time and resort to the original setpathinfo level which takes the ancient
5197 DOS time format with 2 second granularity */
5199 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5200 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5202 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5205 __u16 params, param_offset, offset, byte_count, count;
5207 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5208 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5213 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5214 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5217 pSMB->MaxSetupCount = 0;
5221 pSMB->Reserved2 = 0;
5222 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5223 offset = param_offset + params;
5225 data_offset = (char *)pSMB +
5226 offsetof(struct smb_hdr, Protocol) + offset;
5228 count = sizeof(FILE_BASIC_INFO);
5229 pSMB->MaxParameterCount = cpu_to_le16(2);
5230 /* BB find max SMB PDU from sess */
5231 pSMB->MaxDataCount = cpu_to_le16(1000);
5232 pSMB->SetupCount = 1;
5233 pSMB->Reserved3 = 0;
5234 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5235 byte_count = 3 /* pad */ + params + count;
5236 pSMB->DataCount = cpu_to_le16(count);
5237 pSMB->ParameterCount = cpu_to_le16(params);
5238 pSMB->TotalDataCount = pSMB->DataCount;
5239 pSMB->TotalParameterCount = pSMB->ParameterCount;
5240 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5241 pSMB->DataOffset = cpu_to_le16(offset);
5243 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5244 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5246 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5247 pSMB->Reserved4 = 0;
5248 inc_rfc1001_len(pSMB, byte_count);
5249 pSMB->ByteCount = cpu_to_le16(byte_count);
5250 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5251 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5252 cifs_small_buf_release(pSMB);
5254 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5257 /* Note: On -EAGAIN error only caller can retry on handle based calls
5258 since file handle passed in no longer valid */
5264 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5265 bool delete_file, __u16 fid, __u32 pid_of_opener)
5267 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5270 __u16 params, param_offset, offset, byte_count, count;
5272 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5273 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5278 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5279 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5282 pSMB->MaxSetupCount = 0;
5286 pSMB->Reserved2 = 0;
5287 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5288 offset = param_offset + params;
5290 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5291 data_offset = (char *)(pSMB) + offset + 4;
5294 pSMB->MaxParameterCount = cpu_to_le16(2);
5295 /* BB find max SMB PDU from sess */
5296 pSMB->MaxDataCount = cpu_to_le16(1000);
5297 pSMB->SetupCount = 1;
5298 pSMB->Reserved3 = 0;
5299 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5300 byte_count = 3 /* pad */ + params + count;
5301 pSMB->DataCount = cpu_to_le16(count);
5302 pSMB->ParameterCount = cpu_to_le16(params);
5303 pSMB->TotalDataCount = pSMB->DataCount;
5304 pSMB->TotalParameterCount = pSMB->ParameterCount;
5305 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5306 pSMB->DataOffset = cpu_to_le16(offset);
5308 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5309 pSMB->Reserved4 = 0;
5310 inc_rfc1001_len(pSMB, byte_count);
5311 pSMB->ByteCount = cpu_to_le16(byte_count);
5312 *data_offset = delete_file ? 1 : 0;
5313 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5314 cifs_small_buf_release(pSMB);
5316 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5322 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5323 const char *fileName, const FILE_BASIC_INFO *data,
5324 const struct nls_table *nls_codepage,
5325 struct cifs_sb_info *cifs_sb)
5328 struct cifs_open_parms oparms;
5329 struct cifs_fid fid;
5332 oparms = (struct cifs_open_parms) {
5335 .desired_access = GENERIC_WRITE,
5336 .create_options = cifs_create_options(cifs_sb, 0),
5337 .disposition = FILE_OPEN,
5342 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5346 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5347 CIFSSMBClose(xid, tcon, fid.netfid);
5354 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5355 const char *fileName, const FILE_BASIC_INFO *data,
5356 const struct nls_table *nls_codepage,
5357 struct cifs_sb_info *cifs_sb)
5359 TRANSACTION2_SPI_REQ *pSMB = NULL;
5360 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5363 int bytes_returned = 0;
5365 __u16 params, param_offset, offset, byte_count, count;
5366 int remap = cifs_remap(cifs_sb);
5368 cifs_dbg(FYI, "In SetTimes\n");
5371 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5376 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5378 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5379 PATH_MAX, nls_codepage, remap);
5380 name_len++; /* trailing null */
5383 name_len = copy_path_name(pSMB->FileName, fileName);
5386 params = 6 + name_len;
5387 count = sizeof(FILE_BASIC_INFO);
5388 pSMB->MaxParameterCount = cpu_to_le16(2);
5389 /* BB find max SMB PDU from sess structure BB */
5390 pSMB->MaxDataCount = cpu_to_le16(1000);
5391 pSMB->MaxSetupCount = 0;
5395 pSMB->Reserved2 = 0;
5396 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5397 InformationLevel) - 4;
5398 offset = param_offset + params;
5399 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5400 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5401 pSMB->DataOffset = cpu_to_le16(offset);
5402 pSMB->SetupCount = 1;
5403 pSMB->Reserved3 = 0;
5404 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5405 byte_count = 3 /* pad */ + params + count;
5407 pSMB->DataCount = cpu_to_le16(count);
5408 pSMB->ParameterCount = cpu_to_le16(params);
5409 pSMB->TotalDataCount = pSMB->DataCount;
5410 pSMB->TotalParameterCount = pSMB->ParameterCount;
5411 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5412 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5414 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5415 pSMB->Reserved4 = 0;
5416 inc_rfc1001_len(pSMB, byte_count);
5417 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5418 pSMB->ByteCount = cpu_to_le16(byte_count);
5419 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5420 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5422 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5424 cifs_buf_release(pSMB);
5429 if (rc == -EOPNOTSUPP)
5430 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5431 nls_codepage, cifs_sb);
5437 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5438 const struct cifs_unix_set_info_args *args)
5440 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5441 u64 mode = args->mode;
5443 if (uid_valid(args->uid))
5444 uid = from_kuid(&init_user_ns, args->uid);
5445 if (gid_valid(args->gid))
5446 gid = from_kgid(&init_user_ns, args->gid);
5449 * Samba server ignores set of file size to zero due to bugs in some
5450 * older clients, but we should be precise - we use SetFileSize to
5451 * set file size and do not want to truncate file size to zero
5452 * accidentally as happened on one Samba server beta by putting
5453 * zero instead of -1 here
5455 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5456 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5457 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5458 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5459 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5460 data_offset->Uid = cpu_to_le64(uid);
5461 data_offset->Gid = cpu_to_le64(gid);
5462 /* better to leave device as zero when it is */
5463 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5464 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5465 data_offset->Permissions = cpu_to_le64(mode);
5468 data_offset->Type = cpu_to_le32(UNIX_FILE);
5469 else if (S_ISDIR(mode))
5470 data_offset->Type = cpu_to_le32(UNIX_DIR);
5471 else if (S_ISLNK(mode))
5472 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5473 else if (S_ISCHR(mode))
5474 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5475 else if (S_ISBLK(mode))
5476 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5477 else if (S_ISFIFO(mode))
5478 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5479 else if (S_ISSOCK(mode))
5480 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5484 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5485 const struct cifs_unix_set_info_args *args,
5486 u16 fid, u32 pid_of_opener)
5488 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5491 u16 params, param_offset, offset, byte_count, count;
5493 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5494 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5499 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5500 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5503 pSMB->MaxSetupCount = 0;
5507 pSMB->Reserved2 = 0;
5508 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5509 offset = param_offset + params;
5511 data_offset = (char *)pSMB +
5512 offsetof(struct smb_hdr, Protocol) + offset;
5514 count = sizeof(FILE_UNIX_BASIC_INFO);
5516 pSMB->MaxParameterCount = cpu_to_le16(2);
5517 /* BB find max SMB PDU from sess */
5518 pSMB->MaxDataCount = cpu_to_le16(1000);
5519 pSMB->SetupCount = 1;
5520 pSMB->Reserved3 = 0;
5521 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5522 byte_count = 3 /* pad */ + params + count;
5523 pSMB->DataCount = cpu_to_le16(count);
5524 pSMB->ParameterCount = cpu_to_le16(params);
5525 pSMB->TotalDataCount = pSMB->DataCount;
5526 pSMB->TotalParameterCount = pSMB->ParameterCount;
5527 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5528 pSMB->DataOffset = cpu_to_le16(offset);
5530 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5531 pSMB->Reserved4 = 0;
5532 inc_rfc1001_len(pSMB, byte_count);
5533 pSMB->ByteCount = cpu_to_le16(byte_count);
5535 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5537 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5538 cifs_small_buf_release(pSMB);
5540 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5543 /* Note: On -EAGAIN error only caller can retry on handle based calls
5544 since file handle passed in no longer valid */
5550 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5551 const char *file_name,
5552 const struct cifs_unix_set_info_args *args,
5553 const struct nls_table *nls_codepage, int remap)
5555 TRANSACTION2_SPI_REQ *pSMB = NULL;
5556 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5559 int bytes_returned = 0;
5560 FILE_UNIX_BASIC_INFO *data_offset;
5561 __u16 params, param_offset, offset, count, byte_count;
5563 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5565 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5570 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5572 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5573 PATH_MAX, nls_codepage, remap);
5574 name_len++; /* trailing null */
5577 name_len = copy_path_name(pSMB->FileName, file_name);
5580 params = 6 + name_len;
5581 count = sizeof(FILE_UNIX_BASIC_INFO);
5582 pSMB->MaxParameterCount = cpu_to_le16(2);
5583 /* BB find max SMB PDU from sess structure BB */
5584 pSMB->MaxDataCount = cpu_to_le16(1000);
5585 pSMB->MaxSetupCount = 0;
5589 pSMB->Reserved2 = 0;
5590 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5591 InformationLevel) - 4;
5592 offset = param_offset + params;
5593 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5594 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
5595 memset(data_offset, 0, count);
5596 pSMB->DataOffset = cpu_to_le16(offset);
5597 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5598 pSMB->SetupCount = 1;
5599 pSMB->Reserved3 = 0;
5600 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5601 byte_count = 3 /* pad */ + params + count;
5602 pSMB->ParameterCount = cpu_to_le16(params);
5603 pSMB->DataCount = cpu_to_le16(count);
5604 pSMB->TotalParameterCount = pSMB->ParameterCount;
5605 pSMB->TotalDataCount = pSMB->DataCount;
5606 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5607 pSMB->Reserved4 = 0;
5608 inc_rfc1001_len(pSMB, byte_count);
5610 cifs_fill_unix_set_info(data_offset, args);
5612 pSMB->ByteCount = cpu_to_le16(byte_count);
5613 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5614 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5616 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
5618 cifs_buf_release(pSMB);
5624 #ifdef CONFIG_CIFS_XATTR
5626 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
5627 * function used by listxattr and getxattr type calls. When ea_name is set,
5628 * it looks for that attribute name and stuffs that value into the EAData
5629 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
5630 * buffer. In both cases, the return value is either the length of the
5631 * resulting data or a negative error code. If EAData is a NULL pointer then
5632 * the data isn't copied to it, but the length is returned.
5635 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
5636 const unsigned char *searchName, const unsigned char *ea_name,
5637 char *EAData, size_t buf_size,
5638 struct cifs_sb_info *cifs_sb)
5640 /* BB assumes one setup word */
5641 TRANSACTION2_QPI_REQ *pSMB = NULL;
5642 TRANSACTION2_QPI_RSP *pSMBr = NULL;
5643 int remap = cifs_remap(cifs_sb);
5644 struct nls_table *nls_codepage = cifs_sb->local_nls;
5648 struct fealist *ea_response_data;
5649 struct fea *temp_fea;
5652 __u16 params, byte_count, data_offset;
5653 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
5655 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
5657 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5662 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5664 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
5665 PATH_MAX, nls_codepage, remap);
5666 list_len++; /* trailing null */
5669 list_len = copy_path_name(pSMB->FileName, searchName);
5672 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
5673 pSMB->TotalDataCount = 0;
5674 pSMB->MaxParameterCount = cpu_to_le16(2);
5675 /* BB find exact max SMB PDU from sess structure BB */
5676 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
5677 pSMB->MaxSetupCount = 0;
5681 pSMB->Reserved2 = 0;
5682 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5683 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5684 pSMB->DataCount = 0;
5685 pSMB->DataOffset = 0;
5686 pSMB->SetupCount = 1;
5687 pSMB->Reserved3 = 0;
5688 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
5689 byte_count = params + 1 /* pad */ ;
5690 pSMB->TotalParameterCount = cpu_to_le16(params);
5691 pSMB->ParameterCount = pSMB->TotalParameterCount;
5692 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5693 pSMB->Reserved4 = 0;
5694 inc_rfc1001_len(pSMB, byte_count);
5695 pSMB->ByteCount = cpu_to_le16(byte_count);
5697 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5698 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5700 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
5705 /* BB also check enough total bytes returned */
5706 /* BB we need to improve the validity checking
5707 of these trans2 responses */
5709 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5710 if (rc || get_bcc(&pSMBr->hdr) < 4) {
5711 rc = -EIO; /* bad smb */
5715 /* check that length of list is not more than bcc */
5716 /* check that each entry does not go beyond length
5718 /* check that each element of each entry does not
5719 go beyond end of list */
5720 /* validate_trans2_offsets() */
5721 /* BB check if start of smb + data_offset > &bcc+ bcc */
5723 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5724 ea_response_data = (struct fealist *)
5725 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5727 list_len = le32_to_cpu(ea_response_data->list_len);
5728 cifs_dbg(FYI, "ea length %d\n", list_len);
5729 if (list_len <= 8) {
5730 cifs_dbg(FYI, "empty EA list returned from server\n");
5731 /* didn't find the named attribute */
5737 /* make sure list_len doesn't go past end of SMB */
5738 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
5739 if ((char *)ea_response_data + list_len > end_of_smb) {
5740 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
5745 /* account for ea list len */
5747 temp_fea = &ea_response_data->list;
5748 temp_ptr = (char *)temp_fea;
5749 while (list_len > 0) {
5750 unsigned int name_len;
5755 /* make sure we can read name_len and value_len */
5757 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5762 name_len = temp_fea->name_len;
5763 value_len = le16_to_cpu(temp_fea->value_len);
5764 list_len -= name_len + 1 + value_len;
5766 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5772 if (ea_name_len == name_len &&
5773 memcmp(ea_name, temp_ptr, name_len) == 0) {
5774 temp_ptr += name_len + 1;
5778 if ((size_t)value_len > buf_size) {
5782 memcpy(EAData, temp_ptr, value_len);
5786 /* account for prefix user. and trailing null */
5787 rc += (5 + 1 + name_len);
5788 if (rc < (int) buf_size) {
5789 memcpy(EAData, "user.", 5);
5791 memcpy(EAData, temp_ptr, name_len);
5793 /* null terminate name */
5796 } else if (buf_size == 0) {
5797 /* skip copy - calc size only */
5799 /* stop before overrun buffer */
5804 temp_ptr += name_len + 1 + value_len;
5805 temp_fea = (struct fea *)temp_ptr;
5808 /* didn't find the named attribute */
5813 cifs_buf_release(pSMB);
5821 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
5822 const char *fileName, const char *ea_name, const void *ea_value,
5823 const __u16 ea_value_len, const struct nls_table *nls_codepage,
5824 struct cifs_sb_info *cifs_sb)
5826 struct smb_com_transaction2_spi_req *pSMB = NULL;
5827 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5828 struct fealist *parm_data;
5831 int bytes_returned = 0;
5832 __u16 params, param_offset, byte_count, offset, count;
5833 int remap = cifs_remap(cifs_sb);
5835 cifs_dbg(FYI, "In SetEA\n");
5837 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5842 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5844 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5845 PATH_MAX, nls_codepage, remap);
5846 name_len++; /* trailing null */
5849 name_len = copy_path_name(pSMB->FileName, fileName);
5852 params = 6 + name_len;
5854 /* done calculating parms using name_len of file name,
5855 now use name_len to calculate length of ea name
5856 we are going to create in the inode xattrs */
5857 if (ea_name == NULL)
5860 name_len = strnlen(ea_name, 255);
5862 count = sizeof(*parm_data) + 1 + ea_value_len + name_len;
5863 pSMB->MaxParameterCount = cpu_to_le16(2);
5864 /* BB find max SMB PDU from sess */
5865 pSMB->MaxDataCount = cpu_to_le16(1000);
5866 pSMB->MaxSetupCount = 0;
5870 pSMB->Reserved2 = 0;
5871 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5872 InformationLevel) - 4;
5873 offset = param_offset + params;
5874 pSMB->InformationLevel =
5875 cpu_to_le16(SMB_SET_FILE_EA);
5877 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
5878 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5879 pSMB->DataOffset = cpu_to_le16(offset);
5880 pSMB->SetupCount = 1;
5881 pSMB->Reserved3 = 0;
5882 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5883 byte_count = 3 /* pad */ + params + count;
5884 pSMB->DataCount = cpu_to_le16(count);
5885 parm_data->list_len = cpu_to_le32(count);
5886 parm_data->list.EA_flags = 0;
5887 /* we checked above that name len is less than 255 */
5888 parm_data->list.name_len = (__u8)name_len;
5889 /* EA names are always ASCII */
5891 strncpy(parm_data->list.name, ea_name, name_len);
5892 parm_data->list.name[name_len] = '\0';
5893 parm_data->list.value_len = cpu_to_le16(ea_value_len);
5894 /* caller ensures that ea_value_len is less than 64K but
5895 we need to ensure that it fits within the smb */
5897 /*BB add length check to see if it would fit in
5898 negotiated SMB buffer size BB */
5899 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
5901 memcpy(parm_data->list.name + name_len + 1,
5902 ea_value, ea_value_len);
5904 pSMB->TotalDataCount = pSMB->DataCount;
5905 pSMB->ParameterCount = cpu_to_le16(params);
5906 pSMB->TotalParameterCount = pSMB->ParameterCount;
5907 pSMB->Reserved4 = 0;
5908 inc_rfc1001_len(pSMB, byte_count);
5909 pSMB->ByteCount = cpu_to_le16(byte_count);
5910 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5911 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5913 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
5915 cifs_buf_release(pSMB);