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 = NULL;
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);
103 rc = cifs_wait_for_server_reconnect(server, tcon->retry);
107 spin_lock(&ses->chan_lock);
108 if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
109 spin_unlock(&ses->chan_lock);
112 spin_unlock(&ses->chan_lock);
114 mutex_lock(&ses->session_mutex);
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);
123 mutex_unlock(&ses->session_mutex);
130 spin_unlock(&server->srv_lock);
132 nls_codepage = load_nls_default();
135 * need to prevent multiple threads trying to simultaneously
136 * reconnect the same SMB session
138 spin_lock(&ses->ses_lock);
139 spin_lock(&ses->chan_lock);
140 if (!cifs_chan_needs_reconnect(ses, server) &&
141 ses->ses_status == SES_GOOD) {
142 spin_unlock(&ses->chan_lock);
143 spin_unlock(&ses->ses_lock);
145 /* this means that we only need to tree connect */
146 if (tcon->need_reconnect)
147 goto skip_sess_setup;
149 mutex_unlock(&ses->session_mutex);
152 spin_unlock(&ses->chan_lock);
153 spin_unlock(&ses->ses_lock);
155 rc = cifs_negotiate_protocol(0, ses, server);
157 rc = cifs_setup_session(0, ses, server, nls_codepage);
159 /* do we need to reconnect tcon? */
160 if (rc || !tcon->need_reconnect) {
161 mutex_unlock(&ses->session_mutex);
166 cifs_mark_open_files_invalid(tcon);
167 rc = cifs_tree_connect(0, tcon, nls_codepage);
168 mutex_unlock(&ses->session_mutex);
169 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
172 pr_warn_once("reconnect tcon failed rc = %d\n", rc);
176 atomic_inc(&tconInfoReconnectCount);
178 /* tell server Unix caps we support */
180 reset_cifs_unix_caps(0, tcon, NULL, NULL);
183 * Removed call to reopen open files here. It is safer (and faster) to
184 * reopen files one at a time as needed in read and write.
186 * FIXME: what about file locks? don't we need to reclaim them ASAP?
191 * Check if handle based operation so we know whether we can continue
192 * or not without returning to caller to reset file handle
194 switch (smb_command) {
195 case SMB_COM_READ_ANDX:
196 case SMB_COM_WRITE_ANDX:
198 case SMB_COM_FIND_CLOSE2:
199 case SMB_COM_LOCKING_ANDX:
203 unload_nls(nls_codepage);
207 /* Allocate and return pointer to an SMB request buffer, and set basic
208 SMB information in the SMB header. If the return code is zero, this
209 function must have filled in request_buf pointer */
211 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
216 rc = cifs_reconnect_tcon(tcon, smb_command);
220 *request_buf = cifs_small_buf_get();
221 if (*request_buf == NULL) {
222 /* BB should we add a retry in here if not a writepage? */
226 header_assemble((struct smb_hdr *) *request_buf, smb_command,
230 cifs_stats_inc(&tcon->num_smbs_sent);
236 small_smb_init_no_tc(const int smb_command, const int wct,
237 struct cifs_ses *ses, void **request_buf)
240 struct smb_hdr *buffer;
242 rc = small_smb_init(smb_command, wct, NULL, request_buf);
246 buffer = (struct smb_hdr *)*request_buf;
247 buffer->Mid = get_next_mid(ses->server);
248 if (ses->capabilities & CAP_UNICODE)
249 buffer->Flags2 |= SMBFLG2_UNICODE;
250 if (ses->capabilities & CAP_STATUS32)
251 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
253 /* uid, tid can stay at zero as set in header assemble */
255 /* BB add support for turning on the signing when
256 this function is used after 1st of session setup requests */
261 /* If the return code is zero, this function must fill in request_buf pointer */
263 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
264 void **request_buf, void **response_buf)
266 *request_buf = cifs_buf_get();
267 if (*request_buf == NULL) {
268 /* BB should we add a retry in here if not a writepage? */
271 /* Although the original thought was we needed the response buf for */
272 /* potential retries of smb operations it turns out we can determine */
273 /* from the mid flags when the request buffer can be resent without */
274 /* having to use a second distinct buffer for the response */
276 *response_buf = *request_buf;
278 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
282 cifs_stats_inc(&tcon->num_smbs_sent);
287 /* If the return code is zero, this function must fill in request_buf pointer */
289 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
290 void **request_buf, void **response_buf)
294 rc = cifs_reconnect_tcon(tcon, smb_command);
298 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
302 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
303 void **request_buf, void **response_buf)
305 spin_lock(&tcon->ses->chan_lock);
306 if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) ||
307 tcon->need_reconnect) {
308 spin_unlock(&tcon->ses->chan_lock);
311 spin_unlock(&tcon->ses->chan_lock);
313 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
316 static int validate_t2(struct smb_t2_rsp *pSMB)
318 unsigned int total_size;
320 /* check for plausible wct */
321 if (pSMB->hdr.WordCount < 10)
324 /* check for parm and data offset going beyond end of smb */
325 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
326 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
329 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
330 if (total_size >= 512)
333 /* check that bcc is at least as big as parms + data, and that it is
334 * less than negotiated smb buffer
336 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
337 if (total_size > get_bcc(&pSMB->hdr) ||
338 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
343 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
344 sizeof(struct smb_t2_rsp) + 16);
349 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
353 char *guid = pSMBr->u.extended_response.GUID;
354 struct TCP_Server_Info *server = ses->server;
356 count = get_bcc(&pSMBr->hdr);
357 if (count < SMB1_CLIENT_GUID_SIZE)
360 spin_lock(&cifs_tcp_ses_lock);
361 if (server->srv_count > 1) {
362 spin_unlock(&cifs_tcp_ses_lock);
363 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
364 cifs_dbg(FYI, "server UID changed\n");
365 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
368 spin_unlock(&cifs_tcp_ses_lock);
369 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
372 if (count == SMB1_CLIENT_GUID_SIZE) {
373 server->sec_ntlmssp = true;
375 count -= SMB1_CLIENT_GUID_SIZE;
376 rc = decode_negTokenInit(
377 pSMBr->u.extended_response.SecurityBlob, count, server);
386 should_set_ext_sec_flag(enum securityEnum sectype)
393 if (global_secflags &
394 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
403 CIFSSMBNegotiate(const unsigned int xid,
404 struct cifs_ses *ses,
405 struct TCP_Server_Info *server)
408 NEGOTIATE_RSP *pSMBr;
415 WARN(1, "%s: server is NULL!\n", __func__);
419 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
420 (void **) &pSMB, (void **) &pSMBr);
424 pSMB->hdr.Mid = get_next_mid(server);
425 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
427 if (should_set_ext_sec_flag(ses->sectype)) {
428 cifs_dbg(FYI, "Requesting extended security\n");
429 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
434 * We know that all the name entries in the protocols array
435 * are short (< 16 bytes anyway) and are NUL terminated.
437 for (i = 0; i < CIFS_NUM_PROT; i++) {
438 size_t len = strlen(protocols[i].name) + 1;
440 memcpy(&pSMB->DialectsArray[count], protocols[i].name, len);
443 inc_rfc1001_len(pSMB, count);
444 pSMB->ByteCount = cpu_to_le16(count);
446 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
447 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
451 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
452 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
453 /* Check wct = 1 error case */
454 if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
455 /* core returns wct = 1, but we do not ask for core - otherwise
456 small wct just comes when dialect index is -1 indicating we
457 could not negotiate a common dialect */
460 } else if (pSMBr->hdr.WordCount != 17) {
465 /* else wct == 17, NTLM or better */
467 server->sec_mode = pSMBr->SecurityMode;
468 if ((server->sec_mode & SECMODE_USER) == 0)
469 cifs_dbg(FYI, "share mode security\n");
471 /* one byte, so no need to convert this or EncryptionKeyLen from
473 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
475 set_credits(server, server->maxReq);
476 /* probably no need to store and check maxvcs */
477 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
478 /* set up max_read for readahead check */
479 server->max_read = server->maxBuf;
480 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
481 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
482 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
483 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
484 server->timeAdj *= 60;
486 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
487 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
488 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
489 CIFS_CRYPTO_KEY_SIZE);
490 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
491 server->capabilities & CAP_EXTENDED_SECURITY) {
492 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
493 rc = decode_ext_sec_blob(ses, pSMBr);
494 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
495 rc = -EIO; /* no crypt key only if plain text pwd */
497 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
498 server->capabilities &= ~CAP_EXTENDED_SECURITY;
502 rc = cifs_enable_signing(server, ses->sign);
504 cifs_buf_release(pSMB);
506 cifs_dbg(FYI, "negprot rc %d\n", rc);
511 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
513 struct smb_hdr *smb_buffer;
516 cifs_dbg(FYI, "In tree disconnect\n");
518 /* BB: do we need to check this? These should never be NULL. */
519 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
523 * No need to return error on this operation if tid invalidated and
524 * closed on server already e.g. due to tcp session crashing. Also,
525 * the tcon is no longer on the list, so no need to take lock before
528 spin_lock(&tcon->ses->chan_lock);
529 if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
530 spin_unlock(&tcon->ses->chan_lock);
533 spin_unlock(&tcon->ses->chan_lock);
535 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
536 (void **)&smb_buffer);
540 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
541 cifs_small_buf_release(smb_buffer);
543 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
545 /* No need to return error on this operation if tid invalidated and
546 closed on server already e.g. due to tcp session crashing */
554 * This is a no-op for now. We're not really interested in the reply, but
555 * rather in the fact that the server sent one and that server->lstrp
558 * FIXME: maybe we should consider checking that the reply matches request?
561 cifs_echo_callback(struct mid_q_entry *mid)
563 struct TCP_Server_Info *server = mid->callback_data;
564 struct cifs_credits credits = { .value = 1, .instance = 0 };
567 add_credits(server, &credits, CIFS_ECHO_OP);
571 CIFSSMBEcho(struct TCP_Server_Info *server)
576 struct smb_rqst rqst = { .rq_iov = iov,
579 cifs_dbg(FYI, "In echo request\n");
581 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
585 if (server->capabilities & CAP_UNICODE)
586 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
588 /* set up echo request */
589 smb->hdr.Tid = 0xffff;
590 smb->hdr.WordCount = 1;
591 put_unaligned_le16(1, &smb->EchoCount);
592 put_bcc(1, &smb->hdr);
594 inc_rfc1001_len(smb, 3);
597 iov[0].iov_base = smb;
598 iov[1].iov_len = get_rfc1002_length(smb);
599 iov[1].iov_base = (char *)smb + 4;
601 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
602 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
604 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
606 cifs_small_buf_release(smb);
612 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
614 LOGOFF_ANDX_REQ *pSMB;
617 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
620 * BB: do we need to check validity of ses and server? They should
621 * always be valid since we have an active reference. If not, that
622 * should probably be a BUG()
624 if (!ses || !ses->server)
627 mutex_lock(&ses->session_mutex);
628 spin_lock(&ses->chan_lock);
629 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
630 spin_unlock(&ses->chan_lock);
631 goto session_already_dead; /* no need to send SMBlogoff if uid
632 already closed due to reconnect */
634 spin_unlock(&ses->chan_lock);
636 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
638 mutex_unlock(&ses->session_mutex);
642 pSMB->hdr.Mid = get_next_mid(ses->server);
644 if (ses->server->sign)
645 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
647 pSMB->hdr.Uid = ses->Suid;
649 pSMB->AndXCommand = 0xFF;
650 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
651 cifs_small_buf_release(pSMB);
652 session_already_dead:
653 mutex_unlock(&ses->session_mutex);
655 /* if session dead then we do not need to do ulogoff,
656 since server closed smb session, no sense reporting
664 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
665 const char *fileName, __u16 type,
666 const struct nls_table *nls_codepage, int remap)
668 TRANSACTION2_SPI_REQ *pSMB = NULL;
669 TRANSACTION2_SPI_RSP *pSMBr = NULL;
670 struct unlink_psx_rq *pRqD;
673 int bytes_returned = 0;
674 __u16 params, param_offset, offset, byte_count;
676 cifs_dbg(FYI, "In POSIX delete\n");
678 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
683 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
685 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
686 PATH_MAX, nls_codepage, remap);
687 name_len++; /* trailing null */
690 name_len = copy_path_name(pSMB->FileName, fileName);
693 params = 6 + name_len;
694 pSMB->MaxParameterCount = cpu_to_le16(2);
695 pSMB->MaxDataCount = 0; /* BB double check this with jra */
696 pSMB->MaxSetupCount = 0;
701 param_offset = offsetof(struct smb_com_transaction2_spi_req,
702 InformationLevel) - 4;
703 offset = param_offset + params;
705 /* Setup pointer to Request Data (inode type).
706 * Note that SMB offsets are from the beginning of SMB which is 4 bytes
707 * in, after RFC1001 field
709 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
710 pRqD->type = cpu_to_le16(type);
711 pSMB->ParameterOffset = cpu_to_le16(param_offset);
712 pSMB->DataOffset = cpu_to_le16(offset);
713 pSMB->SetupCount = 1;
715 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
716 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
718 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
719 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
720 pSMB->ParameterCount = cpu_to_le16(params);
721 pSMB->TotalParameterCount = pSMB->ParameterCount;
722 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
724 inc_rfc1001_len(pSMB, byte_count);
725 pSMB->ByteCount = cpu_to_le16(byte_count);
726 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
727 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
729 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
730 cifs_buf_release(pSMB);
732 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
741 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
742 struct cifs_sb_info *cifs_sb)
744 DELETE_FILE_REQ *pSMB = NULL;
745 DELETE_FILE_RSP *pSMBr = NULL;
749 int remap = cifs_remap(cifs_sb);
752 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
757 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
758 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
759 PATH_MAX, cifs_sb->local_nls,
761 name_len++; /* trailing null */
764 name_len = copy_path_name(pSMB->fileName, name);
766 pSMB->SearchAttributes =
767 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
768 pSMB->BufferFormat = 0x04;
769 inc_rfc1001_len(pSMB, name_len + 1);
770 pSMB->ByteCount = cpu_to_le16(name_len + 1);
771 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
772 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
773 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
775 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
777 cifs_buf_release(pSMB);
785 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
786 struct cifs_sb_info *cifs_sb)
788 DELETE_DIRECTORY_REQ *pSMB = NULL;
789 DELETE_DIRECTORY_RSP *pSMBr = NULL;
793 int remap = cifs_remap(cifs_sb);
795 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
797 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
802 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
803 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
804 PATH_MAX, cifs_sb->local_nls,
806 name_len++; /* trailing null */
809 name_len = copy_path_name(pSMB->DirName, name);
812 pSMB->BufferFormat = 0x04;
813 inc_rfc1001_len(pSMB, name_len + 1);
814 pSMB->ByteCount = cpu_to_le16(name_len + 1);
815 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
816 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
817 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
819 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
821 cifs_buf_release(pSMB);
828 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
829 struct cifs_tcon *tcon, const char *name,
830 struct cifs_sb_info *cifs_sb)
833 CREATE_DIRECTORY_REQ *pSMB = NULL;
834 CREATE_DIRECTORY_RSP *pSMBr = NULL;
837 int remap = cifs_remap(cifs_sb);
839 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
841 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
846 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
847 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
848 PATH_MAX, cifs_sb->local_nls,
850 name_len++; /* trailing null */
853 name_len = copy_path_name(pSMB->DirName, name);
856 pSMB->BufferFormat = 0x04;
857 inc_rfc1001_len(pSMB, name_len + 1);
858 pSMB->ByteCount = cpu_to_le16(name_len + 1);
859 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
860 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
861 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
863 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
865 cifs_buf_release(pSMB);
872 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
873 __u32 posix_flags, __u64 mode, __u16 *netfid,
874 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
875 const char *name, const struct nls_table *nls_codepage,
878 TRANSACTION2_SPI_REQ *pSMB = NULL;
879 TRANSACTION2_SPI_RSP *pSMBr = NULL;
882 int bytes_returned = 0;
883 __u16 params, param_offset, offset, byte_count, count;
885 OPEN_PSX_RSP *psx_rsp;
887 cifs_dbg(FYI, "In POSIX Create\n");
889 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
894 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
896 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
897 PATH_MAX, nls_codepage, remap);
898 name_len++; /* trailing null */
901 name_len = copy_path_name(pSMB->FileName, name);
904 params = 6 + name_len;
905 count = sizeof(OPEN_PSX_REQ);
906 pSMB->MaxParameterCount = cpu_to_le16(2);
907 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
908 pSMB->MaxSetupCount = 0;
913 param_offset = offsetof(struct smb_com_transaction2_spi_req,
914 InformationLevel) - 4;
915 offset = param_offset + params;
916 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
917 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
918 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
919 pdata->Permissions = cpu_to_le64(mode);
920 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
921 pdata->OpenFlags = cpu_to_le32(*pOplock);
922 pSMB->ParameterOffset = cpu_to_le16(param_offset);
923 pSMB->DataOffset = cpu_to_le16(offset);
924 pSMB->SetupCount = 1;
926 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
927 byte_count = 3 /* pad */ + params + count;
929 pSMB->DataCount = cpu_to_le16(count);
930 pSMB->ParameterCount = cpu_to_le16(params);
931 pSMB->TotalDataCount = pSMB->DataCount;
932 pSMB->TotalParameterCount = pSMB->ParameterCount;
933 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
935 inc_rfc1001_len(pSMB, byte_count);
936 pSMB->ByteCount = cpu_to_le16(byte_count);
937 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
938 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
940 cifs_dbg(FYI, "Posix create returned %d\n", rc);
944 cifs_dbg(FYI, "copying inode info\n");
945 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
947 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
948 rc = -EIO; /* bad smb */
952 /* copy return information to pRetData */
953 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
954 + le16_to_cpu(pSMBr->t2.DataOffset));
956 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
958 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
959 /* Let caller know file was created so we can set the mode. */
960 /* Do we care about the CreateAction in any other cases? */
961 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
962 *pOplock |= CIFS_CREATE_ACTION;
963 /* check to make sure response data is there */
964 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
965 pRetData->Type = cpu_to_le32(-1); /* unknown */
966 cifs_dbg(NOISY, "unknown type\n");
968 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
969 + sizeof(FILE_UNIX_BASIC_INFO)) {
970 cifs_dbg(VFS, "Open response data too small\n");
971 pRetData->Type = cpu_to_le32(-1);
974 memcpy((char *) pRetData,
975 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
976 sizeof(FILE_UNIX_BASIC_INFO));
980 cifs_buf_release(pSMB);
982 if (posix_flags & SMB_O_DIRECTORY)
983 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
985 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
993 static __u16 convert_disposition(int disposition)
997 switch (disposition) {
999 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1002 ofun = SMBOPEN_OAPPEND;
1005 ofun = SMBOPEN_OCREATE;
1008 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1010 case FILE_OVERWRITE:
1011 ofun = SMBOPEN_OTRUNC;
1013 case FILE_OVERWRITE_IF:
1014 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1017 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1018 ofun = SMBOPEN_OAPPEND; /* regular open */
1024 access_flags_to_smbopen_mode(const int access_flags)
1026 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1028 if (masked_flags == GENERIC_READ)
1029 return SMBOPEN_READ;
1030 else if (masked_flags == GENERIC_WRITE)
1031 return SMBOPEN_WRITE;
1033 /* just go for read/write */
1034 return SMBOPEN_READWRITE;
1038 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1039 const char *fileName, const int openDisposition,
1040 const int access_flags, const int create_options, __u16 *netfid,
1041 int *pOplock, FILE_ALL_INFO *pfile_info,
1042 const struct nls_table *nls_codepage, int remap)
1045 OPENX_REQ *pSMB = NULL;
1046 OPENX_RSP *pSMBr = NULL;
1052 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1057 pSMB->AndXCommand = 0xFF; /* none */
1059 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1060 count = 1; /* account for one byte pad to word boundary */
1062 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1063 fileName, PATH_MAX, nls_codepage, remap);
1064 name_len++; /* trailing null */
1067 count = 0; /* no pad */
1068 name_len = copy_path_name(pSMB->fileName, fileName);
1070 if (*pOplock & REQ_OPLOCK)
1071 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1072 else if (*pOplock & REQ_BATCHOPLOCK)
1073 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1075 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1076 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1077 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1078 /* set file as system file if special file such
1079 as fifo and server expecting SFU style and
1080 no Unix extensions */
1082 if (create_options & CREATE_OPTION_SPECIAL)
1083 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1084 else /* BB FIXME BB */
1085 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1087 if (create_options & CREATE_OPTION_READONLY)
1088 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1091 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1092 CREATE_OPTIONS_MASK); */
1093 /* BB FIXME END BB */
1095 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1096 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1098 inc_rfc1001_len(pSMB, count);
1100 pSMB->ByteCount = cpu_to_le16(count);
1101 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1102 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1103 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1105 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1107 /* BB verify if wct == 15 */
1109 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1111 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1112 /* Let caller know file was created so we can set the mode. */
1113 /* Do we care about the CreateAction in any other cases? */
1115 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1116 *pOplock |= CIFS_CREATE_ACTION; */
1120 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1121 pfile_info->LastAccessTime = 0; /* BB fixme */
1122 pfile_info->LastWriteTime = 0; /* BB fixme */
1123 pfile_info->ChangeTime = 0; /* BB fixme */
1124 pfile_info->Attributes =
1125 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1126 /* the file_info buf is endian converted by caller */
1127 pfile_info->AllocationSize =
1128 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1129 pfile_info->EndOfFile = pfile_info->AllocationSize;
1130 pfile_info->NumberOfLinks = cpu_to_le32(1);
1131 pfile_info->DeletePending = 0;
1135 cifs_buf_release(pSMB);
1142 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1146 OPEN_REQ *req = NULL;
1147 OPEN_RSP *rsp = NULL;
1151 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1152 struct cifs_tcon *tcon = oparms->tcon;
1153 int remap = cifs_remap(cifs_sb);
1154 const struct nls_table *nls = cifs_sb->local_nls;
1155 int create_options = oparms->create_options;
1156 int desired_access = oparms->desired_access;
1157 int disposition = oparms->disposition;
1158 const char *path = oparms->path;
1161 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1166 /* no commands go after this */
1167 req->AndXCommand = 0xFF;
1169 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1170 /* account for one byte pad to word boundary */
1172 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1173 path, PATH_MAX, nls, remap);
1177 req->NameLength = cpu_to_le16(name_len);
1179 /* BB improve check for buffer overruns BB */
1182 name_len = copy_path_name(req->fileName, path);
1183 req->NameLength = cpu_to_le16(name_len);
1186 if (*oplock & REQ_OPLOCK)
1187 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1188 else if (*oplock & REQ_BATCHOPLOCK)
1189 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1191 req->DesiredAccess = cpu_to_le32(desired_access);
1192 req->AllocationSize = 0;
1195 * Set file as system file if special file such as fifo and server
1196 * expecting SFU style and no Unix extensions.
1198 if (create_options & CREATE_OPTION_SPECIAL)
1199 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1201 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1204 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1205 * sensitive checks for other servers such as Samba.
1207 if (tcon->ses->capabilities & CAP_UNIX)
1208 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1210 if (create_options & CREATE_OPTION_READONLY)
1211 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1213 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1214 req->CreateDisposition = cpu_to_le32(disposition);
1215 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1217 /* BB Expirement with various impersonation levels and verify */
1218 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1219 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1222 inc_rfc1001_len(req, count);
1224 req->ByteCount = cpu_to_le16(count);
1225 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1226 (struct smb_hdr *)rsp, &bytes_returned, 0);
1227 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1229 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1230 cifs_buf_release(req);
1236 /* 1 byte no need to le_to_cpu */
1237 *oplock = rsp->OplockLevel;
1238 /* cifs fid stays in le */
1239 oparms->fid->netfid = rsp->Fid;
1240 oparms->fid->access = desired_access;
1242 /* Let caller know file was created so we can set the mode. */
1243 /* Do we care about the CreateAction in any other cases? */
1244 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1245 *oplock |= CIFS_CREATE_ACTION;
1248 /* copy from CreationTime to Attributes */
1249 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1250 /* the file_info buf is endian converted by caller */
1251 buf->AllocationSize = rsp->AllocationSize;
1252 buf->EndOfFile = rsp->EndOfFile;
1253 buf->NumberOfLinks = cpu_to_le32(1);
1254 buf->DeletePending = 0;
1257 cifs_buf_release(req);
1262 cifs_readv_callback(struct mid_q_entry *mid)
1264 struct cifs_readdata *rdata = mid->callback_data;
1265 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1266 struct TCP_Server_Info *server = tcon->ses->server;
1267 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1269 .rq_iter_size = iov_iter_count(&rdata->iter),
1270 .rq_iter = rdata->iter };
1271 struct cifs_credits credits = { .value = 1, .instance = 0 };
1273 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1274 __func__, mid->mid, mid->mid_state, rdata->result,
1277 switch (mid->mid_state) {
1278 case MID_RESPONSE_RECEIVED:
1279 /* result already set, check signature */
1283 rc = cifs_verify_signature(&rqst, server,
1284 mid->sequence_number);
1286 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1289 /* FIXME: should this be counted toward the initiating task? */
1290 task_io_account_read(rdata->got_bytes);
1291 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1293 case MID_REQUEST_SUBMITTED:
1294 case MID_RETRY_NEEDED:
1295 rdata->result = -EAGAIN;
1296 if (server->sign && rdata->got_bytes)
1297 /* reset bytes number since we can not check a sign */
1298 rdata->got_bytes = 0;
1299 /* FIXME: should this be counted toward the initiating task? */
1300 task_io_account_read(rdata->got_bytes);
1301 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1304 rdata->result = -EIO;
1307 queue_work(cifsiod_wq, &rdata->work);
1309 add_credits(server, &credits, 0);
1312 /* cifs_async_readv - send an async write, and set up mid to handle result */
1314 cifs_async_readv(struct cifs_readdata *rdata)
1317 READ_REQ *smb = NULL;
1319 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1320 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1323 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1324 __func__, rdata->offset, rdata->bytes);
1326 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1329 wct = 10; /* old style read */
1330 if ((rdata->offset >> 32) > 0) {
1331 /* can not handle this big offset for old */
1336 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1340 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1341 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1343 smb->AndXCommand = 0xFF; /* none */
1344 smb->Fid = rdata->cfile->fid.netfid;
1345 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1347 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1349 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1350 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1354 /* old style read */
1355 struct smb_com_readx_req *smbr =
1356 (struct smb_com_readx_req *)smb;
1357 smbr->ByteCount = 0;
1360 /* 4 for RFC1001 length + 1 for BCC */
1361 rdata->iov[0].iov_base = smb;
1362 rdata->iov[0].iov_len = 4;
1363 rdata->iov[1].iov_base = (char *)smb + 4;
1364 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1366 kref_get(&rdata->refcount);
1367 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1368 cifs_readv_callback, NULL, rdata, 0, NULL);
1371 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1373 kref_put(&rdata->refcount, cifs_readdata_release);
1375 cifs_small_buf_release(smb);
1380 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1381 unsigned int *nbytes, char **buf, int *pbuf_type)
1384 READ_REQ *pSMB = NULL;
1385 READ_RSP *pSMBr = NULL;
1386 char *pReadData = NULL;
1388 int resp_buf_type = 0;
1390 struct kvec rsp_iov;
1391 __u32 pid = io_parms->pid;
1392 __u16 netfid = io_parms->netfid;
1393 __u64 offset = io_parms->offset;
1394 struct cifs_tcon *tcon = io_parms->tcon;
1395 unsigned int count = io_parms->length;
1397 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1398 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1401 wct = 10; /* old style read */
1402 if ((offset >> 32) > 0) {
1403 /* can not handle this big offset for old */
1409 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1413 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1414 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1416 /* tcon and ses pointer are checked in smb_init */
1417 if (tcon->ses->server == NULL)
1418 return -ECONNABORTED;
1420 pSMB->AndXCommand = 0xFF; /* none */
1422 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1424 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1426 pSMB->Remaining = 0;
1427 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1428 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1430 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1432 /* old style read */
1433 struct smb_com_readx_req *pSMBW =
1434 (struct smb_com_readx_req *)pSMB;
1435 pSMBW->ByteCount = 0;
1438 iov[0].iov_base = (char *)pSMB;
1439 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1440 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1441 CIFS_LOG_ERROR, &rsp_iov);
1442 cifs_small_buf_release(pSMB);
1443 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1444 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1446 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1448 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1449 data_length = data_length << 16;
1450 data_length += le16_to_cpu(pSMBr->DataLength);
1451 *nbytes = data_length;
1453 /*check that DataLength would not go beyond end of SMB */
1454 if ((data_length > CIFSMaxBufSize)
1455 || (data_length > count)) {
1456 cifs_dbg(FYI, "bad length %d for count %d\n",
1457 data_length, count);
1461 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1462 le16_to_cpu(pSMBr->DataOffset);
1463 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1464 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1466 }*/ /* can not use copy_to_user when using page cache*/
1468 memcpy(*buf, pReadData, data_length);
1473 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1474 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1475 /* return buffer to caller to free */
1476 *buf = rsp_iov.iov_base;
1477 if (resp_buf_type == CIFS_SMALL_BUFFER)
1478 *pbuf_type = CIFS_SMALL_BUFFER;
1479 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1480 *pbuf_type = CIFS_LARGE_BUFFER;
1481 } /* else no valid buffer on return - leave as null */
1483 /* Note: On -EAGAIN error only caller can retry on handle based calls
1484 since file handle passed in no longer valid */
1490 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1491 unsigned int *nbytes, const char *buf)
1494 WRITE_REQ *pSMB = NULL;
1495 WRITE_RSP *pSMBr = NULL;
1496 int bytes_returned, wct;
1499 __u32 pid = io_parms->pid;
1500 __u16 netfid = io_parms->netfid;
1501 __u64 offset = io_parms->offset;
1502 struct cifs_tcon *tcon = io_parms->tcon;
1503 unsigned int count = io_parms->length;
1507 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1508 if (tcon->ses == NULL)
1509 return -ECONNABORTED;
1511 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1515 if ((offset >> 32) > 0) {
1516 /* can not handle big offset for old srv */
1521 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1526 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1527 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1529 /* tcon and ses pointer are checked in smb_init */
1530 if (tcon->ses->server == NULL)
1531 return -ECONNABORTED;
1533 pSMB->AndXCommand = 0xFF; /* none */
1535 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1537 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1539 pSMB->Reserved = 0xFFFFFFFF;
1540 pSMB->WriteMode = 0;
1541 pSMB->Remaining = 0;
1543 /* Can increase buffer size if buffer is big enough in some cases ie we
1544 can send more if LARGE_WRITE_X capability returned by the server and if
1545 our buffer is big enough or if we convert to iovecs on socket writes
1546 and eliminate the copy to the CIFS buffer */
1547 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1548 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1550 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1554 if (bytes_sent > count)
1557 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1559 memcpy(pSMB->Data, buf, bytes_sent);
1560 else if (count != 0) {
1562 cifs_buf_release(pSMB);
1564 } /* else setting file size with write of zero bytes */
1566 byte_count = bytes_sent + 1; /* pad */
1567 else /* wct == 12 */
1568 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1570 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1571 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1572 inc_rfc1001_len(pSMB, byte_count);
1575 pSMB->ByteCount = cpu_to_le16(byte_count);
1576 else { /* old style write has byte count 4 bytes earlier
1578 struct smb_com_writex_req *pSMBW =
1579 (struct smb_com_writex_req *)pSMB;
1580 pSMBW->ByteCount = cpu_to_le16(byte_count);
1583 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1584 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1585 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1587 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1589 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1590 *nbytes = (*nbytes) << 16;
1591 *nbytes += le16_to_cpu(pSMBr->Count);
1594 * Mask off high 16 bits when bytes written as returned by the
1595 * server is greater than bytes requested by the client. Some
1596 * OS/2 servers are known to set incorrect CountHigh values.
1598 if (*nbytes > count)
1602 cifs_buf_release(pSMB);
1604 /* Note: On -EAGAIN error only caller can retry on handle based calls
1605 since file handle passed in no longer valid */
1611 * Check the mid_state and signature on received buffer (if any), and queue the
1612 * workqueue completion task.
1615 cifs_writev_callback(struct mid_q_entry *mid)
1617 struct cifs_writedata *wdata = mid->callback_data;
1618 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1619 unsigned int written;
1620 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1621 struct cifs_credits credits = { .value = 1, .instance = 0 };
1623 switch (mid->mid_state) {
1624 case MID_RESPONSE_RECEIVED:
1625 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
1626 if (wdata->result != 0)
1629 written = le16_to_cpu(smb->CountHigh);
1631 written += le16_to_cpu(smb->Count);
1633 * Mask off high 16 bits when bytes written as returned
1634 * by the server is greater than bytes requested by the
1635 * client. OS/2 servers are known to set incorrect
1638 if (written > wdata->bytes)
1641 if (written < wdata->bytes)
1642 wdata->result = -ENOSPC;
1644 wdata->bytes = written;
1646 case MID_REQUEST_SUBMITTED:
1647 case MID_RETRY_NEEDED:
1648 wdata->result = -EAGAIN;
1651 wdata->result = -EIO;
1655 queue_work(cifsiod_wq, &wdata->work);
1657 add_credits(tcon->ses->server, &credits, 0);
1660 /* cifs_async_writev - send an async write, and set up mid to handle result */
1662 cifs_async_writev(struct cifs_writedata *wdata,
1663 void (*release)(struct kref *kref))
1666 WRITE_REQ *smb = NULL;
1668 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1670 struct smb_rqst rqst = { };
1672 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1676 if (wdata->offset >> 32 > 0) {
1677 /* can not handle big offset for old srv */
1682 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
1684 goto async_writev_out;
1686 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
1687 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
1689 smb->AndXCommand = 0xFF; /* none */
1690 smb->Fid = wdata->cfile->fid.netfid;
1691 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
1693 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
1694 smb->Reserved = 0xFFFFFFFF;
1699 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1701 /* 4 for RFC1001 length + 1 for BCC */
1703 iov[0].iov_base = smb;
1704 iov[1].iov_len = get_rfc1002_length(smb) + 1;
1705 iov[1].iov_base = (char *)smb + 4;
1709 rqst.rq_iter = wdata->iter;
1710 rqst.rq_iter_size = iov_iter_count(&wdata->iter);
1712 cifs_dbg(FYI, "async write at %llu %u bytes\n",
1713 wdata->offset, wdata->bytes);
1715 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
1716 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
1719 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
1720 put_bcc(wdata->bytes + 1, &smb->hdr);
1723 struct smb_com_writex_req *smbw =
1724 (struct smb_com_writex_req *)smb;
1725 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
1726 put_bcc(wdata->bytes + 5, &smbw->hdr);
1727 iov[1].iov_len += 4; /* pad bigger by four bytes */
1730 kref_get(&wdata->refcount);
1731 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
1732 cifs_writev_callback, NULL, wdata, 0, NULL);
1735 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1737 kref_put(&wdata->refcount, release);
1740 cifs_small_buf_release(smb);
1745 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
1746 unsigned int *nbytes, struct kvec *iov, int n_vec)
1749 WRITE_REQ *pSMB = NULL;
1752 int resp_buf_type = 0;
1753 __u32 pid = io_parms->pid;
1754 __u16 netfid = io_parms->netfid;
1755 __u64 offset = io_parms->offset;
1756 struct cifs_tcon *tcon = io_parms->tcon;
1757 unsigned int count = io_parms->length;
1758 struct kvec rsp_iov;
1762 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
1764 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1768 if ((offset >> 32) > 0) {
1769 /* can not handle big offset for old srv */
1773 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
1777 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1778 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1780 /* tcon and ses pointer are checked in smb_init */
1781 if (tcon->ses->server == NULL)
1782 return -ECONNABORTED;
1784 pSMB->AndXCommand = 0xFF; /* none */
1786 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1788 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1789 pSMB->Reserved = 0xFFFFFFFF;
1790 pSMB->WriteMode = 0;
1791 pSMB->Remaining = 0;
1794 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1796 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1797 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1798 /* header + 1 byte pad */
1799 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
1801 inc_rfc1001_len(pSMB, count + 1);
1802 else /* wct == 12 */
1803 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
1805 pSMB->ByteCount = cpu_to_le16(count + 1);
1806 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1807 struct smb_com_writex_req *pSMBW =
1808 (struct smb_com_writex_req *)pSMB;
1809 pSMBW->ByteCount = cpu_to_le16(count + 5);
1811 iov[0].iov_base = pSMB;
1813 iov[0].iov_len = smb_hdr_len + 4;
1814 else /* wct == 12 pad bigger by four bytes */
1815 iov[0].iov_len = smb_hdr_len + 8;
1817 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
1819 cifs_small_buf_release(pSMB);
1820 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1822 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
1823 } else if (resp_buf_type == 0) {
1824 /* presumably this can not happen, but best to be safe */
1827 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
1828 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1829 *nbytes = (*nbytes) << 16;
1830 *nbytes += le16_to_cpu(pSMBr->Count);
1833 * Mask off high 16 bits when bytes written as returned by the
1834 * server is greater than bytes requested by the client. OS/2
1835 * servers are known to set incorrect CountHigh values.
1837 if (*nbytes > count)
1841 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1843 /* Note: On -EAGAIN error only caller can retry on handle based calls
1844 since file handle passed in no longer valid */
1849 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
1850 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
1851 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
1854 LOCK_REQ *pSMB = NULL;
1856 struct kvec rsp_iov;
1860 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
1861 num_lock, num_unlock);
1863 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1868 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
1869 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
1870 pSMB->LockType = lock_type;
1871 pSMB->AndXCommand = 0xFF; /* none */
1872 pSMB->Fid = netfid; /* netfid stays le */
1874 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1875 inc_rfc1001_len(pSMB, count);
1876 pSMB->ByteCount = cpu_to_le16(count);
1878 iov[0].iov_base = (char *)pSMB;
1879 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
1880 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1881 iov[1].iov_base = (char *)buf;
1882 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1884 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1885 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
1886 CIFS_NO_RSP_BUF, &rsp_iov);
1887 cifs_small_buf_release(pSMB);
1889 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
1895 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
1896 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
1897 const __u64 offset, const __u32 numUnlock,
1898 const __u32 numLock, const __u8 lockType,
1899 const bool waitFlag, const __u8 oplock_level)
1902 LOCK_REQ *pSMB = NULL;
1903 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
1908 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
1909 (int)waitFlag, numLock);
1910 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1915 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1916 /* no response expected */
1917 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
1919 } else if (waitFlag) {
1920 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1921 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
1926 pSMB->NumberOfLocks = cpu_to_le16(numLock);
1927 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
1928 pSMB->LockType = lockType;
1929 pSMB->OplockLevel = oplock_level;
1930 pSMB->AndXCommand = 0xFF; /* none */
1931 pSMB->Fid = smb_file_id; /* netfid stays le */
1933 if ((numLock != 0) || (numUnlock != 0)) {
1934 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
1935 /* BB where to store pid high? */
1936 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
1937 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
1938 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
1939 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
1940 count = sizeof(LOCKING_ANDX_RANGE);
1945 inc_rfc1001_len(pSMB, count);
1946 pSMB->ByteCount = cpu_to_le16(count);
1949 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1950 (struct smb_hdr *) pSMB, &bytes_returned);
1952 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
1953 cifs_small_buf_release(pSMB);
1954 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1956 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
1958 /* Note: On -EAGAIN error only caller can retry on handle based calls
1959 since file handle passed in no longer valid */
1964 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
1965 const __u16 smb_file_id, const __u32 netpid,
1966 const loff_t start_offset, const __u64 len,
1967 struct file_lock *pLockData, const __u16 lock_type,
1968 const bool waitFlag)
1970 struct smb_com_transaction2_sfi_req *pSMB = NULL;
1971 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
1972 struct cifs_posix_lock *parm_data;
1975 int bytes_returned = 0;
1976 int resp_buf_type = 0;
1977 __u16 params, param_offset, offset, byte_count, count;
1979 struct kvec rsp_iov;
1981 cifs_dbg(FYI, "Posix Lock\n");
1983 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
1988 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
1991 pSMB->MaxSetupCount = 0;
1994 pSMB->Reserved2 = 0;
1995 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
1996 offset = param_offset + params;
1998 count = sizeof(struct cifs_posix_lock);
1999 pSMB->MaxParameterCount = cpu_to_le16(2);
2000 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2001 pSMB->SetupCount = 1;
2002 pSMB->Reserved3 = 0;
2004 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2006 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2007 byte_count = 3 /* pad */ + params + count;
2008 pSMB->DataCount = cpu_to_le16(count);
2009 pSMB->ParameterCount = cpu_to_le16(params);
2010 pSMB->TotalDataCount = pSMB->DataCount;
2011 pSMB->TotalParameterCount = pSMB->ParameterCount;
2012 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2013 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2014 parm_data = (struct cifs_posix_lock *)
2015 (((char *)pSMB) + offset + 4);
2017 parm_data->lock_type = cpu_to_le16(lock_type);
2019 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2020 parm_data->lock_flags = cpu_to_le16(1);
2021 pSMB->Timeout = cpu_to_le32(-1);
2025 parm_data->pid = cpu_to_le32(netpid);
2026 parm_data->start = cpu_to_le64(start_offset);
2027 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2029 pSMB->DataOffset = cpu_to_le16(offset);
2030 pSMB->Fid = smb_file_id;
2031 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2032 pSMB->Reserved4 = 0;
2033 inc_rfc1001_len(pSMB, byte_count);
2034 pSMB->ByteCount = cpu_to_le16(byte_count);
2036 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2037 (struct smb_hdr *) pSMBr, &bytes_returned);
2039 iov[0].iov_base = (char *)pSMB;
2040 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2041 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2042 &resp_buf_type, timeout, &rsp_iov);
2043 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2045 cifs_small_buf_release(pSMB);
2048 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2049 } else if (pLockData) {
2050 /* lock structure can be returned on get */
2053 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2055 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2056 rc = -EIO; /* bad smb */
2059 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2060 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2061 if (data_count < sizeof(struct cifs_posix_lock)) {
2065 parm_data = (struct cifs_posix_lock *)
2066 ((char *)&pSMBr->hdr.Protocol + data_offset);
2067 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2068 pLockData->fl_type = F_UNLCK;
2070 if (parm_data->lock_type ==
2071 cpu_to_le16(CIFS_RDLCK))
2072 pLockData->fl_type = F_RDLCK;
2073 else if (parm_data->lock_type ==
2074 cpu_to_le16(CIFS_WRLCK))
2075 pLockData->fl_type = F_WRLCK;
2077 pLockData->fl_start = le64_to_cpu(parm_data->start);
2078 pLockData->fl_end = pLockData->fl_start +
2079 (le64_to_cpu(parm_data->length) ?
2080 le64_to_cpu(parm_data->length) - 1 : 0);
2081 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2086 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2088 /* Note: On -EAGAIN error only caller can retry on handle based calls
2089 since file handle passed in no longer valid */
2096 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2099 CLOSE_REQ *pSMB = NULL;
2100 cifs_dbg(FYI, "In CIFSSMBClose\n");
2102 /* do not retry on dead session on close */
2103 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2109 pSMB->FileID = (__u16) smb_file_id;
2110 pSMB->LastWriteTime = 0xFFFFFFFF;
2111 pSMB->ByteCount = 0;
2112 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2113 cifs_small_buf_release(pSMB);
2114 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2117 /* EINTR is expected when user ctl-c to kill app */
2118 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2122 /* Since session is dead, file will be closed on server already */
2130 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2133 FLUSH_REQ *pSMB = NULL;
2134 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2136 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2140 pSMB->FileID = (__u16) smb_file_id;
2141 pSMB->ByteCount = 0;
2142 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2143 cifs_small_buf_release(pSMB);
2144 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2146 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2152 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2153 const char *from_name, const char *to_name,
2154 struct cifs_sb_info *cifs_sb)
2157 RENAME_REQ *pSMB = NULL;
2158 RENAME_RSP *pSMBr = NULL;
2160 int name_len, name_len2;
2162 int remap = cifs_remap(cifs_sb);
2164 cifs_dbg(FYI, "In CIFSSMBRename\n");
2166 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2171 pSMB->BufferFormat = 0x04;
2172 pSMB->SearchAttributes =
2173 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2176 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2177 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2178 from_name, PATH_MAX,
2179 cifs_sb->local_nls, remap);
2180 name_len++; /* trailing null */
2182 pSMB->OldFileName[name_len] = 0x04; /* pad */
2183 /* protocol requires ASCII signature byte on Unicode string */
2184 pSMB->OldFileName[name_len + 1] = 0x00;
2186 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2187 to_name, PATH_MAX, cifs_sb->local_nls,
2189 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2190 name_len2 *= 2; /* convert to bytes */
2192 name_len = copy_path_name(pSMB->OldFileName, from_name);
2193 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2194 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2195 name_len2++; /* signature byte */
2198 count = 1 /* 1st signature byte */ + name_len + name_len2;
2199 inc_rfc1001_len(pSMB, count);
2200 pSMB->ByteCount = cpu_to_le16(count);
2202 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2203 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2204 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2206 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2208 cifs_buf_release(pSMB);
2216 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2217 int netfid, const char *target_name,
2218 const struct nls_table *nls_codepage, int remap)
2220 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2221 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2222 struct set_file_rename *rename_info;
2224 char dummy_string[30];
2226 int bytes_returned = 0;
2228 __u16 params, param_offset, offset, count, byte_count;
2230 cifs_dbg(FYI, "Rename to File by handle\n");
2231 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2237 pSMB->MaxSetupCount = 0;
2241 pSMB->Reserved2 = 0;
2242 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2243 offset = param_offset + params;
2245 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2246 data_offset = (char *)(pSMB) + offset + 4;
2247 rename_info = (struct set_file_rename *) data_offset;
2248 pSMB->MaxParameterCount = cpu_to_le16(2);
2249 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2250 pSMB->SetupCount = 1;
2251 pSMB->Reserved3 = 0;
2252 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2253 byte_count = 3 /* pad */ + params;
2254 pSMB->ParameterCount = cpu_to_le16(params);
2255 pSMB->TotalParameterCount = pSMB->ParameterCount;
2256 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2257 pSMB->DataOffset = cpu_to_le16(offset);
2258 /* construct random name ".cifs_tmp<inodenum><mid>" */
2259 rename_info->overwrite = cpu_to_le32(1);
2260 rename_info->root_fid = 0;
2261 /* unicode only call */
2262 if (target_name == NULL) {
2263 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2265 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2266 dummy_string, 24, nls_codepage, remap);
2269 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2270 target_name, PATH_MAX, nls_codepage,
2273 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2274 count = sizeof(struct set_file_rename) + (2 * len_of_str);
2275 byte_count += count;
2276 pSMB->DataCount = cpu_to_le16(count);
2277 pSMB->TotalDataCount = pSMB->DataCount;
2279 pSMB->InformationLevel =
2280 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2281 pSMB->Reserved4 = 0;
2282 inc_rfc1001_len(pSMB, byte_count);
2283 pSMB->ByteCount = cpu_to_le16(byte_count);
2284 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2285 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2286 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2288 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2291 cifs_buf_release(pSMB);
2293 /* Note: On -EAGAIN error only caller can retry on handle based calls
2294 since file handle passed in no longer valid */
2300 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2301 const char *fromName, const __u16 target_tid, const char *toName,
2302 const int flags, const struct nls_table *nls_codepage, int remap)
2305 COPY_REQ *pSMB = NULL;
2306 COPY_RSP *pSMBr = NULL;
2308 int name_len, name_len2;
2311 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2313 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2318 pSMB->BufferFormat = 0x04;
2319 pSMB->Tid2 = target_tid;
2321 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2323 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2324 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2325 fromName, PATH_MAX, nls_codepage,
2327 name_len++; /* trailing null */
2329 pSMB->OldFileName[name_len] = 0x04; /* pad */
2330 /* protocol requires ASCII signature byte on Unicode string */
2331 pSMB->OldFileName[name_len + 1] = 0x00;
2333 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2334 toName, PATH_MAX, nls_codepage, remap);
2335 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2336 name_len2 *= 2; /* convert to bytes */
2338 name_len = copy_path_name(pSMB->OldFileName, fromName);
2339 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2340 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2341 name_len2++; /* signature byte */
2344 count = 1 /* 1st signature byte */ + name_len + name_len2;
2345 inc_rfc1001_len(pSMB, count);
2346 pSMB->ByteCount = cpu_to_le16(count);
2348 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2349 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2351 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2352 rc, le16_to_cpu(pSMBr->CopyCount));
2354 cifs_buf_release(pSMB);
2363 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2364 const char *fromName, const char *toName,
2365 const struct nls_table *nls_codepage, int remap)
2367 TRANSACTION2_SPI_REQ *pSMB = NULL;
2368 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2371 int name_len_target;
2373 int bytes_returned = 0;
2374 __u16 params, param_offset, offset, byte_count;
2376 cifs_dbg(FYI, "In Symlink Unix style\n");
2378 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2383 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2385 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2386 /* find define for this maxpathcomponent */
2387 PATH_MAX, nls_codepage, remap);
2388 name_len++; /* trailing null */
2392 name_len = copy_path_name(pSMB->FileName, fromName);
2394 params = 6 + name_len;
2395 pSMB->MaxSetupCount = 0;
2399 pSMB->Reserved2 = 0;
2400 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2401 InformationLevel) - 4;
2402 offset = param_offset + params;
2404 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2405 data_offset = (char *)pSMB + offset + 4;
2406 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2408 cifsConvertToUTF16((__le16 *) data_offset, toName,
2409 /* find define for this maxpathcomponent */
2410 PATH_MAX, nls_codepage, remap);
2411 name_len_target++; /* trailing null */
2412 name_len_target *= 2;
2414 name_len_target = copy_path_name(data_offset, toName);
2417 pSMB->MaxParameterCount = cpu_to_le16(2);
2418 /* BB find exact max on data count below from sess */
2419 pSMB->MaxDataCount = cpu_to_le16(1000);
2420 pSMB->SetupCount = 1;
2421 pSMB->Reserved3 = 0;
2422 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2423 byte_count = 3 /* pad */ + params + name_len_target;
2424 pSMB->DataCount = cpu_to_le16(name_len_target);
2425 pSMB->ParameterCount = cpu_to_le16(params);
2426 pSMB->TotalDataCount = pSMB->DataCount;
2427 pSMB->TotalParameterCount = pSMB->ParameterCount;
2428 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2429 pSMB->DataOffset = cpu_to_le16(offset);
2430 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2431 pSMB->Reserved4 = 0;
2432 inc_rfc1001_len(pSMB, byte_count);
2433 pSMB->ByteCount = cpu_to_le16(byte_count);
2434 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2435 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2436 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2438 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2441 cifs_buf_release(pSMB);
2444 goto createSymLinkRetry;
2450 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2451 const char *fromName, const char *toName,
2452 const struct nls_table *nls_codepage, int remap)
2454 TRANSACTION2_SPI_REQ *pSMB = NULL;
2455 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2458 int name_len_target;
2460 int bytes_returned = 0;
2461 __u16 params, param_offset, offset, byte_count;
2463 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2464 createHardLinkRetry:
2465 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2470 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2471 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2472 PATH_MAX, nls_codepage, remap);
2473 name_len++; /* trailing null */
2477 name_len = copy_path_name(pSMB->FileName, toName);
2479 params = 6 + name_len;
2480 pSMB->MaxSetupCount = 0;
2484 pSMB->Reserved2 = 0;
2485 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2486 InformationLevel) - 4;
2487 offset = param_offset + params;
2489 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2490 data_offset = (char *)pSMB + offset + 4;
2491 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2493 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2494 PATH_MAX, nls_codepage, remap);
2495 name_len_target++; /* trailing null */
2496 name_len_target *= 2;
2498 name_len_target = copy_path_name(data_offset, fromName);
2501 pSMB->MaxParameterCount = cpu_to_le16(2);
2502 /* BB find exact max on data count below from sess*/
2503 pSMB->MaxDataCount = cpu_to_le16(1000);
2504 pSMB->SetupCount = 1;
2505 pSMB->Reserved3 = 0;
2506 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2507 byte_count = 3 /* pad */ + params + name_len_target;
2508 pSMB->ParameterCount = cpu_to_le16(params);
2509 pSMB->TotalParameterCount = pSMB->ParameterCount;
2510 pSMB->DataCount = cpu_to_le16(name_len_target);
2511 pSMB->TotalDataCount = pSMB->DataCount;
2512 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2513 pSMB->DataOffset = cpu_to_le16(offset);
2514 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2515 pSMB->Reserved4 = 0;
2516 inc_rfc1001_len(pSMB, byte_count);
2517 pSMB->ByteCount = cpu_to_le16(byte_count);
2518 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2519 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2520 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2522 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2525 cifs_buf_release(pSMB);
2527 goto createHardLinkRetry;
2533 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2534 const char *from_name, const char *to_name,
2535 struct cifs_sb_info *cifs_sb)
2538 NT_RENAME_REQ *pSMB = NULL;
2539 RENAME_RSP *pSMBr = NULL;
2541 int name_len, name_len2;
2543 int remap = cifs_remap(cifs_sb);
2545 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2546 winCreateHardLinkRetry:
2548 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2553 pSMB->SearchAttributes =
2554 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2556 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2557 pSMB->ClusterCount = 0;
2559 pSMB->BufferFormat = 0x04;
2561 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2563 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2564 PATH_MAX, cifs_sb->local_nls, remap);
2565 name_len++; /* trailing null */
2568 /* protocol specifies ASCII buffer format (0x04) for unicode */
2569 pSMB->OldFileName[name_len] = 0x04;
2570 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2572 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2573 to_name, PATH_MAX, cifs_sb->local_nls,
2575 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2576 name_len2 *= 2; /* convert to bytes */
2578 name_len = copy_path_name(pSMB->OldFileName, from_name);
2579 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2580 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2581 name_len2++; /* signature byte */
2584 count = 1 /* string type byte */ + name_len + name_len2;
2585 inc_rfc1001_len(pSMB, count);
2586 pSMB->ByteCount = cpu_to_le16(count);
2588 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2589 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2590 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2592 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2594 cifs_buf_release(pSMB);
2596 goto winCreateHardLinkRetry;
2602 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2603 const unsigned char *searchName, char **symlinkinfo,
2604 const struct nls_table *nls_codepage, int remap)
2606 /* SMB_QUERY_FILE_UNIX_LINK */
2607 TRANSACTION2_QPI_REQ *pSMB = NULL;
2608 TRANSACTION2_QPI_RSP *pSMBr = NULL;
2612 __u16 params, byte_count;
2615 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
2618 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2623 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2625 cifsConvertToUTF16((__le16 *) pSMB->FileName,
2626 searchName, PATH_MAX, nls_codepage,
2628 name_len++; /* trailing null */
2631 name_len = copy_path_name(pSMB->FileName, searchName);
2634 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
2635 pSMB->TotalDataCount = 0;
2636 pSMB->MaxParameterCount = cpu_to_le16(2);
2637 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2638 pSMB->MaxSetupCount = 0;
2642 pSMB->Reserved2 = 0;
2643 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2644 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
2645 pSMB->DataCount = 0;
2646 pSMB->DataOffset = 0;
2647 pSMB->SetupCount = 1;
2648 pSMB->Reserved3 = 0;
2649 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2650 byte_count = params + 1 /* pad */ ;
2651 pSMB->TotalParameterCount = cpu_to_le16(params);
2652 pSMB->ParameterCount = pSMB->TotalParameterCount;
2653 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2654 pSMB->Reserved4 = 0;
2655 inc_rfc1001_len(pSMB, byte_count);
2656 pSMB->ByteCount = cpu_to_le16(byte_count);
2658 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2659 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2661 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
2663 /* decode response */
2665 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2666 /* BB also check enough total bytes returned */
2667 if (rc || get_bcc(&pSMBr->hdr) < 2)
2671 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2673 data_start = ((char *) &pSMBr->hdr.Protocol) +
2674 le16_to_cpu(pSMBr->t2.DataOffset);
2676 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2681 /* BB FIXME investigate remapping reserved chars here */
2682 *symlinkinfo = cifs_strndup_from_utf16(data_start,
2683 count, is_unicode, nls_codepage);
2688 cifs_buf_release(pSMB);
2690 goto querySymLinkRetry;
2695 * Recent Windows versions now create symlinks more frequently
2696 * and they use the "reparse point" mechanism below. We can of course
2697 * do symlinks nicely to Samba and other servers which support the
2698 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
2699 * "MF" symlinks optionally, but for recent Windows we really need to
2700 * reenable the code below and fix the cifs_symlink callers to handle this.
2701 * In the interim this code has been moved to its own config option so
2702 * it is not compiled in by default until callers fixed up and more tested.
2705 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2706 __u16 fid, char **symlinkinfo,
2707 const struct nls_table *nls_codepage)
2711 struct smb_com_transaction_ioctl_req *pSMB;
2712 struct smb_com_transaction_ioctl_rsp *pSMBr;
2714 unsigned int sub_len;
2716 struct reparse_symlink_data *reparse_buf;
2717 struct reparse_posix_data *posix_buf;
2718 __u32 data_offset, data_count;
2721 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
2722 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2727 pSMB->TotalParameterCount = 0 ;
2728 pSMB->TotalDataCount = 0;
2729 pSMB->MaxParameterCount = cpu_to_le32(2);
2730 /* BB find exact data count max from sess structure BB */
2731 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
2732 pSMB->MaxSetupCount = 4;
2734 pSMB->ParameterOffset = 0;
2735 pSMB->DataCount = 0;
2736 pSMB->DataOffset = 0;
2737 pSMB->SetupCount = 4;
2738 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2739 pSMB->ParameterCount = pSMB->TotalParameterCount;
2740 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
2741 pSMB->IsFsctl = 1; /* FSCTL */
2742 pSMB->IsRootFlag = 0;
2743 pSMB->Fid = fid; /* file handle always le */
2744 pSMB->ByteCount = 0;
2746 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2747 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2749 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
2753 data_offset = le32_to_cpu(pSMBr->DataOffset);
2754 data_count = le32_to_cpu(pSMBr->DataCount);
2755 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
2756 /* BB also check enough total bytes returned */
2757 rc = -EIO; /* bad smb */
2760 if (!data_count || (data_count > 2048)) {
2762 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
2765 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
2766 reparse_buf = (struct reparse_symlink_data *)
2767 ((char *)&pSMBr->hdr.Protocol + data_offset);
2768 if ((char *)reparse_buf >= end_of_smb) {
2772 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
2773 cifs_dbg(FYI, "NFS style reparse tag\n");
2774 posix_buf = (struct reparse_posix_data *)reparse_buf;
2776 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
2777 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
2778 le64_to_cpu(posix_buf->InodeType));
2783 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
2784 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
2785 cifs_dbg(FYI, "reparse buf beyond SMB\n");
2789 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
2790 sub_len, is_unicode, nls_codepage);
2792 } else if (reparse_buf->ReparseTag !=
2793 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
2798 /* Reparse tag is NTFS symlink */
2799 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
2800 reparse_buf->PathBuffer;
2801 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
2802 if (sub_start + sub_len > end_of_smb) {
2803 cifs_dbg(FYI, "reparse buf beyond SMB\n");
2807 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2812 /* BB FIXME investigate remapping reserved chars here */
2813 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
2818 cifs_buf_release(pSMB);
2821 * Note: On -EAGAIN error only caller can retry on handle based calls
2822 * since file handle passed in no longer valid.
2828 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
2833 struct smb_com_transaction_compr_ioctl_req *pSMB;
2834 struct smb_com_transaction_ioctl_rsp *pSMBr;
2836 cifs_dbg(FYI, "Set compression for %u\n", fid);
2837 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2842 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
2844 pSMB->TotalParameterCount = 0;
2845 pSMB->TotalDataCount = cpu_to_le32(2);
2846 pSMB->MaxParameterCount = 0;
2847 pSMB->MaxDataCount = 0;
2848 pSMB->MaxSetupCount = 4;
2850 pSMB->ParameterOffset = 0;
2851 pSMB->DataCount = cpu_to_le32(2);
2853 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
2854 compression_state) - 4); /* 84 */
2855 pSMB->SetupCount = 4;
2856 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2857 pSMB->ParameterCount = 0;
2858 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
2859 pSMB->IsFsctl = 1; /* FSCTL */
2860 pSMB->IsRootFlag = 0;
2861 pSMB->Fid = fid; /* file handle always le */
2862 /* 3 byte pad, followed by 2 byte compress state */
2863 pSMB->ByteCount = cpu_to_le16(5);
2864 inc_rfc1001_len(pSMB, 5);
2866 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2867 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2869 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
2871 cifs_buf_release(pSMB);
2874 * Note: On -EAGAIN error only caller can retry on handle based calls
2875 * since file handle passed in no longer valid.
2881 #ifdef CONFIG_CIFS_POSIX
2883 #ifdef CONFIG_FS_POSIX_ACL
2885 * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format
2886 * @ace: POSIX ACL entry to store converted ACL into
2887 * @cifs_ace: ACL in cifs format
2889 * Convert an Access Control Entry from wire format to local POSIX xattr
2892 * Note that the @cifs_uid member is used to store both {g,u}id_t.
2894 static void cifs_init_posix_acl(struct posix_acl_entry *ace,
2895 struct cifs_posix_ace *cifs_ace)
2897 /* u8 cifs fields do not need le conversion */
2898 ace->e_perm = cifs_ace->cifs_e_perm;
2899 ace->e_tag = cifs_ace->cifs_e_tag;
2901 switch (ace->e_tag) {
2903 ace->e_uid = make_kuid(&init_user_ns,
2904 le64_to_cpu(cifs_ace->cifs_uid));
2907 ace->e_gid = make_kgid(&init_user_ns,
2908 le64_to_cpu(cifs_ace->cifs_uid));
2915 * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format
2916 * @acl: ACLs returned in POSIX ACL format
2917 * @src: ACLs in cifs format
2918 * @acl_type: type of POSIX ACL requested
2919 * @size_of_data_area: size of SMB we got
2921 * This function converts ACLs from cifs format to POSIX ACL format.
2922 * If @acl is NULL then the size of the buffer required to store POSIX ACLs in
2923 * their uapi format is returned.
2925 static int cifs_to_posix_acl(struct posix_acl **acl, char *src,
2926 const int acl_type, const int size_of_data_area)
2930 struct cifs_posix_ace *pACE;
2931 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
2932 struct posix_acl *kacl = NULL;
2933 struct posix_acl_entry *pa, *pe;
2935 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
2938 if (acl_type == ACL_TYPE_ACCESS) {
2939 count = le16_to_cpu(cifs_acl->access_entry_count);
2940 pACE = &cifs_acl->ace_array[0];
2941 size = sizeof(struct cifs_posix_acl);
2942 size += sizeof(struct cifs_posix_ace) * count;
2943 /* check if we would go beyond end of SMB */
2944 if (size_of_data_area < size) {
2945 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
2946 size_of_data_area, size);
2949 } else if (acl_type == ACL_TYPE_DEFAULT) {
2950 count = le16_to_cpu(cifs_acl->access_entry_count);
2951 size = sizeof(struct cifs_posix_acl);
2952 size += sizeof(struct cifs_posix_ace) * count;
2953 /* skip past access ACEs to get to default ACEs */
2954 pACE = &cifs_acl->ace_array[count];
2955 count = le16_to_cpu(cifs_acl->default_entry_count);
2956 size += sizeof(struct cifs_posix_ace) * count;
2957 /* check if we would go beyond end of SMB */
2958 if (size_of_data_area < size)
2965 /* Allocate number of POSIX ACLs to store in VFS format. */
2966 kacl = posix_acl_alloc(count, GFP_NOFS);
2970 FOREACH_ACL_ENTRY(pa, kacl, pe) {
2971 cifs_init_posix_acl(pa, pACE);
2980 * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format
2981 * @cifs_ace: the cifs ACL entry to store into
2982 * @local_ace: the POSIX ACL entry to convert
2984 static void cifs_init_ace(struct cifs_posix_ace *cifs_ace,
2985 const struct posix_acl_entry *local_ace)
2987 cifs_ace->cifs_e_perm = local_ace->e_perm;
2988 cifs_ace->cifs_e_tag = local_ace->e_tag;
2990 switch (local_ace->e_tag) {
2992 cifs_ace->cifs_uid =
2993 cpu_to_le64(from_kuid(&init_user_ns, local_ace->e_uid));
2996 cifs_ace->cifs_uid =
2997 cpu_to_le64(from_kgid(&init_user_ns, local_ace->e_gid));
3000 cifs_ace->cifs_uid = cpu_to_le64(-1);
3005 * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format
3006 * @parm_data: ACLs in cifs format to conver to
3007 * @acl: ACLs in POSIX ACL format to convert from
3008 * @acl_type: the type of POSIX ACLs stored in @acl
3010 * Return: the number cifs ACL entries after conversion
3012 static __u16 posix_acl_to_cifs(char *parm_data, const struct posix_acl *acl,
3016 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3017 const struct posix_acl_entry *pa, *pe;
3021 if ((acl == NULL) || (cifs_acl == NULL))
3024 count = acl->a_count;
3025 cifs_dbg(FYI, "setting acl with %d entries\n", count);
3028 * Note that the uapi POSIX ACL version is verified by the VFS and is
3029 * independent of the cifs ACL version. Changing the POSIX ACL version
3030 * is a uapi change and if it's changed we will pass down the POSIX ACL
3031 * version in struct posix_acl from the VFS. For now there's really
3032 * only one that all filesystems know how to deal with.
3034 cifs_acl->version = cpu_to_le16(1);
3035 if (acl_type == ACL_TYPE_ACCESS) {
3036 cifs_acl->access_entry_count = cpu_to_le16(count);
3037 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3038 } else if (acl_type == ACL_TYPE_DEFAULT) {
3039 cifs_acl->default_entry_count = cpu_to_le16(count);
3040 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3042 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3045 FOREACH_ACL_ENTRY(pa, acl, pe) {
3046 cifs_init_ace(&cifs_acl->ace_array[i++], pa);
3049 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3050 rc += sizeof(struct cifs_posix_acl);
3051 /* BB add check to make sure ACL does not overflow SMB */
3056 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3057 const unsigned char *searchName, struct posix_acl **acl,
3058 const int acl_type, const struct nls_table *nls_codepage,
3061 /* SMB_QUERY_POSIX_ACL */
3062 TRANSACTION2_QPI_REQ *pSMB = NULL;
3063 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3067 __u16 params, byte_count;
3069 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3072 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3077 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3079 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3080 searchName, PATH_MAX, nls_codepage,
3082 name_len++; /* trailing null */
3084 pSMB->FileName[name_len] = 0;
3085 pSMB->FileName[name_len+1] = 0;
3087 name_len = copy_path_name(pSMB->FileName, searchName);
3090 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3091 pSMB->TotalDataCount = 0;
3092 pSMB->MaxParameterCount = cpu_to_le16(2);
3093 /* BB find exact max data count below from sess structure BB */
3094 pSMB->MaxDataCount = cpu_to_le16(4000);
3095 pSMB->MaxSetupCount = 0;
3099 pSMB->Reserved2 = 0;
3100 pSMB->ParameterOffset = cpu_to_le16(
3101 offsetof(struct smb_com_transaction2_qpi_req,
3102 InformationLevel) - 4);
3103 pSMB->DataCount = 0;
3104 pSMB->DataOffset = 0;
3105 pSMB->SetupCount = 1;
3106 pSMB->Reserved3 = 0;
3107 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3108 byte_count = params + 1 /* pad */ ;
3109 pSMB->TotalParameterCount = cpu_to_le16(params);
3110 pSMB->ParameterCount = pSMB->TotalParameterCount;
3111 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3112 pSMB->Reserved4 = 0;
3113 inc_rfc1001_len(pSMB, byte_count);
3114 pSMB->ByteCount = cpu_to_le16(byte_count);
3116 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3117 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3118 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3120 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3122 /* decode response */
3124 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3125 /* BB also check enough total bytes returned */
3126 if (rc || get_bcc(&pSMBr->hdr) < 2)
3127 rc = -EIO; /* bad smb */
3129 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3130 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3131 rc = cifs_to_posix_acl(acl,
3132 (char *)&pSMBr->hdr.Protocol+data_offset,
3136 cifs_buf_release(pSMB);
3138 * The else branch after SendReceive() doesn't return EAGAIN so if we
3139 * allocated @acl in cifs_to_posix_acl() we are guaranteed to return
3140 * here and don't leak POSIX ACLs.
3147 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3148 const unsigned char *fileName, const struct posix_acl *acl,
3149 const int acl_type, const struct nls_table *nls_codepage,
3152 struct smb_com_transaction2_spi_req *pSMB = NULL;
3153 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3157 int bytes_returned = 0;
3158 __u16 params, byte_count, data_count, param_offset, offset;
3160 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3162 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3166 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3168 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3169 PATH_MAX, nls_codepage, remap);
3170 name_len++; /* trailing null */
3173 name_len = copy_path_name(pSMB->FileName, fileName);
3175 params = 6 + name_len;
3176 pSMB->MaxParameterCount = cpu_to_le16(2);
3177 /* BB find max SMB size from sess */
3178 pSMB->MaxDataCount = cpu_to_le16(1000);
3179 pSMB->MaxSetupCount = 0;
3183 pSMB->Reserved2 = 0;
3184 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3185 InformationLevel) - 4;
3186 offset = param_offset + params;
3187 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3188 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3190 /* convert to on the wire format for POSIX ACL */
3191 data_count = posix_acl_to_cifs(parm_data, acl, acl_type);
3193 if (data_count == 0) {
3195 goto setACLerrorExit;
3197 pSMB->DataOffset = cpu_to_le16(offset);
3198 pSMB->SetupCount = 1;
3199 pSMB->Reserved3 = 0;
3200 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3201 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3202 byte_count = 3 /* pad */ + params + data_count;
3203 pSMB->DataCount = cpu_to_le16(data_count);
3204 pSMB->TotalDataCount = pSMB->DataCount;
3205 pSMB->ParameterCount = cpu_to_le16(params);
3206 pSMB->TotalParameterCount = pSMB->ParameterCount;
3207 pSMB->Reserved4 = 0;
3208 inc_rfc1001_len(pSMB, byte_count);
3209 pSMB->ByteCount = cpu_to_le16(byte_count);
3210 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3211 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3213 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3216 cifs_buf_release(pSMB);
3222 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3223 const unsigned char *searchName, struct posix_acl **acl,
3224 const int acl_type, const struct nls_table *nls_codepage,
3230 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3231 const unsigned char *fileName, const struct posix_acl *acl,
3232 const int acl_type, const struct nls_table *nls_codepage,
3237 #endif /* CONFIG_FS_POSIX_ACL */
3240 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3241 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3244 struct smb_t2_qfi_req *pSMB = NULL;
3245 struct smb_t2_qfi_rsp *pSMBr = NULL;
3247 __u16 params, byte_count;
3249 cifs_dbg(FYI, "In GetExtAttr\n");
3254 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3259 params = 2 /* level */ + 2 /* fid */;
3260 pSMB->t2.TotalDataCount = 0;
3261 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3262 /* BB find exact max data count below from sess structure BB */
3263 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3264 pSMB->t2.MaxSetupCount = 0;
3265 pSMB->t2.Reserved = 0;
3267 pSMB->t2.Timeout = 0;
3268 pSMB->t2.Reserved2 = 0;
3269 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3271 pSMB->t2.DataCount = 0;
3272 pSMB->t2.DataOffset = 0;
3273 pSMB->t2.SetupCount = 1;
3274 pSMB->t2.Reserved3 = 0;
3275 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3276 byte_count = params + 1 /* pad */ ;
3277 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3278 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3279 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3282 inc_rfc1001_len(pSMB, byte_count);
3283 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3285 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3286 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3288 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3290 /* decode response */
3291 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3292 /* BB also check enough total bytes returned */
3293 if (rc || get_bcc(&pSMBr->hdr) < 2)
3294 /* If rc should we check for EOPNOSUPP and
3295 disable the srvino flag? or in caller? */
3296 rc = -EIO; /* bad smb */
3298 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3299 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3300 struct file_chattr_info *pfinfo;
3303 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3307 pfinfo = (struct file_chattr_info *)
3308 (data_offset + (char *) &pSMBr->hdr.Protocol);
3309 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3310 *pMask = le64_to_cpu(pfinfo->mask);
3314 cifs_buf_release(pSMB);
3316 goto GetExtAttrRetry;
3320 #endif /* CONFIG_POSIX */
3323 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3324 * all NT TRANSACTS that we init here have total parm and data under about 400
3325 * bytes (to fit in small cifs buffer size), which is the case so far, it
3326 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3327 * returned setup area) and MaxParameterCount (returned parms size) must be set
3331 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3332 const int parm_len, struct cifs_tcon *tcon,
3337 struct smb_com_ntransact_req *pSMB;
3339 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3343 *ret_buf = (void *)pSMB;
3345 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3346 pSMB->TotalDataCount = 0;
3347 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3348 pSMB->ParameterCount = pSMB->TotalParameterCount;
3349 pSMB->DataCount = pSMB->TotalDataCount;
3350 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3351 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3352 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3353 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3354 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3355 pSMB->SubCommand = cpu_to_le16(sub_command);
3360 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3361 __u32 *pparmlen, __u32 *pdatalen)
3364 __u32 data_count, data_offset, parm_count, parm_offset;
3365 struct smb_com_ntransact_rsp *pSMBr;
3374 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3376 bcc = get_bcc(&pSMBr->hdr);
3377 end_of_smb = 2 /* sizeof byte count */ + bcc +
3378 (char *)&pSMBr->ByteCount;
3380 data_offset = le32_to_cpu(pSMBr->DataOffset);
3381 data_count = le32_to_cpu(pSMBr->DataCount);
3382 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3383 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3385 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3386 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3388 /* should we also check that parm and data areas do not overlap? */
3389 if (*ppparm > end_of_smb) {
3390 cifs_dbg(FYI, "parms start after end of smb\n");
3392 } else if (parm_count + *ppparm > end_of_smb) {
3393 cifs_dbg(FYI, "parm end after end of smb\n");
3395 } else if (*ppdata > end_of_smb) {
3396 cifs_dbg(FYI, "data starts after end of smb\n");
3398 } else if (data_count + *ppdata > end_of_smb) {
3399 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3400 *ppdata, data_count, (data_count + *ppdata),
3403 } else if (parm_count + data_count > bcc) {
3404 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3407 *pdatalen = data_count;
3408 *pparmlen = parm_count;
3412 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3414 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3415 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3419 QUERY_SEC_DESC_REQ *pSMB;
3421 struct kvec rsp_iov;
3423 cifs_dbg(FYI, "GetCifsACL\n");
3428 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3429 8 /* parm len */, tcon, (void **) &pSMB);
3433 pSMB->MaxParameterCount = cpu_to_le32(4);
3434 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3435 pSMB->MaxSetupCount = 0;
3436 pSMB->Fid = fid; /* file handle always le */
3437 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3439 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3440 inc_rfc1001_len(pSMB, 11);
3441 iov[0].iov_base = (char *)pSMB;
3442 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3444 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3446 cifs_small_buf_release(pSMB);
3447 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3449 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3450 } else { /* decode response */
3454 struct smb_com_ntransact_rsp *pSMBr;
3457 /* validate_nttransact */
3458 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3459 &pdata, &parm_len, pbuflen);
3462 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3464 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3465 pSMBr, parm, *acl_inf);
3467 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3468 rc = -EIO; /* bad smb */
3473 /* BB check that data area is minimum length and as big as acl_len */
3475 acl_len = le32_to_cpu(*parm);
3476 if (acl_len != *pbuflen) {
3477 cifs_dbg(VFS, "acl length %d does not match %d\n",
3479 if (*pbuflen > acl_len)
3483 /* check if buffer is big enough for the acl
3484 header followed by the smallest SID */
3485 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3486 (*pbuflen >= 64 * 1024)) {
3487 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3491 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3492 if (*acl_inf == NULL) {
3499 free_rsp_buf(buf_type, rsp_iov.iov_base);
3504 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3505 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3507 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3509 int bytes_returned = 0;
3510 SET_SEC_DESC_REQ *pSMB = NULL;
3514 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3518 pSMB->MaxSetupCount = 0;
3522 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3523 data_count = acllen;
3524 data_offset = param_offset + param_count;
3525 byte_count = 3 /* pad */ + param_count;
3527 pSMB->DataCount = cpu_to_le32(data_count);
3528 pSMB->TotalDataCount = pSMB->DataCount;
3529 pSMB->MaxParameterCount = cpu_to_le32(4);
3530 pSMB->MaxDataCount = cpu_to_le32(16384);
3531 pSMB->ParameterCount = cpu_to_le32(param_count);
3532 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3533 pSMB->TotalParameterCount = pSMB->ParameterCount;
3534 pSMB->DataOffset = cpu_to_le32(data_offset);
3535 pSMB->SetupCount = 0;
3536 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3537 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3539 pSMB->Fid = fid; /* file handle always le */
3540 pSMB->Reserved2 = 0;
3541 pSMB->AclFlags = cpu_to_le32(aclflag);
3543 if (pntsd && acllen) {
3544 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3545 data_offset, pntsd, acllen);
3546 inc_rfc1001_len(pSMB, byte_count + data_count);
3548 inc_rfc1001_len(pSMB, byte_count);
3550 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3551 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3553 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3554 bytes_returned, rc);
3556 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3557 cifs_buf_release(pSMB);
3560 goto setCifsAclRetry;
3566 /* Legacy Query Path Information call for lookup to old servers such
3569 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3570 const char *search_name, FILE_ALL_INFO *data,
3571 const struct nls_table *nls_codepage, int remap)
3573 QUERY_INFORMATION_REQ *pSMB;
3574 QUERY_INFORMATION_RSP *pSMBr;
3579 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3581 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3586 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3588 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3589 search_name, PATH_MAX, nls_codepage,
3591 name_len++; /* trailing null */
3594 name_len = copy_path_name(pSMB->FileName, search_name);
3596 pSMB->BufferFormat = 0x04;
3597 name_len++; /* account for buffer type byte */
3598 inc_rfc1001_len(pSMB, (__u16)name_len);
3599 pSMB->ByteCount = cpu_to_le16(name_len);
3601 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3602 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3604 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3606 struct timespec64 ts;
3607 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3609 /* decode response */
3610 /* BB FIXME - add time zone adjustment BB */
3611 memset(data, 0, sizeof(FILE_ALL_INFO));
3614 /* decode time fields */
3615 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3616 data->LastWriteTime = data->ChangeTime;
3617 data->LastAccessTime = 0;
3618 data->AllocationSize =
3619 cpu_to_le64(le32_to_cpu(pSMBr->size));
3620 data->EndOfFile = data->AllocationSize;
3622 cpu_to_le32(le16_to_cpu(pSMBr->attr));
3624 rc = -EIO; /* bad buffer passed in */
3626 cifs_buf_release(pSMB);
3635 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3636 u16 netfid, FILE_ALL_INFO *pFindData)
3638 struct smb_t2_qfi_req *pSMB = NULL;
3639 struct smb_t2_qfi_rsp *pSMBr = NULL;
3642 __u16 params, byte_count;
3645 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3650 params = 2 /* level */ + 2 /* fid */;
3651 pSMB->t2.TotalDataCount = 0;
3652 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3653 /* BB find exact max data count below from sess structure BB */
3654 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3655 pSMB->t2.MaxSetupCount = 0;
3656 pSMB->t2.Reserved = 0;
3658 pSMB->t2.Timeout = 0;
3659 pSMB->t2.Reserved2 = 0;
3660 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3662 pSMB->t2.DataCount = 0;
3663 pSMB->t2.DataOffset = 0;
3664 pSMB->t2.SetupCount = 1;
3665 pSMB->t2.Reserved3 = 0;
3666 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3667 byte_count = params + 1 /* pad */ ;
3668 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3669 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3670 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3673 inc_rfc1001_len(pSMB, byte_count);
3674 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3676 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3677 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3679 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
3680 } else { /* decode response */
3681 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3683 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3685 else if (get_bcc(&pSMBr->hdr) < 40)
3686 rc = -EIO; /* bad smb */
3687 else if (pFindData) {
3688 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3689 memcpy((char *) pFindData,
3690 (char *) &pSMBr->hdr.Protocol +
3691 data_offset, sizeof(FILE_ALL_INFO));
3695 cifs_buf_release(pSMB);
3697 goto QFileInfoRetry;
3703 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3704 const char *search_name, FILE_ALL_INFO *data,
3705 int legacy /* old style infolevel */,
3706 const struct nls_table *nls_codepage, int remap)
3708 /* level 263 SMB_QUERY_FILE_ALL_INFO */
3709 TRANSACTION2_QPI_REQ *pSMB = NULL;
3710 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3714 __u16 params, byte_count;
3716 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3718 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3723 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3725 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3726 PATH_MAX, nls_codepage, remap);
3727 name_len++; /* trailing null */
3730 name_len = copy_path_name(pSMB->FileName, search_name);
3733 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3734 pSMB->TotalDataCount = 0;
3735 pSMB->MaxParameterCount = cpu_to_le16(2);
3736 /* BB find exact max SMB PDU from sess structure BB */
3737 pSMB->MaxDataCount = cpu_to_le16(4000);
3738 pSMB->MaxSetupCount = 0;
3742 pSMB->Reserved2 = 0;
3743 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3744 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3745 pSMB->DataCount = 0;
3746 pSMB->DataOffset = 0;
3747 pSMB->SetupCount = 1;
3748 pSMB->Reserved3 = 0;
3749 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3750 byte_count = params + 1 /* pad */ ;
3751 pSMB->TotalParameterCount = cpu_to_le16(params);
3752 pSMB->ParameterCount = pSMB->TotalParameterCount;
3754 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3756 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3757 pSMB->Reserved4 = 0;
3758 inc_rfc1001_len(pSMB, byte_count);
3759 pSMB->ByteCount = cpu_to_le16(byte_count);
3761 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3762 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3764 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3765 } else { /* decode response */
3766 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3768 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3770 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3771 rc = -EIO; /* bad smb */
3772 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3773 rc = -EIO; /* 24 or 26 expected but we do not read
3777 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3780 * On legacy responses we do not read the last field,
3781 * EAsize, fortunately since it varies by subdialect and
3782 * also note it differs on Set vs Get, ie two bytes or 4
3783 * bytes depending but we don't care here.
3786 size = sizeof(FILE_INFO_STANDARD);
3788 size = sizeof(FILE_ALL_INFO);
3789 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
3794 cifs_buf_release(pSMB);
3796 goto QPathInfoRetry;
3802 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3803 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3805 struct smb_t2_qfi_req *pSMB = NULL;
3806 struct smb_t2_qfi_rsp *pSMBr = NULL;
3809 __u16 params, byte_count;
3812 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3817 params = 2 /* level */ + 2 /* fid */;
3818 pSMB->t2.TotalDataCount = 0;
3819 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3820 /* BB find exact max data count below from sess structure BB */
3821 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3822 pSMB->t2.MaxSetupCount = 0;
3823 pSMB->t2.Reserved = 0;
3825 pSMB->t2.Timeout = 0;
3826 pSMB->t2.Reserved2 = 0;
3827 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3829 pSMB->t2.DataCount = 0;
3830 pSMB->t2.DataOffset = 0;
3831 pSMB->t2.SetupCount = 1;
3832 pSMB->t2.Reserved3 = 0;
3833 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3834 byte_count = params + 1 /* pad */ ;
3835 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3836 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3837 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3840 inc_rfc1001_len(pSMB, byte_count);
3841 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3843 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3844 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3846 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
3847 } else { /* decode response */
3848 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3850 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3851 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3852 rc = -EIO; /* bad smb */
3854 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3855 memcpy((char *) pFindData,
3856 (char *) &pSMBr->hdr.Protocol +
3858 sizeof(FILE_UNIX_BASIC_INFO));
3862 cifs_buf_release(pSMB);
3864 goto UnixQFileInfoRetry;
3870 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3871 const unsigned char *searchName,
3872 FILE_UNIX_BASIC_INFO *pFindData,
3873 const struct nls_table *nls_codepage, int remap)
3875 /* SMB_QUERY_FILE_UNIX_BASIC */
3876 TRANSACTION2_QPI_REQ *pSMB = NULL;
3877 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3879 int bytes_returned = 0;
3881 __u16 params, byte_count;
3883 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
3885 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3890 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3892 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3893 PATH_MAX, nls_codepage, remap);
3894 name_len++; /* trailing null */
3897 name_len = copy_path_name(pSMB->FileName, searchName);
3900 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3901 pSMB->TotalDataCount = 0;
3902 pSMB->MaxParameterCount = cpu_to_le16(2);
3903 /* BB find exact max SMB PDU from sess structure BB */
3904 pSMB->MaxDataCount = cpu_to_le16(4000);
3905 pSMB->MaxSetupCount = 0;
3909 pSMB->Reserved2 = 0;
3910 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3911 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3912 pSMB->DataCount = 0;
3913 pSMB->DataOffset = 0;
3914 pSMB->SetupCount = 1;
3915 pSMB->Reserved3 = 0;
3916 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3917 byte_count = params + 1 /* pad */ ;
3918 pSMB->TotalParameterCount = cpu_to_le16(params);
3919 pSMB->ParameterCount = pSMB->TotalParameterCount;
3920 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3921 pSMB->Reserved4 = 0;
3922 inc_rfc1001_len(pSMB, byte_count);
3923 pSMB->ByteCount = cpu_to_le16(byte_count);
3925 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3926 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3928 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
3929 } else { /* decode response */
3930 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3932 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3933 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3934 rc = -EIO; /* bad smb */
3936 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3937 memcpy((char *) pFindData,
3938 (char *) &pSMBr->hdr.Protocol +
3940 sizeof(FILE_UNIX_BASIC_INFO));
3943 cifs_buf_release(pSMB);
3945 goto UnixQPathInfoRetry;
3950 /* xid, tcon, searchName and codepage are input parms, rest are returned */
3952 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
3953 const char *searchName, struct cifs_sb_info *cifs_sb,
3954 __u16 *pnetfid, __u16 search_flags,
3955 struct cifs_search_info *psrch_inf, bool msearch)
3957 /* level 257 SMB_ */
3958 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
3959 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
3960 T2_FFIRST_RSP_PARMS *parms;
3962 int bytes_returned = 0;
3963 int name_len, remap;
3964 __u16 params, byte_count;
3965 struct nls_table *nls_codepage;
3967 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
3970 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3975 nls_codepage = cifs_sb->local_nls;
3976 remap = cifs_remap(cifs_sb);
3978 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3980 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3981 PATH_MAX, nls_codepage, remap);
3982 /* We can not add the asterik earlier in case
3983 it got remapped to 0xF03A as if it were part of the
3984 directory name instead of a wildcard */
3987 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
3988 pSMB->FileName[name_len+1] = 0;
3989 pSMB->FileName[name_len+2] = '*';
3990 pSMB->FileName[name_len+3] = 0;
3991 name_len += 4; /* now the trailing null */
3992 /* null terminate just in case */
3993 pSMB->FileName[name_len] = 0;
3994 pSMB->FileName[name_len+1] = 0;
3998 name_len = copy_path_name(pSMB->FileName, searchName);
4000 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4001 name_len = PATH_MAX-2;
4002 /* overwrite nul byte */
4003 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4004 pSMB->FileName[name_len] = '*';
4005 pSMB->FileName[name_len+1] = 0;
4010 params = 12 + name_len /* includes null */ ;
4011 pSMB->TotalDataCount = 0; /* no EAs */
4012 pSMB->MaxParameterCount = cpu_to_le16(10);
4013 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4014 pSMB->MaxSetupCount = 0;
4018 pSMB->Reserved2 = 0;
4019 byte_count = params + 1 /* pad */ ;
4020 pSMB->TotalParameterCount = cpu_to_le16(params);
4021 pSMB->ParameterCount = pSMB->TotalParameterCount;
4022 pSMB->ParameterOffset = cpu_to_le16(
4023 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4025 pSMB->DataCount = 0;
4026 pSMB->DataOffset = 0;
4027 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4028 pSMB->Reserved3 = 0;
4029 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4030 pSMB->SearchAttributes =
4031 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4033 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4034 pSMB->SearchFlags = cpu_to_le16(search_flags);
4035 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4037 /* BB what should we set StorageType to? Does it matter? BB */
4038 pSMB->SearchStorageType = 0;
4039 inc_rfc1001_len(pSMB, byte_count);
4040 pSMB->ByteCount = cpu_to_le16(byte_count);
4042 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4043 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4044 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4046 if (rc) {/* BB add logic to retry regular search if Unix search
4047 rejected unexpectedly by server */
4048 /* BB Add code to handle unsupported level rc */
4049 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4051 cifs_buf_release(pSMB);
4053 /* BB eventually could optimize out free and realloc of buf */
4056 goto findFirstRetry;
4057 } else { /* decode response */
4058 /* BB remember to free buffer if error BB */
4059 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4063 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4064 psrch_inf->unicode = true;
4066 psrch_inf->unicode = false;
4068 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4069 psrch_inf->smallBuf = false;
4070 psrch_inf->srch_entries_start =
4071 (char *) &pSMBr->hdr.Protocol +
4072 le16_to_cpu(pSMBr->t2.DataOffset);
4073 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4074 le16_to_cpu(pSMBr->t2.ParameterOffset));
4076 if (parms->EndofSearch)
4077 psrch_inf->endOfSearch = true;
4079 psrch_inf->endOfSearch = false;
4081 psrch_inf->entries_in_buffer =
4082 le16_to_cpu(parms->SearchCount);
4083 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4084 psrch_inf->entries_in_buffer;
4085 lnoff = le16_to_cpu(parms->LastNameOffset);
4086 if (CIFSMaxBufSize < lnoff) {
4087 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4088 psrch_inf->last_entry = NULL;
4092 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4096 *pnetfid = parms->SearchHandle;
4098 cifs_buf_release(pSMB);
4105 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4106 __u16 searchHandle, __u16 search_flags,
4107 struct cifs_search_info *psrch_inf)
4109 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4110 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4111 T2_FNEXT_RSP_PARMS *parms;
4112 char *response_data;
4115 unsigned int name_len;
4116 __u16 params, byte_count;
4118 cifs_dbg(FYI, "In FindNext\n");
4120 if (psrch_inf->endOfSearch)
4123 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4128 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4130 pSMB->TotalDataCount = 0; /* no EAs */
4131 pSMB->MaxParameterCount = cpu_to_le16(8);
4132 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4133 pSMB->MaxSetupCount = 0;
4137 pSMB->Reserved2 = 0;
4138 pSMB->ParameterOffset = cpu_to_le16(
4139 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4140 pSMB->DataCount = 0;
4141 pSMB->DataOffset = 0;
4142 pSMB->SetupCount = 1;
4143 pSMB->Reserved3 = 0;
4144 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4145 pSMB->SearchHandle = searchHandle; /* always kept as le */
4147 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4148 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4149 pSMB->ResumeKey = psrch_inf->resume_key;
4150 pSMB->SearchFlags = cpu_to_le16(search_flags);
4152 name_len = psrch_inf->resume_name_len;
4154 if (name_len < PATH_MAX) {
4155 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4156 byte_count += name_len;
4157 /* 14 byte parm len above enough for 2 byte null terminator */
4158 pSMB->ResumeFileName[name_len] = 0;
4159 pSMB->ResumeFileName[name_len+1] = 0;
4162 goto FNext2_err_exit;
4164 byte_count = params + 1 /* pad */ ;
4165 pSMB->TotalParameterCount = cpu_to_le16(params);
4166 pSMB->ParameterCount = pSMB->TotalParameterCount;
4167 inc_rfc1001_len(pSMB, byte_count);
4168 pSMB->ByteCount = cpu_to_le16(byte_count);
4170 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4171 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4172 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4175 psrch_inf->endOfSearch = true;
4176 cifs_buf_release(pSMB);
4177 rc = 0; /* search probably was closed at end of search*/
4179 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4180 } else { /* decode response */
4181 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4186 /* BB fixme add lock for file (srch_info) struct here */
4187 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4188 psrch_inf->unicode = true;
4190 psrch_inf->unicode = false;
4191 response_data = (char *) &pSMBr->hdr.Protocol +
4192 le16_to_cpu(pSMBr->t2.ParameterOffset);
4193 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4194 response_data = (char *)&pSMBr->hdr.Protocol +
4195 le16_to_cpu(pSMBr->t2.DataOffset);
4196 if (psrch_inf->smallBuf)
4197 cifs_small_buf_release(
4198 psrch_inf->ntwrk_buf_start);
4200 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4201 psrch_inf->srch_entries_start = response_data;
4202 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4203 psrch_inf->smallBuf = false;
4204 if (parms->EndofSearch)
4205 psrch_inf->endOfSearch = true;
4207 psrch_inf->endOfSearch = false;
4208 psrch_inf->entries_in_buffer =
4209 le16_to_cpu(parms->SearchCount);
4210 psrch_inf->index_of_last_entry +=
4211 psrch_inf->entries_in_buffer;
4212 lnoff = le16_to_cpu(parms->LastNameOffset);
4213 if (CIFSMaxBufSize < lnoff) {
4214 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4215 psrch_inf->last_entry = NULL;
4218 psrch_inf->last_entry =
4219 psrch_inf->srch_entries_start + lnoff;
4221 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4222 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4224 /* BB fixme add unlock here */
4229 /* BB On error, should we leave previous search buf (and count and
4230 last entry fields) intact or free the previous one? */
4232 /* Note: On -EAGAIN error only caller can retry on handle based calls
4233 since file handle passed in no longer valid */
4236 cifs_buf_release(pSMB);
4241 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4242 const __u16 searchHandle)
4245 FINDCLOSE_REQ *pSMB = NULL;
4247 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4248 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4250 /* no sense returning error if session restarted
4251 as file handle has been closed */
4257 pSMB->FileID = searchHandle;
4258 pSMB->ByteCount = 0;
4259 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4260 cifs_small_buf_release(pSMB);
4262 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4264 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4266 /* Since session is dead, search handle closed on server already */
4274 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4275 const char *search_name, __u64 *inode_number,
4276 const struct nls_table *nls_codepage, int remap)
4279 TRANSACTION2_QPI_REQ *pSMB = NULL;
4280 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4281 int name_len, bytes_returned;
4282 __u16 params, byte_count;
4284 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4288 GetInodeNumberRetry:
4289 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4294 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4296 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4297 search_name, PATH_MAX, nls_codepage,
4299 name_len++; /* trailing null */
4302 name_len = copy_path_name(pSMB->FileName, search_name);
4305 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4306 pSMB->TotalDataCount = 0;
4307 pSMB->MaxParameterCount = cpu_to_le16(2);
4308 /* BB find exact max data count below from sess structure BB */
4309 pSMB->MaxDataCount = cpu_to_le16(4000);
4310 pSMB->MaxSetupCount = 0;
4314 pSMB->Reserved2 = 0;
4315 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4316 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4317 pSMB->DataCount = 0;
4318 pSMB->DataOffset = 0;
4319 pSMB->SetupCount = 1;
4320 pSMB->Reserved3 = 0;
4321 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4322 byte_count = params + 1 /* pad */ ;
4323 pSMB->TotalParameterCount = cpu_to_le16(params);
4324 pSMB->ParameterCount = pSMB->TotalParameterCount;
4325 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4326 pSMB->Reserved4 = 0;
4327 inc_rfc1001_len(pSMB, byte_count);
4328 pSMB->ByteCount = cpu_to_le16(byte_count);
4330 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4331 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4333 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4335 /* decode response */
4336 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4337 /* BB also check enough total bytes returned */
4338 if (rc || get_bcc(&pSMBr->hdr) < 2)
4339 /* If rc should we check for EOPNOSUPP and
4340 disable the srvino flag? or in caller? */
4341 rc = -EIO; /* bad smb */
4343 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4344 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4345 struct file_internal_info *pfinfo;
4346 /* BB Do we need a cast or hash here ? */
4348 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4350 goto GetInodeNumOut;
4352 pfinfo = (struct file_internal_info *)
4353 (data_offset + (char *) &pSMBr->hdr.Protocol);
4354 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4358 cifs_buf_release(pSMB);
4360 goto GetInodeNumberRetry;
4365 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4366 const char *search_name, struct dfs_info3_param **target_nodes,
4367 unsigned int *num_of_nodes,
4368 const struct nls_table *nls_codepage, int remap)
4370 /* TRANS2_GET_DFS_REFERRAL */
4371 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4372 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4376 __u16 params, byte_count;
4378 *target_nodes = NULL;
4380 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4381 if (ses == NULL || ses->tcon_ipc == NULL)
4386 * Use smb_init_no_reconnect() instead of smb_init() as
4387 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4388 * causing an infinite recursion.
4390 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4391 (void **)&pSMB, (void **)&pSMBr);
4395 /* server pointer checked in called function,
4396 but should never be null here anyway */
4397 pSMB->hdr.Mid = get_next_mid(ses->server);
4398 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4399 pSMB->hdr.Uid = ses->Suid;
4400 if (ses->capabilities & CAP_STATUS32)
4401 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4402 if (ses->capabilities & CAP_DFS)
4403 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4405 if (ses->capabilities & CAP_UNICODE) {
4406 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4408 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4409 search_name, PATH_MAX, nls_codepage,
4411 name_len++; /* trailing null */
4413 } else { /* BB improve the check for buffer overruns BB */
4414 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4417 if (ses->server->sign)
4418 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4420 pSMB->hdr.Uid = ses->Suid;
4422 params = 2 /* level */ + name_len /*includes null */ ;
4423 pSMB->TotalDataCount = 0;
4424 pSMB->DataCount = 0;
4425 pSMB->DataOffset = 0;
4426 pSMB->MaxParameterCount = 0;
4427 /* BB find exact max SMB PDU from sess structure BB */
4428 pSMB->MaxDataCount = cpu_to_le16(4000);
4429 pSMB->MaxSetupCount = 0;
4433 pSMB->Reserved2 = 0;
4434 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4435 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4436 pSMB->SetupCount = 1;
4437 pSMB->Reserved3 = 0;
4438 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4439 byte_count = params + 3 /* pad */ ;
4440 pSMB->ParameterCount = cpu_to_le16(params);
4441 pSMB->TotalParameterCount = pSMB->ParameterCount;
4442 pSMB->MaxReferralLevel = cpu_to_le16(3);
4443 inc_rfc1001_len(pSMB, byte_count);
4444 pSMB->ByteCount = cpu_to_le16(byte_count);
4446 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4447 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4449 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4452 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4454 /* BB Also check if enough total bytes returned? */
4455 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4456 rc = -EIO; /* bad smb */
4460 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4461 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4463 /* parse returned result into more usable form */
4464 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4465 le16_to_cpu(pSMBr->t2.DataCount),
4466 num_of_nodes, target_nodes, nls_codepage,
4468 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4471 cifs_buf_release(pSMB);
4479 /* Query File System Info such as free space to old servers such as Win 9x */
4481 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4482 struct kstatfs *FSData)
4484 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4485 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4486 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4487 FILE_SYSTEM_ALLOC_INFO *response_data;
4489 int bytes_returned = 0;
4490 __u16 params, byte_count;
4492 cifs_dbg(FYI, "OldQFSInfo\n");
4494 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4499 params = 2; /* level */
4500 pSMB->TotalDataCount = 0;
4501 pSMB->MaxParameterCount = cpu_to_le16(2);
4502 pSMB->MaxDataCount = cpu_to_le16(1000);
4503 pSMB->MaxSetupCount = 0;
4507 pSMB->Reserved2 = 0;
4508 byte_count = params + 1 /* pad */ ;
4509 pSMB->TotalParameterCount = cpu_to_le16(params);
4510 pSMB->ParameterCount = pSMB->TotalParameterCount;
4511 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4512 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4513 pSMB->DataCount = 0;
4514 pSMB->DataOffset = 0;
4515 pSMB->SetupCount = 1;
4516 pSMB->Reserved3 = 0;
4517 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4518 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4519 inc_rfc1001_len(pSMB, byte_count);
4520 pSMB->ByteCount = cpu_to_le16(byte_count);
4522 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4523 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4525 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4526 } else { /* decode response */
4527 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4529 if (rc || get_bcc(&pSMBr->hdr) < 18)
4530 rc = -EIO; /* bad smb */
4532 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4533 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4534 get_bcc(&pSMBr->hdr), data_offset);
4536 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4537 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4539 le16_to_cpu(response_data->BytesPerSector) *
4540 le32_to_cpu(response_data->
4541 SectorsPerAllocationUnit);
4543 * much prefer larger but if server doesn't report
4544 * a valid size than 4K is a reasonable minimum
4546 if (FSData->f_bsize < 512)
4547 FSData->f_bsize = 4096;
4550 le32_to_cpu(response_data->TotalAllocationUnits);
4551 FSData->f_bfree = FSData->f_bavail =
4552 le32_to_cpu(response_data->FreeAllocationUnits);
4553 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4554 (unsigned long long)FSData->f_blocks,
4555 (unsigned long long)FSData->f_bfree,
4559 cifs_buf_release(pSMB);
4562 goto oldQFSInfoRetry;
4568 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4569 struct kstatfs *FSData)
4571 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4572 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4573 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4574 FILE_SYSTEM_INFO *response_data;
4576 int bytes_returned = 0;
4577 __u16 params, byte_count;
4579 cifs_dbg(FYI, "In QFSInfo\n");
4581 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4586 params = 2; /* level */
4587 pSMB->TotalDataCount = 0;
4588 pSMB->MaxParameterCount = cpu_to_le16(2);
4589 pSMB->MaxDataCount = cpu_to_le16(1000);
4590 pSMB->MaxSetupCount = 0;
4594 pSMB->Reserved2 = 0;
4595 byte_count = params + 1 /* pad */ ;
4596 pSMB->TotalParameterCount = cpu_to_le16(params);
4597 pSMB->ParameterCount = pSMB->TotalParameterCount;
4598 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4599 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4600 pSMB->DataCount = 0;
4601 pSMB->DataOffset = 0;
4602 pSMB->SetupCount = 1;
4603 pSMB->Reserved3 = 0;
4604 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4605 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4606 inc_rfc1001_len(pSMB, byte_count);
4607 pSMB->ByteCount = cpu_to_le16(byte_count);
4609 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4610 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4612 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4613 } else { /* decode response */
4614 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4616 if (rc || get_bcc(&pSMBr->hdr) < 24)
4617 rc = -EIO; /* bad smb */
4619 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4623 *) (((char *) &pSMBr->hdr.Protocol) +
4626 le32_to_cpu(response_data->BytesPerSector) *
4627 le32_to_cpu(response_data->
4628 SectorsPerAllocationUnit);
4630 * much prefer larger but if server doesn't report
4631 * a valid size than 4K is a reasonable minimum
4633 if (FSData->f_bsize < 512)
4634 FSData->f_bsize = 4096;
4637 le64_to_cpu(response_data->TotalAllocationUnits);
4638 FSData->f_bfree = FSData->f_bavail =
4639 le64_to_cpu(response_data->FreeAllocationUnits);
4640 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4641 (unsigned long long)FSData->f_blocks,
4642 (unsigned long long)FSData->f_bfree,
4646 cifs_buf_release(pSMB);
4655 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
4657 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
4658 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4659 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4660 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
4662 int bytes_returned = 0;
4663 __u16 params, byte_count;
4665 cifs_dbg(FYI, "In QFSAttributeInfo\n");
4667 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4672 params = 2; /* level */
4673 pSMB->TotalDataCount = 0;
4674 pSMB->MaxParameterCount = cpu_to_le16(2);
4675 /* BB find exact max SMB PDU from sess structure BB */
4676 pSMB->MaxDataCount = cpu_to_le16(1000);
4677 pSMB->MaxSetupCount = 0;
4681 pSMB->Reserved2 = 0;
4682 byte_count = params + 1 /* pad */ ;
4683 pSMB->TotalParameterCount = cpu_to_le16(params);
4684 pSMB->ParameterCount = pSMB->TotalParameterCount;
4685 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4686 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4687 pSMB->DataCount = 0;
4688 pSMB->DataOffset = 0;
4689 pSMB->SetupCount = 1;
4690 pSMB->Reserved3 = 0;
4691 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4692 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4693 inc_rfc1001_len(pSMB, byte_count);
4694 pSMB->ByteCount = cpu_to_le16(byte_count);
4696 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4697 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4699 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
4700 } else { /* decode response */
4701 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4703 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4704 /* BB also check if enough bytes returned */
4705 rc = -EIO; /* bad smb */
4707 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4709 (FILE_SYSTEM_ATTRIBUTE_INFO
4710 *) (((char *) &pSMBr->hdr.Protocol) +
4712 memcpy(&tcon->fsAttrInfo, response_data,
4713 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
4716 cifs_buf_release(pSMB);
4719 goto QFSAttributeRetry;
4725 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
4727 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4728 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4729 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4730 FILE_SYSTEM_DEVICE_INFO *response_data;
4732 int bytes_returned = 0;
4733 __u16 params, byte_count;
4735 cifs_dbg(FYI, "In QFSDeviceInfo\n");
4737 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4742 params = 2; /* level */
4743 pSMB->TotalDataCount = 0;
4744 pSMB->MaxParameterCount = cpu_to_le16(2);
4745 /* BB find exact max SMB PDU from sess structure BB */
4746 pSMB->MaxDataCount = cpu_to_le16(1000);
4747 pSMB->MaxSetupCount = 0;
4751 pSMB->Reserved2 = 0;
4752 byte_count = params + 1 /* pad */ ;
4753 pSMB->TotalParameterCount = cpu_to_le16(params);
4754 pSMB->ParameterCount = pSMB->TotalParameterCount;
4755 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4756 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4758 pSMB->DataCount = 0;
4759 pSMB->DataOffset = 0;
4760 pSMB->SetupCount = 1;
4761 pSMB->Reserved3 = 0;
4762 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4763 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4764 inc_rfc1001_len(pSMB, byte_count);
4765 pSMB->ByteCount = cpu_to_le16(byte_count);
4767 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4768 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4770 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
4771 } else { /* decode response */
4772 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4774 if (rc || get_bcc(&pSMBr->hdr) <
4775 sizeof(FILE_SYSTEM_DEVICE_INFO))
4776 rc = -EIO; /* bad smb */
4778 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4780 (FILE_SYSTEM_DEVICE_INFO *)
4781 (((char *) &pSMBr->hdr.Protocol) +
4783 memcpy(&tcon->fsDevInfo, response_data,
4784 sizeof(FILE_SYSTEM_DEVICE_INFO));
4787 cifs_buf_release(pSMB);
4790 goto QFSDeviceRetry;
4796 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
4798 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
4799 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4800 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4801 FILE_SYSTEM_UNIX_INFO *response_data;
4803 int bytes_returned = 0;
4804 __u16 params, byte_count;
4806 cifs_dbg(FYI, "In QFSUnixInfo\n");
4808 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4809 (void **) &pSMB, (void **) &pSMBr);
4813 params = 2; /* level */
4814 pSMB->TotalDataCount = 0;
4815 pSMB->DataCount = 0;
4816 pSMB->DataOffset = 0;
4817 pSMB->MaxParameterCount = cpu_to_le16(2);
4818 /* BB find exact max SMB PDU from sess structure BB */
4819 pSMB->MaxDataCount = cpu_to_le16(100);
4820 pSMB->MaxSetupCount = 0;
4824 pSMB->Reserved2 = 0;
4825 byte_count = params + 1 /* pad */ ;
4826 pSMB->ParameterCount = cpu_to_le16(params);
4827 pSMB->TotalParameterCount = pSMB->ParameterCount;
4828 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4829 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4830 pSMB->SetupCount = 1;
4831 pSMB->Reserved3 = 0;
4832 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4833 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4834 inc_rfc1001_len(pSMB, byte_count);
4835 pSMB->ByteCount = cpu_to_le16(byte_count);
4837 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4838 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4840 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
4841 } else { /* decode response */
4842 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4844 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4845 rc = -EIO; /* bad smb */
4847 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4849 (FILE_SYSTEM_UNIX_INFO
4850 *) (((char *) &pSMBr->hdr.Protocol) +
4852 memcpy(&tcon->fsUnixInfo, response_data,
4853 sizeof(FILE_SYSTEM_UNIX_INFO));
4856 cifs_buf_release(pSMB);
4866 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
4868 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
4869 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
4870 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
4872 int bytes_returned = 0;
4873 __u16 params, param_offset, offset, byte_count;
4875 cifs_dbg(FYI, "In SETFSUnixInfo\n");
4877 /* BB switch to small buf init to save memory */
4878 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4879 (void **) &pSMB, (void **) &pSMBr);
4883 params = 4; /* 2 bytes zero followed by info level. */
4884 pSMB->MaxSetupCount = 0;
4888 pSMB->Reserved2 = 0;
4889 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
4891 offset = param_offset + params;
4893 pSMB->MaxParameterCount = cpu_to_le16(4);
4894 /* BB find exact max SMB PDU from sess structure BB */
4895 pSMB->MaxDataCount = cpu_to_le16(100);
4896 pSMB->SetupCount = 1;
4897 pSMB->Reserved3 = 0;
4898 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
4899 byte_count = 1 /* pad */ + params + 12;
4901 pSMB->DataCount = cpu_to_le16(12);
4902 pSMB->ParameterCount = cpu_to_le16(params);
4903 pSMB->TotalDataCount = pSMB->DataCount;
4904 pSMB->TotalParameterCount = pSMB->ParameterCount;
4905 pSMB->ParameterOffset = cpu_to_le16(param_offset);
4906 pSMB->DataOffset = cpu_to_le16(offset);
4910 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
4913 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
4914 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4915 pSMB->ClientUnixCap = cpu_to_le64(cap);
4917 inc_rfc1001_len(pSMB, byte_count);
4918 pSMB->ByteCount = cpu_to_le16(byte_count);
4920 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4921 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4923 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
4924 } else { /* decode response */
4925 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4927 rc = -EIO; /* bad smb */
4929 cifs_buf_release(pSMB);
4932 goto SETFSUnixRetry;
4940 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
4941 struct kstatfs *FSData)
4943 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
4944 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4945 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4946 FILE_SYSTEM_POSIX_INFO *response_data;
4948 int bytes_returned = 0;
4949 __u16 params, byte_count;
4951 cifs_dbg(FYI, "In QFSPosixInfo\n");
4953 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4958 params = 2; /* level */
4959 pSMB->TotalDataCount = 0;
4960 pSMB->DataCount = 0;
4961 pSMB->DataOffset = 0;
4962 pSMB->MaxParameterCount = cpu_to_le16(2);
4963 /* BB find exact max SMB PDU from sess structure BB */
4964 pSMB->MaxDataCount = cpu_to_le16(100);
4965 pSMB->MaxSetupCount = 0;
4969 pSMB->Reserved2 = 0;
4970 byte_count = params + 1 /* pad */ ;
4971 pSMB->ParameterCount = cpu_to_le16(params);
4972 pSMB->TotalParameterCount = pSMB->ParameterCount;
4973 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4974 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4975 pSMB->SetupCount = 1;
4976 pSMB->Reserved3 = 0;
4977 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4978 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4979 inc_rfc1001_len(pSMB, byte_count);
4980 pSMB->ByteCount = cpu_to_le16(byte_count);
4982 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4983 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4985 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
4986 } else { /* decode response */
4987 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4989 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4990 rc = -EIO; /* bad smb */
4992 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4994 (FILE_SYSTEM_POSIX_INFO
4995 *) (((char *) &pSMBr->hdr.Protocol) +
4998 le32_to_cpu(response_data->BlockSize);
5000 * much prefer larger but if server doesn't report
5001 * a valid size than 4K is a reasonable minimum
5003 if (FSData->f_bsize < 512)
5004 FSData->f_bsize = 4096;
5007 le64_to_cpu(response_data->TotalBlocks);
5009 le64_to_cpu(response_data->BlocksAvail);
5010 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5011 FSData->f_bavail = FSData->f_bfree;
5014 le64_to_cpu(response_data->UserBlocksAvail);
5016 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5018 le64_to_cpu(response_data->TotalFileNodes);
5019 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5021 le64_to_cpu(response_data->FreeFileNodes);
5024 cifs_buf_release(pSMB);
5034 * We can not use write of zero bytes trick to set file size due to need for
5035 * large file support. Also note that this SetPathInfo is preferred to
5036 * SetFileInfo based method in next routine which is only needed to work around
5037 * a sharing violation bugin Samba which this routine can run into.
5040 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5041 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5042 bool set_allocation)
5044 struct smb_com_transaction2_spi_req *pSMB = NULL;
5045 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5046 struct file_end_of_file_info *parm_data;
5049 int bytes_returned = 0;
5050 int remap = cifs_remap(cifs_sb);
5052 __u16 params, byte_count, data_count, param_offset, offset;
5054 cifs_dbg(FYI, "In SetEOF\n");
5056 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5061 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5063 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5064 PATH_MAX, cifs_sb->local_nls, remap);
5065 name_len++; /* trailing null */
5068 name_len = copy_path_name(pSMB->FileName, file_name);
5070 params = 6 + name_len;
5071 data_count = sizeof(struct file_end_of_file_info);
5072 pSMB->MaxParameterCount = cpu_to_le16(2);
5073 pSMB->MaxDataCount = cpu_to_le16(4100);
5074 pSMB->MaxSetupCount = 0;
5078 pSMB->Reserved2 = 0;
5079 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5080 InformationLevel) - 4;
5081 offset = param_offset + params;
5082 if (set_allocation) {
5083 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5084 pSMB->InformationLevel =
5085 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5087 pSMB->InformationLevel =
5088 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5089 } else /* Set File Size */ {
5090 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5091 pSMB->InformationLevel =
5092 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5094 pSMB->InformationLevel =
5095 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5099 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5101 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5102 pSMB->DataOffset = cpu_to_le16(offset);
5103 pSMB->SetupCount = 1;
5104 pSMB->Reserved3 = 0;
5105 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5106 byte_count = 3 /* pad */ + params + data_count;
5107 pSMB->DataCount = cpu_to_le16(data_count);
5108 pSMB->TotalDataCount = pSMB->DataCount;
5109 pSMB->ParameterCount = cpu_to_le16(params);
5110 pSMB->TotalParameterCount = pSMB->ParameterCount;
5111 pSMB->Reserved4 = 0;
5112 inc_rfc1001_len(pSMB, byte_count);
5113 parm_data->FileSize = cpu_to_le64(size);
5114 pSMB->ByteCount = cpu_to_le16(byte_count);
5115 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5116 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5118 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5120 cifs_buf_release(pSMB);
5129 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5130 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5132 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5133 struct file_end_of_file_info *parm_data;
5135 __u16 params, param_offset, offset, byte_count, count;
5137 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5139 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5144 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5145 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5148 pSMB->MaxSetupCount = 0;
5152 pSMB->Reserved2 = 0;
5153 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5154 offset = param_offset + params;
5156 count = sizeof(struct file_end_of_file_info);
5157 pSMB->MaxParameterCount = cpu_to_le16(2);
5158 /* BB find exact max SMB PDU from sess structure BB */
5159 pSMB->MaxDataCount = cpu_to_le16(1000);
5160 pSMB->SetupCount = 1;
5161 pSMB->Reserved3 = 0;
5162 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5163 byte_count = 3 /* pad */ + params + count;
5164 pSMB->DataCount = cpu_to_le16(count);
5165 pSMB->ParameterCount = cpu_to_le16(params);
5166 pSMB->TotalDataCount = pSMB->DataCount;
5167 pSMB->TotalParameterCount = pSMB->ParameterCount;
5168 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5169 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5171 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5172 pSMB->DataOffset = cpu_to_le16(offset);
5173 parm_data->FileSize = cpu_to_le64(size);
5174 pSMB->Fid = cfile->fid.netfid;
5175 if (set_allocation) {
5176 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5177 pSMB->InformationLevel =
5178 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5180 pSMB->InformationLevel =
5181 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5182 } else /* Set File Size */ {
5183 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5184 pSMB->InformationLevel =
5185 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5187 pSMB->InformationLevel =
5188 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5190 pSMB->Reserved4 = 0;
5191 inc_rfc1001_len(pSMB, byte_count);
5192 pSMB->ByteCount = cpu_to_le16(byte_count);
5193 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5194 cifs_small_buf_release(pSMB);
5196 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5200 /* Note: On -EAGAIN error only caller can retry on handle based calls
5201 since file handle passed in no longer valid */
5206 /* Some legacy servers such as NT4 require that the file times be set on
5207 an open handle, rather than by pathname - this is awkward due to
5208 potential access conflicts on the open, but it is unavoidable for these
5209 old servers since the only other choice is to go from 100 nanosecond DCE
5210 time and resort to the original setpathinfo level which takes the ancient
5211 DOS time format with 2 second granularity */
5213 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5214 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5216 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5219 __u16 params, param_offset, offset, byte_count, count;
5221 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5222 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5227 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5228 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5231 pSMB->MaxSetupCount = 0;
5235 pSMB->Reserved2 = 0;
5236 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5237 offset = param_offset + params;
5239 data_offset = (char *)pSMB +
5240 offsetof(struct smb_hdr, Protocol) + offset;
5242 count = sizeof(FILE_BASIC_INFO);
5243 pSMB->MaxParameterCount = cpu_to_le16(2);
5244 /* BB find max SMB PDU from sess */
5245 pSMB->MaxDataCount = cpu_to_le16(1000);
5246 pSMB->SetupCount = 1;
5247 pSMB->Reserved3 = 0;
5248 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5249 byte_count = 3 /* pad */ + params + count;
5250 pSMB->DataCount = cpu_to_le16(count);
5251 pSMB->ParameterCount = cpu_to_le16(params);
5252 pSMB->TotalDataCount = pSMB->DataCount;
5253 pSMB->TotalParameterCount = pSMB->ParameterCount;
5254 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5255 pSMB->DataOffset = cpu_to_le16(offset);
5257 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5258 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5260 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5261 pSMB->Reserved4 = 0;
5262 inc_rfc1001_len(pSMB, byte_count);
5263 pSMB->ByteCount = cpu_to_le16(byte_count);
5264 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5265 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5266 cifs_small_buf_release(pSMB);
5268 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5271 /* Note: On -EAGAIN error only caller can retry on handle based calls
5272 since file handle passed in no longer valid */
5278 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5279 bool delete_file, __u16 fid, __u32 pid_of_opener)
5281 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5284 __u16 params, param_offset, offset, byte_count, count;
5286 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5287 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5292 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5293 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5296 pSMB->MaxSetupCount = 0;
5300 pSMB->Reserved2 = 0;
5301 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5302 offset = param_offset + params;
5304 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5305 data_offset = (char *)(pSMB) + offset + 4;
5308 pSMB->MaxParameterCount = cpu_to_le16(2);
5309 /* BB find max SMB PDU from sess */
5310 pSMB->MaxDataCount = cpu_to_le16(1000);
5311 pSMB->SetupCount = 1;
5312 pSMB->Reserved3 = 0;
5313 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5314 byte_count = 3 /* pad */ + params + count;
5315 pSMB->DataCount = cpu_to_le16(count);
5316 pSMB->ParameterCount = cpu_to_le16(params);
5317 pSMB->TotalDataCount = pSMB->DataCount;
5318 pSMB->TotalParameterCount = pSMB->ParameterCount;
5319 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5320 pSMB->DataOffset = cpu_to_le16(offset);
5322 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5323 pSMB->Reserved4 = 0;
5324 inc_rfc1001_len(pSMB, byte_count);
5325 pSMB->ByteCount = cpu_to_le16(byte_count);
5326 *data_offset = delete_file ? 1 : 0;
5327 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5328 cifs_small_buf_release(pSMB);
5330 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5336 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5337 const char *fileName, const FILE_BASIC_INFO *data,
5338 const struct nls_table *nls_codepage,
5339 struct cifs_sb_info *cifs_sb)
5342 struct cifs_open_parms oparms;
5343 struct cifs_fid fid;
5346 oparms = (struct cifs_open_parms) {
5349 .desired_access = GENERIC_WRITE,
5350 .create_options = cifs_create_options(cifs_sb, 0),
5351 .disposition = FILE_OPEN,
5356 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5360 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5361 CIFSSMBClose(xid, tcon, fid.netfid);
5368 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5369 const char *fileName, const FILE_BASIC_INFO *data,
5370 const struct nls_table *nls_codepage,
5371 struct cifs_sb_info *cifs_sb)
5373 TRANSACTION2_SPI_REQ *pSMB = NULL;
5374 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5377 int bytes_returned = 0;
5379 __u16 params, param_offset, offset, byte_count, count;
5380 int remap = cifs_remap(cifs_sb);
5382 cifs_dbg(FYI, "In SetTimes\n");
5385 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5390 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5392 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5393 PATH_MAX, nls_codepage, remap);
5394 name_len++; /* trailing null */
5397 name_len = copy_path_name(pSMB->FileName, fileName);
5400 params = 6 + name_len;
5401 count = sizeof(FILE_BASIC_INFO);
5402 pSMB->MaxParameterCount = cpu_to_le16(2);
5403 /* BB find max SMB PDU from sess structure BB */
5404 pSMB->MaxDataCount = cpu_to_le16(1000);
5405 pSMB->MaxSetupCount = 0;
5409 pSMB->Reserved2 = 0;
5410 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5411 InformationLevel) - 4;
5412 offset = param_offset + params;
5413 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5414 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5415 pSMB->DataOffset = cpu_to_le16(offset);
5416 pSMB->SetupCount = 1;
5417 pSMB->Reserved3 = 0;
5418 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5419 byte_count = 3 /* pad */ + params + count;
5421 pSMB->DataCount = cpu_to_le16(count);
5422 pSMB->ParameterCount = cpu_to_le16(params);
5423 pSMB->TotalDataCount = pSMB->DataCount;
5424 pSMB->TotalParameterCount = pSMB->ParameterCount;
5425 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5426 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5428 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5429 pSMB->Reserved4 = 0;
5430 inc_rfc1001_len(pSMB, byte_count);
5431 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5432 pSMB->ByteCount = cpu_to_le16(byte_count);
5433 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5434 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5436 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5438 cifs_buf_release(pSMB);
5443 if (rc == -EOPNOTSUPP)
5444 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5445 nls_codepage, cifs_sb);
5451 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5452 const struct cifs_unix_set_info_args *args)
5454 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5455 u64 mode = args->mode;
5457 if (uid_valid(args->uid))
5458 uid = from_kuid(&init_user_ns, args->uid);
5459 if (gid_valid(args->gid))
5460 gid = from_kgid(&init_user_ns, args->gid);
5463 * Samba server ignores set of file size to zero due to bugs in some
5464 * older clients, but we should be precise - we use SetFileSize to
5465 * set file size and do not want to truncate file size to zero
5466 * accidentally as happened on one Samba server beta by putting
5467 * zero instead of -1 here
5469 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5470 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5471 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5472 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5473 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5474 data_offset->Uid = cpu_to_le64(uid);
5475 data_offset->Gid = cpu_to_le64(gid);
5476 /* better to leave device as zero when it is */
5477 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5478 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5479 data_offset->Permissions = cpu_to_le64(mode);
5482 data_offset->Type = cpu_to_le32(UNIX_FILE);
5483 else if (S_ISDIR(mode))
5484 data_offset->Type = cpu_to_le32(UNIX_DIR);
5485 else if (S_ISLNK(mode))
5486 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5487 else if (S_ISCHR(mode))
5488 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5489 else if (S_ISBLK(mode))
5490 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5491 else if (S_ISFIFO(mode))
5492 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5493 else if (S_ISSOCK(mode))
5494 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5498 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5499 const struct cifs_unix_set_info_args *args,
5500 u16 fid, u32 pid_of_opener)
5502 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5505 u16 params, param_offset, offset, byte_count, count;
5507 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5508 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5513 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5514 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5517 pSMB->MaxSetupCount = 0;
5521 pSMB->Reserved2 = 0;
5522 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5523 offset = param_offset + params;
5525 data_offset = (char *)pSMB +
5526 offsetof(struct smb_hdr, Protocol) + offset;
5528 count = sizeof(FILE_UNIX_BASIC_INFO);
5530 pSMB->MaxParameterCount = cpu_to_le16(2);
5531 /* BB find max SMB PDU from sess */
5532 pSMB->MaxDataCount = cpu_to_le16(1000);
5533 pSMB->SetupCount = 1;
5534 pSMB->Reserved3 = 0;
5535 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5536 byte_count = 3 /* pad */ + params + count;
5537 pSMB->DataCount = cpu_to_le16(count);
5538 pSMB->ParameterCount = cpu_to_le16(params);
5539 pSMB->TotalDataCount = pSMB->DataCount;
5540 pSMB->TotalParameterCount = pSMB->ParameterCount;
5541 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5542 pSMB->DataOffset = cpu_to_le16(offset);
5544 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5545 pSMB->Reserved4 = 0;
5546 inc_rfc1001_len(pSMB, byte_count);
5547 pSMB->ByteCount = cpu_to_le16(byte_count);
5549 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5551 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5552 cifs_small_buf_release(pSMB);
5554 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5557 /* Note: On -EAGAIN error only caller can retry on handle based calls
5558 since file handle passed in no longer valid */
5564 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5565 const char *file_name,
5566 const struct cifs_unix_set_info_args *args,
5567 const struct nls_table *nls_codepage, int remap)
5569 TRANSACTION2_SPI_REQ *pSMB = NULL;
5570 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5573 int bytes_returned = 0;
5574 FILE_UNIX_BASIC_INFO *data_offset;
5575 __u16 params, param_offset, offset, count, byte_count;
5577 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5579 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5584 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5586 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5587 PATH_MAX, nls_codepage, remap);
5588 name_len++; /* trailing null */
5591 name_len = copy_path_name(pSMB->FileName, file_name);
5594 params = 6 + name_len;
5595 count = sizeof(FILE_UNIX_BASIC_INFO);
5596 pSMB->MaxParameterCount = cpu_to_le16(2);
5597 /* BB find max SMB PDU from sess structure BB */
5598 pSMB->MaxDataCount = cpu_to_le16(1000);
5599 pSMB->MaxSetupCount = 0;
5603 pSMB->Reserved2 = 0;
5604 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5605 InformationLevel) - 4;
5606 offset = param_offset + params;
5607 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5608 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
5609 memset(data_offset, 0, count);
5610 pSMB->DataOffset = cpu_to_le16(offset);
5611 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5612 pSMB->SetupCount = 1;
5613 pSMB->Reserved3 = 0;
5614 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5615 byte_count = 3 /* pad */ + params + count;
5616 pSMB->ParameterCount = cpu_to_le16(params);
5617 pSMB->DataCount = cpu_to_le16(count);
5618 pSMB->TotalParameterCount = pSMB->ParameterCount;
5619 pSMB->TotalDataCount = pSMB->DataCount;
5620 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5621 pSMB->Reserved4 = 0;
5622 inc_rfc1001_len(pSMB, byte_count);
5624 cifs_fill_unix_set_info(data_offset, args);
5626 pSMB->ByteCount = cpu_to_le16(byte_count);
5627 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5628 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5630 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
5632 cifs_buf_release(pSMB);
5638 #ifdef CONFIG_CIFS_XATTR
5640 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
5641 * function used by listxattr and getxattr type calls. When ea_name is set,
5642 * it looks for that attribute name and stuffs that value into the EAData
5643 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
5644 * buffer. In both cases, the return value is either the length of the
5645 * resulting data or a negative error code. If EAData is a NULL pointer then
5646 * the data isn't copied to it, but the length is returned.
5649 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
5650 const unsigned char *searchName, const unsigned char *ea_name,
5651 char *EAData, size_t buf_size,
5652 struct cifs_sb_info *cifs_sb)
5654 /* BB assumes one setup word */
5655 TRANSACTION2_QPI_REQ *pSMB = NULL;
5656 TRANSACTION2_QPI_RSP *pSMBr = NULL;
5657 int remap = cifs_remap(cifs_sb);
5658 struct nls_table *nls_codepage = cifs_sb->local_nls;
5662 struct fealist *ea_response_data;
5663 struct fea *temp_fea;
5666 __u16 params, byte_count, data_offset;
5667 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
5669 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
5671 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5676 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5678 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
5679 PATH_MAX, nls_codepage, remap);
5680 list_len++; /* trailing null */
5683 list_len = copy_path_name(pSMB->FileName, searchName);
5686 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
5687 pSMB->TotalDataCount = 0;
5688 pSMB->MaxParameterCount = cpu_to_le16(2);
5689 /* BB find exact max SMB PDU from sess structure BB */
5690 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
5691 pSMB->MaxSetupCount = 0;
5695 pSMB->Reserved2 = 0;
5696 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5697 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5698 pSMB->DataCount = 0;
5699 pSMB->DataOffset = 0;
5700 pSMB->SetupCount = 1;
5701 pSMB->Reserved3 = 0;
5702 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
5703 byte_count = params + 1 /* pad */ ;
5704 pSMB->TotalParameterCount = cpu_to_le16(params);
5705 pSMB->ParameterCount = pSMB->TotalParameterCount;
5706 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5707 pSMB->Reserved4 = 0;
5708 inc_rfc1001_len(pSMB, byte_count);
5709 pSMB->ByteCount = cpu_to_le16(byte_count);
5711 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5712 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5714 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
5719 /* BB also check enough total bytes returned */
5720 /* BB we need to improve the validity checking
5721 of these trans2 responses */
5723 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5724 if (rc || get_bcc(&pSMBr->hdr) < 4) {
5725 rc = -EIO; /* bad smb */
5729 /* check that length of list is not more than bcc */
5730 /* check that each entry does not go beyond length
5732 /* check that each element of each entry does not
5733 go beyond end of list */
5734 /* validate_trans2_offsets() */
5735 /* BB check if start of smb + data_offset > &bcc+ bcc */
5737 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5738 ea_response_data = (struct fealist *)
5739 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5741 list_len = le32_to_cpu(ea_response_data->list_len);
5742 cifs_dbg(FYI, "ea length %d\n", list_len);
5743 if (list_len <= 8) {
5744 cifs_dbg(FYI, "empty EA list returned from server\n");
5745 /* didn't find the named attribute */
5751 /* make sure list_len doesn't go past end of SMB */
5752 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
5753 if ((char *)ea_response_data + list_len > end_of_smb) {
5754 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
5759 /* account for ea list len */
5761 temp_fea = &ea_response_data->list;
5762 temp_ptr = (char *)temp_fea;
5763 while (list_len > 0) {
5764 unsigned int name_len;
5769 /* make sure we can read name_len and value_len */
5771 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5776 name_len = temp_fea->name_len;
5777 value_len = le16_to_cpu(temp_fea->value_len);
5778 list_len -= name_len + 1 + value_len;
5780 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5786 if (ea_name_len == name_len &&
5787 memcmp(ea_name, temp_ptr, name_len) == 0) {
5788 temp_ptr += name_len + 1;
5792 if ((size_t)value_len > buf_size) {
5796 memcpy(EAData, temp_ptr, value_len);
5800 /* account for prefix user. and trailing null */
5801 rc += (5 + 1 + name_len);
5802 if (rc < (int) buf_size) {
5803 memcpy(EAData, "user.", 5);
5805 memcpy(EAData, temp_ptr, name_len);
5807 /* null terminate name */
5810 } else if (buf_size == 0) {
5811 /* skip copy - calc size only */
5813 /* stop before overrun buffer */
5818 temp_ptr += name_len + 1 + value_len;
5819 temp_fea = (struct fea *)temp_ptr;
5822 /* didn't find the named attribute */
5827 cifs_buf_release(pSMB);
5835 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
5836 const char *fileName, const char *ea_name, const void *ea_value,
5837 const __u16 ea_value_len, const struct nls_table *nls_codepage,
5838 struct cifs_sb_info *cifs_sb)
5840 struct smb_com_transaction2_spi_req *pSMB = NULL;
5841 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5842 struct fealist *parm_data;
5845 int bytes_returned = 0;
5846 __u16 params, param_offset, byte_count, offset, count;
5847 int remap = cifs_remap(cifs_sb);
5849 cifs_dbg(FYI, "In SetEA\n");
5851 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5856 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5858 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5859 PATH_MAX, nls_codepage, remap);
5860 name_len++; /* trailing null */
5863 name_len = copy_path_name(pSMB->FileName, fileName);
5866 params = 6 + name_len;
5868 /* done calculating parms using name_len of file name,
5869 now use name_len to calculate length of ea name
5870 we are going to create in the inode xattrs */
5871 if (ea_name == NULL)
5874 name_len = strnlen(ea_name, 255);
5876 count = sizeof(*parm_data) + 1 + ea_value_len + name_len;
5877 pSMB->MaxParameterCount = cpu_to_le16(2);
5878 /* BB find max SMB PDU from sess */
5879 pSMB->MaxDataCount = cpu_to_le16(1000);
5880 pSMB->MaxSetupCount = 0;
5884 pSMB->Reserved2 = 0;
5885 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5886 InformationLevel) - 4;
5887 offset = param_offset + params;
5888 pSMB->InformationLevel =
5889 cpu_to_le16(SMB_SET_FILE_EA);
5891 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
5892 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5893 pSMB->DataOffset = cpu_to_le16(offset);
5894 pSMB->SetupCount = 1;
5895 pSMB->Reserved3 = 0;
5896 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5897 byte_count = 3 /* pad */ + params + count;
5898 pSMB->DataCount = cpu_to_le16(count);
5899 parm_data->list_len = cpu_to_le32(count);
5900 parm_data->list.EA_flags = 0;
5901 /* we checked above that name len is less than 255 */
5902 parm_data->list.name_len = (__u8)name_len;
5903 /* EA names are always ASCII */
5905 strncpy(parm_data->list.name, ea_name, name_len);
5906 parm_data->list.name[name_len] = '\0';
5907 parm_data->list.value_len = cpu_to_le16(ea_value_len);
5908 /* caller ensures that ea_value_len is less than 64K but
5909 we need to ensure that it fits within the smb */
5911 /*BB add length check to see if it would fit in
5912 negotiated SMB buffer size BB */
5913 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
5915 memcpy(parm_data->list.name + name_len + 1,
5916 ea_value, ea_value_len);
5918 pSMB->TotalDataCount = pSMB->DataCount;
5919 pSMB->ParameterCount = cpu_to_le16(params);
5920 pSMB->TotalParameterCount = pSMB->ParameterCount;
5921 pSMB->Reserved4 = 0;
5922 inc_rfc1001_len(pSMB, byte_count);
5923 pSMB->ByteCount = cpu_to_le16(byte_count);
5924 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5925 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5927 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
5929 cifs_buf_release(pSMB);