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"
32 #include "smb2proto.h"
34 #include "smbdirect.h"
35 #ifdef CONFIG_CIFS_DFS_UPCALL
36 #include "dfs_cache.h"
39 #ifdef CONFIG_CIFS_POSIX
44 {CIFS_PROT, "\2NT LM 0.12"},
45 {POSIX_PROT, "\2POSIX 2"},
53 {CIFS_PROT, "\2NT LM 0.12"},
58 /* define the number of elements in the cifs dialect array */
59 #ifdef CONFIG_CIFS_POSIX
60 #define CIFS_NUM_PROT 2
62 #define CIFS_NUM_PROT 1
63 #endif /* CIFS_POSIX */
66 * Mark as invalid, all open files on tree connections since they
67 * were closed when session to server was lost.
70 cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
72 struct cifsFileInfo *open_file = NULL;
73 struct list_head *tmp;
74 struct list_head *tmp1;
76 /* only send once per connect */
77 spin_lock(&cifs_tcp_ses_lock);
78 if (tcon->ses->status != CifsGood ||
79 tcon->tidStatus != CifsNeedReconnect) {
80 spin_unlock(&cifs_tcp_ses_lock);
83 tcon->tidStatus = CifsInFilesInvalidate;
84 spin_unlock(&cifs_tcp_ses_lock);
86 /* list all files open on tree connection and mark them invalid */
87 spin_lock(&tcon->open_file_lock);
88 list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
89 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
90 open_file->invalidHandle = true;
91 open_file->oplock_break_cancelled = true;
93 spin_unlock(&tcon->open_file_lock);
95 mutex_lock(&tcon->crfid.fid_mutex);
96 tcon->crfid.is_valid = false;
97 /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
98 close_cached_dir_lease_locked(&tcon->crfid);
99 memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
100 mutex_unlock(&tcon->crfid.fid_mutex);
102 spin_lock(&cifs_tcp_ses_lock);
103 if (tcon->tidStatus == CifsInFilesInvalidate)
104 tcon->tidStatus = CifsNeedTcon;
105 spin_unlock(&cifs_tcp_ses_lock);
108 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
113 /* reconnect the socket, tcon, and smb session if needed */
115 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
118 struct cifs_ses *ses;
119 struct TCP_Server_Info *server;
120 struct nls_table *nls_codepage;
124 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
125 * tcp and smb session status done differently for those three - in the
132 server = ses->server;
135 * only tree disconnect, open, and write, (and ulogoff which does not
136 * have tcon) are allowed as we start force umount
138 spin_lock(&cifs_tcp_ses_lock);
139 if (tcon->tidStatus == CifsExiting) {
140 if (smb_command != SMB_COM_WRITE_ANDX &&
141 smb_command != SMB_COM_OPEN_ANDX &&
142 smb_command != SMB_COM_TREE_DISCONNECT) {
143 spin_unlock(&cifs_tcp_ses_lock);
144 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
149 spin_unlock(&cifs_tcp_ses_lock);
151 retries = server->nr_targets;
154 * Give demultiplex thread up to 10 seconds to each target available for
155 * reconnect -- should be greater than cifs socket timeout which is 7
158 while (server->tcpStatus == CifsNeedReconnect) {
159 rc = wait_event_interruptible_timeout(server->response_q,
160 (server->tcpStatus != CifsNeedReconnect),
163 cifs_dbg(FYI, "%s: aborting reconnect due to a received signal by the process\n",
168 /* are we still trying to reconnect? */
169 spin_lock(&cifs_tcp_ses_lock);
170 if (server->tcpStatus != CifsNeedReconnect) {
171 spin_unlock(&cifs_tcp_ses_lock);
174 spin_unlock(&cifs_tcp_ses_lock);
176 if (retries && --retries)
180 * on "soft" mounts we wait once. Hard mounts keep
181 * retrying until process is killed or server comes
185 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
188 retries = server->nr_targets;
191 spin_lock(&ses->chan_lock);
192 if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
193 spin_unlock(&ses->chan_lock);
196 spin_unlock(&ses->chan_lock);
198 nls_codepage = load_nls_default();
201 * Recheck after acquire mutex. If another thread is negotiating
202 * and the server never sends an answer the socket will be closed
203 * and tcpStatus set to reconnect.
205 spin_lock(&cifs_tcp_ses_lock);
206 if (server->tcpStatus == CifsNeedReconnect) {
207 spin_unlock(&cifs_tcp_ses_lock);
211 spin_unlock(&cifs_tcp_ses_lock);
214 * need to prevent multiple threads trying to simultaneously
215 * reconnect the same SMB session
217 spin_lock(&ses->chan_lock);
218 if (!cifs_chan_needs_reconnect(ses, server)) {
219 spin_unlock(&ses->chan_lock);
221 /* this means that we only need to tree connect */
222 if (tcon->need_reconnect)
223 goto skip_sess_setup;
228 spin_unlock(&ses->chan_lock);
230 mutex_lock(&ses->session_mutex);
231 rc = cifs_negotiate_protocol(0, ses, server);
233 rc = cifs_setup_session(0, ses, server, nls_codepage);
235 /* do we need to reconnect tcon? */
236 if (rc || !tcon->need_reconnect) {
237 mutex_unlock(&ses->session_mutex);
242 cifs_mark_open_files_invalid(tcon);
243 rc = cifs_tree_connect(0, tcon, nls_codepage);
244 mutex_unlock(&ses->session_mutex);
245 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
248 pr_warn_once("reconnect tcon failed rc = %d\n", rc);
252 atomic_inc(&tconInfoReconnectCount);
254 /* tell server Unix caps we support */
256 reset_cifs_unix_caps(0, tcon, NULL, NULL);
259 * Removed call to reopen open files here. It is safer (and faster) to
260 * reopen files one at a time as needed in read and write.
262 * FIXME: what about file locks? don't we need to reclaim them ASAP?
267 * Check if handle based operation so we know whether we can continue
268 * or not without returning to caller to reset file handle
270 switch (smb_command) {
271 case SMB_COM_READ_ANDX:
272 case SMB_COM_WRITE_ANDX:
274 case SMB_COM_FIND_CLOSE2:
275 case SMB_COM_LOCKING_ANDX:
279 unload_nls(nls_codepage);
283 /* Allocate and return pointer to an SMB request buffer, and set basic
284 SMB information in the SMB header. If the return code is zero, this
285 function must have filled in request_buf pointer */
287 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
292 rc = cifs_reconnect_tcon(tcon, smb_command);
296 *request_buf = cifs_small_buf_get();
297 if (*request_buf == NULL) {
298 /* BB should we add a retry in here if not a writepage? */
302 header_assemble((struct smb_hdr *) *request_buf, smb_command,
306 cifs_stats_inc(&tcon->num_smbs_sent);
312 small_smb_init_no_tc(const int smb_command, const int wct,
313 struct cifs_ses *ses, void **request_buf)
316 struct smb_hdr *buffer;
318 rc = small_smb_init(smb_command, wct, NULL, request_buf);
322 buffer = (struct smb_hdr *)*request_buf;
323 buffer->Mid = get_next_mid(ses->server);
324 if (ses->capabilities & CAP_UNICODE)
325 buffer->Flags2 |= SMBFLG2_UNICODE;
326 if (ses->capabilities & CAP_STATUS32)
327 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
329 /* uid, tid can stay at zero as set in header assemble */
331 /* BB add support for turning on the signing when
332 this function is used after 1st of session setup requests */
337 /* If the return code is zero, this function must fill in request_buf pointer */
339 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
340 void **request_buf, void **response_buf)
342 *request_buf = cifs_buf_get();
343 if (*request_buf == NULL) {
344 /* BB should we add a retry in here if not a writepage? */
347 /* Although the original thought was we needed the response buf for */
348 /* potential retries of smb operations it turns out we can determine */
349 /* from the mid flags when the request buffer can be resent without */
350 /* having to use a second distinct buffer for the response */
352 *response_buf = *request_buf;
354 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
358 cifs_stats_inc(&tcon->num_smbs_sent);
363 /* If the return code is zero, this function must fill in request_buf pointer */
365 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
366 void **request_buf, void **response_buf)
370 rc = cifs_reconnect_tcon(tcon, smb_command);
374 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
378 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
379 void **request_buf, void **response_buf)
381 spin_lock(&tcon->ses->chan_lock);
382 if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) ||
383 tcon->need_reconnect) {
384 spin_unlock(&tcon->ses->chan_lock);
387 spin_unlock(&tcon->ses->chan_lock);
389 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
392 static int validate_t2(struct smb_t2_rsp *pSMB)
394 unsigned int total_size;
396 /* check for plausible wct */
397 if (pSMB->hdr.WordCount < 10)
400 /* check for parm and data offset going beyond end of smb */
401 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
402 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
405 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
406 if (total_size >= 512)
409 /* check that bcc is at least as big as parms + data, and that it is
410 * less than negotiated smb buffer
412 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
413 if (total_size > get_bcc(&pSMB->hdr) ||
414 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
419 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
420 sizeof(struct smb_t2_rsp) + 16);
425 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
429 char *guid = pSMBr->u.extended_response.GUID;
430 struct TCP_Server_Info *server = ses->server;
432 count = get_bcc(&pSMBr->hdr);
433 if (count < SMB1_CLIENT_GUID_SIZE)
436 spin_lock(&cifs_tcp_ses_lock);
437 if (server->srv_count > 1) {
438 spin_unlock(&cifs_tcp_ses_lock);
439 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
440 cifs_dbg(FYI, "server UID changed\n");
441 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
444 spin_unlock(&cifs_tcp_ses_lock);
445 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
448 if (count == SMB1_CLIENT_GUID_SIZE) {
449 server->sec_ntlmssp = true;
451 count -= SMB1_CLIENT_GUID_SIZE;
452 rc = decode_negTokenInit(
453 pSMBr->u.extended_response.SecurityBlob, count, server);
462 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
464 bool srv_sign_required = server->sec_mode & server->vals->signing_required;
465 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
466 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
469 * Is signing required by mnt options? If not then check
470 * global_secflags to see if it is there.
472 if (!mnt_sign_required)
473 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
477 * If signing is required then it's automatically enabled too,
478 * otherwise, check to see if the secflags allow it.
480 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
481 (global_secflags & CIFSSEC_MAY_SIGN);
483 /* If server requires signing, does client allow it? */
484 if (srv_sign_required) {
485 if (!mnt_sign_enabled) {
486 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!\n");
492 /* If client requires signing, does server allow it? */
493 if (mnt_sign_required) {
494 if (!srv_sign_enabled) {
495 cifs_dbg(VFS, "Server does not support signing!\n");
501 if (cifs_rdma_enabled(server) && server->sign)
502 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled\n");
508 should_set_ext_sec_flag(enum securityEnum sectype)
515 if (global_secflags &
516 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
525 CIFSSMBNegotiate(const unsigned int xid,
526 struct cifs_ses *ses,
527 struct TCP_Server_Info *server)
530 NEGOTIATE_RSP *pSMBr;
537 WARN(1, "%s: server is NULL!\n", __func__);
541 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
542 (void **) &pSMB, (void **) &pSMBr);
546 pSMB->hdr.Mid = get_next_mid(server);
547 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
549 if (should_set_ext_sec_flag(ses->sectype)) {
550 cifs_dbg(FYI, "Requesting extended security\n");
551 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
556 * We know that all the name entries in the protocols array
557 * are short (< 16 bytes anyway) and are NUL terminated.
559 for (i = 0; i < CIFS_NUM_PROT; i++) {
560 size_t len = strlen(protocols[i].name) + 1;
562 memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
565 inc_rfc1001_len(pSMB, count);
566 pSMB->ByteCount = cpu_to_le16(count);
568 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
569 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
573 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
574 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
575 /* Check wct = 1 error case */
576 if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
577 /* core returns wct = 1, but we do not ask for core - otherwise
578 small wct just comes when dialect index is -1 indicating we
579 could not negotiate a common dialect */
582 } else if (pSMBr->hdr.WordCount != 17) {
587 /* else wct == 17, NTLM or better */
589 server->sec_mode = pSMBr->SecurityMode;
590 if ((server->sec_mode & SECMODE_USER) == 0)
591 cifs_dbg(FYI, "share mode security\n");
593 /* one byte, so no need to convert this or EncryptionKeyLen from
595 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
597 set_credits(server, server->maxReq);
598 /* probably no need to store and check maxvcs */
599 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
600 /* set up max_read for readahead check */
601 server->max_read = server->maxBuf;
602 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
603 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
604 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
605 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
606 server->timeAdj *= 60;
608 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
609 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
610 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
611 CIFS_CRYPTO_KEY_SIZE);
612 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
613 server->capabilities & CAP_EXTENDED_SECURITY) {
614 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
615 rc = decode_ext_sec_blob(ses, pSMBr);
616 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
617 rc = -EIO; /* no crypt key only if plain text pwd */
619 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
620 server->capabilities &= ~CAP_EXTENDED_SECURITY;
624 rc = cifs_enable_signing(server, ses->sign);
626 cifs_buf_release(pSMB);
628 cifs_dbg(FYI, "negprot rc %d\n", rc);
633 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
635 struct smb_hdr *smb_buffer;
638 cifs_dbg(FYI, "In tree disconnect\n");
640 /* BB: do we need to check this? These should never be NULL. */
641 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
645 * No need to return error on this operation if tid invalidated and
646 * closed on server already e.g. due to tcp session crashing. Also,
647 * the tcon is no longer on the list, so no need to take lock before
650 spin_lock(&tcon->ses->chan_lock);
651 if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
652 spin_unlock(&tcon->ses->chan_lock);
655 spin_unlock(&tcon->ses->chan_lock);
657 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
658 (void **)&smb_buffer);
662 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
663 cifs_small_buf_release(smb_buffer);
665 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
667 /* No need to return error on this operation if tid invalidated and
668 closed on server already e.g. due to tcp session crashing */
676 * This is a no-op for now. We're not really interested in the reply, but
677 * rather in the fact that the server sent one and that server->lstrp
680 * FIXME: maybe we should consider checking that the reply matches request?
683 cifs_echo_callback(struct mid_q_entry *mid)
685 struct TCP_Server_Info *server = mid->callback_data;
686 struct cifs_credits credits = { .value = 1, .instance = 0 };
688 DeleteMidQEntry(mid);
689 add_credits(server, &credits, CIFS_ECHO_OP);
693 CIFSSMBEcho(struct TCP_Server_Info *server)
698 struct smb_rqst rqst = { .rq_iov = iov,
701 cifs_dbg(FYI, "In echo request\n");
703 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
707 if (server->capabilities & CAP_UNICODE)
708 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
710 /* set up echo request */
711 smb->hdr.Tid = 0xffff;
712 smb->hdr.WordCount = 1;
713 put_unaligned_le16(1, &smb->EchoCount);
714 put_bcc(1, &smb->hdr);
716 inc_rfc1001_len(smb, 3);
719 iov[0].iov_base = smb;
720 iov[1].iov_len = get_rfc1002_length(smb);
721 iov[1].iov_base = (char *)smb + 4;
723 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
724 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
726 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
728 cifs_small_buf_release(smb);
734 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
736 LOGOFF_ANDX_REQ *pSMB;
739 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
742 * BB: do we need to check validity of ses and server? They should
743 * always be valid since we have an active reference. If not, that
744 * should probably be a BUG()
746 if (!ses || !ses->server)
749 mutex_lock(&ses->session_mutex);
750 spin_lock(&ses->chan_lock);
751 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
752 spin_unlock(&ses->chan_lock);
753 goto session_already_dead; /* no need to send SMBlogoff if uid
754 already closed due to reconnect */
756 spin_unlock(&ses->chan_lock);
758 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
760 mutex_unlock(&ses->session_mutex);
764 pSMB->hdr.Mid = get_next_mid(ses->server);
766 if (ses->server->sign)
767 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
769 pSMB->hdr.Uid = ses->Suid;
771 pSMB->AndXCommand = 0xFF;
772 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
773 cifs_small_buf_release(pSMB);
774 session_already_dead:
775 mutex_unlock(&ses->session_mutex);
777 /* if session dead then we do not need to do ulogoff,
778 since server closed smb session, no sense reporting
786 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
787 const char *fileName, __u16 type,
788 const struct nls_table *nls_codepage, int remap)
790 TRANSACTION2_SPI_REQ *pSMB = NULL;
791 TRANSACTION2_SPI_RSP *pSMBr = NULL;
792 struct unlink_psx_rq *pRqD;
795 int bytes_returned = 0;
796 __u16 params, param_offset, offset, byte_count;
798 cifs_dbg(FYI, "In POSIX delete\n");
800 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
805 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
807 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
808 PATH_MAX, nls_codepage, remap);
809 name_len++; /* trailing null */
812 name_len = copy_path_name(pSMB->FileName, fileName);
815 params = 6 + name_len;
816 pSMB->MaxParameterCount = cpu_to_le16(2);
817 pSMB->MaxDataCount = 0; /* BB double check this with jra */
818 pSMB->MaxSetupCount = 0;
823 param_offset = offsetof(struct smb_com_transaction2_spi_req,
824 InformationLevel) - 4;
825 offset = param_offset + params;
827 /* Setup pointer to Request Data (inode type).
828 * Note that SMB offsets are from the beginning of SMB which is 4 bytes
829 * in, after RFC1001 field
831 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
832 pRqD->type = cpu_to_le16(type);
833 pSMB->ParameterOffset = cpu_to_le16(param_offset);
834 pSMB->DataOffset = cpu_to_le16(offset);
835 pSMB->SetupCount = 1;
837 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
838 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
840 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
841 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
842 pSMB->ParameterCount = cpu_to_le16(params);
843 pSMB->TotalParameterCount = pSMB->ParameterCount;
844 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
846 inc_rfc1001_len(pSMB, byte_count);
847 pSMB->ByteCount = cpu_to_le16(byte_count);
848 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
849 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
851 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
852 cifs_buf_release(pSMB);
854 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
863 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
864 struct cifs_sb_info *cifs_sb)
866 DELETE_FILE_REQ *pSMB = NULL;
867 DELETE_FILE_RSP *pSMBr = NULL;
871 int remap = cifs_remap(cifs_sb);
874 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
879 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
880 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
881 PATH_MAX, cifs_sb->local_nls,
883 name_len++; /* trailing null */
886 name_len = copy_path_name(pSMB->fileName, name);
888 pSMB->SearchAttributes =
889 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
890 pSMB->BufferFormat = 0x04;
891 inc_rfc1001_len(pSMB, name_len + 1);
892 pSMB->ByteCount = cpu_to_le16(name_len + 1);
893 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
894 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
895 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
897 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
899 cifs_buf_release(pSMB);
907 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
908 struct cifs_sb_info *cifs_sb)
910 DELETE_DIRECTORY_REQ *pSMB = NULL;
911 DELETE_DIRECTORY_RSP *pSMBr = NULL;
915 int remap = cifs_remap(cifs_sb);
917 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
919 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
924 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
925 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
926 PATH_MAX, cifs_sb->local_nls,
928 name_len++; /* trailing null */
931 name_len = copy_path_name(pSMB->DirName, name);
934 pSMB->BufferFormat = 0x04;
935 inc_rfc1001_len(pSMB, name_len + 1);
936 pSMB->ByteCount = cpu_to_le16(name_len + 1);
937 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
938 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
939 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
941 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
943 cifs_buf_release(pSMB);
950 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
951 struct cifs_tcon *tcon, const char *name,
952 struct cifs_sb_info *cifs_sb)
955 CREATE_DIRECTORY_REQ *pSMB = NULL;
956 CREATE_DIRECTORY_RSP *pSMBr = NULL;
959 int remap = cifs_remap(cifs_sb);
961 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
963 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
968 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
969 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
970 PATH_MAX, cifs_sb->local_nls,
972 name_len++; /* trailing null */
975 name_len = copy_path_name(pSMB->DirName, name);
978 pSMB->BufferFormat = 0x04;
979 inc_rfc1001_len(pSMB, name_len + 1);
980 pSMB->ByteCount = cpu_to_le16(name_len + 1);
981 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
982 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
983 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
985 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
987 cifs_buf_release(pSMB);
994 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
995 __u32 posix_flags, __u64 mode, __u16 *netfid,
996 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
997 const char *name, const struct nls_table *nls_codepage,
1000 TRANSACTION2_SPI_REQ *pSMB = NULL;
1001 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1004 int bytes_returned = 0;
1005 __u16 params, param_offset, offset, byte_count, count;
1006 OPEN_PSX_REQ *pdata;
1007 OPEN_PSX_RSP *psx_rsp;
1009 cifs_dbg(FYI, "In POSIX Create\n");
1011 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1016 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1018 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1019 PATH_MAX, nls_codepage, remap);
1020 name_len++; /* trailing null */
1023 name_len = copy_path_name(pSMB->FileName, name);
1026 params = 6 + name_len;
1027 count = sizeof(OPEN_PSX_REQ);
1028 pSMB->MaxParameterCount = cpu_to_le16(2);
1029 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1030 pSMB->MaxSetupCount = 0;
1034 pSMB->Reserved2 = 0;
1035 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1036 InformationLevel) - 4;
1037 offset = param_offset + params;
1038 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
1039 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
1040 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1041 pdata->Permissions = cpu_to_le64(mode);
1042 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1043 pdata->OpenFlags = cpu_to_le32(*pOplock);
1044 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1045 pSMB->DataOffset = cpu_to_le16(offset);
1046 pSMB->SetupCount = 1;
1047 pSMB->Reserved3 = 0;
1048 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1049 byte_count = 3 /* pad */ + params + count;
1051 pSMB->DataCount = cpu_to_le16(count);
1052 pSMB->ParameterCount = cpu_to_le16(params);
1053 pSMB->TotalDataCount = pSMB->DataCount;
1054 pSMB->TotalParameterCount = pSMB->ParameterCount;
1055 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1056 pSMB->Reserved4 = 0;
1057 inc_rfc1001_len(pSMB, byte_count);
1058 pSMB->ByteCount = cpu_to_le16(byte_count);
1059 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1060 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1062 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1063 goto psx_create_err;
1066 cifs_dbg(FYI, "copying inode info\n");
1067 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1069 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1070 rc = -EIO; /* bad smb */
1071 goto psx_create_err;
1074 /* copy return information to pRetData */
1075 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1076 + le16_to_cpu(pSMBr->t2.DataOffset));
1078 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1080 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1081 /* Let caller know file was created so we can set the mode. */
1082 /* Do we care about the CreateAction in any other cases? */
1083 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1084 *pOplock |= CIFS_CREATE_ACTION;
1085 /* check to make sure response data is there */
1086 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1087 pRetData->Type = cpu_to_le32(-1); /* unknown */
1088 cifs_dbg(NOISY, "unknown type\n");
1090 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1091 + sizeof(FILE_UNIX_BASIC_INFO)) {
1092 cifs_dbg(VFS, "Open response data too small\n");
1093 pRetData->Type = cpu_to_le32(-1);
1094 goto psx_create_err;
1096 memcpy((char *) pRetData,
1097 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1098 sizeof(FILE_UNIX_BASIC_INFO));
1102 cifs_buf_release(pSMB);
1104 if (posix_flags & SMB_O_DIRECTORY)
1105 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1107 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1115 static __u16 convert_disposition(int disposition)
1119 switch (disposition) {
1120 case FILE_SUPERSEDE:
1121 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1124 ofun = SMBOPEN_OAPPEND;
1127 ofun = SMBOPEN_OCREATE;
1130 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1132 case FILE_OVERWRITE:
1133 ofun = SMBOPEN_OTRUNC;
1135 case FILE_OVERWRITE_IF:
1136 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1139 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1140 ofun = SMBOPEN_OAPPEND; /* regular open */
1146 access_flags_to_smbopen_mode(const int access_flags)
1148 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1150 if (masked_flags == GENERIC_READ)
1151 return SMBOPEN_READ;
1152 else if (masked_flags == GENERIC_WRITE)
1153 return SMBOPEN_WRITE;
1155 /* just go for read/write */
1156 return SMBOPEN_READWRITE;
1160 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1161 const char *fileName, const int openDisposition,
1162 const int access_flags, const int create_options, __u16 *netfid,
1163 int *pOplock, FILE_ALL_INFO *pfile_info,
1164 const struct nls_table *nls_codepage, int remap)
1167 OPENX_REQ *pSMB = NULL;
1168 OPENX_RSP *pSMBr = NULL;
1174 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1179 pSMB->AndXCommand = 0xFF; /* none */
1181 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1182 count = 1; /* account for one byte pad to word boundary */
1184 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1185 fileName, PATH_MAX, nls_codepage, remap);
1186 name_len++; /* trailing null */
1189 count = 0; /* no pad */
1190 name_len = copy_path_name(pSMB->fileName, fileName);
1192 if (*pOplock & REQ_OPLOCK)
1193 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1194 else if (*pOplock & REQ_BATCHOPLOCK)
1195 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1197 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1198 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1199 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1200 /* set file as system file if special file such
1201 as fifo and server expecting SFU style and
1202 no Unix extensions */
1204 if (create_options & CREATE_OPTION_SPECIAL)
1205 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1206 else /* BB FIXME BB */
1207 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1209 if (create_options & CREATE_OPTION_READONLY)
1210 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1213 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1214 CREATE_OPTIONS_MASK); */
1215 /* BB FIXME END BB */
1217 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1218 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1220 inc_rfc1001_len(pSMB, count);
1222 pSMB->ByteCount = cpu_to_le16(count);
1223 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1224 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1225 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1227 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1229 /* BB verify if wct == 15 */
1231 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1233 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1234 /* Let caller know file was created so we can set the mode. */
1235 /* Do we care about the CreateAction in any other cases? */
1237 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1238 *pOplock |= CIFS_CREATE_ACTION; */
1242 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1243 pfile_info->LastAccessTime = 0; /* BB fixme */
1244 pfile_info->LastWriteTime = 0; /* BB fixme */
1245 pfile_info->ChangeTime = 0; /* BB fixme */
1246 pfile_info->Attributes =
1247 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1248 /* the file_info buf is endian converted by caller */
1249 pfile_info->AllocationSize =
1250 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1251 pfile_info->EndOfFile = pfile_info->AllocationSize;
1252 pfile_info->NumberOfLinks = cpu_to_le32(1);
1253 pfile_info->DeletePending = 0;
1257 cifs_buf_release(pSMB);
1264 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1268 OPEN_REQ *req = NULL;
1269 OPEN_RSP *rsp = NULL;
1273 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1274 struct cifs_tcon *tcon = oparms->tcon;
1275 int remap = cifs_remap(cifs_sb);
1276 const struct nls_table *nls = cifs_sb->local_nls;
1277 int create_options = oparms->create_options;
1278 int desired_access = oparms->desired_access;
1279 int disposition = oparms->disposition;
1280 const char *path = oparms->path;
1283 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1288 /* no commands go after this */
1289 req->AndXCommand = 0xFF;
1291 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1292 /* account for one byte pad to word boundary */
1294 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1295 path, PATH_MAX, nls, remap);
1299 req->NameLength = cpu_to_le16(name_len);
1301 /* BB improve check for buffer overruns BB */
1304 name_len = copy_path_name(req->fileName, path);
1305 req->NameLength = cpu_to_le16(name_len);
1308 if (*oplock & REQ_OPLOCK)
1309 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1310 else if (*oplock & REQ_BATCHOPLOCK)
1311 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1313 req->DesiredAccess = cpu_to_le32(desired_access);
1314 req->AllocationSize = 0;
1317 * Set file as system file if special file such as fifo and server
1318 * expecting SFU style and no Unix extensions.
1320 if (create_options & CREATE_OPTION_SPECIAL)
1321 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1323 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1326 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1327 * sensitive checks for other servers such as Samba.
1329 if (tcon->ses->capabilities & CAP_UNIX)
1330 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1332 if (create_options & CREATE_OPTION_READONLY)
1333 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1335 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1336 req->CreateDisposition = cpu_to_le32(disposition);
1337 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1339 /* BB Expirement with various impersonation levels and verify */
1340 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1341 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1344 inc_rfc1001_len(req, count);
1346 req->ByteCount = cpu_to_le16(count);
1347 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1348 (struct smb_hdr *)rsp, &bytes_returned, 0);
1349 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1351 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1352 cifs_buf_release(req);
1358 /* 1 byte no need to le_to_cpu */
1359 *oplock = rsp->OplockLevel;
1360 /* cifs fid stays in le */
1361 oparms->fid->netfid = rsp->Fid;
1362 oparms->fid->access = desired_access;
1364 /* Let caller know file was created so we can set the mode. */
1365 /* Do we care about the CreateAction in any other cases? */
1366 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1367 *oplock |= CIFS_CREATE_ACTION;
1370 /* copy from CreationTime to Attributes */
1371 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1372 /* the file_info buf is endian converted by caller */
1373 buf->AllocationSize = rsp->AllocationSize;
1374 buf->EndOfFile = rsp->EndOfFile;
1375 buf->NumberOfLinks = cpu_to_le32(1);
1376 buf->DeletePending = 0;
1379 cifs_buf_release(req);
1384 * Discard any remaining data in the current SMB. To do this, we borrow the
1388 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1390 unsigned int rfclen = server->pdu_size;
1391 int remaining = rfclen + server->vals->header_preamble_size -
1394 while (remaining > 0) {
1397 length = cifs_discard_from_socket(server,
1398 min_t(size_t, remaining,
1399 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1402 server->total_read += length;
1403 remaining -= length;
1410 __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
1415 length = cifs_discard_remaining_data(server);
1416 dequeue_mid(mid, malformed);
1417 mid->resp_buf = server->smallbuf;
1418 server->smallbuf = NULL;
1423 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1425 struct cifs_readdata *rdata = mid->callback_data;
1427 return __cifs_readv_discard(server, mid, rdata->result);
1431 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1434 unsigned int data_offset, data_len;
1435 struct cifs_readdata *rdata = mid->callback_data;
1436 char *buf = server->smallbuf;
1437 unsigned int buflen = server->pdu_size +
1438 server->vals->header_preamble_size;
1439 bool use_rdma_mr = false;
1441 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1442 __func__, mid->mid, rdata->offset, rdata->bytes);
1445 * read the rest of READ_RSP header (sans Data array), or whatever we
1446 * can if there's not enough data. At this point, we've read down to
1449 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1450 HEADER_SIZE(server) + 1;
1452 length = cifs_read_from_socket(server,
1453 buf + HEADER_SIZE(server) - 1, len);
1456 server->total_read += length;
1458 if (server->ops->is_session_expired &&
1459 server->ops->is_session_expired(buf)) {
1460 cifs_reconnect(server, true);
1464 if (server->ops->is_status_pending &&
1465 server->ops->is_status_pending(buf, server)) {
1466 cifs_discard_remaining_data(server);
1470 /* set up first two iov for signature check and to get credits */
1471 rdata->iov[0].iov_base = buf;
1472 rdata->iov[0].iov_len = server->vals->header_preamble_size;
1473 rdata->iov[1].iov_base = buf + server->vals->header_preamble_size;
1474 rdata->iov[1].iov_len =
1475 server->total_read - server->vals->header_preamble_size;
1476 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1477 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1478 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
1479 rdata->iov[1].iov_base, rdata->iov[1].iov_len);
1481 /* Was the SMB read successful? */
1482 rdata->result = server->ops->map_error(buf, false);
1483 if (rdata->result != 0) {
1484 cifs_dbg(FYI, "%s: server returned error %d\n",
1485 __func__, rdata->result);
1486 /* normal error on read response */
1487 return __cifs_readv_discard(server, mid, false);
1490 /* Is there enough to get to the rest of the READ_RSP header? */
1491 if (server->total_read < server->vals->read_rsp_size) {
1492 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1493 __func__, server->total_read,
1494 server->vals->read_rsp_size);
1495 rdata->result = -EIO;
1496 return cifs_readv_discard(server, mid);
1499 data_offset = server->ops->read_data_offset(buf) +
1500 server->vals->header_preamble_size;
1501 if (data_offset < server->total_read) {
1503 * win2k8 sometimes sends an offset of 0 when the read
1504 * is beyond the EOF. Treat it as if the data starts just after
1507 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1508 __func__, data_offset);
1509 data_offset = server->total_read;
1510 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1511 /* data_offset is beyond the end of smallbuf */
1512 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1513 __func__, data_offset);
1514 rdata->result = -EIO;
1515 return cifs_readv_discard(server, mid);
1518 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1519 __func__, server->total_read, data_offset);
1521 len = data_offset - server->total_read;
1523 /* read any junk before data into the rest of smallbuf */
1524 length = cifs_read_from_socket(server,
1525 buf + server->total_read, len);
1528 server->total_read += length;
1531 /* how much data is in the response? */
1532 #ifdef CONFIG_CIFS_SMB_DIRECT
1533 use_rdma_mr = rdata->mr;
1535 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1536 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1537 /* data_len is corrupt -- discard frame */
1538 rdata->result = -EIO;
1539 return cifs_readv_discard(server, mid);
1542 length = rdata->read_into_pages(server, rdata, data_len);
1546 server->total_read += length;
1548 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1549 server->total_read, buflen, data_len);
1551 /* discard anything left over */
1552 if (server->total_read < buflen)
1553 return cifs_readv_discard(server, mid);
1555 dequeue_mid(mid, false);
1556 mid->resp_buf = server->smallbuf;
1557 server->smallbuf = NULL;
1562 cifs_readv_callback(struct mid_q_entry *mid)
1564 struct cifs_readdata *rdata = mid->callback_data;
1565 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1566 struct TCP_Server_Info *server = tcon->ses->server;
1567 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1569 .rq_pages = rdata->pages,
1570 .rq_offset = rdata->page_offset,
1571 .rq_npages = rdata->nr_pages,
1572 .rq_pagesz = rdata->pagesz,
1573 .rq_tailsz = rdata->tailsz };
1574 struct cifs_credits credits = { .value = 1, .instance = 0 };
1576 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1577 __func__, mid->mid, mid->mid_state, rdata->result,
1580 switch (mid->mid_state) {
1581 case MID_RESPONSE_RECEIVED:
1582 /* result already set, check signature */
1586 rc = cifs_verify_signature(&rqst, server,
1587 mid->sequence_number);
1589 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1592 /* FIXME: should this be counted toward the initiating task? */
1593 task_io_account_read(rdata->got_bytes);
1594 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1596 case MID_REQUEST_SUBMITTED:
1597 case MID_RETRY_NEEDED:
1598 rdata->result = -EAGAIN;
1599 if (server->sign && rdata->got_bytes)
1600 /* reset bytes number since we can not check a sign */
1601 rdata->got_bytes = 0;
1602 /* FIXME: should this be counted toward the initiating task? */
1603 task_io_account_read(rdata->got_bytes);
1604 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1607 rdata->result = -EIO;
1610 queue_work(cifsiod_wq, &rdata->work);
1611 DeleteMidQEntry(mid);
1612 add_credits(server, &credits, 0);
1615 /* cifs_async_readv - send an async write, and set up mid to handle result */
1617 cifs_async_readv(struct cifs_readdata *rdata)
1620 READ_REQ *smb = NULL;
1622 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1623 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1626 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1627 __func__, rdata->offset, rdata->bytes);
1629 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1632 wct = 10; /* old style read */
1633 if ((rdata->offset >> 32) > 0) {
1634 /* can not handle this big offset for old */
1639 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1643 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1644 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1646 smb->AndXCommand = 0xFF; /* none */
1647 smb->Fid = rdata->cfile->fid.netfid;
1648 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1650 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1652 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1653 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1657 /* old style read */
1658 struct smb_com_readx_req *smbr =
1659 (struct smb_com_readx_req *)smb;
1660 smbr->ByteCount = 0;
1663 /* 4 for RFC1001 length + 1 for BCC */
1664 rdata->iov[0].iov_base = smb;
1665 rdata->iov[0].iov_len = 4;
1666 rdata->iov[1].iov_base = (char *)smb + 4;
1667 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1669 kref_get(&rdata->refcount);
1670 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1671 cifs_readv_callback, NULL, rdata, 0, NULL);
1674 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1676 kref_put(&rdata->refcount, cifs_readdata_release);
1678 cifs_small_buf_release(smb);
1683 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1684 unsigned int *nbytes, char **buf, int *pbuf_type)
1687 READ_REQ *pSMB = NULL;
1688 READ_RSP *pSMBr = NULL;
1689 char *pReadData = NULL;
1691 int resp_buf_type = 0;
1693 struct kvec rsp_iov;
1694 __u32 pid = io_parms->pid;
1695 __u16 netfid = io_parms->netfid;
1696 __u64 offset = io_parms->offset;
1697 struct cifs_tcon *tcon = io_parms->tcon;
1698 unsigned int count = io_parms->length;
1700 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1701 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1704 wct = 10; /* old style read */
1705 if ((offset >> 32) > 0) {
1706 /* can not handle this big offset for old */
1712 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1716 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1717 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1719 /* tcon and ses pointer are checked in smb_init */
1720 if (tcon->ses->server == NULL)
1721 return -ECONNABORTED;
1723 pSMB->AndXCommand = 0xFF; /* none */
1725 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1727 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1729 pSMB->Remaining = 0;
1730 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1731 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1733 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1735 /* old style read */
1736 struct smb_com_readx_req *pSMBW =
1737 (struct smb_com_readx_req *)pSMB;
1738 pSMBW->ByteCount = 0;
1741 iov[0].iov_base = (char *)pSMB;
1742 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1743 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1744 CIFS_LOG_ERROR, &rsp_iov);
1745 cifs_small_buf_release(pSMB);
1746 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1747 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1749 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1751 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1752 data_length = data_length << 16;
1753 data_length += le16_to_cpu(pSMBr->DataLength);
1754 *nbytes = data_length;
1756 /*check that DataLength would not go beyond end of SMB */
1757 if ((data_length > CIFSMaxBufSize)
1758 || (data_length > count)) {
1759 cifs_dbg(FYI, "bad length %d for count %d\n",
1760 data_length, count);
1764 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1765 le16_to_cpu(pSMBr->DataOffset);
1766 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1767 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1769 }*/ /* can not use copy_to_user when using page cache*/
1771 memcpy(*buf, pReadData, data_length);
1776 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1777 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1778 /* return buffer to caller to free */
1779 *buf = rsp_iov.iov_base;
1780 if (resp_buf_type == CIFS_SMALL_BUFFER)
1781 *pbuf_type = CIFS_SMALL_BUFFER;
1782 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1783 *pbuf_type = CIFS_LARGE_BUFFER;
1784 } /* else no valid buffer on return - leave as null */
1786 /* Note: On -EAGAIN error only caller can retry on handle based calls
1787 since file handle passed in no longer valid */
1793 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1794 unsigned int *nbytes, const char *buf)
1797 WRITE_REQ *pSMB = NULL;
1798 WRITE_RSP *pSMBr = NULL;
1799 int bytes_returned, wct;
1802 __u32 pid = io_parms->pid;
1803 __u16 netfid = io_parms->netfid;
1804 __u64 offset = io_parms->offset;
1805 struct cifs_tcon *tcon = io_parms->tcon;
1806 unsigned int count = io_parms->length;
1810 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1811 if (tcon->ses == NULL)
1812 return -ECONNABORTED;
1814 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1818 if ((offset >> 32) > 0) {
1819 /* can not handle big offset for old srv */
1824 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1829 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1830 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1832 /* tcon and ses pointer are checked in smb_init */
1833 if (tcon->ses->server == NULL)
1834 return -ECONNABORTED;
1836 pSMB->AndXCommand = 0xFF; /* none */
1838 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1840 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1842 pSMB->Reserved = 0xFFFFFFFF;
1843 pSMB->WriteMode = 0;
1844 pSMB->Remaining = 0;
1846 /* Can increase buffer size if buffer is big enough in some cases ie we
1847 can send more if LARGE_WRITE_X capability returned by the server and if
1848 our buffer is big enough or if we convert to iovecs on socket writes
1849 and eliminate the copy to the CIFS buffer */
1850 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1851 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1853 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1857 if (bytes_sent > count)
1860 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1862 memcpy(pSMB->Data, buf, bytes_sent);
1863 else if (count != 0) {
1865 cifs_buf_release(pSMB);
1867 } /* else setting file size with write of zero bytes */
1869 byte_count = bytes_sent + 1; /* pad */
1870 else /* wct == 12 */
1871 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1873 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1874 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1875 inc_rfc1001_len(pSMB, byte_count);
1878 pSMB->ByteCount = cpu_to_le16(byte_count);
1879 else { /* old style write has byte count 4 bytes earlier
1881 struct smb_com_writex_req *pSMBW =
1882 (struct smb_com_writex_req *)pSMB;
1883 pSMBW->ByteCount = cpu_to_le16(byte_count);
1886 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1887 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1888 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1890 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1892 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1893 *nbytes = (*nbytes) << 16;
1894 *nbytes += le16_to_cpu(pSMBr->Count);
1897 * Mask off high 16 bits when bytes written as returned by the
1898 * server is greater than bytes requested by the client. Some
1899 * OS/2 servers are known to set incorrect CountHigh values.
1901 if (*nbytes > count)
1905 cifs_buf_release(pSMB);
1907 /* Note: On -EAGAIN error only caller can retry on handle based calls
1908 since file handle passed in no longer valid */
1914 cifs_writedata_release(struct kref *refcount)
1916 struct cifs_writedata *wdata = container_of(refcount,
1917 struct cifs_writedata, refcount);
1918 #ifdef CONFIG_CIFS_SMB_DIRECT
1920 smbd_deregister_mr(wdata->mr);
1926 cifsFileInfo_put(wdata->cfile);
1928 kvfree(wdata->pages);
1933 * Write failed with a retryable error. Resend the write request. It's also
1934 * possible that the page was redirtied so re-clean the page.
1937 cifs_writev_requeue(struct cifs_writedata *wdata)
1940 struct inode *inode = d_inode(wdata->cfile->dentry);
1941 struct TCP_Server_Info *server;
1942 unsigned int rest_len;
1944 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1946 rest_len = wdata->bytes;
1948 struct cifs_writedata *wdata2;
1949 unsigned int j, nr_pages, wsize, tailsz, cur_len;
1951 wsize = server->ops->wp_retry_size(inode);
1952 if (wsize < rest_len) {
1953 nr_pages = wsize / PAGE_SIZE;
1958 cur_len = nr_pages * PAGE_SIZE;
1961 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
1963 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
1966 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
1972 for (j = 0; j < nr_pages; j++) {
1973 wdata2->pages[j] = wdata->pages[i + j];
1974 lock_page(wdata2->pages[j]);
1975 clear_page_dirty_for_io(wdata2->pages[j]);
1978 wdata2->sync_mode = wdata->sync_mode;
1979 wdata2->nr_pages = nr_pages;
1980 wdata2->offset = page_offset(wdata2->pages[0]);
1981 wdata2->pagesz = PAGE_SIZE;
1982 wdata2->tailsz = tailsz;
1983 wdata2->bytes = cur_len;
1985 rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
1987 if (!wdata2->cfile) {
1988 cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
1990 if (!is_retryable_error(rc))
1993 wdata2->pid = wdata2->cfile->pid;
1994 rc = server->ops->async_writev(wdata2,
1995 cifs_writedata_release);
1998 for (j = 0; j < nr_pages; j++) {
1999 unlock_page(wdata2->pages[j]);
2000 if (rc != 0 && !is_retryable_error(rc)) {
2001 SetPageError(wdata2->pages[j]);
2002 end_page_writeback(wdata2->pages[j]);
2003 put_page(wdata2->pages[j]);
2007 kref_put(&wdata2->refcount, cifs_writedata_release);
2009 if (is_retryable_error(rc))
2015 rest_len -= cur_len;
2017 } while (i < wdata->nr_pages);
2019 /* cleanup remaining pages from the original wdata */
2020 for (; i < wdata->nr_pages; i++) {
2021 SetPageError(wdata->pages[i]);
2022 end_page_writeback(wdata->pages[i]);
2023 put_page(wdata->pages[i]);
2026 if (rc != 0 && !is_retryable_error(rc))
2027 mapping_set_error(inode->i_mapping, rc);
2028 kref_put(&wdata->refcount, cifs_writedata_release);
2032 cifs_writev_complete(struct work_struct *work)
2034 struct cifs_writedata *wdata = container_of(work,
2035 struct cifs_writedata, work);
2036 struct inode *inode = d_inode(wdata->cfile->dentry);
2039 if (wdata->result == 0) {
2040 spin_lock(&inode->i_lock);
2041 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2042 spin_unlock(&inode->i_lock);
2043 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2045 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2046 return cifs_writev_requeue(wdata);
2048 for (i = 0; i < wdata->nr_pages; i++) {
2049 struct page *page = wdata->pages[i];
2050 if (wdata->result == -EAGAIN)
2051 __set_page_dirty_nobuffers(page);
2052 else if (wdata->result < 0)
2054 end_page_writeback(page);
2055 cifs_readpage_to_fscache(inode, page);
2058 if (wdata->result != -EAGAIN)
2059 mapping_set_error(inode->i_mapping, wdata->result);
2060 kref_put(&wdata->refcount, cifs_writedata_release);
2063 struct cifs_writedata *
2064 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2066 struct page **pages =
2067 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2069 return cifs_writedata_direct_alloc(pages, complete);
2074 struct cifs_writedata *
2075 cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2077 struct cifs_writedata *wdata;
2079 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2080 if (wdata != NULL) {
2081 wdata->pages = pages;
2082 kref_init(&wdata->refcount);
2083 INIT_LIST_HEAD(&wdata->list);
2084 init_completion(&wdata->done);
2085 INIT_WORK(&wdata->work, complete);
2091 * Check the mid_state and signature on received buffer (if any), and queue the
2092 * workqueue completion task.
2095 cifs_writev_callback(struct mid_q_entry *mid)
2097 struct cifs_writedata *wdata = mid->callback_data;
2098 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2099 unsigned int written;
2100 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2101 struct cifs_credits credits = { .value = 1, .instance = 0 };
2103 switch (mid->mid_state) {
2104 case MID_RESPONSE_RECEIVED:
2105 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2106 if (wdata->result != 0)
2109 written = le16_to_cpu(smb->CountHigh);
2111 written += le16_to_cpu(smb->Count);
2113 * Mask off high 16 bits when bytes written as returned
2114 * by the server is greater than bytes requested by the
2115 * client. OS/2 servers are known to set incorrect
2118 if (written > wdata->bytes)
2121 if (written < wdata->bytes)
2122 wdata->result = -ENOSPC;
2124 wdata->bytes = written;
2126 case MID_REQUEST_SUBMITTED:
2127 case MID_RETRY_NEEDED:
2128 wdata->result = -EAGAIN;
2131 wdata->result = -EIO;
2135 queue_work(cifsiod_wq, &wdata->work);
2136 DeleteMidQEntry(mid);
2137 add_credits(tcon->ses->server, &credits, 0);
2140 /* cifs_async_writev - send an async write, and set up mid to handle result */
2142 cifs_async_writev(struct cifs_writedata *wdata,
2143 void (*release)(struct kref *kref))
2146 WRITE_REQ *smb = NULL;
2148 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2150 struct smb_rqst rqst = { };
2152 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2156 if (wdata->offset >> 32 > 0) {
2157 /* can not handle big offset for old srv */
2162 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2164 goto async_writev_out;
2166 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2167 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2169 smb->AndXCommand = 0xFF; /* none */
2170 smb->Fid = wdata->cfile->fid.netfid;
2171 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2173 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2174 smb->Reserved = 0xFFFFFFFF;
2179 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2181 /* 4 for RFC1001 length + 1 for BCC */
2183 iov[0].iov_base = smb;
2184 iov[1].iov_len = get_rfc1002_length(smb) + 1;
2185 iov[1].iov_base = (char *)smb + 4;
2189 rqst.rq_pages = wdata->pages;
2190 rqst.rq_offset = wdata->page_offset;
2191 rqst.rq_npages = wdata->nr_pages;
2192 rqst.rq_pagesz = wdata->pagesz;
2193 rqst.rq_tailsz = wdata->tailsz;
2195 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2196 wdata->offset, wdata->bytes);
2198 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2199 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2202 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2203 put_bcc(wdata->bytes + 1, &smb->hdr);
2206 struct smb_com_writex_req *smbw =
2207 (struct smb_com_writex_req *)smb;
2208 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2209 put_bcc(wdata->bytes + 5, &smbw->hdr);
2210 iov[1].iov_len += 4; /* pad bigger by four bytes */
2213 kref_get(&wdata->refcount);
2214 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2215 cifs_writev_callback, NULL, wdata, 0, NULL);
2218 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2220 kref_put(&wdata->refcount, release);
2223 cifs_small_buf_release(smb);
2228 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2229 unsigned int *nbytes, struct kvec *iov, int n_vec)
2232 WRITE_REQ *pSMB = NULL;
2235 int resp_buf_type = 0;
2236 __u32 pid = io_parms->pid;
2237 __u16 netfid = io_parms->netfid;
2238 __u64 offset = io_parms->offset;
2239 struct cifs_tcon *tcon = io_parms->tcon;
2240 unsigned int count = io_parms->length;
2241 struct kvec rsp_iov;
2245 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2247 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2251 if ((offset >> 32) > 0) {
2252 /* can not handle big offset for old srv */
2256 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2260 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2261 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2263 /* tcon and ses pointer are checked in smb_init */
2264 if (tcon->ses->server == NULL)
2265 return -ECONNABORTED;
2267 pSMB->AndXCommand = 0xFF; /* none */
2269 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2271 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2272 pSMB->Reserved = 0xFFFFFFFF;
2273 pSMB->WriteMode = 0;
2274 pSMB->Remaining = 0;
2277 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2279 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2280 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2281 /* header + 1 byte pad */
2282 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2284 inc_rfc1001_len(pSMB, count + 1);
2285 else /* wct == 12 */
2286 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2288 pSMB->ByteCount = cpu_to_le16(count + 1);
2289 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2290 struct smb_com_writex_req *pSMBW =
2291 (struct smb_com_writex_req *)pSMB;
2292 pSMBW->ByteCount = cpu_to_le16(count + 5);
2294 iov[0].iov_base = pSMB;
2296 iov[0].iov_len = smb_hdr_len + 4;
2297 else /* wct == 12 pad bigger by four bytes */
2298 iov[0].iov_len = smb_hdr_len + 8;
2300 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2302 cifs_small_buf_release(pSMB);
2303 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2305 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2306 } else if (resp_buf_type == 0) {
2307 /* presumably this can not happen, but best to be safe */
2310 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2311 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2312 *nbytes = (*nbytes) << 16;
2313 *nbytes += le16_to_cpu(pSMBr->Count);
2316 * Mask off high 16 bits when bytes written as returned by the
2317 * server is greater than bytes requested by the client. OS/2
2318 * servers are known to set incorrect CountHigh values.
2320 if (*nbytes > count)
2324 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2326 /* Note: On -EAGAIN error only caller can retry on handle based calls
2327 since file handle passed in no longer valid */
2332 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2333 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2334 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2337 LOCK_REQ *pSMB = NULL;
2339 struct kvec rsp_iov;
2343 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2344 num_lock, num_unlock);
2346 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2351 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2352 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2353 pSMB->LockType = lock_type;
2354 pSMB->AndXCommand = 0xFF; /* none */
2355 pSMB->Fid = netfid; /* netfid stays le */
2357 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2358 inc_rfc1001_len(pSMB, count);
2359 pSMB->ByteCount = cpu_to_le16(count);
2361 iov[0].iov_base = (char *)pSMB;
2362 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2363 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2364 iov[1].iov_base = (char *)buf;
2365 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2367 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2368 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
2369 CIFS_NO_RSP_BUF, &rsp_iov);
2370 cifs_small_buf_release(pSMB);
2372 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2378 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2379 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2380 const __u64 offset, const __u32 numUnlock,
2381 const __u32 numLock, const __u8 lockType,
2382 const bool waitFlag, const __u8 oplock_level)
2385 LOCK_REQ *pSMB = NULL;
2386 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2391 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2392 (int)waitFlag, numLock);
2393 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2398 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2399 /* no response expected */
2400 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
2402 } else if (waitFlag) {
2403 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2404 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2409 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2410 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2411 pSMB->LockType = lockType;
2412 pSMB->OplockLevel = oplock_level;
2413 pSMB->AndXCommand = 0xFF; /* none */
2414 pSMB->Fid = smb_file_id; /* netfid stays le */
2416 if ((numLock != 0) || (numUnlock != 0)) {
2417 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2418 /* BB where to store pid high? */
2419 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2420 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2421 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2422 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2423 count = sizeof(LOCKING_ANDX_RANGE);
2428 inc_rfc1001_len(pSMB, count);
2429 pSMB->ByteCount = cpu_to_le16(count);
2432 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2433 (struct smb_hdr *) pSMB, &bytes_returned);
2435 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2436 cifs_small_buf_release(pSMB);
2437 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2439 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2441 /* Note: On -EAGAIN error only caller can retry on handle based calls
2442 since file handle passed in no longer valid */
2447 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2448 const __u16 smb_file_id, const __u32 netpid,
2449 const loff_t start_offset, const __u64 len,
2450 struct file_lock *pLockData, const __u16 lock_type,
2451 const bool waitFlag)
2453 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2454 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2455 struct cifs_posix_lock *parm_data;
2458 int bytes_returned = 0;
2459 int resp_buf_type = 0;
2460 __u16 params, param_offset, offset, byte_count, count;
2462 struct kvec rsp_iov;
2464 cifs_dbg(FYI, "Posix Lock\n");
2466 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2471 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2474 pSMB->MaxSetupCount = 0;
2477 pSMB->Reserved2 = 0;
2478 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2479 offset = param_offset + params;
2481 count = sizeof(struct cifs_posix_lock);
2482 pSMB->MaxParameterCount = cpu_to_le16(2);
2483 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2484 pSMB->SetupCount = 1;
2485 pSMB->Reserved3 = 0;
2487 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2489 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2490 byte_count = 3 /* pad */ + params + count;
2491 pSMB->DataCount = cpu_to_le16(count);
2492 pSMB->ParameterCount = cpu_to_le16(params);
2493 pSMB->TotalDataCount = pSMB->DataCount;
2494 pSMB->TotalParameterCount = pSMB->ParameterCount;
2495 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2496 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2497 parm_data = (struct cifs_posix_lock *)
2498 (((char *)pSMB) + offset + 4);
2500 parm_data->lock_type = cpu_to_le16(lock_type);
2502 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2503 parm_data->lock_flags = cpu_to_le16(1);
2504 pSMB->Timeout = cpu_to_le32(-1);
2508 parm_data->pid = cpu_to_le32(netpid);
2509 parm_data->start = cpu_to_le64(start_offset);
2510 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2512 pSMB->DataOffset = cpu_to_le16(offset);
2513 pSMB->Fid = smb_file_id;
2514 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2515 pSMB->Reserved4 = 0;
2516 inc_rfc1001_len(pSMB, byte_count);
2517 pSMB->ByteCount = cpu_to_le16(byte_count);
2519 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2520 (struct smb_hdr *) pSMBr, &bytes_returned);
2522 iov[0].iov_base = (char *)pSMB;
2523 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2524 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2525 &resp_buf_type, timeout, &rsp_iov);
2526 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2528 cifs_small_buf_release(pSMB);
2531 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2532 } else if (pLockData) {
2533 /* lock structure can be returned on get */
2536 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2538 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2539 rc = -EIO; /* bad smb */
2542 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2543 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2544 if (data_count < sizeof(struct cifs_posix_lock)) {
2548 parm_data = (struct cifs_posix_lock *)
2549 ((char *)&pSMBr->hdr.Protocol + data_offset);
2550 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2551 pLockData->fl_type = F_UNLCK;
2553 if (parm_data->lock_type ==
2554 cpu_to_le16(CIFS_RDLCK))
2555 pLockData->fl_type = F_RDLCK;
2556 else if (parm_data->lock_type ==
2557 cpu_to_le16(CIFS_WRLCK))
2558 pLockData->fl_type = F_WRLCK;
2560 pLockData->fl_start = le64_to_cpu(parm_data->start);
2561 pLockData->fl_end = pLockData->fl_start +
2562 le64_to_cpu(parm_data->length) - 1;
2563 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2568 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2570 /* Note: On -EAGAIN error only caller can retry on handle based calls
2571 since file handle passed in no longer valid */
2578 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2581 CLOSE_REQ *pSMB = NULL;
2582 cifs_dbg(FYI, "In CIFSSMBClose\n");
2584 /* do not retry on dead session on close */
2585 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2591 pSMB->FileID = (__u16) smb_file_id;
2592 pSMB->LastWriteTime = 0xFFFFFFFF;
2593 pSMB->ByteCount = 0;
2594 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2595 cifs_small_buf_release(pSMB);
2596 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2599 /* EINTR is expected when user ctl-c to kill app */
2600 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2604 /* Since session is dead, file will be closed on server already */
2612 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2615 FLUSH_REQ *pSMB = NULL;
2616 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2618 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2622 pSMB->FileID = (__u16) smb_file_id;
2623 pSMB->ByteCount = 0;
2624 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2625 cifs_small_buf_release(pSMB);
2626 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2628 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2634 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2635 const char *from_name, const char *to_name,
2636 struct cifs_sb_info *cifs_sb)
2639 RENAME_REQ *pSMB = NULL;
2640 RENAME_RSP *pSMBr = NULL;
2642 int name_len, name_len2;
2644 int remap = cifs_remap(cifs_sb);
2646 cifs_dbg(FYI, "In CIFSSMBRename\n");
2648 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2653 pSMB->BufferFormat = 0x04;
2654 pSMB->SearchAttributes =
2655 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2658 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2659 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2660 from_name, PATH_MAX,
2661 cifs_sb->local_nls, remap);
2662 name_len++; /* trailing null */
2664 pSMB->OldFileName[name_len] = 0x04; /* pad */
2665 /* protocol requires ASCII signature byte on Unicode string */
2666 pSMB->OldFileName[name_len + 1] = 0x00;
2668 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2669 to_name, PATH_MAX, cifs_sb->local_nls,
2671 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2672 name_len2 *= 2; /* convert to bytes */
2674 name_len = copy_path_name(pSMB->OldFileName, from_name);
2675 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2676 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2677 name_len2++; /* signature byte */
2680 count = 1 /* 1st signature byte */ + name_len + name_len2;
2681 inc_rfc1001_len(pSMB, count);
2682 pSMB->ByteCount = cpu_to_le16(count);
2684 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2685 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2686 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2688 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2690 cifs_buf_release(pSMB);
2698 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2699 int netfid, const char *target_name,
2700 const struct nls_table *nls_codepage, int remap)
2702 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2703 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2704 struct set_file_rename *rename_info;
2706 char dummy_string[30];
2708 int bytes_returned = 0;
2710 __u16 params, param_offset, offset, count, byte_count;
2712 cifs_dbg(FYI, "Rename to File by handle\n");
2713 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2719 pSMB->MaxSetupCount = 0;
2723 pSMB->Reserved2 = 0;
2724 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2725 offset = param_offset + params;
2727 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2728 data_offset = (char *)(pSMB) + offset + 4;
2729 rename_info = (struct set_file_rename *) data_offset;
2730 pSMB->MaxParameterCount = cpu_to_le16(2);
2731 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2732 pSMB->SetupCount = 1;
2733 pSMB->Reserved3 = 0;
2734 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2735 byte_count = 3 /* pad */ + params;
2736 pSMB->ParameterCount = cpu_to_le16(params);
2737 pSMB->TotalParameterCount = pSMB->ParameterCount;
2738 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2739 pSMB->DataOffset = cpu_to_le16(offset);
2740 /* construct random name ".cifs_tmp<inodenum><mid>" */
2741 rename_info->overwrite = cpu_to_le32(1);
2742 rename_info->root_fid = 0;
2743 /* unicode only call */
2744 if (target_name == NULL) {
2745 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2747 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2748 dummy_string, 24, nls_codepage, remap);
2751 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2752 target_name, PATH_MAX, nls_codepage,
2755 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2756 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2757 byte_count += count;
2758 pSMB->DataCount = cpu_to_le16(count);
2759 pSMB->TotalDataCount = pSMB->DataCount;
2761 pSMB->InformationLevel =
2762 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2763 pSMB->Reserved4 = 0;
2764 inc_rfc1001_len(pSMB, byte_count);
2765 pSMB->ByteCount = cpu_to_le16(byte_count);
2766 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2767 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2768 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2770 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2773 cifs_buf_release(pSMB);
2775 /* Note: On -EAGAIN error only caller can retry on handle based calls
2776 since file handle passed in no longer valid */
2782 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2783 const char *fromName, const __u16 target_tid, const char *toName,
2784 const int flags, const struct nls_table *nls_codepage, int remap)
2787 COPY_REQ *pSMB = NULL;
2788 COPY_RSP *pSMBr = NULL;
2790 int name_len, name_len2;
2793 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2795 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2800 pSMB->BufferFormat = 0x04;
2801 pSMB->Tid2 = target_tid;
2803 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2805 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2806 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2807 fromName, PATH_MAX, nls_codepage,
2809 name_len++; /* trailing null */
2811 pSMB->OldFileName[name_len] = 0x04; /* pad */
2812 /* protocol requires ASCII signature byte on Unicode string */
2813 pSMB->OldFileName[name_len + 1] = 0x00;
2815 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2816 toName, PATH_MAX, nls_codepage, remap);
2817 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2818 name_len2 *= 2; /* convert to bytes */
2820 name_len = copy_path_name(pSMB->OldFileName, fromName);
2821 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2822 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2823 name_len2++; /* signature byte */
2826 count = 1 /* 1st signature byte */ + name_len + name_len2;
2827 inc_rfc1001_len(pSMB, count);
2828 pSMB->ByteCount = cpu_to_le16(count);
2830 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2831 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2833 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2834 rc, le16_to_cpu(pSMBr->CopyCount));
2836 cifs_buf_release(pSMB);
2845 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2846 const char *fromName, const char *toName,
2847 const struct nls_table *nls_codepage, int remap)
2849 TRANSACTION2_SPI_REQ *pSMB = NULL;
2850 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2853 int name_len_target;
2855 int bytes_returned = 0;
2856 __u16 params, param_offset, offset, byte_count;
2858 cifs_dbg(FYI, "In Symlink Unix style\n");
2860 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2865 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2867 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2868 /* find define for this maxpathcomponent */
2869 PATH_MAX, nls_codepage, remap);
2870 name_len++; /* trailing null */
2874 name_len = copy_path_name(pSMB->FileName, fromName);
2876 params = 6 + name_len;
2877 pSMB->MaxSetupCount = 0;
2881 pSMB->Reserved2 = 0;
2882 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2883 InformationLevel) - 4;
2884 offset = param_offset + params;
2886 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2887 data_offset = (char *)pSMB + offset + 4;
2888 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2890 cifsConvertToUTF16((__le16 *) data_offset, toName,
2891 /* find define for this maxpathcomponent */
2892 PATH_MAX, nls_codepage, remap);
2893 name_len_target++; /* trailing null */
2894 name_len_target *= 2;
2896 name_len_target = copy_path_name(data_offset, toName);
2899 pSMB->MaxParameterCount = cpu_to_le16(2);
2900 /* BB find exact max on data count below from sess */
2901 pSMB->MaxDataCount = cpu_to_le16(1000);
2902 pSMB->SetupCount = 1;
2903 pSMB->Reserved3 = 0;
2904 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2905 byte_count = 3 /* pad */ + params + name_len_target;
2906 pSMB->DataCount = cpu_to_le16(name_len_target);
2907 pSMB->ParameterCount = cpu_to_le16(params);
2908 pSMB->TotalDataCount = pSMB->DataCount;
2909 pSMB->TotalParameterCount = pSMB->ParameterCount;
2910 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2911 pSMB->DataOffset = cpu_to_le16(offset);
2912 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2913 pSMB->Reserved4 = 0;
2914 inc_rfc1001_len(pSMB, byte_count);
2915 pSMB->ByteCount = cpu_to_le16(byte_count);
2916 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2917 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2918 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2920 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2923 cifs_buf_release(pSMB);
2926 goto createSymLinkRetry;
2932 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2933 const char *fromName, const char *toName,
2934 const struct nls_table *nls_codepage, int remap)
2936 TRANSACTION2_SPI_REQ *pSMB = NULL;
2937 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2940 int name_len_target;
2942 int bytes_returned = 0;
2943 __u16 params, param_offset, offset, byte_count;
2945 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2946 createHardLinkRetry:
2947 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2952 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2953 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2954 PATH_MAX, nls_codepage, remap);
2955 name_len++; /* trailing null */
2959 name_len = copy_path_name(pSMB->FileName, toName);
2961 params = 6 + name_len;
2962 pSMB->MaxSetupCount = 0;
2966 pSMB->Reserved2 = 0;
2967 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2968 InformationLevel) - 4;
2969 offset = param_offset + params;
2971 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2972 data_offset = (char *)pSMB + offset + 4;
2973 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2975 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2976 PATH_MAX, nls_codepage, remap);
2977 name_len_target++; /* trailing null */
2978 name_len_target *= 2;
2980 name_len_target = copy_path_name(data_offset, fromName);
2983 pSMB->MaxParameterCount = cpu_to_le16(2);
2984 /* BB find exact max on data count below from sess*/
2985 pSMB->MaxDataCount = cpu_to_le16(1000);
2986 pSMB->SetupCount = 1;
2987 pSMB->Reserved3 = 0;
2988 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2989 byte_count = 3 /* pad */ + params + name_len_target;
2990 pSMB->ParameterCount = cpu_to_le16(params);
2991 pSMB->TotalParameterCount = pSMB->ParameterCount;
2992 pSMB->DataCount = cpu_to_le16(name_len_target);
2993 pSMB->TotalDataCount = pSMB->DataCount;
2994 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2995 pSMB->DataOffset = cpu_to_le16(offset);
2996 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2997 pSMB->Reserved4 = 0;
2998 inc_rfc1001_len(pSMB, byte_count);
2999 pSMB->ByteCount = cpu_to_le16(byte_count);
3000 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3001 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3002 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3004 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3007 cifs_buf_release(pSMB);
3009 goto createHardLinkRetry;
3015 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3016 const char *from_name, const char *to_name,
3017 struct cifs_sb_info *cifs_sb)
3020 NT_RENAME_REQ *pSMB = NULL;
3021 RENAME_RSP *pSMBr = NULL;
3023 int name_len, name_len2;
3025 int remap = cifs_remap(cifs_sb);
3027 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3028 winCreateHardLinkRetry:
3030 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3035 pSMB->SearchAttributes =
3036 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3038 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3039 pSMB->ClusterCount = 0;
3041 pSMB->BufferFormat = 0x04;
3043 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3045 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3046 PATH_MAX, cifs_sb->local_nls, remap);
3047 name_len++; /* trailing null */
3050 /* protocol specifies ASCII buffer format (0x04) for unicode */
3051 pSMB->OldFileName[name_len] = 0x04;
3052 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3054 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3055 to_name, PATH_MAX, cifs_sb->local_nls,
3057 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3058 name_len2 *= 2; /* convert to bytes */
3060 name_len = copy_path_name(pSMB->OldFileName, from_name);
3061 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3062 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
3063 name_len2++; /* signature byte */
3066 count = 1 /* string type byte */ + name_len + name_len2;
3067 inc_rfc1001_len(pSMB, count);
3068 pSMB->ByteCount = cpu_to_le16(count);
3070 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3071 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3072 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3074 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3076 cifs_buf_release(pSMB);
3078 goto winCreateHardLinkRetry;
3084 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3085 const unsigned char *searchName, char **symlinkinfo,
3086 const struct nls_table *nls_codepage, int remap)
3088 /* SMB_QUERY_FILE_UNIX_LINK */
3089 TRANSACTION2_QPI_REQ *pSMB = NULL;
3090 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3094 __u16 params, byte_count;
3097 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3100 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3105 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3107 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3108 searchName, PATH_MAX, nls_codepage,
3110 name_len++; /* trailing null */
3113 name_len = copy_path_name(pSMB->FileName, searchName);
3116 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3117 pSMB->TotalDataCount = 0;
3118 pSMB->MaxParameterCount = cpu_to_le16(2);
3119 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3120 pSMB->MaxSetupCount = 0;
3124 pSMB->Reserved2 = 0;
3125 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3126 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3127 pSMB->DataCount = 0;
3128 pSMB->DataOffset = 0;
3129 pSMB->SetupCount = 1;
3130 pSMB->Reserved3 = 0;
3131 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3132 byte_count = params + 1 /* pad */ ;
3133 pSMB->TotalParameterCount = cpu_to_le16(params);
3134 pSMB->ParameterCount = pSMB->TotalParameterCount;
3135 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3136 pSMB->Reserved4 = 0;
3137 inc_rfc1001_len(pSMB, byte_count);
3138 pSMB->ByteCount = cpu_to_le16(byte_count);
3140 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3141 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3143 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3145 /* decode response */
3147 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3148 /* BB also check enough total bytes returned */
3149 if (rc || get_bcc(&pSMBr->hdr) < 2)
3153 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3155 data_start = ((char *) &pSMBr->hdr.Protocol) +
3156 le16_to_cpu(pSMBr->t2.DataOffset);
3158 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3163 /* BB FIXME investigate remapping reserved chars here */
3164 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3165 count, is_unicode, nls_codepage);
3170 cifs_buf_release(pSMB);
3172 goto querySymLinkRetry;
3177 * Recent Windows versions now create symlinks more frequently
3178 * and they use the "reparse point" mechanism below. We can of course
3179 * do symlinks nicely to Samba and other servers which support the
3180 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3181 * "MF" symlinks optionally, but for recent Windows we really need to
3182 * reenable the code below and fix the cifs_symlink callers to handle this.
3183 * In the interim this code has been moved to its own config option so
3184 * it is not compiled in by default until callers fixed up and more tested.
3187 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3188 __u16 fid, char **symlinkinfo,
3189 const struct nls_table *nls_codepage)
3193 struct smb_com_transaction_ioctl_req *pSMB;
3194 struct smb_com_transaction_ioctl_rsp *pSMBr;
3196 unsigned int sub_len;
3198 struct reparse_symlink_data *reparse_buf;
3199 struct reparse_posix_data *posix_buf;
3200 __u32 data_offset, data_count;
3203 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3204 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3209 pSMB->TotalParameterCount = 0 ;
3210 pSMB->TotalDataCount = 0;
3211 pSMB->MaxParameterCount = cpu_to_le32(2);
3212 /* BB find exact data count max from sess structure BB */
3213 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3214 pSMB->MaxSetupCount = 4;
3216 pSMB->ParameterOffset = 0;
3217 pSMB->DataCount = 0;
3218 pSMB->DataOffset = 0;
3219 pSMB->SetupCount = 4;
3220 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3221 pSMB->ParameterCount = pSMB->TotalParameterCount;
3222 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3223 pSMB->IsFsctl = 1; /* FSCTL */
3224 pSMB->IsRootFlag = 0;
3225 pSMB->Fid = fid; /* file handle always le */
3226 pSMB->ByteCount = 0;
3228 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3229 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3231 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3235 data_offset = le32_to_cpu(pSMBr->DataOffset);
3236 data_count = le32_to_cpu(pSMBr->DataCount);
3237 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3238 /* BB also check enough total bytes returned */
3239 rc = -EIO; /* bad smb */
3242 if (!data_count || (data_count > 2048)) {
3244 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3247 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3248 reparse_buf = (struct reparse_symlink_data *)
3249 ((char *)&pSMBr->hdr.Protocol + data_offset);
3250 if ((char *)reparse_buf >= end_of_smb) {
3254 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3255 cifs_dbg(FYI, "NFS style reparse tag\n");
3256 posix_buf = (struct reparse_posix_data *)reparse_buf;
3258 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3259 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3260 le64_to_cpu(posix_buf->InodeType));
3265 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3266 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3267 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3271 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3272 sub_len, is_unicode, nls_codepage);
3274 } else if (reparse_buf->ReparseTag !=
3275 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3280 /* Reparse tag is NTFS symlink */
3281 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3282 reparse_buf->PathBuffer;
3283 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3284 if (sub_start + sub_len > end_of_smb) {
3285 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3289 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3294 /* BB FIXME investigate remapping reserved chars here */
3295 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3300 cifs_buf_release(pSMB);
3303 * Note: On -EAGAIN error only caller can retry on handle based calls
3304 * since file handle passed in no longer valid.
3310 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3315 struct smb_com_transaction_compr_ioctl_req *pSMB;
3316 struct smb_com_transaction_ioctl_rsp *pSMBr;
3318 cifs_dbg(FYI, "Set compression for %u\n", fid);
3319 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3324 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3326 pSMB->TotalParameterCount = 0;
3327 pSMB->TotalDataCount = cpu_to_le32(2);
3328 pSMB->MaxParameterCount = 0;
3329 pSMB->MaxDataCount = 0;
3330 pSMB->MaxSetupCount = 4;
3332 pSMB->ParameterOffset = 0;
3333 pSMB->DataCount = cpu_to_le32(2);
3335 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3336 compression_state) - 4); /* 84 */
3337 pSMB->SetupCount = 4;
3338 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3339 pSMB->ParameterCount = 0;
3340 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3341 pSMB->IsFsctl = 1; /* FSCTL */
3342 pSMB->IsRootFlag = 0;
3343 pSMB->Fid = fid; /* file handle always le */
3344 /* 3 byte pad, followed by 2 byte compress state */
3345 pSMB->ByteCount = cpu_to_le16(5);
3346 inc_rfc1001_len(pSMB, 5);
3348 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3349 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3351 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3353 cifs_buf_release(pSMB);
3356 * Note: On -EAGAIN error only caller can retry on handle based calls
3357 * since file handle passed in no longer valid.
3363 #ifdef CONFIG_CIFS_POSIX
3365 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3366 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3367 struct cifs_posix_ace *cifs_ace)
3369 /* u8 cifs fields do not need le conversion */
3370 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3371 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3372 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3374 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3375 ace->e_perm, ace->e_tag, ace->e_id);
3381 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3382 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3383 const int acl_type, const int size_of_data_area)
3388 struct cifs_posix_ace *pACE;
3389 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3390 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3392 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3395 if (acl_type == ACL_TYPE_ACCESS) {
3396 count = le16_to_cpu(cifs_acl->access_entry_count);
3397 pACE = &cifs_acl->ace_array[0];
3398 size = sizeof(struct cifs_posix_acl);
3399 size += sizeof(struct cifs_posix_ace) * count;
3400 /* check if we would go beyond end of SMB */
3401 if (size_of_data_area < size) {
3402 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3403 size_of_data_area, size);
3406 } else if (acl_type == ACL_TYPE_DEFAULT) {
3407 count = le16_to_cpu(cifs_acl->access_entry_count);
3408 size = sizeof(struct cifs_posix_acl);
3409 size += sizeof(struct cifs_posix_ace) * count;
3410 /* skip past access ACEs to get to default ACEs */
3411 pACE = &cifs_acl->ace_array[count];
3412 count = le16_to_cpu(cifs_acl->default_entry_count);
3413 size += sizeof(struct cifs_posix_ace) * count;
3414 /* check if we would go beyond end of SMB */
3415 if (size_of_data_area < size)
3422 size = posix_acl_xattr_size(count);
3423 if ((buflen == 0) || (local_acl == NULL)) {
3424 /* used to query ACL EA size */
3425 } else if (size > buflen) {
3427 } else /* buffer big enough */ {
3428 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3430 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3431 for (i = 0; i < count ; i++) {
3432 cifs_convert_ace(&ace[i], pACE);
3439 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3440 const struct posix_acl_xattr_entry *local_ace)
3442 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3443 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3444 /* BB is there a better way to handle the large uid? */
3445 if (local_ace->e_id == cpu_to_le32(-1)) {
3446 /* Probably no need to le convert -1 on any arch but can not hurt */
3447 cifs_ace->cifs_uid = cpu_to_le64(-1);
3449 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3451 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3452 ace->e_perm, ace->e_tag, ace->e_id);
3456 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3457 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3458 const int buflen, const int acl_type)
3461 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3462 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3463 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3467 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3470 count = posix_acl_xattr_count((size_t)buflen);
3471 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3472 count, buflen, le32_to_cpu(local_acl->a_version));
3473 if (le32_to_cpu(local_acl->a_version) != 2) {
3474 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3475 le32_to_cpu(local_acl->a_version));
3478 cifs_acl->version = cpu_to_le16(1);
3479 if (acl_type == ACL_TYPE_ACCESS) {
3480 cifs_acl->access_entry_count = cpu_to_le16(count);
3481 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3482 } else if (acl_type == ACL_TYPE_DEFAULT) {
3483 cifs_acl->default_entry_count = cpu_to_le16(count);
3484 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3486 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3489 for (i = 0; i < count; i++)
3490 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3492 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3493 rc += sizeof(struct cifs_posix_acl);
3494 /* BB add check to make sure ACL does not overflow SMB */
3500 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3501 const unsigned char *searchName,
3502 char *acl_inf, const int buflen, const int acl_type,
3503 const struct nls_table *nls_codepage, int remap)
3505 /* SMB_QUERY_POSIX_ACL */
3506 TRANSACTION2_QPI_REQ *pSMB = NULL;
3507 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3511 __u16 params, byte_count;
3513 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3516 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3521 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3523 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3524 searchName, PATH_MAX, nls_codepage,
3526 name_len++; /* trailing null */
3528 pSMB->FileName[name_len] = 0;
3529 pSMB->FileName[name_len+1] = 0;
3531 name_len = copy_path_name(pSMB->FileName, searchName);
3534 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3535 pSMB->TotalDataCount = 0;
3536 pSMB->MaxParameterCount = cpu_to_le16(2);
3537 /* BB find exact max data count below from sess structure BB */
3538 pSMB->MaxDataCount = cpu_to_le16(4000);
3539 pSMB->MaxSetupCount = 0;
3543 pSMB->Reserved2 = 0;
3544 pSMB->ParameterOffset = cpu_to_le16(
3545 offsetof(struct smb_com_transaction2_qpi_req,
3546 InformationLevel) - 4);
3547 pSMB->DataCount = 0;
3548 pSMB->DataOffset = 0;
3549 pSMB->SetupCount = 1;
3550 pSMB->Reserved3 = 0;
3551 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3552 byte_count = params + 1 /* pad */ ;
3553 pSMB->TotalParameterCount = cpu_to_le16(params);
3554 pSMB->ParameterCount = pSMB->TotalParameterCount;
3555 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3556 pSMB->Reserved4 = 0;
3557 inc_rfc1001_len(pSMB, byte_count);
3558 pSMB->ByteCount = cpu_to_le16(byte_count);
3560 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3561 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3562 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3564 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3566 /* decode response */
3568 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3569 /* BB also check enough total bytes returned */
3570 if (rc || get_bcc(&pSMBr->hdr) < 2)
3571 rc = -EIO; /* bad smb */
3573 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3574 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3575 rc = cifs_copy_posix_acl(acl_inf,
3576 (char *)&pSMBr->hdr.Protocol+data_offset,
3577 buflen, acl_type, count);
3580 cifs_buf_release(pSMB);
3587 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3588 const unsigned char *fileName,
3589 const char *local_acl, const int buflen,
3591 const struct nls_table *nls_codepage, int remap)
3593 struct smb_com_transaction2_spi_req *pSMB = NULL;
3594 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3598 int bytes_returned = 0;
3599 __u16 params, byte_count, data_count, param_offset, offset;
3601 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3603 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3607 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3609 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3610 PATH_MAX, nls_codepage, remap);
3611 name_len++; /* trailing null */
3614 name_len = copy_path_name(pSMB->FileName, fileName);
3616 params = 6 + name_len;
3617 pSMB->MaxParameterCount = cpu_to_le16(2);
3618 /* BB find max SMB size from sess */
3619 pSMB->MaxDataCount = cpu_to_le16(1000);
3620 pSMB->MaxSetupCount = 0;
3624 pSMB->Reserved2 = 0;
3625 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3626 InformationLevel) - 4;
3627 offset = param_offset + params;
3628 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3629 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3631 /* convert to on the wire format for POSIX ACL */
3632 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3634 if (data_count == 0) {
3636 goto setACLerrorExit;
3638 pSMB->DataOffset = cpu_to_le16(offset);
3639 pSMB->SetupCount = 1;
3640 pSMB->Reserved3 = 0;
3641 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3642 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3643 byte_count = 3 /* pad */ + params + data_count;
3644 pSMB->DataCount = cpu_to_le16(data_count);
3645 pSMB->TotalDataCount = pSMB->DataCount;
3646 pSMB->ParameterCount = cpu_to_le16(params);
3647 pSMB->TotalParameterCount = pSMB->ParameterCount;
3648 pSMB->Reserved4 = 0;
3649 inc_rfc1001_len(pSMB, byte_count);
3650 pSMB->ByteCount = cpu_to_le16(byte_count);
3651 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3652 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3654 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3657 cifs_buf_release(pSMB);
3663 /* BB fix tabs in this function FIXME BB */
3665 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3666 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3669 struct smb_t2_qfi_req *pSMB = NULL;
3670 struct smb_t2_qfi_rsp *pSMBr = NULL;
3672 __u16 params, byte_count;
3674 cifs_dbg(FYI, "In GetExtAttr\n");
3679 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3684 params = 2 /* level */ + 2 /* fid */;
3685 pSMB->t2.TotalDataCount = 0;
3686 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3687 /* BB find exact max data count below from sess structure BB */
3688 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3689 pSMB->t2.MaxSetupCount = 0;
3690 pSMB->t2.Reserved = 0;
3692 pSMB->t2.Timeout = 0;
3693 pSMB->t2.Reserved2 = 0;
3694 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3696 pSMB->t2.DataCount = 0;
3697 pSMB->t2.DataOffset = 0;
3698 pSMB->t2.SetupCount = 1;
3699 pSMB->t2.Reserved3 = 0;
3700 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3701 byte_count = params + 1 /* pad */ ;
3702 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3703 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3704 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3707 inc_rfc1001_len(pSMB, byte_count);
3708 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3710 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3711 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3713 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3715 /* decode response */
3716 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3717 /* BB also check enough total bytes returned */
3718 if (rc || get_bcc(&pSMBr->hdr) < 2)
3719 /* If rc should we check for EOPNOSUPP and
3720 disable the srvino flag? or in caller? */
3721 rc = -EIO; /* bad smb */
3723 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3724 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3725 struct file_chattr_info *pfinfo;
3726 /* BB Do we need a cast or hash here ? */
3728 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3732 pfinfo = (struct file_chattr_info *)
3733 (data_offset + (char *) &pSMBr->hdr.Protocol);
3734 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3735 *pMask = le64_to_cpu(pfinfo->mask);
3739 cifs_buf_release(pSMB);
3741 goto GetExtAttrRetry;
3745 #endif /* CONFIG_POSIX */
3748 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3749 * all NT TRANSACTS that we init here have total parm and data under about 400
3750 * bytes (to fit in small cifs buffer size), which is the case so far, it
3751 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3752 * returned setup area) and MaxParameterCount (returned parms size) must be set
3756 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3757 const int parm_len, struct cifs_tcon *tcon,
3762 struct smb_com_ntransact_req *pSMB;
3764 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3768 *ret_buf = (void *)pSMB;
3770 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3771 pSMB->TotalDataCount = 0;
3772 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3773 pSMB->ParameterCount = pSMB->TotalParameterCount;
3774 pSMB->DataCount = pSMB->TotalDataCount;
3775 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3776 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3777 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3778 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3779 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3780 pSMB->SubCommand = cpu_to_le16(sub_command);
3785 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3786 __u32 *pparmlen, __u32 *pdatalen)
3789 __u32 data_count, data_offset, parm_count, parm_offset;
3790 struct smb_com_ntransact_rsp *pSMBr;
3799 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3801 bcc = get_bcc(&pSMBr->hdr);
3802 end_of_smb = 2 /* sizeof byte count */ + bcc +
3803 (char *)&pSMBr->ByteCount;
3805 data_offset = le32_to_cpu(pSMBr->DataOffset);
3806 data_count = le32_to_cpu(pSMBr->DataCount);
3807 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3808 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3810 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3811 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3813 /* should we also check that parm and data areas do not overlap? */
3814 if (*ppparm > end_of_smb) {
3815 cifs_dbg(FYI, "parms start after end of smb\n");
3817 } else if (parm_count + *ppparm > end_of_smb) {
3818 cifs_dbg(FYI, "parm end after end of smb\n");
3820 } else if (*ppdata > end_of_smb) {
3821 cifs_dbg(FYI, "data starts after end of smb\n");
3823 } else if (data_count + *ppdata > end_of_smb) {
3824 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3825 *ppdata, data_count, (data_count + *ppdata),
3828 } else if (parm_count + data_count > bcc) {
3829 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3832 *pdatalen = data_count;
3833 *pparmlen = parm_count;
3837 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3839 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3840 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3844 QUERY_SEC_DESC_REQ *pSMB;
3846 struct kvec rsp_iov;
3848 cifs_dbg(FYI, "GetCifsACL\n");
3853 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3854 8 /* parm len */, tcon, (void **) &pSMB);
3858 pSMB->MaxParameterCount = cpu_to_le32(4);
3859 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3860 pSMB->MaxSetupCount = 0;
3861 pSMB->Fid = fid; /* file handle always le */
3862 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3864 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3865 inc_rfc1001_len(pSMB, 11);
3866 iov[0].iov_base = (char *)pSMB;
3867 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3869 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3871 cifs_small_buf_release(pSMB);
3872 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3874 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3875 } else { /* decode response */
3879 struct smb_com_ntransact_rsp *pSMBr;
3882 /* validate_nttransact */
3883 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3884 &pdata, &parm_len, pbuflen);
3887 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3889 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3890 pSMBr, parm, *acl_inf);
3892 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3893 rc = -EIO; /* bad smb */
3898 /* BB check that data area is minimum length and as big as acl_len */
3900 acl_len = le32_to_cpu(*parm);
3901 if (acl_len != *pbuflen) {
3902 cifs_dbg(VFS, "acl length %d does not match %d\n",
3904 if (*pbuflen > acl_len)
3908 /* check if buffer is big enough for the acl
3909 header followed by the smallest SID */
3910 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3911 (*pbuflen >= 64 * 1024)) {
3912 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3916 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3917 if (*acl_inf == NULL) {
3924 free_rsp_buf(buf_type, rsp_iov.iov_base);
3929 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3930 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3932 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3934 int bytes_returned = 0;
3935 SET_SEC_DESC_REQ *pSMB = NULL;
3939 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3943 pSMB->MaxSetupCount = 0;
3947 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3948 data_count = acllen;
3949 data_offset = param_offset + param_count;
3950 byte_count = 3 /* pad */ + param_count;
3952 pSMB->DataCount = cpu_to_le32(data_count);
3953 pSMB->TotalDataCount = pSMB->DataCount;
3954 pSMB->MaxParameterCount = cpu_to_le32(4);
3955 pSMB->MaxDataCount = cpu_to_le32(16384);
3956 pSMB->ParameterCount = cpu_to_le32(param_count);
3957 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3958 pSMB->TotalParameterCount = pSMB->ParameterCount;
3959 pSMB->DataOffset = cpu_to_le32(data_offset);
3960 pSMB->SetupCount = 0;
3961 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3962 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3964 pSMB->Fid = fid; /* file handle always le */
3965 pSMB->Reserved2 = 0;
3966 pSMB->AclFlags = cpu_to_le32(aclflag);
3968 if (pntsd && acllen) {
3969 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3970 data_offset, pntsd, acllen);
3971 inc_rfc1001_len(pSMB, byte_count + data_count);
3973 inc_rfc1001_len(pSMB, byte_count);
3975 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3976 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3978 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3979 bytes_returned, rc);
3981 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3982 cifs_buf_release(pSMB);
3985 goto setCifsAclRetry;
3991 /* Legacy Query Path Information call for lookup to old servers such
3994 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3995 const char *search_name, FILE_ALL_INFO *data,
3996 const struct nls_table *nls_codepage, int remap)
3998 QUERY_INFORMATION_REQ *pSMB;
3999 QUERY_INFORMATION_RSP *pSMBr;
4004 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4006 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4011 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4013 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4014 search_name, PATH_MAX, nls_codepage,
4016 name_len++; /* trailing null */
4019 name_len = copy_path_name(pSMB->FileName, search_name);
4021 pSMB->BufferFormat = 0x04;
4022 name_len++; /* account for buffer type byte */
4023 inc_rfc1001_len(pSMB, (__u16)name_len);
4024 pSMB->ByteCount = cpu_to_le16(name_len);
4026 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4027 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4029 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4031 struct timespec64 ts;
4032 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4034 /* decode response */
4035 /* BB FIXME - add time zone adjustment BB */
4036 memset(data, 0, sizeof(FILE_ALL_INFO));
4039 /* decode time fields */
4040 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4041 data->LastWriteTime = data->ChangeTime;
4042 data->LastAccessTime = 0;
4043 data->AllocationSize =
4044 cpu_to_le64(le32_to_cpu(pSMBr->size));
4045 data->EndOfFile = data->AllocationSize;
4047 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4049 rc = -EIO; /* bad buffer passed in */
4051 cifs_buf_release(pSMB);
4060 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4061 u16 netfid, FILE_ALL_INFO *pFindData)
4063 struct smb_t2_qfi_req *pSMB = NULL;
4064 struct smb_t2_qfi_rsp *pSMBr = NULL;
4067 __u16 params, byte_count;
4070 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4075 params = 2 /* level */ + 2 /* fid */;
4076 pSMB->t2.TotalDataCount = 0;
4077 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4078 /* BB find exact max data count below from sess structure BB */
4079 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4080 pSMB->t2.MaxSetupCount = 0;
4081 pSMB->t2.Reserved = 0;
4083 pSMB->t2.Timeout = 0;
4084 pSMB->t2.Reserved2 = 0;
4085 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4087 pSMB->t2.DataCount = 0;
4088 pSMB->t2.DataOffset = 0;
4089 pSMB->t2.SetupCount = 1;
4090 pSMB->t2.Reserved3 = 0;
4091 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4092 byte_count = params + 1 /* pad */ ;
4093 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4094 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4095 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4098 inc_rfc1001_len(pSMB, byte_count);
4099 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4101 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4102 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4104 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
4105 } else { /* decode response */
4106 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4108 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4110 else if (get_bcc(&pSMBr->hdr) < 40)
4111 rc = -EIO; /* bad smb */
4112 else if (pFindData) {
4113 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4114 memcpy((char *) pFindData,
4115 (char *) &pSMBr->hdr.Protocol +
4116 data_offset, sizeof(FILE_ALL_INFO));
4120 cifs_buf_release(pSMB);
4122 goto QFileInfoRetry;
4128 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4129 const char *search_name, FILE_ALL_INFO *data,
4130 int legacy /* old style infolevel */,
4131 const struct nls_table *nls_codepage, int remap)
4133 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4134 TRANSACTION2_QPI_REQ *pSMB = NULL;
4135 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4139 __u16 params, byte_count;
4141 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4143 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4148 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4150 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4151 PATH_MAX, nls_codepage, remap);
4152 name_len++; /* trailing null */
4155 name_len = copy_path_name(pSMB->FileName, search_name);
4158 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4159 pSMB->TotalDataCount = 0;
4160 pSMB->MaxParameterCount = cpu_to_le16(2);
4161 /* BB find exact max SMB PDU from sess structure BB */
4162 pSMB->MaxDataCount = cpu_to_le16(4000);
4163 pSMB->MaxSetupCount = 0;
4167 pSMB->Reserved2 = 0;
4168 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4169 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4170 pSMB->DataCount = 0;
4171 pSMB->DataOffset = 0;
4172 pSMB->SetupCount = 1;
4173 pSMB->Reserved3 = 0;
4174 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4175 byte_count = params + 1 /* pad */ ;
4176 pSMB->TotalParameterCount = cpu_to_le16(params);
4177 pSMB->ParameterCount = pSMB->TotalParameterCount;
4179 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4181 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4182 pSMB->Reserved4 = 0;
4183 inc_rfc1001_len(pSMB, byte_count);
4184 pSMB->ByteCount = cpu_to_le16(byte_count);
4186 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4187 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4189 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4190 } else { /* decode response */
4191 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4193 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4195 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4196 rc = -EIO; /* bad smb */
4197 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4198 rc = -EIO; /* 24 or 26 expected but we do not read
4202 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4205 * On legacy responses we do not read the last field,
4206 * EAsize, fortunately since it varies by subdialect and
4207 * also note it differs on Set vs Get, ie two bytes or 4
4208 * bytes depending but we don't care here.
4211 size = sizeof(FILE_INFO_STANDARD);
4213 size = sizeof(FILE_ALL_INFO);
4214 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4219 cifs_buf_release(pSMB);
4221 goto QPathInfoRetry;
4227 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4228 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4230 struct smb_t2_qfi_req *pSMB = NULL;
4231 struct smb_t2_qfi_rsp *pSMBr = NULL;
4234 __u16 params, byte_count;
4237 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4242 params = 2 /* level */ + 2 /* fid */;
4243 pSMB->t2.TotalDataCount = 0;
4244 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4245 /* BB find exact max data count below from sess structure BB */
4246 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4247 pSMB->t2.MaxSetupCount = 0;
4248 pSMB->t2.Reserved = 0;
4250 pSMB->t2.Timeout = 0;
4251 pSMB->t2.Reserved2 = 0;
4252 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4254 pSMB->t2.DataCount = 0;
4255 pSMB->t2.DataOffset = 0;
4256 pSMB->t2.SetupCount = 1;
4257 pSMB->t2.Reserved3 = 0;
4258 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4259 byte_count = params + 1 /* pad */ ;
4260 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4261 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4262 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4265 inc_rfc1001_len(pSMB, byte_count);
4266 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4268 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4269 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4271 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
4272 } else { /* decode response */
4273 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4275 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4276 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4277 rc = -EIO; /* bad smb */
4279 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4280 memcpy((char *) pFindData,
4281 (char *) &pSMBr->hdr.Protocol +
4283 sizeof(FILE_UNIX_BASIC_INFO));
4287 cifs_buf_release(pSMB);
4289 goto UnixQFileInfoRetry;
4295 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4296 const unsigned char *searchName,
4297 FILE_UNIX_BASIC_INFO *pFindData,
4298 const struct nls_table *nls_codepage, int remap)
4300 /* SMB_QUERY_FILE_UNIX_BASIC */
4301 TRANSACTION2_QPI_REQ *pSMB = NULL;
4302 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4304 int bytes_returned = 0;
4306 __u16 params, byte_count;
4308 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4310 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4315 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4317 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4318 PATH_MAX, nls_codepage, remap);
4319 name_len++; /* trailing null */
4322 name_len = copy_path_name(pSMB->FileName, searchName);
4325 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4326 pSMB->TotalDataCount = 0;
4327 pSMB->MaxParameterCount = cpu_to_le16(2);
4328 /* BB find exact max SMB PDU from sess structure BB */
4329 pSMB->MaxDataCount = cpu_to_le16(4000);
4330 pSMB->MaxSetupCount = 0;
4334 pSMB->Reserved2 = 0;
4335 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4336 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4337 pSMB->DataCount = 0;
4338 pSMB->DataOffset = 0;
4339 pSMB->SetupCount = 1;
4340 pSMB->Reserved3 = 0;
4341 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4342 byte_count = params + 1 /* pad */ ;
4343 pSMB->TotalParameterCount = cpu_to_le16(params);
4344 pSMB->ParameterCount = pSMB->TotalParameterCount;
4345 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4346 pSMB->Reserved4 = 0;
4347 inc_rfc1001_len(pSMB, byte_count);
4348 pSMB->ByteCount = cpu_to_le16(byte_count);
4350 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4351 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4353 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
4354 } else { /* decode response */
4355 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4357 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4358 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4359 rc = -EIO; /* bad smb */
4361 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4362 memcpy((char *) pFindData,
4363 (char *) &pSMBr->hdr.Protocol +
4365 sizeof(FILE_UNIX_BASIC_INFO));
4368 cifs_buf_release(pSMB);
4370 goto UnixQPathInfoRetry;
4375 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4377 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4378 const char *searchName, struct cifs_sb_info *cifs_sb,
4379 __u16 *pnetfid, __u16 search_flags,
4380 struct cifs_search_info *psrch_inf, bool msearch)
4382 /* level 257 SMB_ */
4383 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4384 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4385 T2_FFIRST_RSP_PARMS *parms;
4387 int bytes_returned = 0;
4388 int name_len, remap;
4389 __u16 params, byte_count;
4390 struct nls_table *nls_codepage;
4392 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4395 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4400 nls_codepage = cifs_sb->local_nls;
4401 remap = cifs_remap(cifs_sb);
4403 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4405 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4406 PATH_MAX, nls_codepage, remap);
4407 /* We can not add the asterik earlier in case
4408 it got remapped to 0xF03A as if it were part of the
4409 directory name instead of a wildcard */
4412 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4413 pSMB->FileName[name_len+1] = 0;
4414 pSMB->FileName[name_len+2] = '*';
4415 pSMB->FileName[name_len+3] = 0;
4416 name_len += 4; /* now the trailing null */
4417 /* null terminate just in case */
4418 pSMB->FileName[name_len] = 0;
4419 pSMB->FileName[name_len+1] = 0;
4423 name_len = copy_path_name(pSMB->FileName, searchName);
4425 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4426 name_len = PATH_MAX-2;
4427 /* overwrite nul byte */
4428 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4429 pSMB->FileName[name_len] = '*';
4430 pSMB->FileName[name_len+1] = 0;
4435 params = 12 + name_len /* includes null */ ;
4436 pSMB->TotalDataCount = 0; /* no EAs */
4437 pSMB->MaxParameterCount = cpu_to_le16(10);
4438 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4439 pSMB->MaxSetupCount = 0;
4443 pSMB->Reserved2 = 0;
4444 byte_count = params + 1 /* pad */ ;
4445 pSMB->TotalParameterCount = cpu_to_le16(params);
4446 pSMB->ParameterCount = pSMB->TotalParameterCount;
4447 pSMB->ParameterOffset = cpu_to_le16(
4448 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4450 pSMB->DataCount = 0;
4451 pSMB->DataOffset = 0;
4452 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4453 pSMB->Reserved3 = 0;
4454 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4455 pSMB->SearchAttributes =
4456 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4458 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4459 pSMB->SearchFlags = cpu_to_le16(search_flags);
4460 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4462 /* BB what should we set StorageType to? Does it matter? BB */
4463 pSMB->SearchStorageType = 0;
4464 inc_rfc1001_len(pSMB, byte_count);
4465 pSMB->ByteCount = cpu_to_le16(byte_count);
4467 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4468 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4469 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4471 if (rc) {/* BB add logic to retry regular search if Unix search
4472 rejected unexpectedly by server */
4473 /* BB Add code to handle unsupported level rc */
4474 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4476 cifs_buf_release(pSMB);
4478 /* BB eventually could optimize out free and realloc of buf */
4481 goto findFirstRetry;
4482 } else { /* decode response */
4483 /* BB remember to free buffer if error BB */
4484 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4488 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4489 psrch_inf->unicode = true;
4491 psrch_inf->unicode = false;
4493 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4494 psrch_inf->smallBuf = false;
4495 psrch_inf->srch_entries_start =
4496 (char *) &pSMBr->hdr.Protocol +
4497 le16_to_cpu(pSMBr->t2.DataOffset);
4498 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4499 le16_to_cpu(pSMBr->t2.ParameterOffset));
4501 if (parms->EndofSearch)
4502 psrch_inf->endOfSearch = true;
4504 psrch_inf->endOfSearch = false;
4506 psrch_inf->entries_in_buffer =
4507 le16_to_cpu(parms->SearchCount);
4508 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4509 psrch_inf->entries_in_buffer;
4510 lnoff = le16_to_cpu(parms->LastNameOffset);
4511 if (CIFSMaxBufSize < lnoff) {
4512 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4513 psrch_inf->last_entry = NULL;
4517 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4521 *pnetfid = parms->SearchHandle;
4523 cifs_buf_release(pSMB);
4530 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4531 __u16 searchHandle, __u16 search_flags,
4532 struct cifs_search_info *psrch_inf)
4534 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4535 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4536 T2_FNEXT_RSP_PARMS *parms;
4537 char *response_data;
4540 unsigned int name_len;
4541 __u16 params, byte_count;
4543 cifs_dbg(FYI, "In FindNext\n");
4545 if (psrch_inf->endOfSearch)
4548 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4553 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4555 pSMB->TotalDataCount = 0; /* no EAs */
4556 pSMB->MaxParameterCount = cpu_to_le16(8);
4557 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4558 pSMB->MaxSetupCount = 0;
4562 pSMB->Reserved2 = 0;
4563 pSMB->ParameterOffset = cpu_to_le16(
4564 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4565 pSMB->DataCount = 0;
4566 pSMB->DataOffset = 0;
4567 pSMB->SetupCount = 1;
4568 pSMB->Reserved3 = 0;
4569 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4570 pSMB->SearchHandle = searchHandle; /* always kept as le */
4572 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4573 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4574 pSMB->ResumeKey = psrch_inf->resume_key;
4575 pSMB->SearchFlags = cpu_to_le16(search_flags);
4577 name_len = psrch_inf->resume_name_len;
4579 if (name_len < PATH_MAX) {
4580 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4581 byte_count += name_len;
4582 /* 14 byte parm len above enough for 2 byte null terminator */
4583 pSMB->ResumeFileName[name_len] = 0;
4584 pSMB->ResumeFileName[name_len+1] = 0;
4587 goto FNext2_err_exit;
4589 byte_count = params + 1 /* pad */ ;
4590 pSMB->TotalParameterCount = cpu_to_le16(params);
4591 pSMB->ParameterCount = pSMB->TotalParameterCount;
4592 inc_rfc1001_len(pSMB, byte_count);
4593 pSMB->ByteCount = cpu_to_le16(byte_count);
4595 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4596 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4597 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4600 psrch_inf->endOfSearch = true;
4601 cifs_buf_release(pSMB);
4602 rc = 0; /* search probably was closed at end of search*/
4604 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4605 } else { /* decode response */
4606 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4611 /* BB fixme add lock for file (srch_info) struct here */
4612 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4613 psrch_inf->unicode = true;
4615 psrch_inf->unicode = false;
4616 response_data = (char *) &pSMBr->hdr.Protocol +
4617 le16_to_cpu(pSMBr->t2.ParameterOffset);
4618 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4619 response_data = (char *)&pSMBr->hdr.Protocol +
4620 le16_to_cpu(pSMBr->t2.DataOffset);
4621 if (psrch_inf->smallBuf)
4622 cifs_small_buf_release(
4623 psrch_inf->ntwrk_buf_start);
4625 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4626 psrch_inf->srch_entries_start = response_data;
4627 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4628 psrch_inf->smallBuf = false;
4629 if (parms->EndofSearch)
4630 psrch_inf->endOfSearch = true;
4632 psrch_inf->endOfSearch = false;
4633 psrch_inf->entries_in_buffer =
4634 le16_to_cpu(parms->SearchCount);
4635 psrch_inf->index_of_last_entry +=
4636 psrch_inf->entries_in_buffer;
4637 lnoff = le16_to_cpu(parms->LastNameOffset);
4638 if (CIFSMaxBufSize < lnoff) {
4639 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4640 psrch_inf->last_entry = NULL;
4643 psrch_inf->last_entry =
4644 psrch_inf->srch_entries_start + lnoff;
4646 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4647 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4649 /* BB fixme add unlock here */
4654 /* BB On error, should we leave previous search buf (and count and
4655 last entry fields) intact or free the previous one? */
4657 /* Note: On -EAGAIN error only caller can retry on handle based calls
4658 since file handle passed in no longer valid */
4661 cifs_buf_release(pSMB);
4666 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4667 const __u16 searchHandle)
4670 FINDCLOSE_REQ *pSMB = NULL;
4672 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4673 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4675 /* no sense returning error if session restarted
4676 as file handle has been closed */
4682 pSMB->FileID = searchHandle;
4683 pSMB->ByteCount = 0;
4684 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4685 cifs_small_buf_release(pSMB);
4687 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4689 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4691 /* Since session is dead, search handle closed on server already */
4699 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4700 const char *search_name, __u64 *inode_number,
4701 const struct nls_table *nls_codepage, int remap)
4704 TRANSACTION2_QPI_REQ *pSMB = NULL;
4705 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4706 int name_len, bytes_returned;
4707 __u16 params, byte_count;
4709 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4713 GetInodeNumberRetry:
4714 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4719 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4721 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4722 search_name, PATH_MAX, nls_codepage,
4724 name_len++; /* trailing null */
4727 name_len = copy_path_name(pSMB->FileName, search_name);
4730 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4731 pSMB->TotalDataCount = 0;
4732 pSMB->MaxParameterCount = cpu_to_le16(2);
4733 /* BB find exact max data count below from sess structure BB */
4734 pSMB->MaxDataCount = cpu_to_le16(4000);
4735 pSMB->MaxSetupCount = 0;
4739 pSMB->Reserved2 = 0;
4740 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4741 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4742 pSMB->DataCount = 0;
4743 pSMB->DataOffset = 0;
4744 pSMB->SetupCount = 1;
4745 pSMB->Reserved3 = 0;
4746 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4747 byte_count = params + 1 /* pad */ ;
4748 pSMB->TotalParameterCount = cpu_to_le16(params);
4749 pSMB->ParameterCount = pSMB->TotalParameterCount;
4750 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4751 pSMB->Reserved4 = 0;
4752 inc_rfc1001_len(pSMB, byte_count);
4753 pSMB->ByteCount = cpu_to_le16(byte_count);
4755 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4756 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4758 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4760 /* decode response */
4761 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4762 /* BB also check enough total bytes returned */
4763 if (rc || get_bcc(&pSMBr->hdr) < 2)
4764 /* If rc should we check for EOPNOSUPP and
4765 disable the srvino flag? or in caller? */
4766 rc = -EIO; /* bad smb */
4768 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4769 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4770 struct file_internal_info *pfinfo;
4771 /* BB Do we need a cast or hash here ? */
4773 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4775 goto GetInodeNumOut;
4777 pfinfo = (struct file_internal_info *)
4778 (data_offset + (char *) &pSMBr->hdr.Protocol);
4779 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4783 cifs_buf_release(pSMB);
4785 goto GetInodeNumberRetry;
4790 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4791 const char *search_name, struct dfs_info3_param **target_nodes,
4792 unsigned int *num_of_nodes,
4793 const struct nls_table *nls_codepage, int remap)
4795 /* TRANS2_GET_DFS_REFERRAL */
4796 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4797 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4801 __u16 params, byte_count;
4803 *target_nodes = NULL;
4805 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4806 if (ses == NULL || ses->tcon_ipc == NULL)
4810 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4815 /* server pointer checked in called function,
4816 but should never be null here anyway */
4817 pSMB->hdr.Mid = get_next_mid(ses->server);
4818 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4819 pSMB->hdr.Uid = ses->Suid;
4820 if (ses->capabilities & CAP_STATUS32)
4821 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4822 if (ses->capabilities & CAP_DFS)
4823 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4825 if (ses->capabilities & CAP_UNICODE) {
4826 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4828 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4829 search_name, PATH_MAX, nls_codepage,
4831 name_len++; /* trailing null */
4833 } else { /* BB improve the check for buffer overruns BB */
4834 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4837 if (ses->server->sign)
4838 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4840 pSMB->hdr.Uid = ses->Suid;
4842 params = 2 /* level */ + name_len /*includes null */ ;
4843 pSMB->TotalDataCount = 0;
4844 pSMB->DataCount = 0;
4845 pSMB->DataOffset = 0;
4846 pSMB->MaxParameterCount = 0;
4847 /* BB find exact max SMB PDU from sess structure BB */
4848 pSMB->MaxDataCount = cpu_to_le16(4000);
4849 pSMB->MaxSetupCount = 0;
4853 pSMB->Reserved2 = 0;
4854 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4855 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4856 pSMB->SetupCount = 1;
4857 pSMB->Reserved3 = 0;
4858 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4859 byte_count = params + 3 /* pad */ ;
4860 pSMB->ParameterCount = cpu_to_le16(params);
4861 pSMB->TotalParameterCount = pSMB->ParameterCount;
4862 pSMB->MaxReferralLevel = cpu_to_le16(3);
4863 inc_rfc1001_len(pSMB, byte_count);
4864 pSMB->ByteCount = cpu_to_le16(byte_count);
4866 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4867 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4869 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4872 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4874 /* BB Also check if enough total bytes returned? */
4875 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4876 rc = -EIO; /* bad smb */
4880 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4881 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4883 /* parse returned result into more usable form */
4884 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4885 le16_to_cpu(pSMBr->t2.DataCount),
4886 num_of_nodes, target_nodes, nls_codepage,
4888 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4891 cifs_buf_release(pSMB);
4899 /* Query File System Info such as free space to old servers such as Win 9x */
4901 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4902 struct kstatfs *FSData)
4904 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4905 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4906 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4907 FILE_SYSTEM_ALLOC_INFO *response_data;
4909 int bytes_returned = 0;
4910 __u16 params, byte_count;
4912 cifs_dbg(FYI, "OldQFSInfo\n");
4914 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4919 params = 2; /* level */
4920 pSMB->TotalDataCount = 0;
4921 pSMB->MaxParameterCount = cpu_to_le16(2);
4922 pSMB->MaxDataCount = cpu_to_le16(1000);
4923 pSMB->MaxSetupCount = 0;
4927 pSMB->Reserved2 = 0;
4928 byte_count = params + 1 /* pad */ ;
4929 pSMB->TotalParameterCount = cpu_to_le16(params);
4930 pSMB->ParameterCount = pSMB->TotalParameterCount;
4931 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4932 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4933 pSMB->DataCount = 0;
4934 pSMB->DataOffset = 0;
4935 pSMB->SetupCount = 1;
4936 pSMB->Reserved3 = 0;
4937 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4938 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4939 inc_rfc1001_len(pSMB, byte_count);
4940 pSMB->ByteCount = cpu_to_le16(byte_count);
4942 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4943 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4945 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4946 } else { /* decode response */
4947 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4949 if (rc || get_bcc(&pSMBr->hdr) < 18)
4950 rc = -EIO; /* bad smb */
4952 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4953 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4954 get_bcc(&pSMBr->hdr), data_offset);
4956 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4957 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4959 le16_to_cpu(response_data->BytesPerSector) *
4960 le32_to_cpu(response_data->
4961 SectorsPerAllocationUnit);
4963 * much prefer larger but if server doesn't report
4964 * a valid size than 4K is a reasonable minimum
4966 if (FSData->f_bsize < 512)
4967 FSData->f_bsize = 4096;
4970 le32_to_cpu(response_data->TotalAllocationUnits);
4971 FSData->f_bfree = FSData->f_bavail =
4972 le32_to_cpu(response_data->FreeAllocationUnits);
4973 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4974 (unsigned long long)FSData->f_blocks,
4975 (unsigned long long)FSData->f_bfree,
4979 cifs_buf_release(pSMB);
4982 goto oldQFSInfoRetry;
4988 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4989 struct kstatfs *FSData)
4991 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4992 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4993 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4994 FILE_SYSTEM_INFO *response_data;
4996 int bytes_returned = 0;
4997 __u16 params, byte_count;
4999 cifs_dbg(FYI, "In QFSInfo\n");
5001 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5006 params = 2; /* level */
5007 pSMB->TotalDataCount = 0;
5008 pSMB->MaxParameterCount = cpu_to_le16(2);
5009 pSMB->MaxDataCount = cpu_to_le16(1000);
5010 pSMB->MaxSetupCount = 0;
5014 pSMB->Reserved2 = 0;
5015 byte_count = params + 1 /* pad */ ;
5016 pSMB->TotalParameterCount = cpu_to_le16(params);
5017 pSMB->ParameterCount = pSMB->TotalParameterCount;
5018 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5019 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5020 pSMB->DataCount = 0;
5021 pSMB->DataOffset = 0;
5022 pSMB->SetupCount = 1;
5023 pSMB->Reserved3 = 0;
5024 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5025 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5026 inc_rfc1001_len(pSMB, byte_count);
5027 pSMB->ByteCount = cpu_to_le16(byte_count);
5029 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5030 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5032 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5033 } else { /* decode response */
5034 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5036 if (rc || get_bcc(&pSMBr->hdr) < 24)
5037 rc = -EIO; /* bad smb */
5039 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5043 *) (((char *) &pSMBr->hdr.Protocol) +
5046 le32_to_cpu(response_data->BytesPerSector) *
5047 le32_to_cpu(response_data->
5048 SectorsPerAllocationUnit);
5050 * much prefer larger but if server doesn't report
5051 * a valid size than 4K is a reasonable minimum
5053 if (FSData->f_bsize < 512)
5054 FSData->f_bsize = 4096;
5057 le64_to_cpu(response_data->TotalAllocationUnits);
5058 FSData->f_bfree = FSData->f_bavail =
5059 le64_to_cpu(response_data->FreeAllocationUnits);
5060 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5061 (unsigned long long)FSData->f_blocks,
5062 (unsigned long long)FSData->f_bfree,
5066 cifs_buf_release(pSMB);
5075 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5077 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5078 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5079 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5080 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5082 int bytes_returned = 0;
5083 __u16 params, byte_count;
5085 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5087 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5092 params = 2; /* level */
5093 pSMB->TotalDataCount = 0;
5094 pSMB->MaxParameterCount = cpu_to_le16(2);
5095 /* BB find exact max SMB PDU from sess structure BB */
5096 pSMB->MaxDataCount = cpu_to_le16(1000);
5097 pSMB->MaxSetupCount = 0;
5101 pSMB->Reserved2 = 0;
5102 byte_count = params + 1 /* pad */ ;
5103 pSMB->TotalParameterCount = cpu_to_le16(params);
5104 pSMB->ParameterCount = pSMB->TotalParameterCount;
5105 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5106 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5107 pSMB->DataCount = 0;
5108 pSMB->DataOffset = 0;
5109 pSMB->SetupCount = 1;
5110 pSMB->Reserved3 = 0;
5111 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5112 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5113 inc_rfc1001_len(pSMB, byte_count);
5114 pSMB->ByteCount = cpu_to_le16(byte_count);
5116 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5117 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5119 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5120 } else { /* decode response */
5121 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5123 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5124 /* BB also check if enough bytes returned */
5125 rc = -EIO; /* bad smb */
5127 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5129 (FILE_SYSTEM_ATTRIBUTE_INFO
5130 *) (((char *) &pSMBr->hdr.Protocol) +
5132 memcpy(&tcon->fsAttrInfo, response_data,
5133 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5136 cifs_buf_release(pSMB);
5139 goto QFSAttributeRetry;
5145 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5147 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5148 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5149 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5150 FILE_SYSTEM_DEVICE_INFO *response_data;
5152 int bytes_returned = 0;
5153 __u16 params, byte_count;
5155 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5157 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5162 params = 2; /* level */
5163 pSMB->TotalDataCount = 0;
5164 pSMB->MaxParameterCount = cpu_to_le16(2);
5165 /* BB find exact max SMB PDU from sess structure BB */
5166 pSMB->MaxDataCount = cpu_to_le16(1000);
5167 pSMB->MaxSetupCount = 0;
5171 pSMB->Reserved2 = 0;
5172 byte_count = params + 1 /* pad */ ;
5173 pSMB->TotalParameterCount = cpu_to_le16(params);
5174 pSMB->ParameterCount = pSMB->TotalParameterCount;
5175 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5176 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5178 pSMB->DataCount = 0;
5179 pSMB->DataOffset = 0;
5180 pSMB->SetupCount = 1;
5181 pSMB->Reserved3 = 0;
5182 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5183 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5184 inc_rfc1001_len(pSMB, byte_count);
5185 pSMB->ByteCount = cpu_to_le16(byte_count);
5187 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5188 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5190 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5191 } else { /* decode response */
5192 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5194 if (rc || get_bcc(&pSMBr->hdr) <
5195 sizeof(FILE_SYSTEM_DEVICE_INFO))
5196 rc = -EIO; /* bad smb */
5198 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5200 (FILE_SYSTEM_DEVICE_INFO *)
5201 (((char *) &pSMBr->hdr.Protocol) +
5203 memcpy(&tcon->fsDevInfo, response_data,
5204 sizeof(FILE_SYSTEM_DEVICE_INFO));
5207 cifs_buf_release(pSMB);
5210 goto QFSDeviceRetry;
5216 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5218 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5219 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5220 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5221 FILE_SYSTEM_UNIX_INFO *response_data;
5223 int bytes_returned = 0;
5224 __u16 params, byte_count;
5226 cifs_dbg(FYI, "In QFSUnixInfo\n");
5228 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5229 (void **) &pSMB, (void **) &pSMBr);
5233 params = 2; /* level */
5234 pSMB->TotalDataCount = 0;
5235 pSMB->DataCount = 0;
5236 pSMB->DataOffset = 0;
5237 pSMB->MaxParameterCount = cpu_to_le16(2);
5238 /* BB find exact max SMB PDU from sess structure BB */
5239 pSMB->MaxDataCount = cpu_to_le16(100);
5240 pSMB->MaxSetupCount = 0;
5244 pSMB->Reserved2 = 0;
5245 byte_count = params + 1 /* pad */ ;
5246 pSMB->ParameterCount = cpu_to_le16(params);
5247 pSMB->TotalParameterCount = pSMB->ParameterCount;
5248 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5249 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5250 pSMB->SetupCount = 1;
5251 pSMB->Reserved3 = 0;
5252 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5253 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5254 inc_rfc1001_len(pSMB, byte_count);
5255 pSMB->ByteCount = cpu_to_le16(byte_count);
5257 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5258 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5260 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5261 } else { /* decode response */
5262 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5264 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5265 rc = -EIO; /* bad smb */
5267 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5269 (FILE_SYSTEM_UNIX_INFO
5270 *) (((char *) &pSMBr->hdr.Protocol) +
5272 memcpy(&tcon->fsUnixInfo, response_data,
5273 sizeof(FILE_SYSTEM_UNIX_INFO));
5276 cifs_buf_release(pSMB);
5286 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5288 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5289 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5290 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5292 int bytes_returned = 0;
5293 __u16 params, param_offset, offset, byte_count;
5295 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5297 /* BB switch to small buf init to save memory */
5298 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5299 (void **) &pSMB, (void **) &pSMBr);
5303 params = 4; /* 2 bytes zero followed by info level. */
5304 pSMB->MaxSetupCount = 0;
5308 pSMB->Reserved2 = 0;
5309 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5311 offset = param_offset + params;
5313 pSMB->MaxParameterCount = cpu_to_le16(4);
5314 /* BB find exact max SMB PDU from sess structure BB */
5315 pSMB->MaxDataCount = cpu_to_le16(100);
5316 pSMB->SetupCount = 1;
5317 pSMB->Reserved3 = 0;
5318 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5319 byte_count = 1 /* pad */ + params + 12;
5321 pSMB->DataCount = cpu_to_le16(12);
5322 pSMB->ParameterCount = cpu_to_le16(params);
5323 pSMB->TotalDataCount = pSMB->DataCount;
5324 pSMB->TotalParameterCount = pSMB->ParameterCount;
5325 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5326 pSMB->DataOffset = cpu_to_le16(offset);
5330 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5333 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5334 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5335 pSMB->ClientUnixCap = cpu_to_le64(cap);
5337 inc_rfc1001_len(pSMB, byte_count);
5338 pSMB->ByteCount = cpu_to_le16(byte_count);
5340 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5341 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5343 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5344 } else { /* decode response */
5345 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5347 rc = -EIO; /* bad smb */
5349 cifs_buf_release(pSMB);
5352 goto SETFSUnixRetry;
5360 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5361 struct kstatfs *FSData)
5363 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5364 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5365 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5366 FILE_SYSTEM_POSIX_INFO *response_data;
5368 int bytes_returned = 0;
5369 __u16 params, byte_count;
5371 cifs_dbg(FYI, "In QFSPosixInfo\n");
5373 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5378 params = 2; /* level */
5379 pSMB->TotalDataCount = 0;
5380 pSMB->DataCount = 0;
5381 pSMB->DataOffset = 0;
5382 pSMB->MaxParameterCount = cpu_to_le16(2);
5383 /* BB find exact max SMB PDU from sess structure BB */
5384 pSMB->MaxDataCount = cpu_to_le16(100);
5385 pSMB->MaxSetupCount = 0;
5389 pSMB->Reserved2 = 0;
5390 byte_count = params + 1 /* pad */ ;
5391 pSMB->ParameterCount = cpu_to_le16(params);
5392 pSMB->TotalParameterCount = pSMB->ParameterCount;
5393 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5394 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5395 pSMB->SetupCount = 1;
5396 pSMB->Reserved3 = 0;
5397 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5398 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5399 inc_rfc1001_len(pSMB, byte_count);
5400 pSMB->ByteCount = cpu_to_le16(byte_count);
5402 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5403 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5405 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5406 } else { /* decode response */
5407 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5409 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5410 rc = -EIO; /* bad smb */
5412 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5414 (FILE_SYSTEM_POSIX_INFO
5415 *) (((char *) &pSMBr->hdr.Protocol) +
5418 le32_to_cpu(response_data->BlockSize);
5420 * much prefer larger but if server doesn't report
5421 * a valid size than 4K is a reasonable minimum
5423 if (FSData->f_bsize < 512)
5424 FSData->f_bsize = 4096;
5427 le64_to_cpu(response_data->TotalBlocks);
5429 le64_to_cpu(response_data->BlocksAvail);
5430 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5431 FSData->f_bavail = FSData->f_bfree;
5434 le64_to_cpu(response_data->UserBlocksAvail);
5436 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5438 le64_to_cpu(response_data->TotalFileNodes);
5439 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5441 le64_to_cpu(response_data->FreeFileNodes);
5444 cifs_buf_release(pSMB);
5454 * We can not use write of zero bytes trick to set file size due to need for
5455 * large file support. Also note that this SetPathInfo is preferred to
5456 * SetFileInfo based method in next routine which is only needed to work around
5457 * a sharing violation bugin Samba which this routine can run into.
5460 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5461 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5462 bool set_allocation)
5464 struct smb_com_transaction2_spi_req *pSMB = NULL;
5465 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5466 struct file_end_of_file_info *parm_data;
5469 int bytes_returned = 0;
5470 int remap = cifs_remap(cifs_sb);
5472 __u16 params, byte_count, data_count, param_offset, offset;
5474 cifs_dbg(FYI, "In SetEOF\n");
5476 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5481 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5483 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5484 PATH_MAX, cifs_sb->local_nls, remap);
5485 name_len++; /* trailing null */
5488 name_len = copy_path_name(pSMB->FileName, file_name);
5490 params = 6 + name_len;
5491 data_count = sizeof(struct file_end_of_file_info);
5492 pSMB->MaxParameterCount = cpu_to_le16(2);
5493 pSMB->MaxDataCount = cpu_to_le16(4100);
5494 pSMB->MaxSetupCount = 0;
5498 pSMB->Reserved2 = 0;
5499 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5500 InformationLevel) - 4;
5501 offset = param_offset + params;
5502 if (set_allocation) {
5503 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5504 pSMB->InformationLevel =
5505 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5507 pSMB->InformationLevel =
5508 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5509 } else /* Set File Size */ {
5510 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5511 pSMB->InformationLevel =
5512 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5514 pSMB->InformationLevel =
5515 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5519 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5521 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5522 pSMB->DataOffset = cpu_to_le16(offset);
5523 pSMB->SetupCount = 1;
5524 pSMB->Reserved3 = 0;
5525 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5526 byte_count = 3 /* pad */ + params + data_count;
5527 pSMB->DataCount = cpu_to_le16(data_count);
5528 pSMB->TotalDataCount = pSMB->DataCount;
5529 pSMB->ParameterCount = cpu_to_le16(params);
5530 pSMB->TotalParameterCount = pSMB->ParameterCount;
5531 pSMB->Reserved4 = 0;
5532 inc_rfc1001_len(pSMB, byte_count);
5533 parm_data->FileSize = cpu_to_le64(size);
5534 pSMB->ByteCount = cpu_to_le16(byte_count);
5535 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5536 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5538 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5540 cifs_buf_release(pSMB);
5549 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5550 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5552 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5553 struct file_end_of_file_info *parm_data;
5555 __u16 params, param_offset, offset, byte_count, count;
5557 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5559 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5564 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5565 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5568 pSMB->MaxSetupCount = 0;
5572 pSMB->Reserved2 = 0;
5573 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5574 offset = param_offset + params;
5576 count = sizeof(struct file_end_of_file_info);
5577 pSMB->MaxParameterCount = cpu_to_le16(2);
5578 /* BB find exact max SMB PDU from sess structure BB */
5579 pSMB->MaxDataCount = cpu_to_le16(1000);
5580 pSMB->SetupCount = 1;
5581 pSMB->Reserved3 = 0;
5582 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5583 byte_count = 3 /* pad */ + params + count;
5584 pSMB->DataCount = cpu_to_le16(count);
5585 pSMB->ParameterCount = cpu_to_le16(params);
5586 pSMB->TotalDataCount = pSMB->DataCount;
5587 pSMB->TotalParameterCount = pSMB->ParameterCount;
5588 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5589 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5591 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5592 pSMB->DataOffset = cpu_to_le16(offset);
5593 parm_data->FileSize = cpu_to_le64(size);
5594 pSMB->Fid = cfile->fid.netfid;
5595 if (set_allocation) {
5596 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5597 pSMB->InformationLevel =
5598 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5600 pSMB->InformationLevel =
5601 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5602 } else /* Set File Size */ {
5603 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5604 pSMB->InformationLevel =
5605 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5607 pSMB->InformationLevel =
5608 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5610 pSMB->Reserved4 = 0;
5611 inc_rfc1001_len(pSMB, byte_count);
5612 pSMB->ByteCount = cpu_to_le16(byte_count);
5613 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5614 cifs_small_buf_release(pSMB);
5616 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5620 /* Note: On -EAGAIN error only caller can retry on handle based calls
5621 since file handle passed in no longer valid */
5626 /* Some legacy servers such as NT4 require that the file times be set on
5627 an open handle, rather than by pathname - this is awkward due to
5628 potential access conflicts on the open, but it is unavoidable for these
5629 old servers since the only other choice is to go from 100 nanosecond DCE
5630 time and resort to the original setpathinfo level which takes the ancient
5631 DOS time format with 2 second granularity */
5633 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5634 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5636 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5639 __u16 params, param_offset, offset, byte_count, count;
5641 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5642 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5647 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5648 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5651 pSMB->MaxSetupCount = 0;
5655 pSMB->Reserved2 = 0;
5656 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5657 offset = param_offset + params;
5659 data_offset = (char *)pSMB +
5660 offsetof(struct smb_hdr, Protocol) + offset;
5662 count = sizeof(FILE_BASIC_INFO);
5663 pSMB->MaxParameterCount = cpu_to_le16(2);
5664 /* BB find max SMB PDU from sess */
5665 pSMB->MaxDataCount = cpu_to_le16(1000);
5666 pSMB->SetupCount = 1;
5667 pSMB->Reserved3 = 0;
5668 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5669 byte_count = 3 /* pad */ + params + count;
5670 pSMB->DataCount = cpu_to_le16(count);
5671 pSMB->ParameterCount = cpu_to_le16(params);
5672 pSMB->TotalDataCount = pSMB->DataCount;
5673 pSMB->TotalParameterCount = pSMB->ParameterCount;
5674 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5675 pSMB->DataOffset = cpu_to_le16(offset);
5677 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5678 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5680 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5681 pSMB->Reserved4 = 0;
5682 inc_rfc1001_len(pSMB, byte_count);
5683 pSMB->ByteCount = cpu_to_le16(byte_count);
5684 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5685 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5686 cifs_small_buf_release(pSMB);
5688 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5691 /* Note: On -EAGAIN error only caller can retry on handle based calls
5692 since file handle passed in no longer valid */
5698 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5699 bool delete_file, __u16 fid, __u32 pid_of_opener)
5701 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5704 __u16 params, param_offset, offset, byte_count, count;
5706 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5707 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5712 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5713 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5716 pSMB->MaxSetupCount = 0;
5720 pSMB->Reserved2 = 0;
5721 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5722 offset = param_offset + params;
5724 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5725 data_offset = (char *)(pSMB) + offset + 4;
5728 pSMB->MaxParameterCount = cpu_to_le16(2);
5729 /* BB find max SMB PDU from sess */
5730 pSMB->MaxDataCount = cpu_to_le16(1000);
5731 pSMB->SetupCount = 1;
5732 pSMB->Reserved3 = 0;
5733 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5734 byte_count = 3 /* pad */ + params + count;
5735 pSMB->DataCount = cpu_to_le16(count);
5736 pSMB->ParameterCount = cpu_to_le16(params);
5737 pSMB->TotalDataCount = pSMB->DataCount;
5738 pSMB->TotalParameterCount = pSMB->ParameterCount;
5739 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5740 pSMB->DataOffset = cpu_to_le16(offset);
5742 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5743 pSMB->Reserved4 = 0;
5744 inc_rfc1001_len(pSMB, byte_count);
5745 pSMB->ByteCount = cpu_to_le16(byte_count);
5746 *data_offset = delete_file ? 1 : 0;
5747 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5748 cifs_small_buf_release(pSMB);
5750 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5756 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5757 const char *fileName, const FILE_BASIC_INFO *data,
5758 const struct nls_table *nls_codepage,
5759 struct cifs_sb_info *cifs_sb)
5762 struct cifs_open_parms oparms;
5763 struct cifs_fid fid;
5767 oparms.cifs_sb = cifs_sb;
5768 oparms.desired_access = GENERIC_WRITE;
5769 oparms.create_options = cifs_create_options(cifs_sb, 0);
5770 oparms.disposition = FILE_OPEN;
5771 oparms.path = fileName;
5773 oparms.reconnect = false;
5775 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5779 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5780 CIFSSMBClose(xid, tcon, fid.netfid);
5787 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5788 const char *fileName, const FILE_BASIC_INFO *data,
5789 const struct nls_table *nls_codepage,
5790 struct cifs_sb_info *cifs_sb)
5792 TRANSACTION2_SPI_REQ *pSMB = NULL;
5793 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5796 int bytes_returned = 0;
5798 __u16 params, param_offset, offset, byte_count, count;
5799 int remap = cifs_remap(cifs_sb);
5801 cifs_dbg(FYI, "In SetTimes\n");
5804 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5809 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5811 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5812 PATH_MAX, nls_codepage, remap);
5813 name_len++; /* trailing null */
5816 name_len = copy_path_name(pSMB->FileName, fileName);
5819 params = 6 + name_len;
5820 count = sizeof(FILE_BASIC_INFO);
5821 pSMB->MaxParameterCount = cpu_to_le16(2);
5822 /* BB find max SMB PDU from sess structure BB */
5823 pSMB->MaxDataCount = cpu_to_le16(1000);
5824 pSMB->MaxSetupCount = 0;
5828 pSMB->Reserved2 = 0;
5829 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5830 InformationLevel) - 4;
5831 offset = param_offset + params;
5832 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5833 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5834 pSMB->DataOffset = cpu_to_le16(offset);
5835 pSMB->SetupCount = 1;
5836 pSMB->Reserved3 = 0;
5837 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5838 byte_count = 3 /* pad */ + params + count;
5840 pSMB->DataCount = cpu_to_le16(count);
5841 pSMB->ParameterCount = cpu_to_le16(params);
5842 pSMB->TotalDataCount = pSMB->DataCount;
5843 pSMB->TotalParameterCount = pSMB->ParameterCount;
5844 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5845 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5847 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5848 pSMB->Reserved4 = 0;
5849 inc_rfc1001_len(pSMB, byte_count);
5850 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5851 pSMB->ByteCount = cpu_to_le16(byte_count);
5852 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5853 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5855 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5857 cifs_buf_release(pSMB);
5862 if (rc == -EOPNOTSUPP)
5863 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5864 nls_codepage, cifs_sb);
5870 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5871 const struct cifs_unix_set_info_args *args)
5873 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5874 u64 mode = args->mode;
5876 if (uid_valid(args->uid))
5877 uid = from_kuid(&init_user_ns, args->uid);
5878 if (gid_valid(args->gid))
5879 gid = from_kgid(&init_user_ns, args->gid);
5882 * Samba server ignores set of file size to zero due to bugs in some
5883 * older clients, but we should be precise - we use SetFileSize to
5884 * set file size and do not want to truncate file size to zero
5885 * accidentally as happened on one Samba server beta by putting
5886 * zero instead of -1 here
5888 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5889 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5890 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5891 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5892 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5893 data_offset->Uid = cpu_to_le64(uid);
5894 data_offset->Gid = cpu_to_le64(gid);
5895 /* better to leave device as zero when it is */
5896 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5897 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5898 data_offset->Permissions = cpu_to_le64(mode);
5901 data_offset->Type = cpu_to_le32(UNIX_FILE);
5902 else if (S_ISDIR(mode))
5903 data_offset->Type = cpu_to_le32(UNIX_DIR);
5904 else if (S_ISLNK(mode))
5905 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5906 else if (S_ISCHR(mode))
5907 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5908 else if (S_ISBLK(mode))
5909 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5910 else if (S_ISFIFO(mode))
5911 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5912 else if (S_ISSOCK(mode))
5913 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5917 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5918 const struct cifs_unix_set_info_args *args,
5919 u16 fid, u32 pid_of_opener)
5921 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5924 u16 params, param_offset, offset, byte_count, count;
5926 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5927 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5932 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5933 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5936 pSMB->MaxSetupCount = 0;
5940 pSMB->Reserved2 = 0;
5941 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5942 offset = param_offset + params;
5944 data_offset = (char *)pSMB +
5945 offsetof(struct smb_hdr, Protocol) + offset;
5947 count = sizeof(FILE_UNIX_BASIC_INFO);
5949 pSMB->MaxParameterCount = cpu_to_le16(2);
5950 /* BB find max SMB PDU from sess */
5951 pSMB->MaxDataCount = cpu_to_le16(1000);
5952 pSMB->SetupCount = 1;
5953 pSMB->Reserved3 = 0;
5954 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5955 byte_count = 3 /* pad */ + params + count;
5956 pSMB->DataCount = cpu_to_le16(count);
5957 pSMB->ParameterCount = cpu_to_le16(params);
5958 pSMB->TotalDataCount = pSMB->DataCount;
5959 pSMB->TotalParameterCount = pSMB->ParameterCount;
5960 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5961 pSMB->DataOffset = cpu_to_le16(offset);
5963 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5964 pSMB->Reserved4 = 0;
5965 inc_rfc1001_len(pSMB, byte_count);
5966 pSMB->ByteCount = cpu_to_le16(byte_count);
5968 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5970 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5971 cifs_small_buf_release(pSMB);
5973 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5976 /* Note: On -EAGAIN error only caller can retry on handle based calls
5977 since file handle passed in no longer valid */
5983 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5984 const char *file_name,
5985 const struct cifs_unix_set_info_args *args,
5986 const struct nls_table *nls_codepage, int remap)
5988 TRANSACTION2_SPI_REQ *pSMB = NULL;
5989 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5992 int bytes_returned = 0;
5993 FILE_UNIX_BASIC_INFO *data_offset;
5994 __u16 params, param_offset, offset, count, byte_count;
5996 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5998 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6003 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6005 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6006 PATH_MAX, nls_codepage, remap);
6007 name_len++; /* trailing null */
6010 name_len = copy_path_name(pSMB->FileName, file_name);
6013 params = 6 + name_len;
6014 count = sizeof(FILE_UNIX_BASIC_INFO);
6015 pSMB->MaxParameterCount = cpu_to_le16(2);
6016 /* BB find max SMB PDU from sess structure BB */
6017 pSMB->MaxDataCount = cpu_to_le16(1000);
6018 pSMB->MaxSetupCount = 0;
6022 pSMB->Reserved2 = 0;
6023 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6024 InformationLevel) - 4;
6025 offset = param_offset + params;
6026 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
6027 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
6028 memset(data_offset, 0, count);
6029 pSMB->DataOffset = cpu_to_le16(offset);
6030 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6031 pSMB->SetupCount = 1;
6032 pSMB->Reserved3 = 0;
6033 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6034 byte_count = 3 /* pad */ + params + count;
6035 pSMB->ParameterCount = cpu_to_le16(params);
6036 pSMB->DataCount = cpu_to_le16(count);
6037 pSMB->TotalParameterCount = pSMB->ParameterCount;
6038 pSMB->TotalDataCount = pSMB->DataCount;
6039 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6040 pSMB->Reserved4 = 0;
6041 inc_rfc1001_len(pSMB, byte_count);
6043 cifs_fill_unix_set_info(data_offset, args);
6045 pSMB->ByteCount = cpu_to_le16(byte_count);
6046 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6047 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6049 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6051 cifs_buf_release(pSMB);
6057 #ifdef CONFIG_CIFS_XATTR
6059 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6060 * function used by listxattr and getxattr type calls. When ea_name is set,
6061 * it looks for that attribute name and stuffs that value into the EAData
6062 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6063 * buffer. In both cases, the return value is either the length of the
6064 * resulting data or a negative error code. If EAData is a NULL pointer then
6065 * the data isn't copied to it, but the length is returned.
6068 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6069 const unsigned char *searchName, const unsigned char *ea_name,
6070 char *EAData, size_t buf_size,
6071 struct cifs_sb_info *cifs_sb)
6073 /* BB assumes one setup word */
6074 TRANSACTION2_QPI_REQ *pSMB = NULL;
6075 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6076 int remap = cifs_remap(cifs_sb);
6077 struct nls_table *nls_codepage = cifs_sb->local_nls;
6081 struct fealist *ea_response_data;
6082 struct fea *temp_fea;
6085 __u16 params, byte_count, data_offset;
6086 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6088 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6090 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6095 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6097 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6098 PATH_MAX, nls_codepage, remap);
6099 list_len++; /* trailing null */
6102 list_len = copy_path_name(pSMB->FileName, searchName);
6105 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6106 pSMB->TotalDataCount = 0;
6107 pSMB->MaxParameterCount = cpu_to_le16(2);
6108 /* BB find exact max SMB PDU from sess structure BB */
6109 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6110 pSMB->MaxSetupCount = 0;
6114 pSMB->Reserved2 = 0;
6115 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6116 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6117 pSMB->DataCount = 0;
6118 pSMB->DataOffset = 0;
6119 pSMB->SetupCount = 1;
6120 pSMB->Reserved3 = 0;
6121 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6122 byte_count = params + 1 /* pad */ ;
6123 pSMB->TotalParameterCount = cpu_to_le16(params);
6124 pSMB->ParameterCount = pSMB->TotalParameterCount;
6125 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6126 pSMB->Reserved4 = 0;
6127 inc_rfc1001_len(pSMB, byte_count);
6128 pSMB->ByteCount = cpu_to_le16(byte_count);
6130 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6131 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6133 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6138 /* BB also check enough total bytes returned */
6139 /* BB we need to improve the validity checking
6140 of these trans2 responses */
6142 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6143 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6144 rc = -EIO; /* bad smb */
6148 /* check that length of list is not more than bcc */
6149 /* check that each entry does not go beyond length
6151 /* check that each element of each entry does not
6152 go beyond end of list */
6153 /* validate_trans2_offsets() */
6154 /* BB check if start of smb + data_offset > &bcc+ bcc */
6156 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6157 ea_response_data = (struct fealist *)
6158 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6160 list_len = le32_to_cpu(ea_response_data->list_len);
6161 cifs_dbg(FYI, "ea length %d\n", list_len);
6162 if (list_len <= 8) {
6163 cifs_dbg(FYI, "empty EA list returned from server\n");
6164 /* didn't find the named attribute */
6170 /* make sure list_len doesn't go past end of SMB */
6171 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6172 if ((char *)ea_response_data + list_len > end_of_smb) {
6173 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6178 /* account for ea list len */
6180 temp_fea = ea_response_data->list;
6181 temp_ptr = (char *)temp_fea;
6182 while (list_len > 0) {
6183 unsigned int name_len;
6188 /* make sure we can read name_len and value_len */
6190 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6195 name_len = temp_fea->name_len;
6196 value_len = le16_to_cpu(temp_fea->value_len);
6197 list_len -= name_len + 1 + value_len;
6199 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6205 if (ea_name_len == name_len &&
6206 memcmp(ea_name, temp_ptr, name_len) == 0) {
6207 temp_ptr += name_len + 1;
6211 if ((size_t)value_len > buf_size) {
6215 memcpy(EAData, temp_ptr, value_len);
6219 /* account for prefix user. and trailing null */
6220 rc += (5 + 1 + name_len);
6221 if (rc < (int) buf_size) {
6222 memcpy(EAData, "user.", 5);
6224 memcpy(EAData, temp_ptr, name_len);
6226 /* null terminate name */
6229 } else if (buf_size == 0) {
6230 /* skip copy - calc size only */
6232 /* stop before overrun buffer */
6237 temp_ptr += name_len + 1 + value_len;
6238 temp_fea = (struct fea *)temp_ptr;
6241 /* didn't find the named attribute */
6246 cifs_buf_release(pSMB);
6254 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6255 const char *fileName, const char *ea_name, const void *ea_value,
6256 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6257 struct cifs_sb_info *cifs_sb)
6259 struct smb_com_transaction2_spi_req *pSMB = NULL;
6260 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6261 struct fealist *parm_data;
6264 int bytes_returned = 0;
6265 __u16 params, param_offset, byte_count, offset, count;
6266 int remap = cifs_remap(cifs_sb);
6268 cifs_dbg(FYI, "In SetEA\n");
6270 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6275 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6277 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6278 PATH_MAX, nls_codepage, remap);
6279 name_len++; /* trailing null */
6282 name_len = copy_path_name(pSMB->FileName, fileName);
6285 params = 6 + name_len;
6287 /* done calculating parms using name_len of file name,
6288 now use name_len to calculate length of ea name
6289 we are going to create in the inode xattrs */
6290 if (ea_name == NULL)
6293 name_len = strnlen(ea_name, 255);
6295 count = sizeof(*parm_data) + ea_value_len + name_len;
6296 pSMB->MaxParameterCount = cpu_to_le16(2);
6297 /* BB find max SMB PDU from sess */
6298 pSMB->MaxDataCount = cpu_to_le16(1000);
6299 pSMB->MaxSetupCount = 0;
6303 pSMB->Reserved2 = 0;
6304 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6305 InformationLevel) - 4;
6306 offset = param_offset + params;
6307 pSMB->InformationLevel =
6308 cpu_to_le16(SMB_SET_FILE_EA);
6310 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6311 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6312 pSMB->DataOffset = cpu_to_le16(offset);
6313 pSMB->SetupCount = 1;
6314 pSMB->Reserved3 = 0;
6315 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6316 byte_count = 3 /* pad */ + params + count;
6317 pSMB->DataCount = cpu_to_le16(count);
6318 parm_data->list_len = cpu_to_le32(count);
6319 parm_data->list[0].EA_flags = 0;
6320 /* we checked above that name len is less than 255 */
6321 parm_data->list[0].name_len = (__u8)name_len;
6322 /* EA names are always ASCII */
6324 strncpy(parm_data->list[0].name, ea_name, name_len);
6325 parm_data->list[0].name[name_len] = 0;
6326 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6327 /* caller ensures that ea_value_len is less than 64K but
6328 we need to ensure that it fits within the smb */
6330 /*BB add length check to see if it would fit in
6331 negotiated SMB buffer size BB */
6332 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6334 memcpy(parm_data->list[0].name+name_len+1,
6335 ea_value, ea_value_len);
6337 pSMB->TotalDataCount = pSMB->DataCount;
6338 pSMB->ParameterCount = cpu_to_le16(params);
6339 pSMB->TotalParameterCount = pSMB->ParameterCount;
6340 pSMB->Reserved4 = 0;
6341 inc_rfc1001_len(pSMB, byte_count);
6342 pSMB->ByteCount = cpu_to_le16(byte_count);
6343 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6344 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6346 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6348 cifs_buf_release(pSMB);