1 // SPDX-License-Identifier: LGPL-2.1
4 * Copyright (C) International Business Machines Corp., 2002,2010
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for constructing the SMB PDUs themselves
11 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
12 /* These are mostly routines that operate on a pathname, or on a tree id */
13 /* (mounted volume), but there are eight handle based routines which must be */
14 /* treated slightly differently for reconnection purposes since we never */
15 /* want to reuse a stale file handle and only the caller knows the file info */
18 #include <linux/kernel.h>
19 #include <linux/vfs.h>
20 #include <linux/slab.h>
21 #include <linux/posix_acl_xattr.h>
22 #include <linux/pagemap.h>
23 #include <linux/swap.h>
24 #include <linux/task_io_accounting_ops.h>
25 #include <linux/uaccess.h>
29 #include "cifsproto.h"
30 #include "cifs_unicode.h"
31 #include "cifs_debug.h"
33 #include "smbdirect.h"
34 #ifdef CONFIG_CIFS_DFS_UPCALL
35 #include "dfs_cache.h"
38 #ifdef CONFIG_CIFS_POSIX
43 {CIFS_PROT, "\2NT LM 0.12"},
44 {POSIX_PROT, "\2POSIX 2"},
52 {CIFS_PROT, "\2NT LM 0.12"},
57 /* define the number of elements in the cifs dialect array */
58 #ifdef CONFIG_CIFS_POSIX
59 #define CIFS_NUM_PROT 2
61 #define CIFS_NUM_PROT 1
62 #endif /* CIFS_POSIX */
65 /* reconnect the socket, tcon, and smb session if needed */
67 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
71 struct TCP_Server_Info *server;
72 struct nls_table *nls_codepage = NULL;
75 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
76 * tcp and smb session status done differently for those three - in the
86 * only tree disconnect, open, and write, (and ulogoff which does not
87 * have tcon) are allowed as we start umount
89 spin_lock(&tcon->tc_lock);
90 if (tcon->status == TID_EXITING) {
91 if (smb_command != SMB_COM_TREE_DISCONNECT) {
92 spin_unlock(&tcon->tc_lock);
93 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
98 spin_unlock(&tcon->tc_lock);
101 rc = cifs_wait_for_server_reconnect(server, tcon->retry);
105 spin_lock(&ses->chan_lock);
106 if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
107 spin_unlock(&ses->chan_lock);
110 spin_unlock(&ses->chan_lock);
112 mutex_lock(&ses->session_mutex);
114 * Recheck after acquire mutex. If another thread is negotiating
115 * and the server never sends an answer the socket will be closed
116 * and tcpStatus set to reconnect.
118 spin_lock(&server->srv_lock);
119 if (server->tcpStatus == CifsNeedReconnect) {
120 spin_unlock(&server->srv_lock);
121 mutex_unlock(&ses->session_mutex);
128 spin_unlock(&server->srv_lock);
130 nls_codepage = ses->local_nls;
133 * need to prevent multiple threads trying to simultaneously
134 * reconnect the same SMB session
136 spin_lock(&ses->ses_lock);
137 spin_lock(&ses->chan_lock);
138 if (!cifs_chan_needs_reconnect(ses, server) &&
139 ses->ses_status == SES_GOOD) {
140 spin_unlock(&ses->chan_lock);
141 spin_unlock(&ses->ses_lock);
143 /* this means that we only need to tree connect */
144 if (tcon->need_reconnect)
145 goto skip_sess_setup;
147 mutex_unlock(&ses->session_mutex);
150 spin_unlock(&ses->chan_lock);
151 spin_unlock(&ses->ses_lock);
153 rc = cifs_negotiate_protocol(0, ses, server);
155 rc = cifs_setup_session(0, ses, server, nls_codepage);
157 /* do we need to reconnect tcon? */
158 if (rc || !tcon->need_reconnect) {
159 mutex_unlock(&ses->session_mutex);
164 cifs_mark_open_files_invalid(tcon);
165 rc = cifs_tree_connect(0, tcon, nls_codepage);
166 mutex_unlock(&ses->session_mutex);
167 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
170 pr_warn_once("reconnect tcon failed rc = %d\n", rc);
174 atomic_inc(&tconInfoReconnectCount);
176 /* tell server Unix caps we support */
178 reset_cifs_unix_caps(0, tcon, NULL, NULL);
181 * Removed call to reopen open files here. It is safer (and faster) to
182 * reopen files one at a time as needed in read and write.
184 * FIXME: what about file locks? don't we need to reclaim them ASAP?
189 * Check if handle based operation so we know whether we can continue
190 * or not without returning to caller to reset file handle
192 switch (smb_command) {
193 case SMB_COM_READ_ANDX:
194 case SMB_COM_WRITE_ANDX:
196 case SMB_COM_FIND_CLOSE2:
197 case SMB_COM_LOCKING_ANDX:
204 /* Allocate and return pointer to an SMB request buffer, and set basic
205 SMB information in the SMB header. If the return code is zero, this
206 function must have filled in request_buf pointer */
208 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
213 rc = cifs_reconnect_tcon(tcon, smb_command);
217 *request_buf = cifs_small_buf_get();
218 if (*request_buf == NULL) {
219 /* BB should we add a retry in here if not a writepage? */
223 header_assemble((struct smb_hdr *) *request_buf, smb_command,
227 cifs_stats_inc(&tcon->num_smbs_sent);
233 small_smb_init_no_tc(const int smb_command, const int wct,
234 struct cifs_ses *ses, void **request_buf)
237 struct smb_hdr *buffer;
239 rc = small_smb_init(smb_command, wct, NULL, request_buf);
243 buffer = (struct smb_hdr *)*request_buf;
244 buffer->Mid = get_next_mid(ses->server);
245 if (ses->capabilities & CAP_UNICODE)
246 buffer->Flags2 |= SMBFLG2_UNICODE;
247 if (ses->capabilities & CAP_STATUS32)
248 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
250 /* uid, tid can stay at zero as set in header assemble */
252 /* BB add support for turning on the signing when
253 this function is used after 1st of session setup requests */
258 /* If the return code is zero, this function must fill in request_buf pointer */
260 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
261 void **request_buf, void **response_buf)
263 *request_buf = cifs_buf_get();
264 if (*request_buf == NULL) {
265 /* BB should we add a retry in here if not a writepage? */
268 /* Although the original thought was we needed the response buf for */
269 /* potential retries of smb operations it turns out we can determine */
270 /* from the mid flags when the request buffer can be resent without */
271 /* having to use a second distinct buffer for the response */
273 *response_buf = *request_buf;
275 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
279 cifs_stats_inc(&tcon->num_smbs_sent);
284 /* If the return code is zero, this function must fill in request_buf pointer */
286 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
287 void **request_buf, void **response_buf)
291 rc = cifs_reconnect_tcon(tcon, smb_command);
295 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
299 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
300 void **request_buf, void **response_buf)
302 spin_lock(&tcon->ses->chan_lock);
303 if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) ||
304 tcon->need_reconnect) {
305 spin_unlock(&tcon->ses->chan_lock);
308 spin_unlock(&tcon->ses->chan_lock);
310 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
313 static int validate_t2(struct smb_t2_rsp *pSMB)
315 unsigned int total_size;
317 /* check for plausible wct */
318 if (pSMB->hdr.WordCount < 10)
321 /* check for parm and data offset going beyond end of smb */
322 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
323 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
326 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
327 if (total_size >= 512)
330 /* check that bcc is at least as big as parms + data, and that it is
331 * less than negotiated smb buffer
333 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
334 if (total_size > get_bcc(&pSMB->hdr) ||
335 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
340 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
341 sizeof(struct smb_t2_rsp) + 16);
346 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
350 char *guid = pSMBr->u.extended_response.GUID;
351 struct TCP_Server_Info *server = ses->server;
353 count = get_bcc(&pSMBr->hdr);
354 if (count < SMB1_CLIENT_GUID_SIZE)
357 spin_lock(&cifs_tcp_ses_lock);
358 if (server->srv_count > 1) {
359 spin_unlock(&cifs_tcp_ses_lock);
360 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
361 cifs_dbg(FYI, "server UID changed\n");
362 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
365 spin_unlock(&cifs_tcp_ses_lock);
366 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
369 if (count == SMB1_CLIENT_GUID_SIZE) {
370 server->sec_ntlmssp = true;
372 count -= SMB1_CLIENT_GUID_SIZE;
373 rc = decode_negTokenInit(
374 pSMBr->u.extended_response.SecurityBlob, count, server);
383 should_set_ext_sec_flag(enum securityEnum sectype)
390 if (global_secflags &
391 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
400 CIFSSMBNegotiate(const unsigned int xid,
401 struct cifs_ses *ses,
402 struct TCP_Server_Info *server)
405 NEGOTIATE_RSP *pSMBr;
412 WARN(1, "%s: server is NULL!\n", __func__);
416 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
417 (void **) &pSMB, (void **) &pSMBr);
421 pSMB->hdr.Mid = get_next_mid(server);
422 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
424 if (should_set_ext_sec_flag(ses->sectype)) {
425 cifs_dbg(FYI, "Requesting extended security\n");
426 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
431 * We know that all the name entries in the protocols array
432 * are short (< 16 bytes anyway) and are NUL terminated.
434 for (i = 0; i < CIFS_NUM_PROT; i++) {
435 size_t len = strlen(protocols[i].name) + 1;
437 memcpy(&pSMB->DialectsArray[count], protocols[i].name, len);
440 inc_rfc1001_len(pSMB, count);
441 pSMB->ByteCount = cpu_to_le16(count);
443 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
444 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
448 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
449 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
450 /* Check wct = 1 error case */
451 if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
452 /* core returns wct = 1, but we do not ask for core - otherwise
453 small wct just comes when dialect index is -1 indicating we
454 could not negotiate a common dialect */
457 } else if (pSMBr->hdr.WordCount != 17) {
462 /* else wct == 17, NTLM or better */
464 server->sec_mode = pSMBr->SecurityMode;
465 if ((server->sec_mode & SECMODE_USER) == 0)
466 cifs_dbg(FYI, "share mode security\n");
468 /* one byte, so no need to convert this or EncryptionKeyLen from
470 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
472 set_credits(server, server->maxReq);
473 /* probably no need to store and check maxvcs */
474 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
475 /* set up max_read for readpages check */
476 server->max_read = server->maxBuf;
477 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
478 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
479 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
480 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
481 server->timeAdj *= 60;
483 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
484 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
485 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
486 CIFS_CRYPTO_KEY_SIZE);
487 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
488 server->capabilities & CAP_EXTENDED_SECURITY) {
489 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
490 rc = decode_ext_sec_blob(ses, pSMBr);
491 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
492 rc = -EIO; /* no crypt key only if plain text pwd */
494 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
495 server->capabilities &= ~CAP_EXTENDED_SECURITY;
499 rc = cifs_enable_signing(server, ses->sign);
501 cifs_buf_release(pSMB);
503 cifs_dbg(FYI, "negprot rc %d\n", rc);
508 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
510 struct smb_hdr *smb_buffer;
513 cifs_dbg(FYI, "In tree disconnect\n");
515 /* BB: do we need to check this? These should never be NULL. */
516 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
520 * No need to return error on this operation if tid invalidated and
521 * closed on server already e.g. due to tcp session crashing. Also,
522 * the tcon is no longer on the list, so no need to take lock before
525 spin_lock(&tcon->ses->chan_lock);
526 if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
527 spin_unlock(&tcon->ses->chan_lock);
530 spin_unlock(&tcon->ses->chan_lock);
532 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
533 (void **)&smb_buffer);
537 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
538 cifs_small_buf_release(smb_buffer);
540 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
542 /* No need to return error on this operation if tid invalidated and
543 closed on server already e.g. due to tcp session crashing */
551 * This is a no-op for now. We're not really interested in the reply, but
552 * rather in the fact that the server sent one and that server->lstrp
555 * FIXME: maybe we should consider checking that the reply matches request?
558 cifs_echo_callback(struct mid_q_entry *mid)
560 struct TCP_Server_Info *server = mid->callback_data;
561 struct cifs_credits credits = { .value = 1, .instance = 0 };
564 add_credits(server, &credits, CIFS_ECHO_OP);
568 CIFSSMBEcho(struct TCP_Server_Info *server)
573 struct smb_rqst rqst = { .rq_iov = iov,
576 cifs_dbg(FYI, "In echo request\n");
578 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
582 if (server->capabilities & CAP_UNICODE)
583 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
585 /* set up echo request */
586 smb->hdr.Tid = 0xffff;
587 smb->hdr.WordCount = 1;
588 put_unaligned_le16(1, &smb->EchoCount);
589 put_bcc(1, &smb->hdr);
591 inc_rfc1001_len(smb, 3);
594 iov[0].iov_base = smb;
595 iov[1].iov_len = get_rfc1002_length(smb);
596 iov[1].iov_base = (char *)smb + 4;
598 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
599 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
601 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
603 cifs_small_buf_release(smb);
609 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
611 LOGOFF_ANDX_REQ *pSMB;
614 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
617 * BB: do we need to check validity of ses and server? They should
618 * always be valid since we have an active reference. If not, that
619 * should probably be a BUG()
621 if (!ses || !ses->server)
624 mutex_lock(&ses->session_mutex);
625 spin_lock(&ses->chan_lock);
626 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
627 spin_unlock(&ses->chan_lock);
628 goto session_already_dead; /* no need to send SMBlogoff if uid
629 already closed due to reconnect */
631 spin_unlock(&ses->chan_lock);
633 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
635 mutex_unlock(&ses->session_mutex);
639 pSMB->hdr.Mid = get_next_mid(ses->server);
641 if (ses->server->sign)
642 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
644 pSMB->hdr.Uid = ses->Suid;
646 pSMB->AndXCommand = 0xFF;
647 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
648 cifs_small_buf_release(pSMB);
649 session_already_dead:
650 mutex_unlock(&ses->session_mutex);
652 /* if session dead then we do not need to do ulogoff,
653 since server closed smb session, no sense reporting
661 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
662 const char *fileName, __u16 type,
663 const struct nls_table *nls_codepage, int remap)
665 TRANSACTION2_SPI_REQ *pSMB = NULL;
666 TRANSACTION2_SPI_RSP *pSMBr = NULL;
667 struct unlink_psx_rq *pRqD;
670 int bytes_returned = 0;
671 __u16 params, param_offset, offset, byte_count;
673 cifs_dbg(FYI, "In POSIX delete\n");
675 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
680 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
682 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
683 PATH_MAX, nls_codepage, remap);
684 name_len++; /* trailing null */
687 name_len = copy_path_name(pSMB->FileName, fileName);
690 params = 6 + name_len;
691 pSMB->MaxParameterCount = cpu_to_le16(2);
692 pSMB->MaxDataCount = 0; /* BB double check this with jra */
693 pSMB->MaxSetupCount = 0;
698 param_offset = offsetof(struct smb_com_transaction2_spi_req,
699 InformationLevel) - 4;
700 offset = param_offset + params;
702 /* Setup pointer to Request Data (inode type).
703 * Note that SMB offsets are from the beginning of SMB which is 4 bytes
704 * in, after RFC1001 field
706 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
707 pRqD->type = cpu_to_le16(type);
708 pSMB->ParameterOffset = cpu_to_le16(param_offset);
709 pSMB->DataOffset = cpu_to_le16(offset);
710 pSMB->SetupCount = 1;
712 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
713 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
715 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
716 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
717 pSMB->ParameterCount = cpu_to_le16(params);
718 pSMB->TotalParameterCount = pSMB->ParameterCount;
719 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
721 inc_rfc1001_len(pSMB, byte_count);
722 pSMB->ByteCount = cpu_to_le16(byte_count);
723 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
724 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
726 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
727 cifs_buf_release(pSMB);
729 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
738 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
739 struct cifs_sb_info *cifs_sb)
741 DELETE_FILE_REQ *pSMB = NULL;
742 DELETE_FILE_RSP *pSMBr = NULL;
746 int remap = cifs_remap(cifs_sb);
749 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
754 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
755 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
756 PATH_MAX, cifs_sb->local_nls,
758 name_len++; /* trailing null */
761 name_len = copy_path_name(pSMB->fileName, name);
763 pSMB->SearchAttributes =
764 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
765 pSMB->BufferFormat = 0x04;
766 inc_rfc1001_len(pSMB, name_len + 1);
767 pSMB->ByteCount = cpu_to_le16(name_len + 1);
768 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
769 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
770 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
772 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
774 cifs_buf_release(pSMB);
782 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
783 struct cifs_sb_info *cifs_sb)
785 DELETE_DIRECTORY_REQ *pSMB = NULL;
786 DELETE_DIRECTORY_RSP *pSMBr = NULL;
790 int remap = cifs_remap(cifs_sb);
792 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
794 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
799 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
800 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
801 PATH_MAX, cifs_sb->local_nls,
803 name_len++; /* trailing null */
806 name_len = copy_path_name(pSMB->DirName, name);
809 pSMB->BufferFormat = 0x04;
810 inc_rfc1001_len(pSMB, name_len + 1);
811 pSMB->ByteCount = cpu_to_le16(name_len + 1);
812 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
813 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
814 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
816 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
818 cifs_buf_release(pSMB);
825 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
826 struct cifs_tcon *tcon, const char *name,
827 struct cifs_sb_info *cifs_sb)
830 CREATE_DIRECTORY_REQ *pSMB = NULL;
831 CREATE_DIRECTORY_RSP *pSMBr = NULL;
834 int remap = cifs_remap(cifs_sb);
836 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
838 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
843 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
844 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
845 PATH_MAX, cifs_sb->local_nls,
847 name_len++; /* trailing null */
850 name_len = copy_path_name(pSMB->DirName, name);
853 pSMB->BufferFormat = 0x04;
854 inc_rfc1001_len(pSMB, name_len + 1);
855 pSMB->ByteCount = cpu_to_le16(name_len + 1);
856 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
857 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
858 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
860 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
862 cifs_buf_release(pSMB);
869 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
870 __u32 posix_flags, __u64 mode, __u16 *netfid,
871 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
872 const char *name, const struct nls_table *nls_codepage,
875 TRANSACTION2_SPI_REQ *pSMB = NULL;
876 TRANSACTION2_SPI_RSP *pSMBr = NULL;
879 int bytes_returned = 0;
880 __u16 params, param_offset, offset, byte_count, count;
882 OPEN_PSX_RSP *psx_rsp;
884 cifs_dbg(FYI, "In POSIX Create\n");
886 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
891 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
893 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
894 PATH_MAX, nls_codepage, remap);
895 name_len++; /* trailing null */
898 name_len = copy_path_name(pSMB->FileName, name);
901 params = 6 + name_len;
902 count = sizeof(OPEN_PSX_REQ);
903 pSMB->MaxParameterCount = cpu_to_le16(2);
904 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
905 pSMB->MaxSetupCount = 0;
910 param_offset = offsetof(struct smb_com_transaction2_spi_req,
911 InformationLevel) - 4;
912 offset = param_offset + params;
913 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
914 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
915 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
916 pdata->Permissions = cpu_to_le64(mode);
917 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
918 pdata->OpenFlags = cpu_to_le32(*pOplock);
919 pSMB->ParameterOffset = cpu_to_le16(param_offset);
920 pSMB->DataOffset = cpu_to_le16(offset);
921 pSMB->SetupCount = 1;
923 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
924 byte_count = 3 /* pad */ + params + count;
926 pSMB->DataCount = cpu_to_le16(count);
927 pSMB->ParameterCount = cpu_to_le16(params);
928 pSMB->TotalDataCount = pSMB->DataCount;
929 pSMB->TotalParameterCount = pSMB->ParameterCount;
930 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
932 inc_rfc1001_len(pSMB, byte_count);
933 pSMB->ByteCount = cpu_to_le16(byte_count);
934 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
935 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
937 cifs_dbg(FYI, "Posix create returned %d\n", rc);
941 cifs_dbg(FYI, "copying inode info\n");
942 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
944 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
945 rc = -EIO; /* bad smb */
949 /* copy return information to pRetData */
950 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
951 + le16_to_cpu(pSMBr->t2.DataOffset));
953 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
955 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
956 /* Let caller know file was created so we can set the mode. */
957 /* Do we care about the CreateAction in any other cases? */
958 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
959 *pOplock |= CIFS_CREATE_ACTION;
960 /* check to make sure response data is there */
961 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
962 pRetData->Type = cpu_to_le32(-1); /* unknown */
963 cifs_dbg(NOISY, "unknown type\n");
965 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
966 + sizeof(FILE_UNIX_BASIC_INFO)) {
967 cifs_dbg(VFS, "Open response data too small\n");
968 pRetData->Type = cpu_to_le32(-1);
971 memcpy((char *) pRetData,
972 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
973 sizeof(FILE_UNIX_BASIC_INFO));
977 cifs_buf_release(pSMB);
979 if (posix_flags & SMB_O_DIRECTORY)
980 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
982 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
990 static __u16 convert_disposition(int disposition)
994 switch (disposition) {
996 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
999 ofun = SMBOPEN_OAPPEND;
1002 ofun = SMBOPEN_OCREATE;
1005 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1007 case FILE_OVERWRITE:
1008 ofun = SMBOPEN_OTRUNC;
1010 case FILE_OVERWRITE_IF:
1011 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1014 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1015 ofun = SMBOPEN_OAPPEND; /* regular open */
1021 access_flags_to_smbopen_mode(const int access_flags)
1023 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1025 if (masked_flags == GENERIC_READ)
1026 return SMBOPEN_READ;
1027 else if (masked_flags == GENERIC_WRITE)
1028 return SMBOPEN_WRITE;
1030 /* just go for read/write */
1031 return SMBOPEN_READWRITE;
1035 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1036 const char *fileName, const int openDisposition,
1037 const int access_flags, const int create_options, __u16 *netfid,
1038 int *pOplock, FILE_ALL_INFO *pfile_info,
1039 const struct nls_table *nls_codepage, int remap)
1042 OPENX_REQ *pSMB = NULL;
1043 OPENX_RSP *pSMBr = NULL;
1049 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1054 pSMB->AndXCommand = 0xFF; /* none */
1056 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1057 count = 1; /* account for one byte pad to word boundary */
1059 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1060 fileName, PATH_MAX, nls_codepage, remap);
1061 name_len++; /* trailing null */
1064 count = 0; /* no pad */
1065 name_len = copy_path_name(pSMB->fileName, fileName);
1067 if (*pOplock & REQ_OPLOCK)
1068 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1069 else if (*pOplock & REQ_BATCHOPLOCK)
1070 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1072 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1073 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1074 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1075 /* set file as system file if special file such
1076 as fifo and server expecting SFU style and
1077 no Unix extensions */
1079 if (create_options & CREATE_OPTION_SPECIAL)
1080 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1081 else /* BB FIXME BB */
1082 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1084 if (create_options & CREATE_OPTION_READONLY)
1085 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1088 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1089 CREATE_OPTIONS_MASK); */
1090 /* BB FIXME END BB */
1092 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1093 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1095 inc_rfc1001_len(pSMB, count);
1097 pSMB->ByteCount = cpu_to_le16(count);
1098 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1099 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1100 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1102 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1104 /* BB verify if wct == 15 */
1106 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1108 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1109 /* Let caller know file was created so we can set the mode. */
1110 /* Do we care about the CreateAction in any other cases? */
1112 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1113 *pOplock |= CIFS_CREATE_ACTION; */
1117 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1118 pfile_info->LastAccessTime = 0; /* BB fixme */
1119 pfile_info->LastWriteTime = 0; /* BB fixme */
1120 pfile_info->ChangeTime = 0; /* BB fixme */
1121 pfile_info->Attributes =
1122 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1123 /* the file_info buf is endian converted by caller */
1124 pfile_info->AllocationSize =
1125 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1126 pfile_info->EndOfFile = pfile_info->AllocationSize;
1127 pfile_info->NumberOfLinks = cpu_to_le32(1);
1128 pfile_info->DeletePending = 0;
1132 cifs_buf_release(pSMB);
1139 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1143 OPEN_REQ *req = NULL;
1144 OPEN_RSP *rsp = NULL;
1148 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1149 struct cifs_tcon *tcon = oparms->tcon;
1150 int remap = cifs_remap(cifs_sb);
1151 const struct nls_table *nls = cifs_sb->local_nls;
1152 int create_options = oparms->create_options;
1153 int desired_access = oparms->desired_access;
1154 int disposition = oparms->disposition;
1155 const char *path = oparms->path;
1158 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1163 /* no commands go after this */
1164 req->AndXCommand = 0xFF;
1166 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1167 /* account for one byte pad to word boundary */
1169 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1170 path, PATH_MAX, nls, remap);
1174 req->NameLength = cpu_to_le16(name_len);
1176 /* BB improve check for buffer overruns BB */
1179 name_len = copy_path_name(req->fileName, path);
1180 req->NameLength = cpu_to_le16(name_len);
1183 if (*oplock & REQ_OPLOCK)
1184 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1185 else if (*oplock & REQ_BATCHOPLOCK)
1186 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1188 req->DesiredAccess = cpu_to_le32(desired_access);
1189 req->AllocationSize = 0;
1192 * Set file as system file if special file such as fifo and server
1193 * expecting SFU style and no Unix extensions.
1195 if (create_options & CREATE_OPTION_SPECIAL)
1196 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1198 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1201 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1202 * sensitive checks for other servers such as Samba.
1204 if (tcon->ses->capabilities & CAP_UNIX)
1205 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1207 if (create_options & CREATE_OPTION_READONLY)
1208 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1210 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1211 req->CreateDisposition = cpu_to_le32(disposition);
1212 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1214 /* BB Expirement with various impersonation levels and verify */
1215 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1216 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1219 inc_rfc1001_len(req, count);
1221 req->ByteCount = cpu_to_le16(count);
1222 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1223 (struct smb_hdr *)rsp, &bytes_returned, 0);
1224 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1226 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1227 cifs_buf_release(req);
1233 /* 1 byte no need to le_to_cpu */
1234 *oplock = rsp->OplockLevel;
1235 /* cifs fid stays in le */
1236 oparms->fid->netfid = rsp->Fid;
1237 oparms->fid->access = desired_access;
1239 /* Let caller know file was created so we can set the mode. */
1240 /* Do we care about the CreateAction in any other cases? */
1241 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1242 *oplock |= CIFS_CREATE_ACTION;
1245 /* copy from CreationTime to Attributes */
1246 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1247 /* the file_info buf is endian converted by caller */
1248 buf->AllocationSize = rsp->AllocationSize;
1249 buf->EndOfFile = rsp->EndOfFile;
1250 buf->NumberOfLinks = cpu_to_le32(1);
1251 buf->DeletePending = 0;
1254 cifs_buf_release(req);
1259 cifs_readv_callback(struct mid_q_entry *mid)
1261 struct cifs_readdata *rdata = mid->callback_data;
1262 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1263 struct TCP_Server_Info *server = tcon->ses->server;
1264 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1266 .rq_pages = rdata->pages,
1267 .rq_offset = rdata->page_offset,
1268 .rq_npages = rdata->nr_pages,
1269 .rq_pagesz = rdata->pagesz,
1270 .rq_tailsz = rdata->tailsz };
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_pages = wdata->pages;
1710 rqst.rq_offset = wdata->page_offset;
1711 rqst.rq_npages = wdata->nr_pages;
1712 rqst.rq_pagesz = wdata->pagesz;
1713 rqst.rq_tailsz = wdata->tailsz;
1715 cifs_dbg(FYI, "async write at %llu %u bytes\n",
1716 wdata->offset, wdata->bytes);
1718 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
1719 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
1722 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
1723 put_bcc(wdata->bytes + 1, &smb->hdr);
1726 struct smb_com_writex_req *smbw =
1727 (struct smb_com_writex_req *)smb;
1728 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
1729 put_bcc(wdata->bytes + 5, &smbw->hdr);
1730 iov[1].iov_len += 4; /* pad bigger by four bytes */
1733 kref_get(&wdata->refcount);
1734 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
1735 cifs_writev_callback, NULL, wdata, 0, NULL);
1738 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1740 kref_put(&wdata->refcount, release);
1743 cifs_small_buf_release(smb);
1748 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
1749 unsigned int *nbytes, struct kvec *iov, int n_vec)
1752 WRITE_REQ *pSMB = NULL;
1755 int resp_buf_type = 0;
1756 __u32 pid = io_parms->pid;
1757 __u16 netfid = io_parms->netfid;
1758 __u64 offset = io_parms->offset;
1759 struct cifs_tcon *tcon = io_parms->tcon;
1760 unsigned int count = io_parms->length;
1761 struct kvec rsp_iov;
1765 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
1767 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1771 if ((offset >> 32) > 0) {
1772 /* can not handle big offset for old srv */
1776 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
1780 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1781 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1783 /* tcon and ses pointer are checked in smb_init */
1784 if (tcon->ses->server == NULL)
1785 return -ECONNABORTED;
1787 pSMB->AndXCommand = 0xFF; /* none */
1789 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1791 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1792 pSMB->Reserved = 0xFFFFFFFF;
1793 pSMB->WriteMode = 0;
1794 pSMB->Remaining = 0;
1797 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1799 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1800 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1801 /* header + 1 byte pad */
1802 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
1804 inc_rfc1001_len(pSMB, count + 1);
1805 else /* wct == 12 */
1806 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
1808 pSMB->ByteCount = cpu_to_le16(count + 1);
1809 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1810 struct smb_com_writex_req *pSMBW =
1811 (struct smb_com_writex_req *)pSMB;
1812 pSMBW->ByteCount = cpu_to_le16(count + 5);
1814 iov[0].iov_base = pSMB;
1816 iov[0].iov_len = smb_hdr_len + 4;
1817 else /* wct == 12 pad bigger by four bytes */
1818 iov[0].iov_len = smb_hdr_len + 8;
1820 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
1822 cifs_small_buf_release(pSMB);
1823 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1825 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
1826 } else if (resp_buf_type == 0) {
1827 /* presumably this can not happen, but best to be safe */
1830 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
1831 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1832 *nbytes = (*nbytes) << 16;
1833 *nbytes += le16_to_cpu(pSMBr->Count);
1836 * Mask off high 16 bits when bytes written as returned by the
1837 * server is greater than bytes requested by the client. OS/2
1838 * servers are known to set incorrect CountHigh values.
1840 if (*nbytes > count)
1844 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1846 /* Note: On -EAGAIN error only caller can retry on handle based calls
1847 since file handle passed in no longer valid */
1852 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
1853 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
1854 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
1857 LOCK_REQ *pSMB = NULL;
1859 struct kvec rsp_iov;
1863 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
1864 num_lock, num_unlock);
1866 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1871 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
1872 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
1873 pSMB->LockType = lock_type;
1874 pSMB->AndXCommand = 0xFF; /* none */
1875 pSMB->Fid = netfid; /* netfid stays le */
1877 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1878 inc_rfc1001_len(pSMB, count);
1879 pSMB->ByteCount = cpu_to_le16(count);
1881 iov[0].iov_base = (char *)pSMB;
1882 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
1883 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1884 iov[1].iov_base = (char *)buf;
1885 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1887 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1888 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
1889 CIFS_NO_RSP_BUF, &rsp_iov);
1890 cifs_small_buf_release(pSMB);
1892 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
1898 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
1899 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
1900 const __u64 offset, const __u32 numUnlock,
1901 const __u32 numLock, const __u8 lockType,
1902 const bool waitFlag, const __u8 oplock_level)
1905 LOCK_REQ *pSMB = NULL;
1906 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
1911 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
1912 (int)waitFlag, numLock);
1913 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1918 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1919 /* no response expected */
1920 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
1922 } else if (waitFlag) {
1923 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1924 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
1929 pSMB->NumberOfLocks = cpu_to_le16(numLock);
1930 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
1931 pSMB->LockType = lockType;
1932 pSMB->OplockLevel = oplock_level;
1933 pSMB->AndXCommand = 0xFF; /* none */
1934 pSMB->Fid = smb_file_id; /* netfid stays le */
1936 if ((numLock != 0) || (numUnlock != 0)) {
1937 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
1938 /* BB where to store pid high? */
1939 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
1940 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
1941 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
1942 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
1943 count = sizeof(LOCKING_ANDX_RANGE);
1948 inc_rfc1001_len(pSMB, count);
1949 pSMB->ByteCount = cpu_to_le16(count);
1952 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1953 (struct smb_hdr *) pSMB, &bytes_returned);
1955 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
1956 cifs_small_buf_release(pSMB);
1957 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1959 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
1961 /* Note: On -EAGAIN error only caller can retry on handle based calls
1962 since file handle passed in no longer valid */
1967 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
1968 const __u16 smb_file_id, const __u32 netpid,
1969 const loff_t start_offset, const __u64 len,
1970 struct file_lock *pLockData, const __u16 lock_type,
1971 const bool waitFlag)
1973 struct smb_com_transaction2_sfi_req *pSMB = NULL;
1974 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
1975 struct cifs_posix_lock *parm_data;
1978 int bytes_returned = 0;
1979 int resp_buf_type = 0;
1980 __u16 params, param_offset, offset, byte_count, count;
1982 struct kvec rsp_iov;
1984 cifs_dbg(FYI, "Posix Lock\n");
1986 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
1991 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
1994 pSMB->MaxSetupCount = 0;
1997 pSMB->Reserved2 = 0;
1998 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
1999 offset = param_offset + params;
2001 count = sizeof(struct cifs_posix_lock);
2002 pSMB->MaxParameterCount = cpu_to_le16(2);
2003 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2004 pSMB->SetupCount = 1;
2005 pSMB->Reserved3 = 0;
2007 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2009 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2010 byte_count = 3 /* pad */ + params + count;
2011 pSMB->DataCount = cpu_to_le16(count);
2012 pSMB->ParameterCount = cpu_to_le16(params);
2013 pSMB->TotalDataCount = pSMB->DataCount;
2014 pSMB->TotalParameterCount = pSMB->ParameterCount;
2015 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2016 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2017 parm_data = (struct cifs_posix_lock *)
2018 (((char *)pSMB) + offset + 4);
2020 parm_data->lock_type = cpu_to_le16(lock_type);
2022 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2023 parm_data->lock_flags = cpu_to_le16(1);
2024 pSMB->Timeout = cpu_to_le32(-1);
2028 parm_data->pid = cpu_to_le32(netpid);
2029 parm_data->start = cpu_to_le64(start_offset);
2030 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2032 pSMB->DataOffset = cpu_to_le16(offset);
2033 pSMB->Fid = smb_file_id;
2034 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2035 pSMB->Reserved4 = 0;
2036 inc_rfc1001_len(pSMB, byte_count);
2037 pSMB->ByteCount = cpu_to_le16(byte_count);
2039 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2040 (struct smb_hdr *) pSMBr, &bytes_returned);
2042 iov[0].iov_base = (char *)pSMB;
2043 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2044 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2045 &resp_buf_type, timeout, &rsp_iov);
2046 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2048 cifs_small_buf_release(pSMB);
2051 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2052 } else if (pLockData) {
2053 /* lock structure can be returned on get */
2056 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2058 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2059 rc = -EIO; /* bad smb */
2062 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2063 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2064 if (data_count < sizeof(struct cifs_posix_lock)) {
2068 parm_data = (struct cifs_posix_lock *)
2069 ((char *)&pSMBr->hdr.Protocol + data_offset);
2070 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2071 pLockData->fl_type = F_UNLCK;
2073 if (parm_data->lock_type ==
2074 cpu_to_le16(CIFS_RDLCK))
2075 pLockData->fl_type = F_RDLCK;
2076 else if (parm_data->lock_type ==
2077 cpu_to_le16(CIFS_WRLCK))
2078 pLockData->fl_type = F_WRLCK;
2080 pLockData->fl_start = le64_to_cpu(parm_data->start);
2081 pLockData->fl_end = pLockData->fl_start +
2082 (le64_to_cpu(parm_data->length) ?
2083 le64_to_cpu(parm_data->length) - 1 : 0);
2084 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2089 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2091 /* Note: On -EAGAIN error only caller can retry on handle based calls
2092 since file handle passed in no longer valid */
2099 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2102 CLOSE_REQ *pSMB = NULL;
2103 cifs_dbg(FYI, "In CIFSSMBClose\n");
2105 /* do not retry on dead session on close */
2106 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2112 pSMB->FileID = (__u16) smb_file_id;
2113 pSMB->LastWriteTime = 0xFFFFFFFF;
2114 pSMB->ByteCount = 0;
2115 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2116 cifs_small_buf_release(pSMB);
2117 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2120 /* EINTR is expected when user ctl-c to kill app */
2121 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2125 /* Since session is dead, file will be closed on server already */
2133 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2136 FLUSH_REQ *pSMB = NULL;
2137 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2139 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2143 pSMB->FileID = (__u16) smb_file_id;
2144 pSMB->ByteCount = 0;
2145 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2146 cifs_small_buf_release(pSMB);
2147 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2149 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2155 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2156 const char *from_name, const char *to_name,
2157 struct cifs_sb_info *cifs_sb)
2160 RENAME_REQ *pSMB = NULL;
2161 RENAME_RSP *pSMBr = NULL;
2163 int name_len, name_len2;
2165 int remap = cifs_remap(cifs_sb);
2167 cifs_dbg(FYI, "In CIFSSMBRename\n");
2169 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2174 pSMB->BufferFormat = 0x04;
2175 pSMB->SearchAttributes =
2176 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2179 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2180 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2181 from_name, PATH_MAX,
2182 cifs_sb->local_nls, remap);
2183 name_len++; /* trailing null */
2185 pSMB->OldFileName[name_len] = 0x04; /* pad */
2186 /* protocol requires ASCII signature byte on Unicode string */
2187 pSMB->OldFileName[name_len + 1] = 0x00;
2189 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2190 to_name, PATH_MAX, cifs_sb->local_nls,
2192 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2193 name_len2 *= 2; /* convert to bytes */
2195 name_len = copy_path_name(pSMB->OldFileName, from_name);
2196 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2197 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2198 name_len2++; /* signature byte */
2201 count = 1 /* 1st signature byte */ + name_len + name_len2;
2202 inc_rfc1001_len(pSMB, count);
2203 pSMB->ByteCount = cpu_to_le16(count);
2205 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2206 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2207 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2209 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2211 cifs_buf_release(pSMB);
2219 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2220 int netfid, const char *target_name,
2221 const struct nls_table *nls_codepage, int remap)
2223 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2224 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2225 struct set_file_rename *rename_info;
2227 char dummy_string[30];
2229 int bytes_returned = 0;
2231 __u16 params, param_offset, offset, count, byte_count;
2233 cifs_dbg(FYI, "Rename to File by handle\n");
2234 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2240 pSMB->MaxSetupCount = 0;
2244 pSMB->Reserved2 = 0;
2245 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2246 offset = param_offset + params;
2248 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2249 data_offset = (char *)(pSMB) + offset + 4;
2250 rename_info = (struct set_file_rename *) data_offset;
2251 pSMB->MaxParameterCount = cpu_to_le16(2);
2252 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2253 pSMB->SetupCount = 1;
2254 pSMB->Reserved3 = 0;
2255 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2256 byte_count = 3 /* pad */ + params;
2257 pSMB->ParameterCount = cpu_to_le16(params);
2258 pSMB->TotalParameterCount = pSMB->ParameterCount;
2259 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2260 pSMB->DataOffset = cpu_to_le16(offset);
2261 /* construct random name ".cifs_tmp<inodenum><mid>" */
2262 rename_info->overwrite = cpu_to_le32(1);
2263 rename_info->root_fid = 0;
2264 /* unicode only call */
2265 if (target_name == NULL) {
2266 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2268 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2269 dummy_string, 24, nls_codepage, remap);
2272 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2273 target_name, PATH_MAX, nls_codepage,
2276 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2277 count = sizeof(struct set_file_rename) + (2 * len_of_str);
2278 byte_count += count;
2279 pSMB->DataCount = cpu_to_le16(count);
2280 pSMB->TotalDataCount = pSMB->DataCount;
2282 pSMB->InformationLevel =
2283 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2284 pSMB->Reserved4 = 0;
2285 inc_rfc1001_len(pSMB, byte_count);
2286 pSMB->ByteCount = cpu_to_le16(byte_count);
2287 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2288 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2289 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2291 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2294 cifs_buf_release(pSMB);
2296 /* Note: On -EAGAIN error only caller can retry on handle based calls
2297 since file handle passed in no longer valid */
2303 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2304 const char *fromName, const __u16 target_tid, const char *toName,
2305 const int flags, const struct nls_table *nls_codepage, int remap)
2308 COPY_REQ *pSMB = NULL;
2309 COPY_RSP *pSMBr = NULL;
2311 int name_len, name_len2;
2314 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2316 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2321 pSMB->BufferFormat = 0x04;
2322 pSMB->Tid2 = target_tid;
2324 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2326 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2327 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2328 fromName, PATH_MAX, nls_codepage,
2330 name_len++; /* trailing null */
2332 pSMB->OldFileName[name_len] = 0x04; /* pad */
2333 /* protocol requires ASCII signature byte on Unicode string */
2334 pSMB->OldFileName[name_len + 1] = 0x00;
2336 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2337 toName, PATH_MAX, nls_codepage, remap);
2338 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2339 name_len2 *= 2; /* convert to bytes */
2341 name_len = copy_path_name(pSMB->OldFileName, fromName);
2342 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2343 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2344 name_len2++; /* signature byte */
2347 count = 1 /* 1st signature byte */ + name_len + name_len2;
2348 inc_rfc1001_len(pSMB, count);
2349 pSMB->ByteCount = cpu_to_le16(count);
2351 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2352 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2354 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2355 rc, le16_to_cpu(pSMBr->CopyCount));
2357 cifs_buf_release(pSMB);
2366 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2367 const char *fromName, const char *toName,
2368 const struct nls_table *nls_codepage, int remap)
2370 TRANSACTION2_SPI_REQ *pSMB = NULL;
2371 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2374 int name_len_target;
2376 int bytes_returned = 0;
2377 __u16 params, param_offset, offset, byte_count;
2379 cifs_dbg(FYI, "In Symlink Unix style\n");
2381 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2386 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2388 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2389 /* find define for this maxpathcomponent */
2390 PATH_MAX, nls_codepage, remap);
2391 name_len++; /* trailing null */
2395 name_len = copy_path_name(pSMB->FileName, fromName);
2397 params = 6 + name_len;
2398 pSMB->MaxSetupCount = 0;
2402 pSMB->Reserved2 = 0;
2403 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2404 InformationLevel) - 4;
2405 offset = param_offset + params;
2407 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2408 data_offset = (char *)pSMB + offset + 4;
2409 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2411 cifsConvertToUTF16((__le16 *) data_offset, toName,
2412 /* find define for this maxpathcomponent */
2413 PATH_MAX, nls_codepage, remap);
2414 name_len_target++; /* trailing null */
2415 name_len_target *= 2;
2417 name_len_target = copy_path_name(data_offset, toName);
2420 pSMB->MaxParameterCount = cpu_to_le16(2);
2421 /* BB find exact max on data count below from sess */
2422 pSMB->MaxDataCount = cpu_to_le16(1000);
2423 pSMB->SetupCount = 1;
2424 pSMB->Reserved3 = 0;
2425 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2426 byte_count = 3 /* pad */ + params + name_len_target;
2427 pSMB->DataCount = cpu_to_le16(name_len_target);
2428 pSMB->ParameterCount = cpu_to_le16(params);
2429 pSMB->TotalDataCount = pSMB->DataCount;
2430 pSMB->TotalParameterCount = pSMB->ParameterCount;
2431 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2432 pSMB->DataOffset = cpu_to_le16(offset);
2433 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2434 pSMB->Reserved4 = 0;
2435 inc_rfc1001_len(pSMB, byte_count);
2436 pSMB->ByteCount = cpu_to_le16(byte_count);
2437 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2438 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2439 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2441 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2444 cifs_buf_release(pSMB);
2447 goto createSymLinkRetry;
2453 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2454 const char *fromName, const char *toName,
2455 const struct nls_table *nls_codepage, int remap)
2457 TRANSACTION2_SPI_REQ *pSMB = NULL;
2458 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2461 int name_len_target;
2463 int bytes_returned = 0;
2464 __u16 params, param_offset, offset, byte_count;
2466 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2467 createHardLinkRetry:
2468 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2473 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2474 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2475 PATH_MAX, nls_codepage, remap);
2476 name_len++; /* trailing null */
2480 name_len = copy_path_name(pSMB->FileName, toName);
2482 params = 6 + name_len;
2483 pSMB->MaxSetupCount = 0;
2487 pSMB->Reserved2 = 0;
2488 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2489 InformationLevel) - 4;
2490 offset = param_offset + params;
2492 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2493 data_offset = (char *)pSMB + offset + 4;
2494 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2496 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2497 PATH_MAX, nls_codepage, remap);
2498 name_len_target++; /* trailing null */
2499 name_len_target *= 2;
2501 name_len_target = copy_path_name(data_offset, fromName);
2504 pSMB->MaxParameterCount = cpu_to_le16(2);
2505 /* BB find exact max on data count below from sess*/
2506 pSMB->MaxDataCount = cpu_to_le16(1000);
2507 pSMB->SetupCount = 1;
2508 pSMB->Reserved3 = 0;
2509 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2510 byte_count = 3 /* pad */ + params + name_len_target;
2511 pSMB->ParameterCount = cpu_to_le16(params);
2512 pSMB->TotalParameterCount = pSMB->ParameterCount;
2513 pSMB->DataCount = cpu_to_le16(name_len_target);
2514 pSMB->TotalDataCount = pSMB->DataCount;
2515 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2516 pSMB->DataOffset = cpu_to_le16(offset);
2517 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2518 pSMB->Reserved4 = 0;
2519 inc_rfc1001_len(pSMB, byte_count);
2520 pSMB->ByteCount = cpu_to_le16(byte_count);
2521 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2522 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2523 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2525 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2528 cifs_buf_release(pSMB);
2530 goto createHardLinkRetry;
2536 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2537 const char *from_name, const char *to_name,
2538 struct cifs_sb_info *cifs_sb)
2541 NT_RENAME_REQ *pSMB = NULL;
2542 RENAME_RSP *pSMBr = NULL;
2544 int name_len, name_len2;
2546 int remap = cifs_remap(cifs_sb);
2548 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2549 winCreateHardLinkRetry:
2551 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2556 pSMB->SearchAttributes =
2557 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2559 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2560 pSMB->ClusterCount = 0;
2562 pSMB->BufferFormat = 0x04;
2564 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2566 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2567 PATH_MAX, cifs_sb->local_nls, remap);
2568 name_len++; /* trailing null */
2571 /* protocol specifies ASCII buffer format (0x04) for unicode */
2572 pSMB->OldFileName[name_len] = 0x04;
2573 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2575 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2576 to_name, PATH_MAX, cifs_sb->local_nls,
2578 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2579 name_len2 *= 2; /* convert to bytes */
2581 name_len = copy_path_name(pSMB->OldFileName, from_name);
2582 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2583 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2584 name_len2++; /* signature byte */
2587 count = 1 /* string type byte */ + name_len + name_len2;
2588 inc_rfc1001_len(pSMB, count);
2589 pSMB->ByteCount = cpu_to_le16(count);
2591 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2592 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2593 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2595 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2597 cifs_buf_release(pSMB);
2599 goto winCreateHardLinkRetry;
2605 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2606 const unsigned char *searchName, char **symlinkinfo,
2607 const struct nls_table *nls_codepage, int remap)
2609 /* SMB_QUERY_FILE_UNIX_LINK */
2610 TRANSACTION2_QPI_REQ *pSMB = NULL;
2611 TRANSACTION2_QPI_RSP *pSMBr = NULL;
2615 __u16 params, byte_count;
2618 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
2621 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2626 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2628 cifsConvertToUTF16((__le16 *) pSMB->FileName,
2629 searchName, PATH_MAX, nls_codepage,
2631 name_len++; /* trailing null */
2634 name_len = copy_path_name(pSMB->FileName, searchName);
2637 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
2638 pSMB->TotalDataCount = 0;
2639 pSMB->MaxParameterCount = cpu_to_le16(2);
2640 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2641 pSMB->MaxSetupCount = 0;
2645 pSMB->Reserved2 = 0;
2646 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2647 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
2648 pSMB->DataCount = 0;
2649 pSMB->DataOffset = 0;
2650 pSMB->SetupCount = 1;
2651 pSMB->Reserved3 = 0;
2652 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2653 byte_count = params + 1 /* pad */ ;
2654 pSMB->TotalParameterCount = cpu_to_le16(params);
2655 pSMB->ParameterCount = pSMB->TotalParameterCount;
2656 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2657 pSMB->Reserved4 = 0;
2658 inc_rfc1001_len(pSMB, byte_count);
2659 pSMB->ByteCount = cpu_to_le16(byte_count);
2661 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2662 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2664 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
2666 /* decode response */
2668 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2669 /* BB also check enough total bytes returned */
2670 if (rc || get_bcc(&pSMBr->hdr) < 2)
2674 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2676 data_start = ((char *) &pSMBr->hdr.Protocol) +
2677 le16_to_cpu(pSMBr->t2.DataOffset);
2679 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2684 /* BB FIXME investigate remapping reserved chars here */
2685 *symlinkinfo = cifs_strndup_from_utf16(data_start,
2686 count, is_unicode, nls_codepage);
2691 cifs_buf_release(pSMB);
2693 goto querySymLinkRetry;
2698 * Recent Windows versions now create symlinks more frequently
2699 * and they use the "reparse point" mechanism below. We can of course
2700 * do symlinks nicely to Samba and other servers which support the
2701 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
2702 * "MF" symlinks optionally, but for recent Windows we really need to
2703 * reenable the code below and fix the cifs_symlink callers to handle this.
2704 * In the interim this code has been moved to its own config option so
2705 * it is not compiled in by default until callers fixed up and more tested.
2708 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2709 __u16 fid, char **symlinkinfo,
2710 const struct nls_table *nls_codepage)
2714 struct smb_com_transaction_ioctl_req *pSMB;
2715 struct smb_com_transaction_ioctl_rsp *pSMBr;
2717 unsigned int sub_len;
2719 struct reparse_symlink_data *reparse_buf;
2720 struct reparse_posix_data *posix_buf;
2721 __u32 data_offset, data_count;
2724 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
2725 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2730 pSMB->TotalParameterCount = 0 ;
2731 pSMB->TotalDataCount = 0;
2732 pSMB->MaxParameterCount = cpu_to_le32(2);
2733 /* BB find exact data count max from sess structure BB */
2734 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
2735 pSMB->MaxSetupCount = 4;
2737 pSMB->ParameterOffset = 0;
2738 pSMB->DataCount = 0;
2739 pSMB->DataOffset = 0;
2740 pSMB->SetupCount = 4;
2741 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2742 pSMB->ParameterCount = pSMB->TotalParameterCount;
2743 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
2744 pSMB->IsFsctl = 1; /* FSCTL */
2745 pSMB->IsRootFlag = 0;
2746 pSMB->Fid = fid; /* file handle always le */
2747 pSMB->ByteCount = 0;
2749 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2750 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2752 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
2756 data_offset = le32_to_cpu(pSMBr->DataOffset);
2757 data_count = le32_to_cpu(pSMBr->DataCount);
2758 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
2759 /* BB also check enough total bytes returned */
2760 rc = -EIO; /* bad smb */
2763 if (!data_count || (data_count > 2048)) {
2765 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
2768 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
2769 reparse_buf = (struct reparse_symlink_data *)
2770 ((char *)&pSMBr->hdr.Protocol + data_offset);
2771 if ((char *)reparse_buf >= end_of_smb) {
2775 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
2776 cifs_dbg(FYI, "NFS style reparse tag\n");
2777 posix_buf = (struct reparse_posix_data *)reparse_buf;
2779 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
2780 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
2781 le64_to_cpu(posix_buf->InodeType));
2786 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
2787 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
2788 cifs_dbg(FYI, "reparse buf beyond SMB\n");
2792 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
2793 sub_len, is_unicode, nls_codepage);
2795 } else if (reparse_buf->ReparseTag !=
2796 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
2801 /* Reparse tag is NTFS symlink */
2802 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
2803 reparse_buf->PathBuffer;
2804 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
2805 if (sub_start + sub_len > end_of_smb) {
2806 cifs_dbg(FYI, "reparse buf beyond SMB\n");
2810 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2815 /* BB FIXME investigate remapping reserved chars here */
2816 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
2821 cifs_buf_release(pSMB);
2824 * Note: On -EAGAIN error only caller can retry on handle based calls
2825 * since file handle passed in no longer valid.
2831 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
2836 struct smb_com_transaction_compr_ioctl_req *pSMB;
2837 struct smb_com_transaction_ioctl_rsp *pSMBr;
2839 cifs_dbg(FYI, "Set compression for %u\n", fid);
2840 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2845 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
2847 pSMB->TotalParameterCount = 0;
2848 pSMB->TotalDataCount = cpu_to_le32(2);
2849 pSMB->MaxParameterCount = 0;
2850 pSMB->MaxDataCount = 0;
2851 pSMB->MaxSetupCount = 4;
2853 pSMB->ParameterOffset = 0;
2854 pSMB->DataCount = cpu_to_le32(2);
2856 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
2857 compression_state) - 4); /* 84 */
2858 pSMB->SetupCount = 4;
2859 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2860 pSMB->ParameterCount = 0;
2861 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
2862 pSMB->IsFsctl = 1; /* FSCTL */
2863 pSMB->IsRootFlag = 0;
2864 pSMB->Fid = fid; /* file handle always le */
2865 /* 3 byte pad, followed by 2 byte compress state */
2866 pSMB->ByteCount = cpu_to_le16(5);
2867 inc_rfc1001_len(pSMB, 5);
2869 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2870 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2872 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
2874 cifs_buf_release(pSMB);
2877 * Note: On -EAGAIN error only caller can retry on handle based calls
2878 * since file handle passed in no longer valid.
2884 #ifdef CONFIG_CIFS_POSIX
2886 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
2887 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
2888 struct cifs_posix_ace *cifs_ace)
2890 /* u8 cifs fields do not need le conversion */
2891 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
2892 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
2893 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
2895 cifs_dbg(FYI, "perm %d tag %d id %d\n",
2896 ace->e_perm, ace->e_tag, ace->e_id);
2902 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
2903 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
2904 const int acl_type, const int size_of_data_area)
2909 struct cifs_posix_ace *pACE;
2910 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
2911 struct posix_acl_xattr_header *local_acl = (void *)trgt;
2913 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
2916 if (acl_type == ACL_TYPE_ACCESS) {
2917 count = le16_to_cpu(cifs_acl->access_entry_count);
2918 pACE = &cifs_acl->ace_array[0];
2919 size = sizeof(struct cifs_posix_acl);
2920 size += sizeof(struct cifs_posix_ace) * count;
2921 /* check if we would go beyond end of SMB */
2922 if (size_of_data_area < size) {
2923 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
2924 size_of_data_area, size);
2927 } else if (acl_type == ACL_TYPE_DEFAULT) {
2928 count = le16_to_cpu(cifs_acl->access_entry_count);
2929 size = sizeof(struct cifs_posix_acl);
2930 size += sizeof(struct cifs_posix_ace) * count;
2931 /* skip past access ACEs to get to default ACEs */
2932 pACE = &cifs_acl->ace_array[count];
2933 count = le16_to_cpu(cifs_acl->default_entry_count);
2934 size += sizeof(struct cifs_posix_ace) * count;
2935 /* check if we would go beyond end of SMB */
2936 if (size_of_data_area < size)
2943 size = posix_acl_xattr_size(count);
2944 if ((buflen == 0) || (local_acl == NULL)) {
2945 /* used to query ACL EA size */
2946 } else if (size > buflen) {
2948 } else /* buffer big enough */ {
2949 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
2951 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
2952 for (i = 0; i < count ; i++) {
2953 cifs_convert_ace(&ace[i], pACE);
2960 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
2961 const struct posix_acl_xattr_entry *local_ace)
2963 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
2964 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
2965 /* BB is there a better way to handle the large uid? */
2966 if (local_ace->e_id == cpu_to_le32(-1)) {
2967 /* Probably no need to le convert -1 on any arch but can not hurt */
2968 cifs_ace->cifs_uid = cpu_to_le64(-1);
2970 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
2972 cifs_dbg(FYI, "perm %d tag %d id %d\n",
2973 ace->e_perm, ace->e_tag, ace->e_id);
2977 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
2978 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
2979 const int buflen, const int acl_type)
2982 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
2983 struct posix_acl_xattr_header *local_acl = (void *)pACL;
2984 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
2988 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
2991 count = posix_acl_xattr_count((size_t)buflen);
2992 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
2993 count, buflen, le32_to_cpu(local_acl->a_version));
2994 if (le32_to_cpu(local_acl->a_version) != 2) {
2995 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
2996 le32_to_cpu(local_acl->a_version));
2999 cifs_acl->version = cpu_to_le16(1);
3000 if (acl_type == ACL_TYPE_ACCESS) {
3001 cifs_acl->access_entry_count = cpu_to_le16(count);
3002 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3003 } else if (acl_type == ACL_TYPE_DEFAULT) {
3004 cifs_acl->default_entry_count = cpu_to_le16(count);
3005 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3007 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3010 for (i = 0; i < count; i++)
3011 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3013 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3014 rc += sizeof(struct cifs_posix_acl);
3015 /* BB add check to make sure ACL does not overflow SMB */
3021 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3022 const unsigned char *searchName,
3023 char *acl_inf, const int buflen, const int acl_type,
3024 const struct nls_table *nls_codepage, int remap)
3026 /* SMB_QUERY_POSIX_ACL */
3027 TRANSACTION2_QPI_REQ *pSMB = NULL;
3028 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3032 __u16 params, byte_count;
3034 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3037 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3042 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3044 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3045 searchName, PATH_MAX, nls_codepage,
3047 name_len++; /* trailing null */
3049 pSMB->FileName[name_len] = 0;
3050 pSMB->FileName[name_len+1] = 0;
3052 name_len = copy_path_name(pSMB->FileName, searchName);
3055 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3056 pSMB->TotalDataCount = 0;
3057 pSMB->MaxParameterCount = cpu_to_le16(2);
3058 /* BB find exact max data count below from sess structure BB */
3059 pSMB->MaxDataCount = cpu_to_le16(4000);
3060 pSMB->MaxSetupCount = 0;
3064 pSMB->Reserved2 = 0;
3065 pSMB->ParameterOffset = cpu_to_le16(
3066 offsetof(struct smb_com_transaction2_qpi_req,
3067 InformationLevel) - 4);
3068 pSMB->DataCount = 0;
3069 pSMB->DataOffset = 0;
3070 pSMB->SetupCount = 1;
3071 pSMB->Reserved3 = 0;
3072 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3073 byte_count = params + 1 /* pad */ ;
3074 pSMB->TotalParameterCount = cpu_to_le16(params);
3075 pSMB->ParameterCount = pSMB->TotalParameterCount;
3076 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3077 pSMB->Reserved4 = 0;
3078 inc_rfc1001_len(pSMB, byte_count);
3079 pSMB->ByteCount = cpu_to_le16(byte_count);
3081 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3082 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3083 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3085 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3087 /* decode response */
3089 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3090 /* BB also check enough total bytes returned */
3091 if (rc || get_bcc(&pSMBr->hdr) < 2)
3092 rc = -EIO; /* bad smb */
3094 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3095 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3096 rc = cifs_copy_posix_acl(acl_inf,
3097 (char *)&pSMBr->hdr.Protocol+data_offset,
3098 buflen, acl_type, count);
3101 cifs_buf_release(pSMB);
3108 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3109 const unsigned char *fileName,
3110 const char *local_acl, const int buflen,
3112 const struct nls_table *nls_codepage, int remap)
3114 struct smb_com_transaction2_spi_req *pSMB = NULL;
3115 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3119 int bytes_returned = 0;
3120 __u16 params, byte_count, data_count, param_offset, offset;
3122 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3124 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3128 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3130 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3131 PATH_MAX, nls_codepage, remap);
3132 name_len++; /* trailing null */
3135 name_len = copy_path_name(pSMB->FileName, fileName);
3137 params = 6 + name_len;
3138 pSMB->MaxParameterCount = cpu_to_le16(2);
3139 /* BB find max SMB size from sess */
3140 pSMB->MaxDataCount = cpu_to_le16(1000);
3141 pSMB->MaxSetupCount = 0;
3145 pSMB->Reserved2 = 0;
3146 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3147 InformationLevel) - 4;
3148 offset = param_offset + params;
3149 parm_data = ((char *)pSMB) + sizeof(pSMB->hdr.smb_buf_length) + offset;
3150 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3152 /* convert to on the wire format for POSIX ACL */
3153 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3155 if (data_count == 0) {
3157 goto setACLerrorExit;
3159 pSMB->DataOffset = cpu_to_le16(offset);
3160 pSMB->SetupCount = 1;
3161 pSMB->Reserved3 = 0;
3162 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3163 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3164 byte_count = 3 /* pad */ + params + data_count;
3165 pSMB->DataCount = cpu_to_le16(data_count);
3166 pSMB->TotalDataCount = pSMB->DataCount;
3167 pSMB->ParameterCount = cpu_to_le16(params);
3168 pSMB->TotalParameterCount = pSMB->ParameterCount;
3169 pSMB->Reserved4 = 0;
3170 inc_rfc1001_len(pSMB, byte_count);
3171 pSMB->ByteCount = cpu_to_le16(byte_count);
3172 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3173 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3175 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3178 cifs_buf_release(pSMB);
3185 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3186 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3189 struct smb_t2_qfi_req *pSMB = NULL;
3190 struct smb_t2_qfi_rsp *pSMBr = NULL;
3192 __u16 params, byte_count;
3194 cifs_dbg(FYI, "In GetExtAttr\n");
3199 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3204 params = 2 /* level */ + 2 /* fid */;
3205 pSMB->t2.TotalDataCount = 0;
3206 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3207 /* BB find exact max data count below from sess structure BB */
3208 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3209 pSMB->t2.MaxSetupCount = 0;
3210 pSMB->t2.Reserved = 0;
3212 pSMB->t2.Timeout = 0;
3213 pSMB->t2.Reserved2 = 0;
3214 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3216 pSMB->t2.DataCount = 0;
3217 pSMB->t2.DataOffset = 0;
3218 pSMB->t2.SetupCount = 1;
3219 pSMB->t2.Reserved3 = 0;
3220 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3221 byte_count = params + 1 /* pad */ ;
3222 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3223 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3224 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3227 inc_rfc1001_len(pSMB, byte_count);
3228 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3230 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3231 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3233 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3235 /* decode response */
3236 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3237 /* BB also check enough total bytes returned */
3238 if (rc || get_bcc(&pSMBr->hdr) < 2)
3239 /* If rc should we check for EOPNOSUPP and
3240 disable the srvino flag? or in caller? */
3241 rc = -EIO; /* bad smb */
3243 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3244 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3245 struct file_chattr_info *pfinfo;
3248 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3252 pfinfo = (struct file_chattr_info *)
3253 (data_offset + (char *) &pSMBr->hdr.Protocol);
3254 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3255 *pMask = le64_to_cpu(pfinfo->mask);
3259 cifs_buf_release(pSMB);
3261 goto GetExtAttrRetry;
3265 #endif /* CONFIG_POSIX */
3268 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3269 * all NT TRANSACTS that we init here have total parm and data under about 400
3270 * bytes (to fit in small cifs buffer size), which is the case so far, it
3271 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3272 * returned setup area) and MaxParameterCount (returned parms size) must be set
3276 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3277 const int parm_len, struct cifs_tcon *tcon,
3282 struct smb_com_ntransact_req *pSMB;
3284 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3288 *ret_buf = (void *)pSMB;
3290 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3291 pSMB->TotalDataCount = 0;
3292 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3293 pSMB->ParameterCount = pSMB->TotalParameterCount;
3294 pSMB->DataCount = pSMB->TotalDataCount;
3295 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3296 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3297 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3298 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3299 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3300 pSMB->SubCommand = cpu_to_le16(sub_command);
3305 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3306 __u32 *pparmlen, __u32 *pdatalen)
3309 __u32 data_count, data_offset, parm_count, parm_offset;
3310 struct smb_com_ntransact_rsp *pSMBr;
3319 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3321 bcc = get_bcc(&pSMBr->hdr);
3322 end_of_smb = 2 /* sizeof byte count */ + bcc +
3323 (char *)&pSMBr->ByteCount;
3325 data_offset = le32_to_cpu(pSMBr->DataOffset);
3326 data_count = le32_to_cpu(pSMBr->DataCount);
3327 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3328 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3330 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3331 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3333 /* should we also check that parm and data areas do not overlap? */
3334 if (*ppparm > end_of_smb) {
3335 cifs_dbg(FYI, "parms start after end of smb\n");
3337 } else if (parm_count + *ppparm > end_of_smb) {
3338 cifs_dbg(FYI, "parm end after end of smb\n");
3340 } else if (*ppdata > end_of_smb) {
3341 cifs_dbg(FYI, "data starts after end of smb\n");
3343 } else if (data_count + *ppdata > end_of_smb) {
3344 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3345 *ppdata, data_count, (data_count + *ppdata),
3348 } else if (parm_count + data_count > bcc) {
3349 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3352 *pdatalen = data_count;
3353 *pparmlen = parm_count;
3357 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3359 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3360 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3364 QUERY_SEC_DESC_REQ *pSMB;
3366 struct kvec rsp_iov;
3368 cifs_dbg(FYI, "GetCifsACL\n");
3373 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3374 8 /* parm len */, tcon, (void **) &pSMB);
3378 pSMB->MaxParameterCount = cpu_to_le32(4);
3379 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3380 pSMB->MaxSetupCount = 0;
3381 pSMB->Fid = fid; /* file handle always le */
3382 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3384 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3385 inc_rfc1001_len(pSMB, 11);
3386 iov[0].iov_base = (char *)pSMB;
3387 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3389 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3391 cifs_small_buf_release(pSMB);
3392 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3394 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3395 } else { /* decode response */
3399 struct smb_com_ntransact_rsp *pSMBr;
3402 /* validate_nttransact */
3403 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3404 &pdata, &parm_len, pbuflen);
3407 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3409 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3410 pSMBr, parm, *acl_inf);
3412 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3413 rc = -EIO; /* bad smb */
3418 /* BB check that data area is minimum length and as big as acl_len */
3420 acl_len = le32_to_cpu(*parm);
3421 if (acl_len != *pbuflen) {
3422 cifs_dbg(VFS, "acl length %d does not match %d\n",
3424 if (*pbuflen > acl_len)
3428 /* check if buffer is big enough for the acl
3429 header followed by the smallest SID */
3430 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3431 (*pbuflen >= 64 * 1024)) {
3432 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3436 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3437 if (*acl_inf == NULL) {
3444 free_rsp_buf(buf_type, rsp_iov.iov_base);
3449 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3450 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3452 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3454 int bytes_returned = 0;
3455 SET_SEC_DESC_REQ *pSMB = NULL;
3459 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3463 pSMB->MaxSetupCount = 0;
3467 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3468 data_count = acllen;
3469 data_offset = param_offset + param_count;
3470 byte_count = 3 /* pad */ + param_count;
3472 pSMB->DataCount = cpu_to_le32(data_count);
3473 pSMB->TotalDataCount = pSMB->DataCount;
3474 pSMB->MaxParameterCount = cpu_to_le32(4);
3475 pSMB->MaxDataCount = cpu_to_le32(16384);
3476 pSMB->ParameterCount = cpu_to_le32(param_count);
3477 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3478 pSMB->TotalParameterCount = pSMB->ParameterCount;
3479 pSMB->DataOffset = cpu_to_le32(data_offset);
3480 pSMB->SetupCount = 0;
3481 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3482 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3484 pSMB->Fid = fid; /* file handle always le */
3485 pSMB->Reserved2 = 0;
3486 pSMB->AclFlags = cpu_to_le32(aclflag);
3488 if (pntsd && acllen) {
3489 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3490 data_offset, pntsd, acllen);
3491 inc_rfc1001_len(pSMB, byte_count + data_count);
3493 inc_rfc1001_len(pSMB, byte_count);
3495 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3496 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3498 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3499 bytes_returned, rc);
3501 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3502 cifs_buf_release(pSMB);
3505 goto setCifsAclRetry;
3511 /* Legacy Query Path Information call for lookup to old servers such
3514 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3515 const char *search_name, FILE_ALL_INFO *data,
3516 const struct nls_table *nls_codepage, int remap)
3518 QUERY_INFORMATION_REQ *pSMB;
3519 QUERY_INFORMATION_RSP *pSMBr;
3524 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3526 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3531 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3533 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3534 search_name, PATH_MAX, nls_codepage,
3536 name_len++; /* trailing null */
3539 name_len = copy_path_name(pSMB->FileName, search_name);
3541 pSMB->BufferFormat = 0x04;
3542 name_len++; /* account for buffer type byte */
3543 inc_rfc1001_len(pSMB, (__u16)name_len);
3544 pSMB->ByteCount = cpu_to_le16(name_len);
3546 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3547 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3549 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3551 struct timespec64 ts;
3552 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3554 /* decode response */
3555 /* BB FIXME - add time zone adjustment BB */
3556 memset(data, 0, sizeof(FILE_ALL_INFO));
3559 /* decode time fields */
3560 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3561 data->LastWriteTime = data->ChangeTime;
3562 data->LastAccessTime = 0;
3563 data->AllocationSize =
3564 cpu_to_le64(le32_to_cpu(pSMBr->size));
3565 data->EndOfFile = data->AllocationSize;
3567 cpu_to_le32(le16_to_cpu(pSMBr->attr));
3569 rc = -EIO; /* bad buffer passed in */
3571 cifs_buf_release(pSMB);
3580 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3581 u16 netfid, FILE_ALL_INFO *pFindData)
3583 struct smb_t2_qfi_req *pSMB = NULL;
3584 struct smb_t2_qfi_rsp *pSMBr = NULL;
3587 __u16 params, byte_count;
3590 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3595 params = 2 /* level */ + 2 /* fid */;
3596 pSMB->t2.TotalDataCount = 0;
3597 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3598 /* BB find exact max data count below from sess structure BB */
3599 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3600 pSMB->t2.MaxSetupCount = 0;
3601 pSMB->t2.Reserved = 0;
3603 pSMB->t2.Timeout = 0;
3604 pSMB->t2.Reserved2 = 0;
3605 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3607 pSMB->t2.DataCount = 0;
3608 pSMB->t2.DataOffset = 0;
3609 pSMB->t2.SetupCount = 1;
3610 pSMB->t2.Reserved3 = 0;
3611 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3612 byte_count = params + 1 /* pad */ ;
3613 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3614 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3615 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3618 inc_rfc1001_len(pSMB, byte_count);
3619 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3621 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3622 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3624 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
3625 } else { /* decode response */
3626 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3628 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3630 else if (get_bcc(&pSMBr->hdr) < 40)
3631 rc = -EIO; /* bad smb */
3632 else if (pFindData) {
3633 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3634 memcpy((char *) pFindData,
3635 (char *) &pSMBr->hdr.Protocol +
3636 data_offset, sizeof(FILE_ALL_INFO));
3640 cifs_buf_release(pSMB);
3642 goto QFileInfoRetry;
3648 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3649 const char *search_name, FILE_ALL_INFO *data,
3650 int legacy /* old style infolevel */,
3651 const struct nls_table *nls_codepage, int remap)
3653 /* level 263 SMB_QUERY_FILE_ALL_INFO */
3654 TRANSACTION2_QPI_REQ *pSMB = NULL;
3655 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3659 __u16 params, byte_count;
3661 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3663 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3668 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3670 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3671 PATH_MAX, nls_codepage, remap);
3672 name_len++; /* trailing null */
3675 name_len = copy_path_name(pSMB->FileName, search_name);
3678 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3679 pSMB->TotalDataCount = 0;
3680 pSMB->MaxParameterCount = cpu_to_le16(2);
3681 /* BB find exact max SMB PDU from sess structure BB */
3682 pSMB->MaxDataCount = cpu_to_le16(4000);
3683 pSMB->MaxSetupCount = 0;
3687 pSMB->Reserved2 = 0;
3688 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3689 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3690 pSMB->DataCount = 0;
3691 pSMB->DataOffset = 0;
3692 pSMB->SetupCount = 1;
3693 pSMB->Reserved3 = 0;
3694 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3695 byte_count = params + 1 /* pad */ ;
3696 pSMB->TotalParameterCount = cpu_to_le16(params);
3697 pSMB->ParameterCount = pSMB->TotalParameterCount;
3699 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3701 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3702 pSMB->Reserved4 = 0;
3703 inc_rfc1001_len(pSMB, byte_count);
3704 pSMB->ByteCount = cpu_to_le16(byte_count);
3706 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3707 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3709 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3710 } else { /* decode response */
3711 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3713 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3715 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3716 rc = -EIO; /* bad smb */
3717 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3718 rc = -EIO; /* 24 or 26 expected but we do not read
3722 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3725 * On legacy responses we do not read the last field,
3726 * EAsize, fortunately since it varies by subdialect and
3727 * also note it differs on Set vs Get, ie two bytes or 4
3728 * bytes depending but we don't care here.
3731 size = sizeof(FILE_INFO_STANDARD);
3733 size = sizeof(FILE_ALL_INFO);
3734 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
3739 cifs_buf_release(pSMB);
3741 goto QPathInfoRetry;
3747 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3748 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3750 struct smb_t2_qfi_req *pSMB = NULL;
3751 struct smb_t2_qfi_rsp *pSMBr = NULL;
3754 __u16 params, byte_count;
3757 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3762 params = 2 /* level */ + 2 /* fid */;
3763 pSMB->t2.TotalDataCount = 0;
3764 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3765 /* BB find exact max data count below from sess structure BB */
3766 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3767 pSMB->t2.MaxSetupCount = 0;
3768 pSMB->t2.Reserved = 0;
3770 pSMB->t2.Timeout = 0;
3771 pSMB->t2.Reserved2 = 0;
3772 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3774 pSMB->t2.DataCount = 0;
3775 pSMB->t2.DataOffset = 0;
3776 pSMB->t2.SetupCount = 1;
3777 pSMB->t2.Reserved3 = 0;
3778 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3779 byte_count = params + 1 /* pad */ ;
3780 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3781 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3782 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3785 inc_rfc1001_len(pSMB, byte_count);
3786 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3788 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3789 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3791 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
3792 } else { /* decode response */
3793 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3795 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3796 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3797 rc = -EIO; /* bad smb */
3799 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3800 memcpy((char *) pFindData,
3801 (char *) &pSMBr->hdr.Protocol +
3803 sizeof(FILE_UNIX_BASIC_INFO));
3807 cifs_buf_release(pSMB);
3809 goto UnixQFileInfoRetry;
3815 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3816 const unsigned char *searchName,
3817 FILE_UNIX_BASIC_INFO *pFindData,
3818 const struct nls_table *nls_codepage, int remap)
3820 /* SMB_QUERY_FILE_UNIX_BASIC */
3821 TRANSACTION2_QPI_REQ *pSMB = NULL;
3822 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3824 int bytes_returned = 0;
3826 __u16 params, byte_count;
3828 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
3830 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3835 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3837 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3838 PATH_MAX, nls_codepage, remap);
3839 name_len++; /* trailing null */
3842 name_len = copy_path_name(pSMB->FileName, searchName);
3845 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3846 pSMB->TotalDataCount = 0;
3847 pSMB->MaxParameterCount = cpu_to_le16(2);
3848 /* BB find exact max SMB PDU from sess structure BB */
3849 pSMB->MaxDataCount = cpu_to_le16(4000);
3850 pSMB->MaxSetupCount = 0;
3854 pSMB->Reserved2 = 0;
3855 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3856 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3857 pSMB->DataCount = 0;
3858 pSMB->DataOffset = 0;
3859 pSMB->SetupCount = 1;
3860 pSMB->Reserved3 = 0;
3861 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3862 byte_count = params + 1 /* pad */ ;
3863 pSMB->TotalParameterCount = cpu_to_le16(params);
3864 pSMB->ParameterCount = pSMB->TotalParameterCount;
3865 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3866 pSMB->Reserved4 = 0;
3867 inc_rfc1001_len(pSMB, byte_count);
3868 pSMB->ByteCount = cpu_to_le16(byte_count);
3870 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3871 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3873 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
3874 } else { /* decode response */
3875 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3877 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3878 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3879 rc = -EIO; /* bad smb */
3881 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3882 memcpy((char *) pFindData,
3883 (char *) &pSMBr->hdr.Protocol +
3885 sizeof(FILE_UNIX_BASIC_INFO));
3888 cifs_buf_release(pSMB);
3890 goto UnixQPathInfoRetry;
3895 /* xid, tcon, searchName and codepage are input parms, rest are returned */
3897 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
3898 const char *searchName, struct cifs_sb_info *cifs_sb,
3899 __u16 *pnetfid, __u16 search_flags,
3900 struct cifs_search_info *psrch_inf, bool msearch)
3902 /* level 257 SMB_ */
3903 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
3904 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
3905 T2_FFIRST_RSP_PARMS *parms;
3906 struct nls_table *nls_codepage;
3908 __u16 params, byte_count;
3909 int bytes_returned = 0;
3910 int name_len, remap;
3913 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
3916 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3921 nls_codepage = cifs_sb->local_nls;
3922 remap = cifs_remap(cifs_sb);
3924 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3926 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3927 PATH_MAX, nls_codepage, remap);
3928 /* We can not add the asterik earlier in case
3929 it got remapped to 0xF03A as if it were part of the
3930 directory name instead of a wildcard */
3933 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
3934 pSMB->FileName[name_len+1] = 0;
3935 pSMB->FileName[name_len+2] = '*';
3936 pSMB->FileName[name_len+3] = 0;
3937 name_len += 4; /* now the trailing null */
3938 /* null terminate just in case */
3939 pSMB->FileName[name_len] = 0;
3940 pSMB->FileName[name_len+1] = 0;
3944 name_len = copy_path_name(pSMB->FileName, searchName);
3946 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
3947 name_len = PATH_MAX-2;
3948 /* overwrite nul byte */
3949 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
3950 pSMB->FileName[name_len] = '*';
3951 pSMB->FileName[name_len+1] = 0;
3956 params = 12 + name_len /* includes null */ ;
3957 pSMB->TotalDataCount = 0; /* no EAs */
3958 pSMB->MaxParameterCount = cpu_to_le16(10);
3959 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
3960 pSMB->MaxSetupCount = 0;
3964 pSMB->Reserved2 = 0;
3965 byte_count = params + 1 /* pad */ ;
3966 pSMB->TotalParameterCount = cpu_to_le16(params);
3967 pSMB->ParameterCount = pSMB->TotalParameterCount;
3968 pSMB->ParameterOffset = cpu_to_le16(
3969 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
3971 pSMB->DataCount = 0;
3972 pSMB->DataOffset = 0;
3973 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
3974 pSMB->Reserved3 = 0;
3975 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
3976 pSMB->SearchAttributes =
3977 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3979 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
3980 pSMB->SearchFlags = cpu_to_le16(search_flags);
3981 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
3983 /* BB what should we set StorageType to? Does it matter? BB */
3984 pSMB->SearchStorageType = 0;
3985 inc_rfc1001_len(pSMB, byte_count);
3986 pSMB->ByteCount = cpu_to_le16(byte_count);
3988 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3989 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3990 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
3994 * BB: add logic to retry regular search if Unix search rejected
3995 * unexpectedly by server.
3997 /* BB: add code to handle unsupported level rc */
3998 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
3999 cifs_buf_release(pSMB);
4001 * BB: eventually could optimize out free and realloc of buf for
4005 goto findFirstRetry;
4008 /* decode response */
4009 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4011 cifs_buf_release(pSMB);
4015 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4016 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4017 psrch_inf->smallBuf = false;
4018 psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol +
4019 le16_to_cpu(pSMBr->t2.DataOffset);
4021 parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol +
4022 le16_to_cpu(pSMBr->t2.ParameterOffset));
4023 psrch_inf->endOfSearch = !!parms->EndofSearch;
4025 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4026 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4027 psrch_inf->entries_in_buffer;
4028 lnoff = le16_to_cpu(parms->LastNameOffset);
4029 if (CIFSMaxBufSize < lnoff) {
4030 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4031 psrch_inf->last_entry = NULL;
4033 psrch_inf->last_entry = psrch_inf->srch_entries_start + lnoff;
4035 *pnetfid = parms->SearchHandle;
4040 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4041 __u16 searchHandle, __u16 search_flags,
4042 struct cifs_search_info *psrch_inf)
4044 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4045 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4046 T2_FNEXT_RSP_PARMS *parms;
4047 unsigned int name_len;
4049 __u16 params, byte_count;
4050 char *response_data;
4054 cifs_dbg(FYI, "In FindNext\n");
4056 if (psrch_inf->endOfSearch)
4059 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4064 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4066 pSMB->TotalDataCount = 0; /* no EAs */
4067 pSMB->MaxParameterCount = cpu_to_le16(8);
4068 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4069 pSMB->MaxSetupCount = 0;
4073 pSMB->Reserved2 = 0;
4074 pSMB->ParameterOffset = cpu_to_le16(
4075 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4076 pSMB->DataCount = 0;
4077 pSMB->DataOffset = 0;
4078 pSMB->SetupCount = 1;
4079 pSMB->Reserved3 = 0;
4080 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4081 pSMB->SearchHandle = searchHandle; /* always kept as le */
4083 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4084 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4085 pSMB->ResumeKey = psrch_inf->resume_key;
4086 pSMB->SearchFlags = cpu_to_le16(search_flags);
4088 name_len = psrch_inf->resume_name_len;
4090 if (name_len < PATH_MAX) {
4091 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4092 byte_count += name_len;
4093 /* 14 byte parm len above enough for 2 byte null terminator */
4094 pSMB->ResumeFileName[name_len] = 0;
4095 pSMB->ResumeFileName[name_len+1] = 0;
4097 cifs_buf_release(pSMB);
4100 byte_count = params + 1 /* pad */ ;
4101 pSMB->TotalParameterCount = cpu_to_le16(params);
4102 pSMB->ParameterCount = pSMB->TotalParameterCount;
4103 inc_rfc1001_len(pSMB, byte_count);
4104 pSMB->ByteCount = cpu_to_le16(byte_count);
4106 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4107 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4108 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4111 cifs_buf_release(pSMB);
4113 psrch_inf->endOfSearch = true;
4114 rc = 0; /* search probably was closed at end of search*/
4116 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4121 /* decode response */
4122 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4124 cifs_buf_release(pSMB);
4127 /* BB fixme add lock for file (srch_info) struct here */
4128 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4129 response_data = (char *)&pSMBr->hdr.Protocol +
4130 le16_to_cpu(pSMBr->t2.ParameterOffset);
4131 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4132 response_data = (char *)&pSMBr->hdr.Protocol +
4133 le16_to_cpu(pSMBr->t2.DataOffset);
4135 if (psrch_inf->smallBuf)
4136 cifs_small_buf_release(psrch_inf->ntwrk_buf_start);
4138 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4140 psrch_inf->srch_entries_start = response_data;
4141 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4142 psrch_inf->smallBuf = false;
4143 psrch_inf->endOfSearch = !!parms->EndofSearch;
4144 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4145 psrch_inf->index_of_last_entry += psrch_inf->entries_in_buffer;
4146 lnoff = le16_to_cpu(parms->LastNameOffset);
4147 if (CIFSMaxBufSize < lnoff) {
4148 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4149 psrch_inf->last_entry = NULL;
4151 psrch_inf->last_entry =
4152 psrch_inf->srch_entries_start + lnoff;
4154 /* BB fixme add unlock here */
4157 * BB: On error, should we leave previous search buf
4158 * (and count and last entry fields) intact or free the previous one?
4160 * Note: On -EAGAIN error only caller can retry on handle based calls
4161 * since file handle passed in no longer valid.
4167 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4168 const __u16 searchHandle)
4171 FINDCLOSE_REQ *pSMB = NULL;
4173 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4174 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4176 /* no sense returning error if session restarted
4177 as file handle has been closed */
4183 pSMB->FileID = searchHandle;
4184 pSMB->ByteCount = 0;
4185 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4186 cifs_small_buf_release(pSMB);
4188 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4190 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4192 /* Since session is dead, search handle closed on server already */
4200 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4201 const char *search_name, __u64 *inode_number,
4202 const struct nls_table *nls_codepage, int remap)
4205 TRANSACTION2_QPI_REQ *pSMB = NULL;
4206 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4207 int name_len, bytes_returned;
4208 __u16 params, byte_count;
4210 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4214 GetInodeNumberRetry:
4215 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4220 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4222 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4223 search_name, PATH_MAX, nls_codepage,
4225 name_len++; /* trailing null */
4228 name_len = copy_path_name(pSMB->FileName, search_name);
4231 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4232 pSMB->TotalDataCount = 0;
4233 pSMB->MaxParameterCount = cpu_to_le16(2);
4234 /* BB find exact max data count below from sess structure BB */
4235 pSMB->MaxDataCount = cpu_to_le16(4000);
4236 pSMB->MaxSetupCount = 0;
4240 pSMB->Reserved2 = 0;
4241 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4242 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4243 pSMB->DataCount = 0;
4244 pSMB->DataOffset = 0;
4245 pSMB->SetupCount = 1;
4246 pSMB->Reserved3 = 0;
4247 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4248 byte_count = params + 1 /* pad */ ;
4249 pSMB->TotalParameterCount = cpu_to_le16(params);
4250 pSMB->ParameterCount = pSMB->TotalParameterCount;
4251 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4252 pSMB->Reserved4 = 0;
4253 inc_rfc1001_len(pSMB, byte_count);
4254 pSMB->ByteCount = cpu_to_le16(byte_count);
4256 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4257 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4259 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4261 /* decode response */
4262 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4263 /* BB also check enough total bytes returned */
4264 if (rc || get_bcc(&pSMBr->hdr) < 2)
4265 /* If rc should we check for EOPNOSUPP and
4266 disable the srvino flag? or in caller? */
4267 rc = -EIO; /* bad smb */
4269 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4270 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4271 struct file_internal_info *pfinfo;
4272 /* BB Do we need a cast or hash here ? */
4274 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4276 goto GetInodeNumOut;
4278 pfinfo = (struct file_internal_info *)
4279 (data_offset + (char *) &pSMBr->hdr.Protocol);
4280 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4284 cifs_buf_release(pSMB);
4286 goto GetInodeNumberRetry;
4291 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4292 const char *search_name, struct dfs_info3_param **target_nodes,
4293 unsigned int *num_of_nodes,
4294 const struct nls_table *nls_codepage, int remap)
4296 /* TRANS2_GET_DFS_REFERRAL */
4297 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4298 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4302 __u16 params, byte_count;
4304 *target_nodes = NULL;
4306 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4307 if (ses == NULL || ses->tcon_ipc == NULL)
4312 * Use smb_init_no_reconnect() instead of smb_init() as
4313 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4314 * causing an infinite recursion.
4316 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4317 (void **)&pSMB, (void **)&pSMBr);
4321 /* server pointer checked in called function,
4322 but should never be null here anyway */
4323 pSMB->hdr.Mid = get_next_mid(ses->server);
4324 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4325 pSMB->hdr.Uid = ses->Suid;
4326 if (ses->capabilities & CAP_STATUS32)
4327 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4328 if (ses->capabilities & CAP_DFS)
4329 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4331 if (ses->capabilities & CAP_UNICODE) {
4332 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4334 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4335 search_name, PATH_MAX, nls_codepage,
4337 name_len++; /* trailing null */
4339 } else { /* BB improve the check for buffer overruns BB */
4340 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4343 if (ses->server->sign)
4344 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4346 pSMB->hdr.Uid = ses->Suid;
4348 params = 2 /* level */ + name_len /*includes null */ ;
4349 pSMB->TotalDataCount = 0;
4350 pSMB->DataCount = 0;
4351 pSMB->DataOffset = 0;
4352 pSMB->MaxParameterCount = 0;
4353 /* BB find exact max SMB PDU from sess structure BB */
4354 pSMB->MaxDataCount = cpu_to_le16(4000);
4355 pSMB->MaxSetupCount = 0;
4359 pSMB->Reserved2 = 0;
4360 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4361 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4362 pSMB->SetupCount = 1;
4363 pSMB->Reserved3 = 0;
4364 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4365 byte_count = params + 3 /* pad */ ;
4366 pSMB->ParameterCount = cpu_to_le16(params);
4367 pSMB->TotalParameterCount = pSMB->ParameterCount;
4368 pSMB->MaxReferralLevel = cpu_to_le16(3);
4369 inc_rfc1001_len(pSMB, byte_count);
4370 pSMB->ByteCount = cpu_to_le16(byte_count);
4372 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4373 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4375 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4378 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4380 /* BB Also check if enough total bytes returned? */
4381 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4382 rc = -EIO; /* bad smb */
4386 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4387 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4389 /* parse returned result into more usable form */
4390 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4391 le16_to_cpu(pSMBr->t2.DataCount),
4392 num_of_nodes, target_nodes, nls_codepage,
4394 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4397 cifs_buf_release(pSMB);
4405 /* Query File System Info such as free space to old servers such as Win 9x */
4407 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4408 struct kstatfs *FSData)
4410 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4411 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4412 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4413 FILE_SYSTEM_ALLOC_INFO *response_data;
4415 int bytes_returned = 0;
4416 __u16 params, byte_count;
4418 cifs_dbg(FYI, "OldQFSInfo\n");
4420 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4425 params = 2; /* level */
4426 pSMB->TotalDataCount = 0;
4427 pSMB->MaxParameterCount = cpu_to_le16(2);
4428 pSMB->MaxDataCount = cpu_to_le16(1000);
4429 pSMB->MaxSetupCount = 0;
4433 pSMB->Reserved2 = 0;
4434 byte_count = params + 1 /* pad */ ;
4435 pSMB->TotalParameterCount = cpu_to_le16(params);
4436 pSMB->ParameterCount = pSMB->TotalParameterCount;
4437 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4438 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4439 pSMB->DataCount = 0;
4440 pSMB->DataOffset = 0;
4441 pSMB->SetupCount = 1;
4442 pSMB->Reserved3 = 0;
4443 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4444 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4445 inc_rfc1001_len(pSMB, byte_count);
4446 pSMB->ByteCount = cpu_to_le16(byte_count);
4448 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4449 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4451 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4452 } else { /* decode response */
4453 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4455 if (rc || get_bcc(&pSMBr->hdr) < 18)
4456 rc = -EIO; /* bad smb */
4458 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4459 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4460 get_bcc(&pSMBr->hdr), data_offset);
4462 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4463 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4465 le16_to_cpu(response_data->BytesPerSector) *
4466 le32_to_cpu(response_data->
4467 SectorsPerAllocationUnit);
4469 * much prefer larger but if server doesn't report
4470 * a valid size than 4K is a reasonable minimum
4472 if (FSData->f_bsize < 512)
4473 FSData->f_bsize = 4096;
4476 le32_to_cpu(response_data->TotalAllocationUnits);
4477 FSData->f_bfree = FSData->f_bavail =
4478 le32_to_cpu(response_data->FreeAllocationUnits);
4479 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4480 (unsigned long long)FSData->f_blocks,
4481 (unsigned long long)FSData->f_bfree,
4485 cifs_buf_release(pSMB);
4488 goto oldQFSInfoRetry;
4494 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4495 struct kstatfs *FSData)
4497 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4498 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4499 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4500 FILE_SYSTEM_INFO *response_data;
4502 int bytes_returned = 0;
4503 __u16 params, byte_count;
4505 cifs_dbg(FYI, "In QFSInfo\n");
4507 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4512 params = 2; /* level */
4513 pSMB->TotalDataCount = 0;
4514 pSMB->MaxParameterCount = cpu_to_le16(2);
4515 pSMB->MaxDataCount = cpu_to_le16(1000);
4516 pSMB->MaxSetupCount = 0;
4520 pSMB->Reserved2 = 0;
4521 byte_count = params + 1 /* pad */ ;
4522 pSMB->TotalParameterCount = cpu_to_le16(params);
4523 pSMB->ParameterCount = pSMB->TotalParameterCount;
4524 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4525 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4526 pSMB->DataCount = 0;
4527 pSMB->DataOffset = 0;
4528 pSMB->SetupCount = 1;
4529 pSMB->Reserved3 = 0;
4530 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4531 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4532 inc_rfc1001_len(pSMB, byte_count);
4533 pSMB->ByteCount = cpu_to_le16(byte_count);
4535 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4536 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4538 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4539 } else { /* decode response */
4540 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4542 if (rc || get_bcc(&pSMBr->hdr) < 24)
4543 rc = -EIO; /* bad smb */
4545 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4549 *) (((char *) &pSMBr->hdr.Protocol) +
4552 le32_to_cpu(response_data->BytesPerSector) *
4553 le32_to_cpu(response_data->
4554 SectorsPerAllocationUnit);
4556 * much prefer larger but if server doesn't report
4557 * a valid size than 4K is a reasonable minimum
4559 if (FSData->f_bsize < 512)
4560 FSData->f_bsize = 4096;
4563 le64_to_cpu(response_data->TotalAllocationUnits);
4564 FSData->f_bfree = FSData->f_bavail =
4565 le64_to_cpu(response_data->FreeAllocationUnits);
4566 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4567 (unsigned long long)FSData->f_blocks,
4568 (unsigned long long)FSData->f_bfree,
4572 cifs_buf_release(pSMB);
4581 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
4583 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
4584 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4585 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4586 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
4588 int bytes_returned = 0;
4589 __u16 params, byte_count;
4591 cifs_dbg(FYI, "In QFSAttributeInfo\n");
4593 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4598 params = 2; /* level */
4599 pSMB->TotalDataCount = 0;
4600 pSMB->MaxParameterCount = cpu_to_le16(2);
4601 /* BB find exact max SMB PDU from sess structure BB */
4602 pSMB->MaxDataCount = cpu_to_le16(1000);
4603 pSMB->MaxSetupCount = 0;
4607 pSMB->Reserved2 = 0;
4608 byte_count = params + 1 /* pad */ ;
4609 pSMB->TotalParameterCount = cpu_to_le16(params);
4610 pSMB->ParameterCount = pSMB->TotalParameterCount;
4611 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4612 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4613 pSMB->DataCount = 0;
4614 pSMB->DataOffset = 0;
4615 pSMB->SetupCount = 1;
4616 pSMB->Reserved3 = 0;
4617 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4618 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4619 inc_rfc1001_len(pSMB, byte_count);
4620 pSMB->ByteCount = cpu_to_le16(byte_count);
4622 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4623 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4625 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
4626 } else { /* decode response */
4627 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4629 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4630 /* BB also check if enough bytes returned */
4631 rc = -EIO; /* bad smb */
4633 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4635 (FILE_SYSTEM_ATTRIBUTE_INFO
4636 *) (((char *) &pSMBr->hdr.Protocol) +
4638 memcpy(&tcon->fsAttrInfo, response_data,
4639 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
4642 cifs_buf_release(pSMB);
4645 goto QFSAttributeRetry;
4651 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
4653 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4654 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4655 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4656 FILE_SYSTEM_DEVICE_INFO *response_data;
4658 int bytes_returned = 0;
4659 __u16 params, byte_count;
4661 cifs_dbg(FYI, "In QFSDeviceInfo\n");
4663 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4668 params = 2; /* level */
4669 pSMB->TotalDataCount = 0;
4670 pSMB->MaxParameterCount = cpu_to_le16(2);
4671 /* BB find exact max SMB PDU from sess structure BB */
4672 pSMB->MaxDataCount = cpu_to_le16(1000);
4673 pSMB->MaxSetupCount = 0;
4677 pSMB->Reserved2 = 0;
4678 byte_count = params + 1 /* pad */ ;
4679 pSMB->TotalParameterCount = cpu_to_le16(params);
4680 pSMB->ParameterCount = pSMB->TotalParameterCount;
4681 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4682 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4684 pSMB->DataCount = 0;
4685 pSMB->DataOffset = 0;
4686 pSMB->SetupCount = 1;
4687 pSMB->Reserved3 = 0;
4688 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4689 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4690 inc_rfc1001_len(pSMB, byte_count);
4691 pSMB->ByteCount = cpu_to_le16(byte_count);
4693 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4694 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4696 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
4697 } else { /* decode response */
4698 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4700 if (rc || get_bcc(&pSMBr->hdr) <
4701 sizeof(FILE_SYSTEM_DEVICE_INFO))
4702 rc = -EIO; /* bad smb */
4704 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4706 (FILE_SYSTEM_DEVICE_INFO *)
4707 (((char *) &pSMBr->hdr.Protocol) +
4709 memcpy(&tcon->fsDevInfo, response_data,
4710 sizeof(FILE_SYSTEM_DEVICE_INFO));
4713 cifs_buf_release(pSMB);
4716 goto QFSDeviceRetry;
4722 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
4724 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
4725 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4726 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4727 FILE_SYSTEM_UNIX_INFO *response_data;
4729 int bytes_returned = 0;
4730 __u16 params, byte_count;
4732 cifs_dbg(FYI, "In QFSUnixInfo\n");
4734 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4735 (void **) &pSMB, (void **) &pSMBr);
4739 params = 2; /* level */
4740 pSMB->TotalDataCount = 0;
4741 pSMB->DataCount = 0;
4742 pSMB->DataOffset = 0;
4743 pSMB->MaxParameterCount = cpu_to_le16(2);
4744 /* BB find exact max SMB PDU from sess structure BB */
4745 pSMB->MaxDataCount = cpu_to_le16(100);
4746 pSMB->MaxSetupCount = 0;
4750 pSMB->Reserved2 = 0;
4751 byte_count = params + 1 /* pad */ ;
4752 pSMB->ParameterCount = cpu_to_le16(params);
4753 pSMB->TotalParameterCount = pSMB->ParameterCount;
4754 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4755 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4756 pSMB->SetupCount = 1;
4757 pSMB->Reserved3 = 0;
4758 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4759 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4760 inc_rfc1001_len(pSMB, byte_count);
4761 pSMB->ByteCount = cpu_to_le16(byte_count);
4763 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4764 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4766 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
4767 } else { /* decode response */
4768 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4770 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4771 rc = -EIO; /* bad smb */
4773 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4775 (FILE_SYSTEM_UNIX_INFO
4776 *) (((char *) &pSMBr->hdr.Protocol) +
4778 memcpy(&tcon->fsUnixInfo, response_data,
4779 sizeof(FILE_SYSTEM_UNIX_INFO));
4782 cifs_buf_release(pSMB);
4792 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
4794 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
4795 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
4796 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
4798 int bytes_returned = 0;
4799 __u16 params, param_offset, offset, byte_count;
4801 cifs_dbg(FYI, "In SETFSUnixInfo\n");
4803 /* BB switch to small buf init to save memory */
4804 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4805 (void **) &pSMB, (void **) &pSMBr);
4809 params = 4; /* 2 bytes zero followed by info level. */
4810 pSMB->MaxSetupCount = 0;
4814 pSMB->Reserved2 = 0;
4815 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
4817 offset = param_offset + params;
4819 pSMB->MaxParameterCount = cpu_to_le16(4);
4820 /* BB find exact max SMB PDU from sess structure BB */
4821 pSMB->MaxDataCount = cpu_to_le16(100);
4822 pSMB->SetupCount = 1;
4823 pSMB->Reserved3 = 0;
4824 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
4825 byte_count = 1 /* pad */ + params + 12;
4827 pSMB->DataCount = cpu_to_le16(12);
4828 pSMB->ParameterCount = cpu_to_le16(params);
4829 pSMB->TotalDataCount = pSMB->DataCount;
4830 pSMB->TotalParameterCount = pSMB->ParameterCount;
4831 pSMB->ParameterOffset = cpu_to_le16(param_offset);
4832 pSMB->DataOffset = cpu_to_le16(offset);
4836 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
4839 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
4840 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4841 pSMB->ClientUnixCap = cpu_to_le64(cap);
4843 inc_rfc1001_len(pSMB, byte_count);
4844 pSMB->ByteCount = cpu_to_le16(byte_count);
4846 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4847 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4849 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
4850 } else { /* decode response */
4851 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4853 rc = -EIO; /* bad smb */
4855 cifs_buf_release(pSMB);
4858 goto SETFSUnixRetry;
4866 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
4867 struct kstatfs *FSData)
4869 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
4870 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4871 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4872 FILE_SYSTEM_POSIX_INFO *response_data;
4874 int bytes_returned = 0;
4875 __u16 params, byte_count;
4877 cifs_dbg(FYI, "In QFSPosixInfo\n");
4879 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4884 params = 2; /* level */
4885 pSMB->TotalDataCount = 0;
4886 pSMB->DataCount = 0;
4887 pSMB->DataOffset = 0;
4888 pSMB->MaxParameterCount = cpu_to_le16(2);
4889 /* BB find exact max SMB PDU from sess structure BB */
4890 pSMB->MaxDataCount = cpu_to_le16(100);
4891 pSMB->MaxSetupCount = 0;
4895 pSMB->Reserved2 = 0;
4896 byte_count = params + 1 /* pad */ ;
4897 pSMB->ParameterCount = cpu_to_le16(params);
4898 pSMB->TotalParameterCount = pSMB->ParameterCount;
4899 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4900 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4901 pSMB->SetupCount = 1;
4902 pSMB->Reserved3 = 0;
4903 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4904 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4905 inc_rfc1001_len(pSMB, byte_count);
4906 pSMB->ByteCount = cpu_to_le16(byte_count);
4908 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4909 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4911 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
4912 } else { /* decode response */
4913 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4915 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4916 rc = -EIO; /* bad smb */
4918 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4920 (FILE_SYSTEM_POSIX_INFO
4921 *) (((char *) &pSMBr->hdr.Protocol) +
4924 le32_to_cpu(response_data->BlockSize);
4926 * much prefer larger but if server doesn't report
4927 * a valid size than 4K is a reasonable minimum
4929 if (FSData->f_bsize < 512)
4930 FSData->f_bsize = 4096;
4933 le64_to_cpu(response_data->TotalBlocks);
4935 le64_to_cpu(response_data->BlocksAvail);
4936 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
4937 FSData->f_bavail = FSData->f_bfree;
4940 le64_to_cpu(response_data->UserBlocksAvail);
4942 if (response_data->TotalFileNodes != cpu_to_le64(-1))
4944 le64_to_cpu(response_data->TotalFileNodes);
4945 if (response_data->FreeFileNodes != cpu_to_le64(-1))
4947 le64_to_cpu(response_data->FreeFileNodes);
4950 cifs_buf_release(pSMB);
4960 * We can not use write of zero bytes trick to set file size due to need for
4961 * large file support. Also note that this SetPathInfo is preferred to
4962 * SetFileInfo based method in next routine which is only needed to work around
4963 * a sharing violation bugin Samba which this routine can run into.
4966 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
4967 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
4968 bool set_allocation)
4970 struct smb_com_transaction2_spi_req *pSMB = NULL;
4971 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
4972 struct file_end_of_file_info *parm_data;
4975 int bytes_returned = 0;
4976 int remap = cifs_remap(cifs_sb);
4978 __u16 params, byte_count, data_count, param_offset, offset;
4980 cifs_dbg(FYI, "In SetEOF\n");
4982 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4987 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4989 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
4990 PATH_MAX, cifs_sb->local_nls, remap);
4991 name_len++; /* trailing null */
4994 name_len = copy_path_name(pSMB->FileName, file_name);
4996 params = 6 + name_len;
4997 data_count = sizeof(struct file_end_of_file_info);
4998 pSMB->MaxParameterCount = cpu_to_le16(2);
4999 pSMB->MaxDataCount = cpu_to_le16(4100);
5000 pSMB->MaxSetupCount = 0;
5004 pSMB->Reserved2 = 0;
5005 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5006 InformationLevel) - 4;
5007 offset = param_offset + params;
5008 if (set_allocation) {
5009 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5010 pSMB->InformationLevel =
5011 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5013 pSMB->InformationLevel =
5014 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5015 } else /* Set File Size */ {
5016 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5017 pSMB->InformationLevel =
5018 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5020 pSMB->InformationLevel =
5021 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5025 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5027 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5028 pSMB->DataOffset = cpu_to_le16(offset);
5029 pSMB->SetupCount = 1;
5030 pSMB->Reserved3 = 0;
5031 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5032 byte_count = 3 /* pad */ + params + data_count;
5033 pSMB->DataCount = cpu_to_le16(data_count);
5034 pSMB->TotalDataCount = pSMB->DataCount;
5035 pSMB->ParameterCount = cpu_to_le16(params);
5036 pSMB->TotalParameterCount = pSMB->ParameterCount;
5037 pSMB->Reserved4 = 0;
5038 inc_rfc1001_len(pSMB, byte_count);
5039 parm_data->FileSize = cpu_to_le64(size);
5040 pSMB->ByteCount = cpu_to_le16(byte_count);
5041 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5042 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5044 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5046 cifs_buf_release(pSMB);
5055 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5056 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5058 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5059 struct file_end_of_file_info *parm_data;
5061 __u16 params, param_offset, offset, byte_count, count;
5063 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5065 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5070 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5071 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5074 pSMB->MaxSetupCount = 0;
5078 pSMB->Reserved2 = 0;
5079 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5080 offset = param_offset + params;
5082 count = sizeof(struct file_end_of_file_info);
5083 pSMB->MaxParameterCount = cpu_to_le16(2);
5084 /* BB find exact max SMB PDU from sess structure BB */
5085 pSMB->MaxDataCount = cpu_to_le16(1000);
5086 pSMB->SetupCount = 1;
5087 pSMB->Reserved3 = 0;
5088 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5089 byte_count = 3 /* pad */ + params + count;
5090 pSMB->DataCount = cpu_to_le16(count);
5091 pSMB->ParameterCount = cpu_to_le16(params);
5092 pSMB->TotalDataCount = pSMB->DataCount;
5093 pSMB->TotalParameterCount = pSMB->ParameterCount;
5094 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5095 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5097 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5098 pSMB->DataOffset = cpu_to_le16(offset);
5099 parm_data->FileSize = cpu_to_le64(size);
5100 pSMB->Fid = cfile->fid.netfid;
5101 if (set_allocation) {
5102 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5103 pSMB->InformationLevel =
5104 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5106 pSMB->InformationLevel =
5107 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5108 } else /* Set File Size */ {
5109 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5110 pSMB->InformationLevel =
5111 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5113 pSMB->InformationLevel =
5114 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5116 pSMB->Reserved4 = 0;
5117 inc_rfc1001_len(pSMB, byte_count);
5118 pSMB->ByteCount = cpu_to_le16(byte_count);
5119 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5120 cifs_small_buf_release(pSMB);
5122 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5126 /* Note: On -EAGAIN error only caller can retry on handle based calls
5127 since file handle passed in no longer valid */
5132 /* Some legacy servers such as NT4 require that the file times be set on
5133 an open handle, rather than by pathname - this is awkward due to
5134 potential access conflicts on the open, but it is unavoidable for these
5135 old servers since the only other choice is to go from 100 nanosecond DCE
5136 time and resort to the original setpathinfo level which takes the ancient
5137 DOS time format with 2 second granularity */
5139 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5140 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5142 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5145 __u16 params, param_offset, offset, byte_count, count;
5147 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5148 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5153 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5154 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5157 pSMB->MaxSetupCount = 0;
5161 pSMB->Reserved2 = 0;
5162 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5163 offset = param_offset + params;
5165 data_offset = (char *)pSMB +
5166 offsetof(struct smb_hdr, Protocol) + offset;
5168 count = sizeof(FILE_BASIC_INFO);
5169 pSMB->MaxParameterCount = cpu_to_le16(2);
5170 /* BB find max SMB PDU from sess */
5171 pSMB->MaxDataCount = cpu_to_le16(1000);
5172 pSMB->SetupCount = 1;
5173 pSMB->Reserved3 = 0;
5174 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5175 byte_count = 3 /* pad */ + params + count;
5176 pSMB->DataCount = cpu_to_le16(count);
5177 pSMB->ParameterCount = cpu_to_le16(params);
5178 pSMB->TotalDataCount = pSMB->DataCount;
5179 pSMB->TotalParameterCount = pSMB->ParameterCount;
5180 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5181 pSMB->DataOffset = cpu_to_le16(offset);
5183 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5184 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5186 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5187 pSMB->Reserved4 = 0;
5188 inc_rfc1001_len(pSMB, byte_count);
5189 pSMB->ByteCount = cpu_to_le16(byte_count);
5190 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5191 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5192 cifs_small_buf_release(pSMB);
5194 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5197 /* Note: On -EAGAIN error only caller can retry on handle based calls
5198 since file handle passed in no longer valid */
5204 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5205 bool delete_file, __u16 fid, __u32 pid_of_opener)
5207 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5210 __u16 params, param_offset, offset, byte_count, count;
5212 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5213 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5218 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5219 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5222 pSMB->MaxSetupCount = 0;
5226 pSMB->Reserved2 = 0;
5227 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5228 offset = param_offset + params;
5230 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5231 data_offset = (char *)(pSMB) + offset + 4;
5234 pSMB->MaxParameterCount = cpu_to_le16(2);
5235 /* BB find max SMB PDU from sess */
5236 pSMB->MaxDataCount = cpu_to_le16(1000);
5237 pSMB->SetupCount = 1;
5238 pSMB->Reserved3 = 0;
5239 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5240 byte_count = 3 /* pad */ + params + count;
5241 pSMB->DataCount = cpu_to_le16(count);
5242 pSMB->ParameterCount = cpu_to_le16(params);
5243 pSMB->TotalDataCount = pSMB->DataCount;
5244 pSMB->TotalParameterCount = pSMB->ParameterCount;
5245 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5246 pSMB->DataOffset = cpu_to_le16(offset);
5248 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5249 pSMB->Reserved4 = 0;
5250 inc_rfc1001_len(pSMB, byte_count);
5251 pSMB->ByteCount = cpu_to_le16(byte_count);
5252 *data_offset = delete_file ? 1 : 0;
5253 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5254 cifs_small_buf_release(pSMB);
5256 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5262 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5263 const char *fileName, const FILE_BASIC_INFO *data,
5264 const struct nls_table *nls_codepage,
5265 struct cifs_sb_info *cifs_sb)
5268 struct cifs_open_parms oparms;
5269 struct cifs_fid fid;
5272 oparms = (struct cifs_open_parms) {
5275 .desired_access = GENERIC_WRITE,
5276 .create_options = cifs_create_options(cifs_sb, 0),
5277 .disposition = FILE_OPEN,
5282 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5286 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5287 CIFSSMBClose(xid, tcon, fid.netfid);
5294 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5295 const char *fileName, const FILE_BASIC_INFO *data,
5296 const struct nls_table *nls_codepage,
5297 struct cifs_sb_info *cifs_sb)
5299 TRANSACTION2_SPI_REQ *pSMB = NULL;
5300 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5303 int bytes_returned = 0;
5305 __u16 params, param_offset, offset, byte_count, count;
5306 int remap = cifs_remap(cifs_sb);
5308 cifs_dbg(FYI, "In SetTimes\n");
5311 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5316 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5318 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5319 PATH_MAX, nls_codepage, remap);
5320 name_len++; /* trailing null */
5323 name_len = copy_path_name(pSMB->FileName, fileName);
5326 params = 6 + name_len;
5327 count = sizeof(FILE_BASIC_INFO);
5328 pSMB->MaxParameterCount = cpu_to_le16(2);
5329 /* BB find max SMB PDU from sess structure BB */
5330 pSMB->MaxDataCount = cpu_to_le16(1000);
5331 pSMB->MaxSetupCount = 0;
5335 pSMB->Reserved2 = 0;
5336 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5337 InformationLevel) - 4;
5338 offset = param_offset + params;
5339 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5340 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5341 pSMB->DataOffset = cpu_to_le16(offset);
5342 pSMB->SetupCount = 1;
5343 pSMB->Reserved3 = 0;
5344 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5345 byte_count = 3 /* pad */ + params + count;
5347 pSMB->DataCount = cpu_to_le16(count);
5348 pSMB->ParameterCount = cpu_to_le16(params);
5349 pSMB->TotalDataCount = pSMB->DataCount;
5350 pSMB->TotalParameterCount = pSMB->ParameterCount;
5351 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5352 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5354 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5355 pSMB->Reserved4 = 0;
5356 inc_rfc1001_len(pSMB, byte_count);
5357 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5358 pSMB->ByteCount = cpu_to_le16(byte_count);
5359 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5360 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5362 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5364 cifs_buf_release(pSMB);
5369 if (rc == -EOPNOTSUPP)
5370 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5371 nls_codepage, cifs_sb);
5377 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5378 const struct cifs_unix_set_info_args *args)
5380 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5381 u64 mode = args->mode;
5383 if (uid_valid(args->uid))
5384 uid = from_kuid(&init_user_ns, args->uid);
5385 if (gid_valid(args->gid))
5386 gid = from_kgid(&init_user_ns, args->gid);
5389 * Samba server ignores set of file size to zero due to bugs in some
5390 * older clients, but we should be precise - we use SetFileSize to
5391 * set file size and do not want to truncate file size to zero
5392 * accidentally as happened on one Samba server beta by putting
5393 * zero instead of -1 here
5395 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5396 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5397 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5398 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5399 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5400 data_offset->Uid = cpu_to_le64(uid);
5401 data_offset->Gid = cpu_to_le64(gid);
5402 /* better to leave device as zero when it is */
5403 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5404 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5405 data_offset->Permissions = cpu_to_le64(mode);
5408 data_offset->Type = cpu_to_le32(UNIX_FILE);
5409 else if (S_ISDIR(mode))
5410 data_offset->Type = cpu_to_le32(UNIX_DIR);
5411 else if (S_ISLNK(mode))
5412 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5413 else if (S_ISCHR(mode))
5414 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5415 else if (S_ISBLK(mode))
5416 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5417 else if (S_ISFIFO(mode))
5418 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5419 else if (S_ISSOCK(mode))
5420 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5424 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5425 const struct cifs_unix_set_info_args *args,
5426 u16 fid, u32 pid_of_opener)
5428 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5431 u16 params, param_offset, offset, byte_count, count;
5433 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5434 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5439 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5440 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5443 pSMB->MaxSetupCount = 0;
5447 pSMB->Reserved2 = 0;
5448 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5449 offset = param_offset + params;
5451 data_offset = (char *)pSMB +
5452 offsetof(struct smb_hdr, Protocol) + offset;
5454 count = sizeof(FILE_UNIX_BASIC_INFO);
5456 pSMB->MaxParameterCount = cpu_to_le16(2);
5457 /* BB find max SMB PDU from sess */
5458 pSMB->MaxDataCount = cpu_to_le16(1000);
5459 pSMB->SetupCount = 1;
5460 pSMB->Reserved3 = 0;
5461 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5462 byte_count = 3 /* pad */ + params + count;
5463 pSMB->DataCount = cpu_to_le16(count);
5464 pSMB->ParameterCount = cpu_to_le16(params);
5465 pSMB->TotalDataCount = pSMB->DataCount;
5466 pSMB->TotalParameterCount = pSMB->ParameterCount;
5467 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5468 pSMB->DataOffset = cpu_to_le16(offset);
5470 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5471 pSMB->Reserved4 = 0;
5472 inc_rfc1001_len(pSMB, byte_count);
5473 pSMB->ByteCount = cpu_to_le16(byte_count);
5475 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5477 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5478 cifs_small_buf_release(pSMB);
5480 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5483 /* Note: On -EAGAIN error only caller can retry on handle based calls
5484 since file handle passed in no longer valid */
5490 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5491 const char *file_name,
5492 const struct cifs_unix_set_info_args *args,
5493 const struct nls_table *nls_codepage, int remap)
5495 TRANSACTION2_SPI_REQ *pSMB = NULL;
5496 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5499 int bytes_returned = 0;
5500 FILE_UNIX_BASIC_INFO *data_offset;
5501 __u16 params, param_offset, offset, count, byte_count;
5503 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5505 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5510 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5512 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5513 PATH_MAX, nls_codepage, remap);
5514 name_len++; /* trailing null */
5517 name_len = copy_path_name(pSMB->FileName, file_name);
5520 params = 6 + name_len;
5521 count = sizeof(FILE_UNIX_BASIC_INFO);
5522 pSMB->MaxParameterCount = cpu_to_le16(2);
5523 /* BB find max SMB PDU from sess structure BB */
5524 pSMB->MaxDataCount = cpu_to_le16(1000);
5525 pSMB->MaxSetupCount = 0;
5529 pSMB->Reserved2 = 0;
5530 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5531 InformationLevel) - 4;
5532 offset = param_offset + params;
5533 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5534 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
5535 memset(data_offset, 0, count);
5536 pSMB->DataOffset = cpu_to_le16(offset);
5537 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5538 pSMB->SetupCount = 1;
5539 pSMB->Reserved3 = 0;
5540 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5541 byte_count = 3 /* pad */ + params + count;
5542 pSMB->ParameterCount = cpu_to_le16(params);
5543 pSMB->DataCount = cpu_to_le16(count);
5544 pSMB->TotalParameterCount = pSMB->ParameterCount;
5545 pSMB->TotalDataCount = pSMB->DataCount;
5546 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5547 pSMB->Reserved4 = 0;
5548 inc_rfc1001_len(pSMB, byte_count);
5550 cifs_fill_unix_set_info(data_offset, args);
5552 pSMB->ByteCount = cpu_to_le16(byte_count);
5553 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5554 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5556 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
5558 cifs_buf_release(pSMB);
5564 #ifdef CONFIG_CIFS_XATTR
5566 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
5567 * function used by listxattr and getxattr type calls. When ea_name is set,
5568 * it looks for that attribute name and stuffs that value into the EAData
5569 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
5570 * buffer. In both cases, the return value is either the length of the
5571 * resulting data or a negative error code. If EAData is a NULL pointer then
5572 * the data isn't copied to it, but the length is returned.
5575 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
5576 const unsigned char *searchName, const unsigned char *ea_name,
5577 char *EAData, size_t buf_size,
5578 struct cifs_sb_info *cifs_sb)
5580 /* BB assumes one setup word */
5581 TRANSACTION2_QPI_REQ *pSMB = NULL;
5582 TRANSACTION2_QPI_RSP *pSMBr = NULL;
5583 int remap = cifs_remap(cifs_sb);
5584 struct nls_table *nls_codepage = cifs_sb->local_nls;
5588 struct fealist *ea_response_data;
5589 struct fea *temp_fea;
5592 __u16 params, byte_count, data_offset;
5593 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
5595 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
5597 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5602 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5604 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
5605 PATH_MAX, nls_codepage, remap);
5606 list_len++; /* trailing null */
5609 list_len = copy_path_name(pSMB->FileName, searchName);
5612 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
5613 pSMB->TotalDataCount = 0;
5614 pSMB->MaxParameterCount = cpu_to_le16(2);
5615 /* BB find exact max SMB PDU from sess structure BB */
5616 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
5617 pSMB->MaxSetupCount = 0;
5621 pSMB->Reserved2 = 0;
5622 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5623 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5624 pSMB->DataCount = 0;
5625 pSMB->DataOffset = 0;
5626 pSMB->SetupCount = 1;
5627 pSMB->Reserved3 = 0;
5628 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
5629 byte_count = params + 1 /* pad */ ;
5630 pSMB->TotalParameterCount = cpu_to_le16(params);
5631 pSMB->ParameterCount = pSMB->TotalParameterCount;
5632 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5633 pSMB->Reserved4 = 0;
5634 inc_rfc1001_len(pSMB, byte_count);
5635 pSMB->ByteCount = cpu_to_le16(byte_count);
5637 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5638 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5640 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
5645 /* BB also check enough total bytes returned */
5646 /* BB we need to improve the validity checking
5647 of these trans2 responses */
5649 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5650 if (rc || get_bcc(&pSMBr->hdr) < 4) {
5651 rc = -EIO; /* bad smb */
5655 /* check that length of list is not more than bcc */
5656 /* check that each entry does not go beyond length
5658 /* check that each element of each entry does not
5659 go beyond end of list */
5660 /* validate_trans2_offsets() */
5661 /* BB check if start of smb + data_offset > &bcc+ bcc */
5663 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5664 ea_response_data = (struct fealist *)
5665 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5667 list_len = le32_to_cpu(ea_response_data->list_len);
5668 cifs_dbg(FYI, "ea length %d\n", list_len);
5669 if (list_len <= 8) {
5670 cifs_dbg(FYI, "empty EA list returned from server\n");
5671 /* didn't find the named attribute */
5677 /* make sure list_len doesn't go past end of SMB */
5678 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
5679 if ((char *)ea_response_data + list_len > end_of_smb) {
5680 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
5685 /* account for ea list len */
5687 temp_fea = &ea_response_data->list;
5688 temp_ptr = (char *)temp_fea;
5689 while (list_len > 0) {
5690 unsigned int name_len;
5695 /* make sure we can read name_len and value_len */
5697 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5702 name_len = temp_fea->name_len;
5703 value_len = le16_to_cpu(temp_fea->value_len);
5704 list_len -= name_len + 1 + value_len;
5706 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5712 if (ea_name_len == name_len &&
5713 memcmp(ea_name, temp_ptr, name_len) == 0) {
5714 temp_ptr += name_len + 1;
5718 if ((size_t)value_len > buf_size) {
5722 memcpy(EAData, temp_ptr, value_len);
5726 /* account for prefix user. and trailing null */
5727 rc += (5 + 1 + name_len);
5728 if (rc < (int) buf_size) {
5729 memcpy(EAData, "user.", 5);
5731 memcpy(EAData, temp_ptr, name_len);
5733 /* null terminate name */
5736 } else if (buf_size == 0) {
5737 /* skip copy - calc size only */
5739 /* stop before overrun buffer */
5744 temp_ptr += name_len + 1 + value_len;
5745 temp_fea = (struct fea *)temp_ptr;
5748 /* didn't find the named attribute */
5753 cifs_buf_release(pSMB);
5761 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
5762 const char *fileName, const char *ea_name, const void *ea_value,
5763 const __u16 ea_value_len, const struct nls_table *nls_codepage,
5764 struct cifs_sb_info *cifs_sb)
5766 struct smb_com_transaction2_spi_req *pSMB = NULL;
5767 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5768 struct fealist *parm_data;
5771 int bytes_returned = 0;
5772 __u16 params, param_offset, byte_count, offset, count;
5773 int remap = cifs_remap(cifs_sb);
5775 cifs_dbg(FYI, "In SetEA\n");
5777 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5782 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5784 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5785 PATH_MAX, nls_codepage, remap);
5786 name_len++; /* trailing null */
5789 name_len = copy_path_name(pSMB->FileName, fileName);
5792 params = 6 + name_len;
5794 /* done calculating parms using name_len of file name,
5795 now use name_len to calculate length of ea name
5796 we are going to create in the inode xattrs */
5797 if (ea_name == NULL)
5800 name_len = strnlen(ea_name, 255);
5802 count = sizeof(*parm_data) + 1 + ea_value_len + name_len;
5803 pSMB->MaxParameterCount = cpu_to_le16(2);
5804 /* BB find max SMB PDU from sess */
5805 pSMB->MaxDataCount = cpu_to_le16(1000);
5806 pSMB->MaxSetupCount = 0;
5810 pSMB->Reserved2 = 0;
5811 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5812 InformationLevel) - 4;
5813 offset = param_offset + params;
5814 pSMB->InformationLevel =
5815 cpu_to_le16(SMB_SET_FILE_EA);
5817 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
5818 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5819 pSMB->DataOffset = cpu_to_le16(offset);
5820 pSMB->SetupCount = 1;
5821 pSMB->Reserved3 = 0;
5822 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5823 byte_count = 3 /* pad */ + params + count;
5824 pSMB->DataCount = cpu_to_le16(count);
5825 parm_data->list_len = cpu_to_le32(count);
5826 parm_data->list.EA_flags = 0;
5827 /* we checked above that name len is less than 255 */
5828 parm_data->list.name_len = (__u8)name_len;
5829 /* EA names are always ASCII */
5831 strncpy(parm_data->list.name, ea_name, name_len);
5832 parm_data->list.name[name_len] = '\0';
5833 parm_data->list.value_len = cpu_to_le16(ea_value_len);
5834 /* caller ensures that ea_value_len is less than 64K but
5835 we need to ensure that it fits within the smb */
5837 /*BB add length check to see if it would fit in
5838 negotiated SMB buffer size BB */
5839 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
5841 memcpy(parm_data->list.name + name_len + 1,
5842 ea_value, ea_value_len);
5844 pSMB->TotalDataCount = pSMB->DataCount;
5845 pSMB->ParameterCount = cpu_to_le16(params);
5846 pSMB->TotalParameterCount = pSMB->ParameterCount;
5847 pSMB->Reserved4 = 0;
5848 inc_rfc1001_len(pSMB, byte_count);
5849 pSMB->ByteCount = cpu_to_le16(byte_count);
5850 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5851 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5853 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
5855 cifs_buf_release(pSMB);