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 /* list all files open on tree connection and mark them invalid */
77 spin_lock(&tcon->open_file_lock);
78 list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
79 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
80 open_file->invalidHandle = true;
81 open_file->oplock_break_cancelled = true;
83 spin_unlock(&tcon->open_file_lock);
85 mutex_lock(&tcon->crfid.fid_mutex);
86 tcon->crfid.is_valid = false;
87 /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
88 close_cached_dir_lease_locked(&tcon->crfid);
89 memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
90 mutex_unlock(&tcon->crfid.fid_mutex);
93 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
98 /* reconnect the socket, tcon, and smb session if needed */
100 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
103 struct cifs_ses *ses;
104 struct TCP_Server_Info *server;
105 struct nls_table *nls_codepage;
109 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
110 * tcp and smb session status done differently for those three - in the
117 server = ses->server;
120 * only tree disconnect, open, and write, (and ulogoff which does not
121 * have tcon) are allowed as we start force umount
123 if (tcon->tidStatus == CifsExiting) {
124 if (smb_command != SMB_COM_WRITE_ANDX &&
125 smb_command != SMB_COM_OPEN_ANDX &&
126 smb_command != SMB_COM_TREE_DISCONNECT) {
127 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
133 retries = server->nr_targets;
136 * Give demultiplex thread up to 10 seconds to each target available for
137 * reconnect -- should be greater than cifs socket timeout which is 7
140 while (server->tcpStatus == CifsNeedReconnect) {
141 rc = wait_event_interruptible_timeout(server->response_q,
142 (server->tcpStatus != CifsNeedReconnect),
145 cifs_dbg(FYI, "%s: aborting reconnect due to a received signal by the process\n",
150 /* are we still trying to reconnect? */
151 if (server->tcpStatus != CifsNeedReconnect)
154 if (retries && --retries)
158 * on "soft" mounts we wait once. Hard mounts keep
159 * retrying until process is killed or server comes
163 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
166 retries = server->nr_targets;
169 if (!ses->need_reconnect && !tcon->need_reconnect)
172 nls_codepage = load_nls_default();
175 * need to prevent multiple threads trying to simultaneously
176 * reconnect the same SMB session
178 mutex_lock(&ses->session_mutex);
181 * Recheck after acquire mutex. If another thread is negotiating
182 * and the server never sends an answer the socket will be closed
183 * and tcpStatus set to reconnect.
185 if (server->tcpStatus == CifsNeedReconnect) {
187 mutex_unlock(&ses->session_mutex);
191 rc = cifs_negotiate_protocol(0, ses);
192 if (rc == 0 && ses->need_reconnect)
193 rc = cifs_setup_session(0, ses, nls_codepage);
195 /* do we need to reconnect tcon? */
196 if (rc || !tcon->need_reconnect) {
197 mutex_unlock(&ses->session_mutex);
201 cifs_mark_open_files_invalid(tcon);
202 rc = cifs_tree_connect(0, tcon, nls_codepage);
203 mutex_unlock(&ses->session_mutex);
204 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
207 pr_warn_once("reconnect tcon failed rc = %d\n", rc);
211 atomic_inc(&tconInfoReconnectCount);
213 /* tell server Unix caps we support */
215 reset_cifs_unix_caps(0, tcon, NULL, NULL);
218 * Removed call to reopen open files here. It is safer (and faster) to
219 * reopen files one at a time as needed in read and write.
221 * FIXME: what about file locks? don't we need to reclaim them ASAP?
226 * Check if handle based operation so we know whether we can continue
227 * or not without returning to caller to reset file handle
229 switch (smb_command) {
230 case SMB_COM_READ_ANDX:
231 case SMB_COM_WRITE_ANDX:
233 case SMB_COM_FIND_CLOSE2:
234 case SMB_COM_LOCKING_ANDX:
238 unload_nls(nls_codepage);
242 /* Allocate and return pointer to an SMB request buffer, and set basic
243 SMB information in the SMB header. If the return code is zero, this
244 function must have filled in request_buf pointer */
246 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
251 rc = cifs_reconnect_tcon(tcon, smb_command);
255 *request_buf = cifs_small_buf_get();
256 if (*request_buf == NULL) {
257 /* BB should we add a retry in here if not a writepage? */
261 header_assemble((struct smb_hdr *) *request_buf, smb_command,
265 cifs_stats_inc(&tcon->num_smbs_sent);
271 small_smb_init_no_tc(const int smb_command, const int wct,
272 struct cifs_ses *ses, void **request_buf)
275 struct smb_hdr *buffer;
277 rc = small_smb_init(smb_command, wct, NULL, request_buf);
281 buffer = (struct smb_hdr *)*request_buf;
282 buffer->Mid = get_next_mid(ses->server);
283 if (ses->capabilities & CAP_UNICODE)
284 buffer->Flags2 |= SMBFLG2_UNICODE;
285 if (ses->capabilities & CAP_STATUS32)
286 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
288 /* uid, tid can stay at zero as set in header assemble */
290 /* BB add support for turning on the signing when
291 this function is used after 1st of session setup requests */
296 /* If the return code is zero, this function must fill in request_buf pointer */
298 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
299 void **request_buf, void **response_buf)
301 *request_buf = cifs_buf_get();
302 if (*request_buf == NULL) {
303 /* BB should we add a retry in here if not a writepage? */
306 /* Although the original thought was we needed the response buf for */
307 /* potential retries of smb operations it turns out we can determine */
308 /* from the mid flags when the request buffer can be resent without */
309 /* having to use a second distinct buffer for the response */
311 *response_buf = *request_buf;
313 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
317 cifs_stats_inc(&tcon->num_smbs_sent);
322 /* If the return code is zero, this function must fill in request_buf pointer */
324 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
325 void **request_buf, void **response_buf)
329 rc = cifs_reconnect_tcon(tcon, smb_command);
333 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
337 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
338 void **request_buf, void **response_buf)
340 if (tcon->ses->need_reconnect || tcon->need_reconnect)
343 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
346 static int validate_t2(struct smb_t2_rsp *pSMB)
348 unsigned int total_size;
350 /* check for plausible wct */
351 if (pSMB->hdr.WordCount < 10)
354 /* check for parm and data offset going beyond end of smb */
355 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
356 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
359 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
360 if (total_size >= 512)
363 /* check that bcc is at least as big as parms + data, and that it is
364 * less than negotiated smb buffer
366 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
367 if (total_size > get_bcc(&pSMB->hdr) ||
368 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
373 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
374 sizeof(struct smb_t2_rsp) + 16);
379 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
383 char *guid = pSMBr->u.extended_response.GUID;
384 struct TCP_Server_Info *server = ses->server;
386 count = get_bcc(&pSMBr->hdr);
387 if (count < SMB1_CLIENT_GUID_SIZE)
390 spin_lock(&cifs_tcp_ses_lock);
391 if (server->srv_count > 1) {
392 spin_unlock(&cifs_tcp_ses_lock);
393 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
394 cifs_dbg(FYI, "server UID changed\n");
395 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
398 spin_unlock(&cifs_tcp_ses_lock);
399 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
402 if (count == SMB1_CLIENT_GUID_SIZE) {
403 server->sec_ntlmssp = true;
405 count -= SMB1_CLIENT_GUID_SIZE;
406 rc = decode_negTokenInit(
407 pSMBr->u.extended_response.SecurityBlob, count, server);
416 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
418 bool srv_sign_required = server->sec_mode & server->vals->signing_required;
419 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
420 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
423 * Is signing required by mnt options? If not then check
424 * global_secflags to see if it is there.
426 if (!mnt_sign_required)
427 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
431 * If signing is required then it's automatically enabled too,
432 * otherwise, check to see if the secflags allow it.
434 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
435 (global_secflags & CIFSSEC_MAY_SIGN);
437 /* If server requires signing, does client allow it? */
438 if (srv_sign_required) {
439 if (!mnt_sign_enabled) {
440 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!\n");
446 /* If client requires signing, does server allow it? */
447 if (mnt_sign_required) {
448 if (!srv_sign_enabled) {
449 cifs_dbg(VFS, "Server does not support signing!\n");
455 if (cifs_rdma_enabled(server) && server->sign)
456 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled\n");
462 should_set_ext_sec_flag(enum securityEnum sectype)
469 if (global_secflags &
470 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
479 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
482 NEGOTIATE_RSP *pSMBr;
486 struct TCP_Server_Info *server = ses->server;
490 WARN(1, "%s: server is NULL!\n", __func__);
494 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
495 (void **) &pSMB, (void **) &pSMBr);
499 pSMB->hdr.Mid = get_next_mid(server);
500 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
502 if (should_set_ext_sec_flag(ses->sectype)) {
503 cifs_dbg(FYI, "Requesting extended security\n");
504 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
509 * We know that all the name entries in the protocols array
510 * are short (< 16 bytes anyway) and are NUL terminated.
512 for (i = 0; i < CIFS_NUM_PROT; i++) {
513 size_t len = strlen(protocols[i].name) + 1;
515 memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
518 inc_rfc1001_len(pSMB, count);
519 pSMB->ByteCount = cpu_to_le16(count);
521 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
522 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
526 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
527 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
528 /* Check wct = 1 error case */
529 if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
530 /* core returns wct = 1, but we do not ask for core - otherwise
531 small wct just comes when dialect index is -1 indicating we
532 could not negotiate a common dialect */
535 } else if (pSMBr->hdr.WordCount != 17) {
540 /* else wct == 17, NTLM or better */
542 server->sec_mode = pSMBr->SecurityMode;
543 if ((server->sec_mode & SECMODE_USER) == 0)
544 cifs_dbg(FYI, "share mode security\n");
546 /* one byte, so no need to convert this or EncryptionKeyLen from
548 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
550 set_credits(server, server->maxReq);
551 /* probably no need to store and check maxvcs */
552 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
553 /* set up max_read for readpages check */
554 server->max_read = server->maxBuf;
555 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
556 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
557 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
558 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
559 server->timeAdj *= 60;
561 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
562 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
563 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
564 CIFS_CRYPTO_KEY_SIZE);
565 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
566 server->capabilities & CAP_EXTENDED_SECURITY) {
567 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
568 rc = decode_ext_sec_blob(ses, pSMBr);
569 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
570 rc = -EIO; /* no crypt key only if plain text pwd */
572 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
573 server->capabilities &= ~CAP_EXTENDED_SECURITY;
577 rc = cifs_enable_signing(server, ses->sign);
579 cifs_buf_release(pSMB);
581 cifs_dbg(FYI, "negprot rc %d\n", rc);
586 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
588 struct smb_hdr *smb_buffer;
591 cifs_dbg(FYI, "In tree disconnect\n");
593 /* BB: do we need to check this? These should never be NULL. */
594 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
598 * No need to return error on this operation if tid invalidated and
599 * closed on server already e.g. due to tcp session crashing. Also,
600 * the tcon is no longer on the list, so no need to take lock before
603 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
606 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
607 (void **)&smb_buffer);
611 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
612 cifs_small_buf_release(smb_buffer);
614 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
616 /* No need to return error on this operation if tid invalidated and
617 closed on server already e.g. due to tcp session crashing */
625 * This is a no-op for now. We're not really interested in the reply, but
626 * rather in the fact that the server sent one and that server->lstrp
629 * FIXME: maybe we should consider checking that the reply matches request?
632 cifs_echo_callback(struct mid_q_entry *mid)
634 struct TCP_Server_Info *server = mid->callback_data;
635 struct cifs_credits credits = { .value = 1, .instance = 0 };
637 DeleteMidQEntry(mid);
638 add_credits(server, &credits, CIFS_ECHO_OP);
642 CIFSSMBEcho(struct TCP_Server_Info *server)
647 struct smb_rqst rqst = { .rq_iov = iov,
650 cifs_dbg(FYI, "In echo request\n");
652 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
656 if (server->capabilities & CAP_UNICODE)
657 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
659 /* set up echo request */
660 smb->hdr.Tid = 0xffff;
661 smb->hdr.WordCount = 1;
662 put_unaligned_le16(1, &smb->EchoCount);
663 put_bcc(1, &smb->hdr);
665 inc_rfc1001_len(smb, 3);
668 iov[0].iov_base = smb;
669 iov[1].iov_len = get_rfc1002_length(smb);
670 iov[1].iov_base = (char *)smb + 4;
672 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
673 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
675 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
677 cifs_small_buf_release(smb);
683 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
685 LOGOFF_ANDX_REQ *pSMB;
688 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
691 * BB: do we need to check validity of ses and server? They should
692 * always be valid since we have an active reference. If not, that
693 * should probably be a BUG()
695 if (!ses || !ses->server)
698 mutex_lock(&ses->session_mutex);
699 if (ses->need_reconnect)
700 goto session_already_dead; /* no need to send SMBlogoff if uid
701 already closed due to reconnect */
702 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
704 mutex_unlock(&ses->session_mutex);
708 pSMB->hdr.Mid = get_next_mid(ses->server);
710 if (ses->server->sign)
711 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
713 pSMB->hdr.Uid = ses->Suid;
715 pSMB->AndXCommand = 0xFF;
716 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
717 cifs_small_buf_release(pSMB);
718 session_already_dead:
719 mutex_unlock(&ses->session_mutex);
721 /* if session dead then we do not need to do ulogoff,
722 since server closed smb session, no sense reporting
730 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
731 const char *fileName, __u16 type,
732 const struct nls_table *nls_codepage, int remap)
734 TRANSACTION2_SPI_REQ *pSMB = NULL;
735 TRANSACTION2_SPI_RSP *pSMBr = NULL;
736 struct unlink_psx_rq *pRqD;
739 int bytes_returned = 0;
740 __u16 params, param_offset, offset, byte_count;
742 cifs_dbg(FYI, "In POSIX delete\n");
744 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
749 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
751 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
752 PATH_MAX, nls_codepage, remap);
753 name_len++; /* trailing null */
756 name_len = copy_path_name(pSMB->FileName, fileName);
759 params = 6 + name_len;
760 pSMB->MaxParameterCount = cpu_to_le16(2);
761 pSMB->MaxDataCount = 0; /* BB double check this with jra */
762 pSMB->MaxSetupCount = 0;
767 param_offset = offsetof(struct smb_com_transaction2_spi_req,
768 InformationLevel) - 4;
769 offset = param_offset + params;
771 /* Setup pointer to Request Data (inode type).
772 * Note that SMB offsets are from the beginning of SMB which is 4 bytes
773 * in, after RFC1001 field
775 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
776 pRqD->type = cpu_to_le16(type);
777 pSMB->ParameterOffset = cpu_to_le16(param_offset);
778 pSMB->DataOffset = cpu_to_le16(offset);
779 pSMB->SetupCount = 1;
781 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
782 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
784 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
785 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
786 pSMB->ParameterCount = cpu_to_le16(params);
787 pSMB->TotalParameterCount = pSMB->ParameterCount;
788 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
790 inc_rfc1001_len(pSMB, byte_count);
791 pSMB->ByteCount = cpu_to_le16(byte_count);
792 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
793 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
795 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
796 cifs_buf_release(pSMB);
798 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
807 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
808 struct cifs_sb_info *cifs_sb)
810 DELETE_FILE_REQ *pSMB = NULL;
811 DELETE_FILE_RSP *pSMBr = NULL;
815 int remap = cifs_remap(cifs_sb);
818 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
823 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
824 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
825 PATH_MAX, cifs_sb->local_nls,
827 name_len++; /* trailing null */
830 name_len = copy_path_name(pSMB->fileName, name);
832 pSMB->SearchAttributes =
833 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
834 pSMB->BufferFormat = 0x04;
835 inc_rfc1001_len(pSMB, name_len + 1);
836 pSMB->ByteCount = cpu_to_le16(name_len + 1);
837 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
838 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
839 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
841 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
843 cifs_buf_release(pSMB);
851 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
852 struct cifs_sb_info *cifs_sb)
854 DELETE_DIRECTORY_REQ *pSMB = NULL;
855 DELETE_DIRECTORY_RSP *pSMBr = NULL;
859 int remap = cifs_remap(cifs_sb);
861 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
863 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
868 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
869 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
870 PATH_MAX, cifs_sb->local_nls,
872 name_len++; /* trailing null */
875 name_len = copy_path_name(pSMB->DirName, name);
878 pSMB->BufferFormat = 0x04;
879 inc_rfc1001_len(pSMB, name_len + 1);
880 pSMB->ByteCount = cpu_to_le16(name_len + 1);
881 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
882 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
883 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
885 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
887 cifs_buf_release(pSMB);
894 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
895 struct cifs_tcon *tcon, const char *name,
896 struct cifs_sb_info *cifs_sb)
899 CREATE_DIRECTORY_REQ *pSMB = NULL;
900 CREATE_DIRECTORY_RSP *pSMBr = NULL;
903 int remap = cifs_remap(cifs_sb);
905 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
907 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
912 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
913 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
914 PATH_MAX, cifs_sb->local_nls,
916 name_len++; /* trailing null */
919 name_len = copy_path_name(pSMB->DirName, name);
922 pSMB->BufferFormat = 0x04;
923 inc_rfc1001_len(pSMB, name_len + 1);
924 pSMB->ByteCount = cpu_to_le16(name_len + 1);
925 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
926 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
927 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
929 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
931 cifs_buf_release(pSMB);
938 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
939 __u32 posix_flags, __u64 mode, __u16 *netfid,
940 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
941 const char *name, const struct nls_table *nls_codepage,
944 TRANSACTION2_SPI_REQ *pSMB = NULL;
945 TRANSACTION2_SPI_RSP *pSMBr = NULL;
948 int bytes_returned = 0;
949 __u16 params, param_offset, offset, byte_count, count;
951 OPEN_PSX_RSP *psx_rsp;
953 cifs_dbg(FYI, "In POSIX Create\n");
955 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
960 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
962 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
963 PATH_MAX, nls_codepage, remap);
964 name_len++; /* trailing null */
967 name_len = copy_path_name(pSMB->FileName, name);
970 params = 6 + name_len;
971 count = sizeof(OPEN_PSX_REQ);
972 pSMB->MaxParameterCount = cpu_to_le16(2);
973 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
974 pSMB->MaxSetupCount = 0;
979 param_offset = offsetof(struct smb_com_transaction2_spi_req,
980 InformationLevel) - 4;
981 offset = param_offset + params;
982 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
983 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
984 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
985 pdata->Permissions = cpu_to_le64(mode);
986 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
987 pdata->OpenFlags = cpu_to_le32(*pOplock);
988 pSMB->ParameterOffset = cpu_to_le16(param_offset);
989 pSMB->DataOffset = cpu_to_le16(offset);
990 pSMB->SetupCount = 1;
992 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
993 byte_count = 3 /* pad */ + params + count;
995 pSMB->DataCount = cpu_to_le16(count);
996 pSMB->ParameterCount = cpu_to_le16(params);
997 pSMB->TotalDataCount = pSMB->DataCount;
998 pSMB->TotalParameterCount = pSMB->ParameterCount;
999 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1000 pSMB->Reserved4 = 0;
1001 inc_rfc1001_len(pSMB, byte_count);
1002 pSMB->ByteCount = cpu_to_le16(byte_count);
1003 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1004 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1006 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1007 goto psx_create_err;
1010 cifs_dbg(FYI, "copying inode info\n");
1011 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1013 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1014 rc = -EIO; /* bad smb */
1015 goto psx_create_err;
1018 /* copy return information to pRetData */
1019 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1020 + le16_to_cpu(pSMBr->t2.DataOffset));
1022 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1024 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1025 /* Let caller know file was created so we can set the mode. */
1026 /* Do we care about the CreateAction in any other cases? */
1027 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1028 *pOplock |= CIFS_CREATE_ACTION;
1029 /* check to make sure response data is there */
1030 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1031 pRetData->Type = cpu_to_le32(-1); /* unknown */
1032 cifs_dbg(NOISY, "unknown type\n");
1034 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1035 + sizeof(FILE_UNIX_BASIC_INFO)) {
1036 cifs_dbg(VFS, "Open response data too small\n");
1037 pRetData->Type = cpu_to_le32(-1);
1038 goto psx_create_err;
1040 memcpy((char *) pRetData,
1041 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1042 sizeof(FILE_UNIX_BASIC_INFO));
1046 cifs_buf_release(pSMB);
1048 if (posix_flags & SMB_O_DIRECTORY)
1049 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1051 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1059 static __u16 convert_disposition(int disposition)
1063 switch (disposition) {
1064 case FILE_SUPERSEDE:
1065 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1068 ofun = SMBOPEN_OAPPEND;
1071 ofun = SMBOPEN_OCREATE;
1074 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1076 case FILE_OVERWRITE:
1077 ofun = SMBOPEN_OTRUNC;
1079 case FILE_OVERWRITE_IF:
1080 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1083 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1084 ofun = SMBOPEN_OAPPEND; /* regular open */
1090 access_flags_to_smbopen_mode(const int access_flags)
1092 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1094 if (masked_flags == GENERIC_READ)
1095 return SMBOPEN_READ;
1096 else if (masked_flags == GENERIC_WRITE)
1097 return SMBOPEN_WRITE;
1099 /* just go for read/write */
1100 return SMBOPEN_READWRITE;
1104 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1105 const char *fileName, const int openDisposition,
1106 const int access_flags, const int create_options, __u16 *netfid,
1107 int *pOplock, FILE_ALL_INFO *pfile_info,
1108 const struct nls_table *nls_codepage, int remap)
1111 OPENX_REQ *pSMB = NULL;
1112 OPENX_RSP *pSMBr = NULL;
1118 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1123 pSMB->AndXCommand = 0xFF; /* none */
1125 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1126 count = 1; /* account for one byte pad to word boundary */
1128 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1129 fileName, PATH_MAX, nls_codepage, remap);
1130 name_len++; /* trailing null */
1133 count = 0; /* no pad */
1134 name_len = copy_path_name(pSMB->fileName, fileName);
1136 if (*pOplock & REQ_OPLOCK)
1137 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1138 else if (*pOplock & REQ_BATCHOPLOCK)
1139 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1141 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1142 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1143 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1144 /* set file as system file if special file such
1145 as fifo and server expecting SFU style and
1146 no Unix extensions */
1148 if (create_options & CREATE_OPTION_SPECIAL)
1149 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1150 else /* BB FIXME BB */
1151 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1153 if (create_options & CREATE_OPTION_READONLY)
1154 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1157 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1158 CREATE_OPTIONS_MASK); */
1159 /* BB FIXME END BB */
1161 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1162 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1164 inc_rfc1001_len(pSMB, count);
1166 pSMB->ByteCount = cpu_to_le16(count);
1167 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1168 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1169 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1171 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1173 /* BB verify if wct == 15 */
1175 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1177 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1178 /* Let caller know file was created so we can set the mode. */
1179 /* Do we care about the CreateAction in any other cases? */
1181 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1182 *pOplock |= CIFS_CREATE_ACTION; */
1186 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1187 pfile_info->LastAccessTime = 0; /* BB fixme */
1188 pfile_info->LastWriteTime = 0; /* BB fixme */
1189 pfile_info->ChangeTime = 0; /* BB fixme */
1190 pfile_info->Attributes =
1191 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1192 /* the file_info buf is endian converted by caller */
1193 pfile_info->AllocationSize =
1194 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1195 pfile_info->EndOfFile = pfile_info->AllocationSize;
1196 pfile_info->NumberOfLinks = cpu_to_le32(1);
1197 pfile_info->DeletePending = 0;
1201 cifs_buf_release(pSMB);
1208 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1212 OPEN_REQ *req = NULL;
1213 OPEN_RSP *rsp = NULL;
1217 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1218 struct cifs_tcon *tcon = oparms->tcon;
1219 int remap = cifs_remap(cifs_sb);
1220 const struct nls_table *nls = cifs_sb->local_nls;
1221 int create_options = oparms->create_options;
1222 int desired_access = oparms->desired_access;
1223 int disposition = oparms->disposition;
1224 const char *path = oparms->path;
1227 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1232 /* no commands go after this */
1233 req->AndXCommand = 0xFF;
1235 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1236 /* account for one byte pad to word boundary */
1238 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1239 path, PATH_MAX, nls, remap);
1243 req->NameLength = cpu_to_le16(name_len);
1245 /* BB improve check for buffer overruns BB */
1248 name_len = copy_path_name(req->fileName, path);
1249 req->NameLength = cpu_to_le16(name_len);
1252 if (*oplock & REQ_OPLOCK)
1253 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1254 else if (*oplock & REQ_BATCHOPLOCK)
1255 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1257 req->DesiredAccess = cpu_to_le32(desired_access);
1258 req->AllocationSize = 0;
1261 * Set file as system file if special file such as fifo and server
1262 * expecting SFU style and no Unix extensions.
1264 if (create_options & CREATE_OPTION_SPECIAL)
1265 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1267 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1270 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1271 * sensitive checks for other servers such as Samba.
1273 if (tcon->ses->capabilities & CAP_UNIX)
1274 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1276 if (create_options & CREATE_OPTION_READONLY)
1277 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1279 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1280 req->CreateDisposition = cpu_to_le32(disposition);
1281 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1283 /* BB Expirement with various impersonation levels and verify */
1284 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1285 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1288 inc_rfc1001_len(req, count);
1290 req->ByteCount = cpu_to_le16(count);
1291 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1292 (struct smb_hdr *)rsp, &bytes_returned, 0);
1293 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1295 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1296 cifs_buf_release(req);
1302 /* 1 byte no need to le_to_cpu */
1303 *oplock = rsp->OplockLevel;
1304 /* cifs fid stays in le */
1305 oparms->fid->netfid = rsp->Fid;
1306 oparms->fid->access = desired_access;
1308 /* Let caller know file was created so we can set the mode. */
1309 /* Do we care about the CreateAction in any other cases? */
1310 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1311 *oplock |= CIFS_CREATE_ACTION;
1314 /* copy from CreationTime to Attributes */
1315 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1316 /* the file_info buf is endian converted by caller */
1317 buf->AllocationSize = rsp->AllocationSize;
1318 buf->EndOfFile = rsp->EndOfFile;
1319 buf->NumberOfLinks = cpu_to_le32(1);
1320 buf->DeletePending = 0;
1323 cifs_buf_release(req);
1328 * Discard any remaining data in the current SMB. To do this, we borrow the
1332 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1334 unsigned int rfclen = server->pdu_size;
1335 int remaining = rfclen + server->vals->header_preamble_size -
1338 while (remaining > 0) {
1341 length = cifs_discard_from_socket(server,
1342 min_t(size_t, remaining,
1343 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1346 server->total_read += length;
1347 remaining -= length;
1354 __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
1359 length = cifs_discard_remaining_data(server);
1360 dequeue_mid(mid, malformed);
1361 mid->resp_buf = server->smallbuf;
1362 server->smallbuf = NULL;
1367 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1369 struct cifs_readdata *rdata = mid->callback_data;
1371 return __cifs_readv_discard(server, mid, rdata->result);
1375 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1378 unsigned int data_offset, data_len;
1379 struct cifs_readdata *rdata = mid->callback_data;
1380 char *buf = server->smallbuf;
1381 unsigned int buflen = server->pdu_size +
1382 server->vals->header_preamble_size;
1383 bool use_rdma_mr = false;
1385 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1386 __func__, mid->mid, rdata->offset, rdata->bytes);
1389 * read the rest of READ_RSP header (sans Data array), or whatever we
1390 * can if there's not enough data. At this point, we've read down to
1393 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1394 HEADER_SIZE(server) + 1;
1396 length = cifs_read_from_socket(server,
1397 buf + HEADER_SIZE(server) - 1, len);
1400 server->total_read += length;
1402 if (server->ops->is_session_expired &&
1403 server->ops->is_session_expired(buf)) {
1404 cifs_reconnect(server);
1408 if (server->ops->is_status_pending &&
1409 server->ops->is_status_pending(buf, server)) {
1410 cifs_discard_remaining_data(server);
1414 /* set up first two iov for signature check and to get credits */
1415 rdata->iov[0].iov_base = buf;
1416 rdata->iov[0].iov_len = server->vals->header_preamble_size;
1417 rdata->iov[1].iov_base = buf + server->vals->header_preamble_size;
1418 rdata->iov[1].iov_len =
1419 server->total_read - server->vals->header_preamble_size;
1420 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1421 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1422 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
1423 rdata->iov[1].iov_base, rdata->iov[1].iov_len);
1425 /* Was the SMB read successful? */
1426 rdata->result = server->ops->map_error(buf, false);
1427 if (rdata->result != 0) {
1428 cifs_dbg(FYI, "%s: server returned error %d\n",
1429 __func__, rdata->result);
1430 /* normal error on read response */
1431 return __cifs_readv_discard(server, mid, false);
1434 /* Is there enough to get to the rest of the READ_RSP header? */
1435 if (server->total_read < server->vals->read_rsp_size) {
1436 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1437 __func__, server->total_read,
1438 server->vals->read_rsp_size);
1439 rdata->result = -EIO;
1440 return cifs_readv_discard(server, mid);
1443 data_offset = server->ops->read_data_offset(buf) +
1444 server->vals->header_preamble_size;
1445 if (data_offset < server->total_read) {
1447 * win2k8 sometimes sends an offset of 0 when the read
1448 * is beyond the EOF. Treat it as if the data starts just after
1451 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1452 __func__, data_offset);
1453 data_offset = server->total_read;
1454 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1455 /* data_offset is beyond the end of smallbuf */
1456 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1457 __func__, data_offset);
1458 rdata->result = -EIO;
1459 return cifs_readv_discard(server, mid);
1462 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1463 __func__, server->total_read, data_offset);
1465 len = data_offset - server->total_read;
1467 /* read any junk before data into the rest of smallbuf */
1468 length = cifs_read_from_socket(server,
1469 buf + server->total_read, len);
1472 server->total_read += length;
1475 /* how much data is in the response? */
1476 #ifdef CONFIG_CIFS_SMB_DIRECT
1477 use_rdma_mr = rdata->mr;
1479 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1480 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1481 /* data_len is corrupt -- discard frame */
1482 rdata->result = -EIO;
1483 return cifs_readv_discard(server, mid);
1486 length = rdata->read_into_pages(server, rdata, data_len);
1490 server->total_read += length;
1492 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1493 server->total_read, buflen, data_len);
1495 /* discard anything left over */
1496 if (server->total_read < buflen)
1497 return cifs_readv_discard(server, mid);
1499 dequeue_mid(mid, false);
1500 mid->resp_buf = server->smallbuf;
1501 server->smallbuf = NULL;
1506 cifs_readv_callback(struct mid_q_entry *mid)
1508 struct cifs_readdata *rdata = mid->callback_data;
1509 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1510 struct TCP_Server_Info *server = tcon->ses->server;
1511 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1513 .rq_pages = rdata->pages,
1514 .rq_offset = rdata->page_offset,
1515 .rq_npages = rdata->nr_pages,
1516 .rq_pagesz = rdata->pagesz,
1517 .rq_tailsz = rdata->tailsz };
1518 struct cifs_credits credits = { .value = 1, .instance = 0 };
1520 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1521 __func__, mid->mid, mid->mid_state, rdata->result,
1524 switch (mid->mid_state) {
1525 case MID_RESPONSE_RECEIVED:
1526 /* result already set, check signature */
1530 rc = cifs_verify_signature(&rqst, server,
1531 mid->sequence_number);
1533 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1536 /* FIXME: should this be counted toward the initiating task? */
1537 task_io_account_read(rdata->got_bytes);
1538 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1540 case MID_REQUEST_SUBMITTED:
1541 case MID_RETRY_NEEDED:
1542 rdata->result = -EAGAIN;
1543 if (server->sign && rdata->got_bytes)
1544 /* reset bytes number since we can not check a sign */
1545 rdata->got_bytes = 0;
1546 /* FIXME: should this be counted toward the initiating task? */
1547 task_io_account_read(rdata->got_bytes);
1548 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1551 rdata->result = -EIO;
1554 queue_work(cifsiod_wq, &rdata->work);
1555 DeleteMidQEntry(mid);
1556 add_credits(server, &credits, 0);
1559 /* cifs_async_readv - send an async write, and set up mid to handle result */
1561 cifs_async_readv(struct cifs_readdata *rdata)
1564 READ_REQ *smb = NULL;
1566 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1567 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1570 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1571 __func__, rdata->offset, rdata->bytes);
1573 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1576 wct = 10; /* old style read */
1577 if ((rdata->offset >> 32) > 0) {
1578 /* can not handle this big offset for old */
1583 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1587 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1588 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1590 smb->AndXCommand = 0xFF; /* none */
1591 smb->Fid = rdata->cfile->fid.netfid;
1592 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1594 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1596 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1597 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1601 /* old style read */
1602 struct smb_com_readx_req *smbr =
1603 (struct smb_com_readx_req *)smb;
1604 smbr->ByteCount = 0;
1607 /* 4 for RFC1001 length + 1 for BCC */
1608 rdata->iov[0].iov_base = smb;
1609 rdata->iov[0].iov_len = 4;
1610 rdata->iov[1].iov_base = (char *)smb + 4;
1611 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1613 kref_get(&rdata->refcount);
1614 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1615 cifs_readv_callback, NULL, rdata, 0, NULL);
1618 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1620 kref_put(&rdata->refcount, cifs_readdata_release);
1622 cifs_small_buf_release(smb);
1627 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1628 unsigned int *nbytes, char **buf, int *pbuf_type)
1631 READ_REQ *pSMB = NULL;
1632 READ_RSP *pSMBr = NULL;
1633 char *pReadData = NULL;
1635 int resp_buf_type = 0;
1637 struct kvec rsp_iov;
1638 __u32 pid = io_parms->pid;
1639 __u16 netfid = io_parms->netfid;
1640 __u64 offset = io_parms->offset;
1641 struct cifs_tcon *tcon = io_parms->tcon;
1642 unsigned int count = io_parms->length;
1644 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1645 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1648 wct = 10; /* old style read */
1649 if ((offset >> 32) > 0) {
1650 /* can not handle this big offset for old */
1656 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1660 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1661 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1663 /* tcon and ses pointer are checked in smb_init */
1664 if (tcon->ses->server == NULL)
1665 return -ECONNABORTED;
1667 pSMB->AndXCommand = 0xFF; /* none */
1669 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1671 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1673 pSMB->Remaining = 0;
1674 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1675 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1677 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1679 /* old style read */
1680 struct smb_com_readx_req *pSMBW =
1681 (struct smb_com_readx_req *)pSMB;
1682 pSMBW->ByteCount = 0;
1685 iov[0].iov_base = (char *)pSMB;
1686 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1687 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1688 CIFS_LOG_ERROR, &rsp_iov);
1689 cifs_small_buf_release(pSMB);
1690 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1691 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1693 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1695 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1696 data_length = data_length << 16;
1697 data_length += le16_to_cpu(pSMBr->DataLength);
1698 *nbytes = data_length;
1700 /*check that DataLength would not go beyond end of SMB */
1701 if ((data_length > CIFSMaxBufSize)
1702 || (data_length > count)) {
1703 cifs_dbg(FYI, "bad length %d for count %d\n",
1704 data_length, count);
1708 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1709 le16_to_cpu(pSMBr->DataOffset);
1710 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1711 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1713 }*/ /* can not use copy_to_user when using page cache*/
1715 memcpy(*buf, pReadData, data_length);
1720 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1721 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1722 /* return buffer to caller to free */
1723 *buf = rsp_iov.iov_base;
1724 if (resp_buf_type == CIFS_SMALL_BUFFER)
1725 *pbuf_type = CIFS_SMALL_BUFFER;
1726 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1727 *pbuf_type = CIFS_LARGE_BUFFER;
1728 } /* else no valid buffer on return - leave as null */
1730 /* Note: On -EAGAIN error only caller can retry on handle based calls
1731 since file handle passed in no longer valid */
1737 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1738 unsigned int *nbytes, const char *buf)
1741 WRITE_REQ *pSMB = NULL;
1742 WRITE_RSP *pSMBr = NULL;
1743 int bytes_returned, wct;
1746 __u32 pid = io_parms->pid;
1747 __u16 netfid = io_parms->netfid;
1748 __u64 offset = io_parms->offset;
1749 struct cifs_tcon *tcon = io_parms->tcon;
1750 unsigned int count = io_parms->length;
1754 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1755 if (tcon->ses == NULL)
1756 return -ECONNABORTED;
1758 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1762 if ((offset >> 32) > 0) {
1763 /* can not handle big offset for old srv */
1768 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1773 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1774 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1776 /* tcon and ses pointer are checked in smb_init */
1777 if (tcon->ses->server == NULL)
1778 return -ECONNABORTED;
1780 pSMB->AndXCommand = 0xFF; /* none */
1782 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1784 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1786 pSMB->Reserved = 0xFFFFFFFF;
1787 pSMB->WriteMode = 0;
1788 pSMB->Remaining = 0;
1790 /* Can increase buffer size if buffer is big enough in some cases ie we
1791 can send more if LARGE_WRITE_X capability returned by the server and if
1792 our buffer is big enough or if we convert to iovecs on socket writes
1793 and eliminate the copy to the CIFS buffer */
1794 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1795 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1797 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1801 if (bytes_sent > count)
1804 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1806 memcpy(pSMB->Data, buf, bytes_sent);
1807 else if (count != 0) {
1809 cifs_buf_release(pSMB);
1811 } /* else setting file size with write of zero bytes */
1813 byte_count = bytes_sent + 1; /* pad */
1814 else /* wct == 12 */
1815 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1817 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1818 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1819 inc_rfc1001_len(pSMB, byte_count);
1822 pSMB->ByteCount = cpu_to_le16(byte_count);
1823 else { /* old style write has byte count 4 bytes earlier
1825 struct smb_com_writex_req *pSMBW =
1826 (struct smb_com_writex_req *)pSMB;
1827 pSMBW->ByteCount = cpu_to_le16(byte_count);
1830 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1831 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1832 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1834 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1836 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1837 *nbytes = (*nbytes) << 16;
1838 *nbytes += le16_to_cpu(pSMBr->Count);
1841 * Mask off high 16 bits when bytes written as returned by the
1842 * server is greater than bytes requested by the client. Some
1843 * OS/2 servers are known to set incorrect CountHigh values.
1845 if (*nbytes > count)
1849 cifs_buf_release(pSMB);
1851 /* Note: On -EAGAIN error only caller can retry on handle based calls
1852 since file handle passed in no longer valid */
1858 cifs_writedata_release(struct kref *refcount)
1860 struct cifs_writedata *wdata = container_of(refcount,
1861 struct cifs_writedata, refcount);
1862 #ifdef CONFIG_CIFS_SMB_DIRECT
1864 smbd_deregister_mr(wdata->mr);
1870 cifsFileInfo_put(wdata->cfile);
1872 kvfree(wdata->pages);
1877 * Write failed with a retryable error. Resend the write request. It's also
1878 * possible that the page was redirtied so re-clean the page.
1881 cifs_writev_requeue(struct cifs_writedata *wdata)
1884 struct inode *inode = d_inode(wdata->cfile->dentry);
1885 struct TCP_Server_Info *server;
1886 unsigned int rest_len;
1888 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1890 rest_len = wdata->bytes;
1892 struct cifs_writedata *wdata2;
1893 unsigned int j, nr_pages, wsize, tailsz, cur_len;
1895 wsize = server->ops->wp_retry_size(inode);
1896 if (wsize < rest_len) {
1897 nr_pages = wsize / PAGE_SIZE;
1902 cur_len = nr_pages * PAGE_SIZE;
1905 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
1907 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
1910 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
1916 for (j = 0; j < nr_pages; j++) {
1917 wdata2->pages[j] = wdata->pages[i + j];
1918 lock_page(wdata2->pages[j]);
1919 clear_page_dirty_for_io(wdata2->pages[j]);
1922 wdata2->sync_mode = wdata->sync_mode;
1923 wdata2->nr_pages = nr_pages;
1924 wdata2->offset = page_offset(wdata2->pages[0]);
1925 wdata2->pagesz = PAGE_SIZE;
1926 wdata2->tailsz = tailsz;
1927 wdata2->bytes = cur_len;
1929 rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
1931 if (!wdata2->cfile) {
1932 cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
1934 if (!is_retryable_error(rc))
1937 wdata2->pid = wdata2->cfile->pid;
1938 rc = server->ops->async_writev(wdata2,
1939 cifs_writedata_release);
1942 for (j = 0; j < nr_pages; j++) {
1943 unlock_page(wdata2->pages[j]);
1944 if (rc != 0 && !is_retryable_error(rc)) {
1945 SetPageError(wdata2->pages[j]);
1946 end_page_writeback(wdata2->pages[j]);
1947 put_page(wdata2->pages[j]);
1951 kref_put(&wdata2->refcount, cifs_writedata_release);
1953 if (is_retryable_error(rc))
1959 rest_len -= cur_len;
1961 } while (i < wdata->nr_pages);
1963 /* cleanup remaining pages from the original wdata */
1964 for (; i < wdata->nr_pages; i++) {
1965 SetPageError(wdata->pages[i]);
1966 end_page_writeback(wdata->pages[i]);
1967 put_page(wdata->pages[i]);
1970 if (rc != 0 && !is_retryable_error(rc))
1971 mapping_set_error(inode->i_mapping, rc);
1972 kref_put(&wdata->refcount, cifs_writedata_release);
1976 cifs_writev_complete(struct work_struct *work)
1978 struct cifs_writedata *wdata = container_of(work,
1979 struct cifs_writedata, work);
1980 struct inode *inode = d_inode(wdata->cfile->dentry);
1983 if (wdata->result == 0) {
1984 spin_lock(&inode->i_lock);
1985 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
1986 spin_unlock(&inode->i_lock);
1987 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
1989 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
1990 return cifs_writev_requeue(wdata);
1992 for (i = 0; i < wdata->nr_pages; i++) {
1993 struct page *page = wdata->pages[i];
1994 if (wdata->result == -EAGAIN)
1995 __set_page_dirty_nobuffers(page);
1996 else if (wdata->result < 0)
1998 end_page_writeback(page);
1999 cifs_readpage_to_fscache(inode, page);
2002 if (wdata->result != -EAGAIN)
2003 mapping_set_error(inode->i_mapping, wdata->result);
2004 kref_put(&wdata->refcount, cifs_writedata_release);
2007 struct cifs_writedata *
2008 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2010 struct page **pages =
2011 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2013 return cifs_writedata_direct_alloc(pages, complete);
2018 struct cifs_writedata *
2019 cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2021 struct cifs_writedata *wdata;
2023 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2024 if (wdata != NULL) {
2025 wdata->pages = pages;
2026 kref_init(&wdata->refcount);
2027 INIT_LIST_HEAD(&wdata->list);
2028 init_completion(&wdata->done);
2029 INIT_WORK(&wdata->work, complete);
2035 * Check the mid_state and signature on received buffer (if any), and queue the
2036 * workqueue completion task.
2039 cifs_writev_callback(struct mid_q_entry *mid)
2041 struct cifs_writedata *wdata = mid->callback_data;
2042 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2043 unsigned int written;
2044 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2045 struct cifs_credits credits = { .value = 1, .instance = 0 };
2047 switch (mid->mid_state) {
2048 case MID_RESPONSE_RECEIVED:
2049 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2050 if (wdata->result != 0)
2053 written = le16_to_cpu(smb->CountHigh);
2055 written += le16_to_cpu(smb->Count);
2057 * Mask off high 16 bits when bytes written as returned
2058 * by the server is greater than bytes requested by the
2059 * client. OS/2 servers are known to set incorrect
2062 if (written > wdata->bytes)
2065 if (written < wdata->bytes)
2066 wdata->result = -ENOSPC;
2068 wdata->bytes = written;
2070 case MID_REQUEST_SUBMITTED:
2071 case MID_RETRY_NEEDED:
2072 wdata->result = -EAGAIN;
2075 wdata->result = -EIO;
2079 queue_work(cifsiod_wq, &wdata->work);
2080 DeleteMidQEntry(mid);
2081 add_credits(tcon->ses->server, &credits, 0);
2084 /* cifs_async_writev - send an async write, and set up mid to handle result */
2086 cifs_async_writev(struct cifs_writedata *wdata,
2087 void (*release)(struct kref *kref))
2090 WRITE_REQ *smb = NULL;
2092 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2094 struct smb_rqst rqst = { };
2096 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2100 if (wdata->offset >> 32 > 0) {
2101 /* can not handle big offset for old srv */
2106 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2108 goto async_writev_out;
2110 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2111 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2113 smb->AndXCommand = 0xFF; /* none */
2114 smb->Fid = wdata->cfile->fid.netfid;
2115 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2117 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2118 smb->Reserved = 0xFFFFFFFF;
2123 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2125 /* 4 for RFC1001 length + 1 for BCC */
2127 iov[0].iov_base = smb;
2128 iov[1].iov_len = get_rfc1002_length(smb) + 1;
2129 iov[1].iov_base = (char *)smb + 4;
2133 rqst.rq_pages = wdata->pages;
2134 rqst.rq_offset = wdata->page_offset;
2135 rqst.rq_npages = wdata->nr_pages;
2136 rqst.rq_pagesz = wdata->pagesz;
2137 rqst.rq_tailsz = wdata->tailsz;
2139 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2140 wdata->offset, wdata->bytes);
2142 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2143 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2146 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2147 put_bcc(wdata->bytes + 1, &smb->hdr);
2150 struct smb_com_writex_req *smbw =
2151 (struct smb_com_writex_req *)smb;
2152 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2153 put_bcc(wdata->bytes + 5, &smbw->hdr);
2154 iov[1].iov_len += 4; /* pad bigger by four bytes */
2157 kref_get(&wdata->refcount);
2158 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2159 cifs_writev_callback, NULL, wdata, 0, NULL);
2162 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2164 kref_put(&wdata->refcount, release);
2167 cifs_small_buf_release(smb);
2172 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2173 unsigned int *nbytes, struct kvec *iov, int n_vec)
2176 WRITE_REQ *pSMB = NULL;
2179 int resp_buf_type = 0;
2180 __u32 pid = io_parms->pid;
2181 __u16 netfid = io_parms->netfid;
2182 __u64 offset = io_parms->offset;
2183 struct cifs_tcon *tcon = io_parms->tcon;
2184 unsigned int count = io_parms->length;
2185 struct kvec rsp_iov;
2189 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2191 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2195 if ((offset >> 32) > 0) {
2196 /* can not handle big offset for old srv */
2200 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2204 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2205 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2207 /* tcon and ses pointer are checked in smb_init */
2208 if (tcon->ses->server == NULL)
2209 return -ECONNABORTED;
2211 pSMB->AndXCommand = 0xFF; /* none */
2213 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2215 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2216 pSMB->Reserved = 0xFFFFFFFF;
2217 pSMB->WriteMode = 0;
2218 pSMB->Remaining = 0;
2221 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2223 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2224 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2225 /* header + 1 byte pad */
2226 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2228 inc_rfc1001_len(pSMB, count + 1);
2229 else /* wct == 12 */
2230 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2232 pSMB->ByteCount = cpu_to_le16(count + 1);
2233 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2234 struct smb_com_writex_req *pSMBW =
2235 (struct smb_com_writex_req *)pSMB;
2236 pSMBW->ByteCount = cpu_to_le16(count + 5);
2238 iov[0].iov_base = pSMB;
2240 iov[0].iov_len = smb_hdr_len + 4;
2241 else /* wct == 12 pad bigger by four bytes */
2242 iov[0].iov_len = smb_hdr_len + 8;
2244 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2246 cifs_small_buf_release(pSMB);
2247 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2249 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2250 } else if (resp_buf_type == 0) {
2251 /* presumably this can not happen, but best to be safe */
2254 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2255 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2256 *nbytes = (*nbytes) << 16;
2257 *nbytes += le16_to_cpu(pSMBr->Count);
2260 * Mask off high 16 bits when bytes written as returned by the
2261 * server is greater than bytes requested by the client. OS/2
2262 * servers are known to set incorrect CountHigh values.
2264 if (*nbytes > count)
2268 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2270 /* Note: On -EAGAIN error only caller can retry on handle based calls
2271 since file handle passed in no longer valid */
2276 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2277 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2278 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2281 LOCK_REQ *pSMB = NULL;
2283 struct kvec rsp_iov;
2287 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2288 num_lock, num_unlock);
2290 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2295 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2296 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2297 pSMB->LockType = lock_type;
2298 pSMB->AndXCommand = 0xFF; /* none */
2299 pSMB->Fid = netfid; /* netfid stays le */
2301 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2302 inc_rfc1001_len(pSMB, count);
2303 pSMB->ByteCount = cpu_to_le16(count);
2305 iov[0].iov_base = (char *)pSMB;
2306 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2307 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2308 iov[1].iov_base = (char *)buf;
2309 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2311 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2312 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
2313 CIFS_NO_RSP_BUF, &rsp_iov);
2314 cifs_small_buf_release(pSMB);
2316 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2322 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2323 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2324 const __u64 offset, const __u32 numUnlock,
2325 const __u32 numLock, const __u8 lockType,
2326 const bool waitFlag, const __u8 oplock_level)
2329 LOCK_REQ *pSMB = NULL;
2330 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2335 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2336 (int)waitFlag, numLock);
2337 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2342 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2343 /* no response expected */
2344 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
2346 } else if (waitFlag) {
2347 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2348 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2353 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2354 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2355 pSMB->LockType = lockType;
2356 pSMB->OplockLevel = oplock_level;
2357 pSMB->AndXCommand = 0xFF; /* none */
2358 pSMB->Fid = smb_file_id; /* netfid stays le */
2360 if ((numLock != 0) || (numUnlock != 0)) {
2361 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2362 /* BB where to store pid high? */
2363 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2364 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2365 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2366 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2367 count = sizeof(LOCKING_ANDX_RANGE);
2372 inc_rfc1001_len(pSMB, count);
2373 pSMB->ByteCount = cpu_to_le16(count);
2376 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2377 (struct smb_hdr *) pSMB, &bytes_returned);
2379 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2380 cifs_small_buf_release(pSMB);
2381 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2383 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2385 /* Note: On -EAGAIN error only caller can retry on handle based calls
2386 since file handle passed in no longer valid */
2391 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2392 const __u16 smb_file_id, const __u32 netpid,
2393 const loff_t start_offset, const __u64 len,
2394 struct file_lock *pLockData, const __u16 lock_type,
2395 const bool waitFlag)
2397 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2398 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2399 struct cifs_posix_lock *parm_data;
2402 int bytes_returned = 0;
2403 int resp_buf_type = 0;
2404 __u16 params, param_offset, offset, byte_count, count;
2406 struct kvec rsp_iov;
2408 cifs_dbg(FYI, "Posix Lock\n");
2410 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2415 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2418 pSMB->MaxSetupCount = 0;
2421 pSMB->Reserved2 = 0;
2422 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2423 offset = param_offset + params;
2425 count = sizeof(struct cifs_posix_lock);
2426 pSMB->MaxParameterCount = cpu_to_le16(2);
2427 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2428 pSMB->SetupCount = 1;
2429 pSMB->Reserved3 = 0;
2431 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2433 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2434 byte_count = 3 /* pad */ + params + count;
2435 pSMB->DataCount = cpu_to_le16(count);
2436 pSMB->ParameterCount = cpu_to_le16(params);
2437 pSMB->TotalDataCount = pSMB->DataCount;
2438 pSMB->TotalParameterCount = pSMB->ParameterCount;
2439 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2440 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2441 parm_data = (struct cifs_posix_lock *)
2442 (((char *)pSMB) + offset + 4);
2444 parm_data->lock_type = cpu_to_le16(lock_type);
2446 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2447 parm_data->lock_flags = cpu_to_le16(1);
2448 pSMB->Timeout = cpu_to_le32(-1);
2452 parm_data->pid = cpu_to_le32(netpid);
2453 parm_data->start = cpu_to_le64(start_offset);
2454 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2456 pSMB->DataOffset = cpu_to_le16(offset);
2457 pSMB->Fid = smb_file_id;
2458 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2459 pSMB->Reserved4 = 0;
2460 inc_rfc1001_len(pSMB, byte_count);
2461 pSMB->ByteCount = cpu_to_le16(byte_count);
2463 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2464 (struct smb_hdr *) pSMBr, &bytes_returned);
2466 iov[0].iov_base = (char *)pSMB;
2467 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2468 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2469 &resp_buf_type, timeout, &rsp_iov);
2470 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2472 cifs_small_buf_release(pSMB);
2475 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2476 } else if (pLockData) {
2477 /* lock structure can be returned on get */
2480 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2482 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2483 rc = -EIO; /* bad smb */
2486 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2487 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2488 if (data_count < sizeof(struct cifs_posix_lock)) {
2492 parm_data = (struct cifs_posix_lock *)
2493 ((char *)&pSMBr->hdr.Protocol + data_offset);
2494 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2495 pLockData->fl_type = F_UNLCK;
2497 if (parm_data->lock_type ==
2498 cpu_to_le16(CIFS_RDLCK))
2499 pLockData->fl_type = F_RDLCK;
2500 else if (parm_data->lock_type ==
2501 cpu_to_le16(CIFS_WRLCK))
2502 pLockData->fl_type = F_WRLCK;
2504 pLockData->fl_start = le64_to_cpu(parm_data->start);
2505 pLockData->fl_end = pLockData->fl_start +
2506 le64_to_cpu(parm_data->length) - 1;
2507 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2512 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2514 /* Note: On -EAGAIN error only caller can retry on handle based calls
2515 since file handle passed in no longer valid */
2522 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2525 CLOSE_REQ *pSMB = NULL;
2526 cifs_dbg(FYI, "In CIFSSMBClose\n");
2528 /* do not retry on dead session on close */
2529 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2535 pSMB->FileID = (__u16) smb_file_id;
2536 pSMB->LastWriteTime = 0xFFFFFFFF;
2537 pSMB->ByteCount = 0;
2538 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2539 cifs_small_buf_release(pSMB);
2540 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2543 /* EINTR is expected when user ctl-c to kill app */
2544 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2548 /* Since session is dead, file will be closed on server already */
2556 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2559 FLUSH_REQ *pSMB = NULL;
2560 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2562 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2566 pSMB->FileID = (__u16) smb_file_id;
2567 pSMB->ByteCount = 0;
2568 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2569 cifs_small_buf_release(pSMB);
2570 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2572 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2578 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2579 const char *from_name, const char *to_name,
2580 struct cifs_sb_info *cifs_sb)
2583 RENAME_REQ *pSMB = NULL;
2584 RENAME_RSP *pSMBr = NULL;
2586 int name_len, name_len2;
2588 int remap = cifs_remap(cifs_sb);
2590 cifs_dbg(FYI, "In CIFSSMBRename\n");
2592 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2597 pSMB->BufferFormat = 0x04;
2598 pSMB->SearchAttributes =
2599 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2602 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2603 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2604 from_name, PATH_MAX,
2605 cifs_sb->local_nls, remap);
2606 name_len++; /* trailing null */
2608 pSMB->OldFileName[name_len] = 0x04; /* pad */
2609 /* protocol requires ASCII signature byte on Unicode string */
2610 pSMB->OldFileName[name_len + 1] = 0x00;
2612 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2613 to_name, PATH_MAX, cifs_sb->local_nls,
2615 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2616 name_len2 *= 2; /* convert to bytes */
2618 name_len = copy_path_name(pSMB->OldFileName, from_name);
2619 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2620 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2621 name_len2++; /* signature byte */
2624 count = 1 /* 1st signature byte */ + name_len + name_len2;
2625 inc_rfc1001_len(pSMB, count);
2626 pSMB->ByteCount = cpu_to_le16(count);
2628 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2629 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2630 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2632 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2634 cifs_buf_release(pSMB);
2642 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2643 int netfid, const char *target_name,
2644 const struct nls_table *nls_codepage, int remap)
2646 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2647 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2648 struct set_file_rename *rename_info;
2650 char dummy_string[30];
2652 int bytes_returned = 0;
2654 __u16 params, param_offset, offset, count, byte_count;
2656 cifs_dbg(FYI, "Rename to File by handle\n");
2657 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2663 pSMB->MaxSetupCount = 0;
2667 pSMB->Reserved2 = 0;
2668 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2669 offset = param_offset + params;
2671 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2672 data_offset = (char *)(pSMB) + offset + 4;
2673 rename_info = (struct set_file_rename *) data_offset;
2674 pSMB->MaxParameterCount = cpu_to_le16(2);
2675 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2676 pSMB->SetupCount = 1;
2677 pSMB->Reserved3 = 0;
2678 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2679 byte_count = 3 /* pad */ + params;
2680 pSMB->ParameterCount = cpu_to_le16(params);
2681 pSMB->TotalParameterCount = pSMB->ParameterCount;
2682 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2683 pSMB->DataOffset = cpu_to_le16(offset);
2684 /* construct random name ".cifs_tmp<inodenum><mid>" */
2685 rename_info->overwrite = cpu_to_le32(1);
2686 rename_info->root_fid = 0;
2687 /* unicode only call */
2688 if (target_name == NULL) {
2689 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2691 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2692 dummy_string, 24, nls_codepage, remap);
2695 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2696 target_name, PATH_MAX, nls_codepage,
2699 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2700 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2701 byte_count += count;
2702 pSMB->DataCount = cpu_to_le16(count);
2703 pSMB->TotalDataCount = pSMB->DataCount;
2705 pSMB->InformationLevel =
2706 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2707 pSMB->Reserved4 = 0;
2708 inc_rfc1001_len(pSMB, byte_count);
2709 pSMB->ByteCount = cpu_to_le16(byte_count);
2710 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2711 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2712 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2714 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2717 cifs_buf_release(pSMB);
2719 /* Note: On -EAGAIN error only caller can retry on handle based calls
2720 since file handle passed in no longer valid */
2726 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2727 const char *fromName, const __u16 target_tid, const char *toName,
2728 const int flags, const struct nls_table *nls_codepage, int remap)
2731 COPY_REQ *pSMB = NULL;
2732 COPY_RSP *pSMBr = NULL;
2734 int name_len, name_len2;
2737 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2739 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2744 pSMB->BufferFormat = 0x04;
2745 pSMB->Tid2 = target_tid;
2747 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2749 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2750 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2751 fromName, PATH_MAX, nls_codepage,
2753 name_len++; /* trailing null */
2755 pSMB->OldFileName[name_len] = 0x04; /* pad */
2756 /* protocol requires ASCII signature byte on Unicode string */
2757 pSMB->OldFileName[name_len + 1] = 0x00;
2759 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2760 toName, PATH_MAX, nls_codepage, remap);
2761 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2762 name_len2 *= 2; /* convert to bytes */
2764 name_len = copy_path_name(pSMB->OldFileName, fromName);
2765 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2766 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2767 name_len2++; /* signature byte */
2770 count = 1 /* 1st signature byte */ + name_len + name_len2;
2771 inc_rfc1001_len(pSMB, count);
2772 pSMB->ByteCount = cpu_to_le16(count);
2774 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2775 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2777 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2778 rc, le16_to_cpu(pSMBr->CopyCount));
2780 cifs_buf_release(pSMB);
2789 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2790 const char *fromName, const char *toName,
2791 const struct nls_table *nls_codepage, int remap)
2793 TRANSACTION2_SPI_REQ *pSMB = NULL;
2794 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2797 int name_len_target;
2799 int bytes_returned = 0;
2800 __u16 params, param_offset, offset, byte_count;
2802 cifs_dbg(FYI, "In Symlink Unix style\n");
2804 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2809 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2811 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2812 /* find define for this maxpathcomponent */
2813 PATH_MAX, nls_codepage, remap);
2814 name_len++; /* trailing null */
2818 name_len = copy_path_name(pSMB->FileName, fromName);
2820 params = 6 + name_len;
2821 pSMB->MaxSetupCount = 0;
2825 pSMB->Reserved2 = 0;
2826 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2827 InformationLevel) - 4;
2828 offset = param_offset + params;
2830 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2831 data_offset = (char *)pSMB + offset + 4;
2832 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2834 cifsConvertToUTF16((__le16 *) data_offset, toName,
2835 /* find define for this maxpathcomponent */
2836 PATH_MAX, nls_codepage, remap);
2837 name_len_target++; /* trailing null */
2838 name_len_target *= 2;
2840 name_len_target = copy_path_name(data_offset, toName);
2843 pSMB->MaxParameterCount = cpu_to_le16(2);
2844 /* BB find exact max on data count below from sess */
2845 pSMB->MaxDataCount = cpu_to_le16(1000);
2846 pSMB->SetupCount = 1;
2847 pSMB->Reserved3 = 0;
2848 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2849 byte_count = 3 /* pad */ + params + name_len_target;
2850 pSMB->DataCount = cpu_to_le16(name_len_target);
2851 pSMB->ParameterCount = cpu_to_le16(params);
2852 pSMB->TotalDataCount = pSMB->DataCount;
2853 pSMB->TotalParameterCount = pSMB->ParameterCount;
2854 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2855 pSMB->DataOffset = cpu_to_le16(offset);
2856 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2857 pSMB->Reserved4 = 0;
2858 inc_rfc1001_len(pSMB, byte_count);
2859 pSMB->ByteCount = cpu_to_le16(byte_count);
2860 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2861 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2862 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2864 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2867 cifs_buf_release(pSMB);
2870 goto createSymLinkRetry;
2876 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2877 const char *fromName, const char *toName,
2878 const struct nls_table *nls_codepage, int remap)
2880 TRANSACTION2_SPI_REQ *pSMB = NULL;
2881 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2884 int name_len_target;
2886 int bytes_returned = 0;
2887 __u16 params, param_offset, offset, byte_count;
2889 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2890 createHardLinkRetry:
2891 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2896 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2897 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2898 PATH_MAX, nls_codepage, remap);
2899 name_len++; /* trailing null */
2903 name_len = copy_path_name(pSMB->FileName, toName);
2905 params = 6 + name_len;
2906 pSMB->MaxSetupCount = 0;
2910 pSMB->Reserved2 = 0;
2911 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2912 InformationLevel) - 4;
2913 offset = param_offset + params;
2915 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2916 data_offset = (char *)pSMB + offset + 4;
2917 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2919 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2920 PATH_MAX, nls_codepage, remap);
2921 name_len_target++; /* trailing null */
2922 name_len_target *= 2;
2924 name_len_target = copy_path_name(data_offset, fromName);
2927 pSMB->MaxParameterCount = cpu_to_le16(2);
2928 /* BB find exact max on data count below from sess*/
2929 pSMB->MaxDataCount = cpu_to_le16(1000);
2930 pSMB->SetupCount = 1;
2931 pSMB->Reserved3 = 0;
2932 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2933 byte_count = 3 /* pad */ + params + name_len_target;
2934 pSMB->ParameterCount = cpu_to_le16(params);
2935 pSMB->TotalParameterCount = pSMB->ParameterCount;
2936 pSMB->DataCount = cpu_to_le16(name_len_target);
2937 pSMB->TotalDataCount = pSMB->DataCount;
2938 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2939 pSMB->DataOffset = cpu_to_le16(offset);
2940 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2941 pSMB->Reserved4 = 0;
2942 inc_rfc1001_len(pSMB, byte_count);
2943 pSMB->ByteCount = cpu_to_le16(byte_count);
2944 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2945 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2946 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2948 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2951 cifs_buf_release(pSMB);
2953 goto createHardLinkRetry;
2959 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2960 const char *from_name, const char *to_name,
2961 struct cifs_sb_info *cifs_sb)
2964 NT_RENAME_REQ *pSMB = NULL;
2965 RENAME_RSP *pSMBr = NULL;
2967 int name_len, name_len2;
2969 int remap = cifs_remap(cifs_sb);
2971 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2972 winCreateHardLinkRetry:
2974 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2979 pSMB->SearchAttributes =
2980 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2982 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2983 pSMB->ClusterCount = 0;
2985 pSMB->BufferFormat = 0x04;
2987 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2989 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2990 PATH_MAX, cifs_sb->local_nls, remap);
2991 name_len++; /* trailing null */
2994 /* protocol specifies ASCII buffer format (0x04) for unicode */
2995 pSMB->OldFileName[name_len] = 0x04;
2996 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2998 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2999 to_name, PATH_MAX, cifs_sb->local_nls,
3001 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3002 name_len2 *= 2; /* convert to bytes */
3004 name_len = copy_path_name(pSMB->OldFileName, from_name);
3005 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3006 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
3007 name_len2++; /* signature byte */
3010 count = 1 /* string type byte */ + name_len + name_len2;
3011 inc_rfc1001_len(pSMB, count);
3012 pSMB->ByteCount = cpu_to_le16(count);
3014 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3015 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3016 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3018 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3020 cifs_buf_release(pSMB);
3022 goto winCreateHardLinkRetry;
3028 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3029 const unsigned char *searchName, char **symlinkinfo,
3030 const struct nls_table *nls_codepage, int remap)
3032 /* SMB_QUERY_FILE_UNIX_LINK */
3033 TRANSACTION2_QPI_REQ *pSMB = NULL;
3034 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3038 __u16 params, byte_count;
3041 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3044 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3049 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3051 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3052 searchName, PATH_MAX, nls_codepage,
3054 name_len++; /* trailing null */
3057 name_len = copy_path_name(pSMB->FileName, searchName);
3060 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3061 pSMB->TotalDataCount = 0;
3062 pSMB->MaxParameterCount = cpu_to_le16(2);
3063 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3064 pSMB->MaxSetupCount = 0;
3068 pSMB->Reserved2 = 0;
3069 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3070 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3071 pSMB->DataCount = 0;
3072 pSMB->DataOffset = 0;
3073 pSMB->SetupCount = 1;
3074 pSMB->Reserved3 = 0;
3075 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3076 byte_count = params + 1 /* pad */ ;
3077 pSMB->TotalParameterCount = cpu_to_le16(params);
3078 pSMB->ParameterCount = pSMB->TotalParameterCount;
3079 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3080 pSMB->Reserved4 = 0;
3081 inc_rfc1001_len(pSMB, byte_count);
3082 pSMB->ByteCount = cpu_to_le16(byte_count);
3084 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3085 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3087 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3089 /* decode response */
3091 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3092 /* BB also check enough total bytes returned */
3093 if (rc || get_bcc(&pSMBr->hdr) < 2)
3097 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3099 data_start = ((char *) &pSMBr->hdr.Protocol) +
3100 le16_to_cpu(pSMBr->t2.DataOffset);
3102 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3107 /* BB FIXME investigate remapping reserved chars here */
3108 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3109 count, is_unicode, nls_codepage);
3114 cifs_buf_release(pSMB);
3116 goto querySymLinkRetry;
3121 * Recent Windows versions now create symlinks more frequently
3122 * and they use the "reparse point" mechanism below. We can of course
3123 * do symlinks nicely to Samba and other servers which support the
3124 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3125 * "MF" symlinks optionally, but for recent Windows we really need to
3126 * reenable the code below and fix the cifs_symlink callers to handle this.
3127 * In the interim this code has been moved to its own config option so
3128 * it is not compiled in by default until callers fixed up and more tested.
3131 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3132 __u16 fid, char **symlinkinfo,
3133 const struct nls_table *nls_codepage)
3137 struct smb_com_transaction_ioctl_req *pSMB;
3138 struct smb_com_transaction_ioctl_rsp *pSMBr;
3140 unsigned int sub_len;
3142 struct reparse_symlink_data *reparse_buf;
3143 struct reparse_posix_data *posix_buf;
3144 __u32 data_offset, data_count;
3147 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3148 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3153 pSMB->TotalParameterCount = 0 ;
3154 pSMB->TotalDataCount = 0;
3155 pSMB->MaxParameterCount = cpu_to_le32(2);
3156 /* BB find exact data count max from sess structure BB */
3157 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3158 pSMB->MaxSetupCount = 4;
3160 pSMB->ParameterOffset = 0;
3161 pSMB->DataCount = 0;
3162 pSMB->DataOffset = 0;
3163 pSMB->SetupCount = 4;
3164 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3165 pSMB->ParameterCount = pSMB->TotalParameterCount;
3166 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3167 pSMB->IsFsctl = 1; /* FSCTL */
3168 pSMB->IsRootFlag = 0;
3169 pSMB->Fid = fid; /* file handle always le */
3170 pSMB->ByteCount = 0;
3172 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3173 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3175 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3179 data_offset = le32_to_cpu(pSMBr->DataOffset);
3180 data_count = le32_to_cpu(pSMBr->DataCount);
3181 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3182 /* BB also check enough total bytes returned */
3183 rc = -EIO; /* bad smb */
3186 if (!data_count || (data_count > 2048)) {
3188 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3191 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3192 reparse_buf = (struct reparse_symlink_data *)
3193 ((char *)&pSMBr->hdr.Protocol + data_offset);
3194 if ((char *)reparse_buf >= end_of_smb) {
3198 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3199 cifs_dbg(FYI, "NFS style reparse tag\n");
3200 posix_buf = (struct reparse_posix_data *)reparse_buf;
3202 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3203 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3204 le64_to_cpu(posix_buf->InodeType));
3209 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3210 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3211 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3215 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3216 sub_len, is_unicode, nls_codepage);
3218 } else if (reparse_buf->ReparseTag !=
3219 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3224 /* Reparse tag is NTFS symlink */
3225 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3226 reparse_buf->PathBuffer;
3227 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3228 if (sub_start + sub_len > end_of_smb) {
3229 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3233 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3238 /* BB FIXME investigate remapping reserved chars here */
3239 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3244 cifs_buf_release(pSMB);
3247 * Note: On -EAGAIN error only caller can retry on handle based calls
3248 * since file handle passed in no longer valid.
3254 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3259 struct smb_com_transaction_compr_ioctl_req *pSMB;
3260 struct smb_com_transaction_ioctl_rsp *pSMBr;
3262 cifs_dbg(FYI, "Set compression for %u\n", fid);
3263 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3268 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3270 pSMB->TotalParameterCount = 0;
3271 pSMB->TotalDataCount = cpu_to_le32(2);
3272 pSMB->MaxParameterCount = 0;
3273 pSMB->MaxDataCount = 0;
3274 pSMB->MaxSetupCount = 4;
3276 pSMB->ParameterOffset = 0;
3277 pSMB->DataCount = cpu_to_le32(2);
3279 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3280 compression_state) - 4); /* 84 */
3281 pSMB->SetupCount = 4;
3282 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3283 pSMB->ParameterCount = 0;
3284 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3285 pSMB->IsFsctl = 1; /* FSCTL */
3286 pSMB->IsRootFlag = 0;
3287 pSMB->Fid = fid; /* file handle always le */
3288 /* 3 byte pad, followed by 2 byte compress state */
3289 pSMB->ByteCount = cpu_to_le16(5);
3290 inc_rfc1001_len(pSMB, 5);
3292 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3293 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3295 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3297 cifs_buf_release(pSMB);
3300 * Note: On -EAGAIN error only caller can retry on handle based calls
3301 * since file handle passed in no longer valid.
3307 #ifdef CONFIG_CIFS_POSIX
3309 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3310 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3311 struct cifs_posix_ace *cifs_ace)
3313 /* u8 cifs fields do not need le conversion */
3314 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3315 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3316 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3318 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3319 ace->e_perm, ace->e_tag, ace->e_id);
3325 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3326 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3327 const int acl_type, const int size_of_data_area)
3332 struct cifs_posix_ace *pACE;
3333 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3334 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3336 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3339 if (acl_type == ACL_TYPE_ACCESS) {
3340 count = le16_to_cpu(cifs_acl->access_entry_count);
3341 pACE = &cifs_acl->ace_array[0];
3342 size = sizeof(struct cifs_posix_acl);
3343 size += sizeof(struct cifs_posix_ace) * count;
3344 /* check if we would go beyond end of SMB */
3345 if (size_of_data_area < size) {
3346 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3347 size_of_data_area, size);
3350 } else if (acl_type == ACL_TYPE_DEFAULT) {
3351 count = le16_to_cpu(cifs_acl->access_entry_count);
3352 size = sizeof(struct cifs_posix_acl);
3353 size += sizeof(struct cifs_posix_ace) * count;
3354 /* skip past access ACEs to get to default ACEs */
3355 pACE = &cifs_acl->ace_array[count];
3356 count = le16_to_cpu(cifs_acl->default_entry_count);
3357 size += sizeof(struct cifs_posix_ace) * count;
3358 /* check if we would go beyond end of SMB */
3359 if (size_of_data_area < size)
3366 size = posix_acl_xattr_size(count);
3367 if ((buflen == 0) || (local_acl == NULL)) {
3368 /* used to query ACL EA size */
3369 } else if (size > buflen) {
3371 } else /* buffer big enough */ {
3372 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3374 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3375 for (i = 0; i < count ; i++) {
3376 cifs_convert_ace(&ace[i], pACE);
3383 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3384 const struct posix_acl_xattr_entry *local_ace)
3386 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3387 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3388 /* BB is there a better way to handle the large uid? */
3389 if (local_ace->e_id == cpu_to_le32(-1)) {
3390 /* Probably no need to le convert -1 on any arch but can not hurt */
3391 cifs_ace->cifs_uid = cpu_to_le64(-1);
3393 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3395 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3396 ace->e_perm, ace->e_tag, ace->e_id);
3400 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3401 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3402 const int buflen, const int acl_type)
3405 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3406 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3407 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3411 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3414 count = posix_acl_xattr_count((size_t)buflen);
3415 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3416 count, buflen, le32_to_cpu(local_acl->a_version));
3417 if (le32_to_cpu(local_acl->a_version) != 2) {
3418 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3419 le32_to_cpu(local_acl->a_version));
3422 cifs_acl->version = cpu_to_le16(1);
3423 if (acl_type == ACL_TYPE_ACCESS) {
3424 cifs_acl->access_entry_count = cpu_to_le16(count);
3425 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3426 } else if (acl_type == ACL_TYPE_DEFAULT) {
3427 cifs_acl->default_entry_count = cpu_to_le16(count);
3428 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3430 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3433 for (i = 0; i < count; i++)
3434 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3436 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3437 rc += sizeof(struct cifs_posix_acl);
3438 /* BB add check to make sure ACL does not overflow SMB */
3444 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3445 const unsigned char *searchName,
3446 char *acl_inf, const int buflen, const int acl_type,
3447 const struct nls_table *nls_codepage, int remap)
3449 /* SMB_QUERY_POSIX_ACL */
3450 TRANSACTION2_QPI_REQ *pSMB = NULL;
3451 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3455 __u16 params, byte_count;
3457 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3460 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3465 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3467 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3468 searchName, PATH_MAX, nls_codepage,
3470 name_len++; /* trailing null */
3472 pSMB->FileName[name_len] = 0;
3473 pSMB->FileName[name_len+1] = 0;
3475 name_len = copy_path_name(pSMB->FileName, searchName);
3478 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3479 pSMB->TotalDataCount = 0;
3480 pSMB->MaxParameterCount = cpu_to_le16(2);
3481 /* BB find exact max data count below from sess structure BB */
3482 pSMB->MaxDataCount = cpu_to_le16(4000);
3483 pSMB->MaxSetupCount = 0;
3487 pSMB->Reserved2 = 0;
3488 pSMB->ParameterOffset = cpu_to_le16(
3489 offsetof(struct smb_com_transaction2_qpi_req,
3490 InformationLevel) - 4);
3491 pSMB->DataCount = 0;
3492 pSMB->DataOffset = 0;
3493 pSMB->SetupCount = 1;
3494 pSMB->Reserved3 = 0;
3495 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3496 byte_count = params + 1 /* pad */ ;
3497 pSMB->TotalParameterCount = cpu_to_le16(params);
3498 pSMB->ParameterCount = pSMB->TotalParameterCount;
3499 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3500 pSMB->Reserved4 = 0;
3501 inc_rfc1001_len(pSMB, byte_count);
3502 pSMB->ByteCount = cpu_to_le16(byte_count);
3504 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3505 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3506 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3508 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3510 /* decode response */
3512 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3513 /* BB also check enough total bytes returned */
3514 if (rc || get_bcc(&pSMBr->hdr) < 2)
3515 rc = -EIO; /* bad smb */
3517 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3518 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3519 rc = cifs_copy_posix_acl(acl_inf,
3520 (char *)&pSMBr->hdr.Protocol+data_offset,
3521 buflen, acl_type, count);
3524 cifs_buf_release(pSMB);
3531 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3532 const unsigned char *fileName,
3533 const char *local_acl, const int buflen,
3535 const struct nls_table *nls_codepage, int remap)
3537 struct smb_com_transaction2_spi_req *pSMB = NULL;
3538 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3542 int bytes_returned = 0;
3543 __u16 params, byte_count, data_count, param_offset, offset;
3545 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3547 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3551 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3553 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3554 PATH_MAX, nls_codepage, remap);
3555 name_len++; /* trailing null */
3558 name_len = copy_path_name(pSMB->FileName, fileName);
3560 params = 6 + name_len;
3561 pSMB->MaxParameterCount = cpu_to_le16(2);
3562 /* BB find max SMB size from sess */
3563 pSMB->MaxDataCount = cpu_to_le16(1000);
3564 pSMB->MaxSetupCount = 0;
3568 pSMB->Reserved2 = 0;
3569 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3570 InformationLevel) - 4;
3571 offset = param_offset + params;
3572 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3573 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3575 /* convert to on the wire format for POSIX ACL */
3576 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3578 if (data_count == 0) {
3580 goto setACLerrorExit;
3582 pSMB->DataOffset = cpu_to_le16(offset);
3583 pSMB->SetupCount = 1;
3584 pSMB->Reserved3 = 0;
3585 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3586 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3587 byte_count = 3 /* pad */ + params + data_count;
3588 pSMB->DataCount = cpu_to_le16(data_count);
3589 pSMB->TotalDataCount = pSMB->DataCount;
3590 pSMB->ParameterCount = cpu_to_le16(params);
3591 pSMB->TotalParameterCount = pSMB->ParameterCount;
3592 pSMB->Reserved4 = 0;
3593 inc_rfc1001_len(pSMB, byte_count);
3594 pSMB->ByteCount = cpu_to_le16(byte_count);
3595 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3596 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3598 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3601 cifs_buf_release(pSMB);
3607 /* BB fix tabs in this function FIXME BB */
3609 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3610 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3613 struct smb_t2_qfi_req *pSMB = NULL;
3614 struct smb_t2_qfi_rsp *pSMBr = NULL;
3616 __u16 params, byte_count;
3618 cifs_dbg(FYI, "In GetExtAttr\n");
3623 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3628 params = 2 /* level */ + 2 /* fid */;
3629 pSMB->t2.TotalDataCount = 0;
3630 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3631 /* BB find exact max data count below from sess structure BB */
3632 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3633 pSMB->t2.MaxSetupCount = 0;
3634 pSMB->t2.Reserved = 0;
3636 pSMB->t2.Timeout = 0;
3637 pSMB->t2.Reserved2 = 0;
3638 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3640 pSMB->t2.DataCount = 0;
3641 pSMB->t2.DataOffset = 0;
3642 pSMB->t2.SetupCount = 1;
3643 pSMB->t2.Reserved3 = 0;
3644 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3645 byte_count = params + 1 /* pad */ ;
3646 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3647 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3648 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3651 inc_rfc1001_len(pSMB, byte_count);
3652 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3654 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3655 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3657 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3659 /* decode response */
3660 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3661 /* BB also check enough total bytes returned */
3662 if (rc || get_bcc(&pSMBr->hdr) < 2)
3663 /* If rc should we check for EOPNOSUPP and
3664 disable the srvino flag? or in caller? */
3665 rc = -EIO; /* bad smb */
3667 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3668 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3669 struct file_chattr_info *pfinfo;
3670 /* BB Do we need a cast or hash here ? */
3672 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3676 pfinfo = (struct file_chattr_info *)
3677 (data_offset + (char *) &pSMBr->hdr.Protocol);
3678 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3679 *pMask = le64_to_cpu(pfinfo->mask);
3683 cifs_buf_release(pSMB);
3685 goto GetExtAttrRetry;
3689 #endif /* CONFIG_POSIX */
3692 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3693 * all NT TRANSACTS that we init here have total parm and data under about 400
3694 * bytes (to fit in small cifs buffer size), which is the case so far, it
3695 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3696 * returned setup area) and MaxParameterCount (returned parms size) must be set
3700 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3701 const int parm_len, struct cifs_tcon *tcon,
3706 struct smb_com_ntransact_req *pSMB;
3708 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3712 *ret_buf = (void *)pSMB;
3714 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3715 pSMB->TotalDataCount = 0;
3716 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3717 pSMB->ParameterCount = pSMB->TotalParameterCount;
3718 pSMB->DataCount = pSMB->TotalDataCount;
3719 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3720 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3721 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3722 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3723 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3724 pSMB->SubCommand = cpu_to_le16(sub_command);
3729 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3730 __u32 *pparmlen, __u32 *pdatalen)
3733 __u32 data_count, data_offset, parm_count, parm_offset;
3734 struct smb_com_ntransact_rsp *pSMBr;
3743 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3745 bcc = get_bcc(&pSMBr->hdr);
3746 end_of_smb = 2 /* sizeof byte count */ + bcc +
3747 (char *)&pSMBr->ByteCount;
3749 data_offset = le32_to_cpu(pSMBr->DataOffset);
3750 data_count = le32_to_cpu(pSMBr->DataCount);
3751 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3752 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3754 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3755 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3757 /* should we also check that parm and data areas do not overlap? */
3758 if (*ppparm > end_of_smb) {
3759 cifs_dbg(FYI, "parms start after end of smb\n");
3761 } else if (parm_count + *ppparm > end_of_smb) {
3762 cifs_dbg(FYI, "parm end after end of smb\n");
3764 } else if (*ppdata > end_of_smb) {
3765 cifs_dbg(FYI, "data starts after end of smb\n");
3767 } else if (data_count + *ppdata > end_of_smb) {
3768 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3769 *ppdata, data_count, (data_count + *ppdata),
3772 } else if (parm_count + data_count > bcc) {
3773 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3776 *pdatalen = data_count;
3777 *pparmlen = parm_count;
3781 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3783 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3784 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3788 QUERY_SEC_DESC_REQ *pSMB;
3790 struct kvec rsp_iov;
3792 cifs_dbg(FYI, "GetCifsACL\n");
3797 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3798 8 /* parm len */, tcon, (void **) &pSMB);
3802 pSMB->MaxParameterCount = cpu_to_le32(4);
3803 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3804 pSMB->MaxSetupCount = 0;
3805 pSMB->Fid = fid; /* file handle always le */
3806 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3808 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3809 inc_rfc1001_len(pSMB, 11);
3810 iov[0].iov_base = (char *)pSMB;
3811 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3813 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3815 cifs_small_buf_release(pSMB);
3816 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3818 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3819 } else { /* decode response */
3823 struct smb_com_ntransact_rsp *pSMBr;
3826 /* validate_nttransact */
3827 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3828 &pdata, &parm_len, pbuflen);
3831 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3833 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3834 pSMBr, parm, *acl_inf);
3836 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3837 rc = -EIO; /* bad smb */
3842 /* BB check that data area is minimum length and as big as acl_len */
3844 acl_len = le32_to_cpu(*parm);
3845 if (acl_len != *pbuflen) {
3846 cifs_dbg(VFS, "acl length %d does not match %d\n",
3848 if (*pbuflen > acl_len)
3852 /* check if buffer is big enough for the acl
3853 header followed by the smallest SID */
3854 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3855 (*pbuflen >= 64 * 1024)) {
3856 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3860 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3861 if (*acl_inf == NULL) {
3868 free_rsp_buf(buf_type, rsp_iov.iov_base);
3873 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3874 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3876 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3878 int bytes_returned = 0;
3879 SET_SEC_DESC_REQ *pSMB = NULL;
3883 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3887 pSMB->MaxSetupCount = 0;
3891 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3892 data_count = acllen;
3893 data_offset = param_offset + param_count;
3894 byte_count = 3 /* pad */ + param_count;
3896 pSMB->DataCount = cpu_to_le32(data_count);
3897 pSMB->TotalDataCount = pSMB->DataCount;
3898 pSMB->MaxParameterCount = cpu_to_le32(4);
3899 pSMB->MaxDataCount = cpu_to_le32(16384);
3900 pSMB->ParameterCount = cpu_to_le32(param_count);
3901 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3902 pSMB->TotalParameterCount = pSMB->ParameterCount;
3903 pSMB->DataOffset = cpu_to_le32(data_offset);
3904 pSMB->SetupCount = 0;
3905 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3906 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3908 pSMB->Fid = fid; /* file handle always le */
3909 pSMB->Reserved2 = 0;
3910 pSMB->AclFlags = cpu_to_le32(aclflag);
3912 if (pntsd && acllen) {
3913 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3914 data_offset, pntsd, acllen);
3915 inc_rfc1001_len(pSMB, byte_count + data_count);
3917 inc_rfc1001_len(pSMB, byte_count);
3919 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3920 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3922 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3923 bytes_returned, rc);
3925 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3926 cifs_buf_release(pSMB);
3929 goto setCifsAclRetry;
3935 /* Legacy Query Path Information call for lookup to old servers such
3938 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3939 const char *search_name, FILE_ALL_INFO *data,
3940 const struct nls_table *nls_codepage, int remap)
3942 QUERY_INFORMATION_REQ *pSMB;
3943 QUERY_INFORMATION_RSP *pSMBr;
3948 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3950 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3955 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3957 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3958 search_name, PATH_MAX, nls_codepage,
3960 name_len++; /* trailing null */
3963 name_len = copy_path_name(pSMB->FileName, search_name);
3965 pSMB->BufferFormat = 0x04;
3966 name_len++; /* account for buffer type byte */
3967 inc_rfc1001_len(pSMB, (__u16)name_len);
3968 pSMB->ByteCount = cpu_to_le16(name_len);
3970 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3971 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3973 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3975 struct timespec64 ts;
3976 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3978 /* decode response */
3979 /* BB FIXME - add time zone adjustment BB */
3980 memset(data, 0, sizeof(FILE_ALL_INFO));
3983 /* decode time fields */
3984 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3985 data->LastWriteTime = data->ChangeTime;
3986 data->LastAccessTime = 0;
3987 data->AllocationSize =
3988 cpu_to_le64(le32_to_cpu(pSMBr->size));
3989 data->EndOfFile = data->AllocationSize;
3991 cpu_to_le32(le16_to_cpu(pSMBr->attr));
3993 rc = -EIO; /* bad buffer passed in */
3995 cifs_buf_release(pSMB);
4004 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4005 u16 netfid, FILE_ALL_INFO *pFindData)
4007 struct smb_t2_qfi_req *pSMB = NULL;
4008 struct smb_t2_qfi_rsp *pSMBr = NULL;
4011 __u16 params, byte_count;
4014 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4019 params = 2 /* level */ + 2 /* fid */;
4020 pSMB->t2.TotalDataCount = 0;
4021 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4022 /* BB find exact max data count below from sess structure BB */
4023 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4024 pSMB->t2.MaxSetupCount = 0;
4025 pSMB->t2.Reserved = 0;
4027 pSMB->t2.Timeout = 0;
4028 pSMB->t2.Reserved2 = 0;
4029 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4031 pSMB->t2.DataCount = 0;
4032 pSMB->t2.DataOffset = 0;
4033 pSMB->t2.SetupCount = 1;
4034 pSMB->t2.Reserved3 = 0;
4035 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4036 byte_count = params + 1 /* pad */ ;
4037 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4038 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4039 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4042 inc_rfc1001_len(pSMB, byte_count);
4043 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4045 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4046 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4048 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
4049 } else { /* decode response */
4050 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4052 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4054 else if (get_bcc(&pSMBr->hdr) < 40)
4055 rc = -EIO; /* bad smb */
4056 else if (pFindData) {
4057 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4058 memcpy((char *) pFindData,
4059 (char *) &pSMBr->hdr.Protocol +
4060 data_offset, sizeof(FILE_ALL_INFO));
4064 cifs_buf_release(pSMB);
4066 goto QFileInfoRetry;
4072 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4073 const char *search_name, FILE_ALL_INFO *data,
4074 int legacy /* old style infolevel */,
4075 const struct nls_table *nls_codepage, int remap)
4077 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4078 TRANSACTION2_QPI_REQ *pSMB = NULL;
4079 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4083 __u16 params, byte_count;
4085 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4087 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4092 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4094 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4095 PATH_MAX, nls_codepage, remap);
4096 name_len++; /* trailing null */
4099 name_len = copy_path_name(pSMB->FileName, search_name);
4102 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4103 pSMB->TotalDataCount = 0;
4104 pSMB->MaxParameterCount = cpu_to_le16(2);
4105 /* BB find exact max SMB PDU from sess structure BB */
4106 pSMB->MaxDataCount = cpu_to_le16(4000);
4107 pSMB->MaxSetupCount = 0;
4111 pSMB->Reserved2 = 0;
4112 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4113 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4114 pSMB->DataCount = 0;
4115 pSMB->DataOffset = 0;
4116 pSMB->SetupCount = 1;
4117 pSMB->Reserved3 = 0;
4118 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4119 byte_count = params + 1 /* pad */ ;
4120 pSMB->TotalParameterCount = cpu_to_le16(params);
4121 pSMB->ParameterCount = pSMB->TotalParameterCount;
4123 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4125 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4126 pSMB->Reserved4 = 0;
4127 inc_rfc1001_len(pSMB, byte_count);
4128 pSMB->ByteCount = cpu_to_le16(byte_count);
4130 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4131 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4133 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4134 } else { /* decode response */
4135 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4137 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4139 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4140 rc = -EIO; /* bad smb */
4141 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4142 rc = -EIO; /* 24 or 26 expected but we do not read
4146 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4149 * On legacy responses we do not read the last field,
4150 * EAsize, fortunately since it varies by subdialect and
4151 * also note it differs on Set vs Get, ie two bytes or 4
4152 * bytes depending but we don't care here.
4155 size = sizeof(FILE_INFO_STANDARD);
4157 size = sizeof(FILE_ALL_INFO);
4158 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4163 cifs_buf_release(pSMB);
4165 goto QPathInfoRetry;
4171 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4172 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4174 struct smb_t2_qfi_req *pSMB = NULL;
4175 struct smb_t2_qfi_rsp *pSMBr = NULL;
4178 __u16 params, byte_count;
4181 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4186 params = 2 /* level */ + 2 /* fid */;
4187 pSMB->t2.TotalDataCount = 0;
4188 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4189 /* BB find exact max data count below from sess structure BB */
4190 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4191 pSMB->t2.MaxSetupCount = 0;
4192 pSMB->t2.Reserved = 0;
4194 pSMB->t2.Timeout = 0;
4195 pSMB->t2.Reserved2 = 0;
4196 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4198 pSMB->t2.DataCount = 0;
4199 pSMB->t2.DataOffset = 0;
4200 pSMB->t2.SetupCount = 1;
4201 pSMB->t2.Reserved3 = 0;
4202 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4203 byte_count = params + 1 /* pad */ ;
4204 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4205 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4206 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4209 inc_rfc1001_len(pSMB, byte_count);
4210 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4212 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4213 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4215 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
4216 } else { /* decode response */
4217 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4219 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4220 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4221 rc = -EIO; /* bad smb */
4223 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4224 memcpy((char *) pFindData,
4225 (char *) &pSMBr->hdr.Protocol +
4227 sizeof(FILE_UNIX_BASIC_INFO));
4231 cifs_buf_release(pSMB);
4233 goto UnixQFileInfoRetry;
4239 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4240 const unsigned char *searchName,
4241 FILE_UNIX_BASIC_INFO *pFindData,
4242 const struct nls_table *nls_codepage, int remap)
4244 /* SMB_QUERY_FILE_UNIX_BASIC */
4245 TRANSACTION2_QPI_REQ *pSMB = NULL;
4246 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4248 int bytes_returned = 0;
4250 __u16 params, byte_count;
4252 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4254 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4259 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4261 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4262 PATH_MAX, nls_codepage, remap);
4263 name_len++; /* trailing null */
4266 name_len = copy_path_name(pSMB->FileName, searchName);
4269 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4270 pSMB->TotalDataCount = 0;
4271 pSMB->MaxParameterCount = cpu_to_le16(2);
4272 /* BB find exact max SMB PDU from sess structure BB */
4273 pSMB->MaxDataCount = cpu_to_le16(4000);
4274 pSMB->MaxSetupCount = 0;
4278 pSMB->Reserved2 = 0;
4279 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4280 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4281 pSMB->DataCount = 0;
4282 pSMB->DataOffset = 0;
4283 pSMB->SetupCount = 1;
4284 pSMB->Reserved3 = 0;
4285 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4286 byte_count = params + 1 /* pad */ ;
4287 pSMB->TotalParameterCount = cpu_to_le16(params);
4288 pSMB->ParameterCount = pSMB->TotalParameterCount;
4289 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4290 pSMB->Reserved4 = 0;
4291 inc_rfc1001_len(pSMB, byte_count);
4292 pSMB->ByteCount = cpu_to_le16(byte_count);
4294 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4295 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4297 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
4298 } else { /* decode response */
4299 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4301 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4302 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4303 rc = -EIO; /* bad smb */
4305 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4306 memcpy((char *) pFindData,
4307 (char *) &pSMBr->hdr.Protocol +
4309 sizeof(FILE_UNIX_BASIC_INFO));
4312 cifs_buf_release(pSMB);
4314 goto UnixQPathInfoRetry;
4319 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4321 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4322 const char *searchName, struct cifs_sb_info *cifs_sb,
4323 __u16 *pnetfid, __u16 search_flags,
4324 struct cifs_search_info *psrch_inf, bool msearch)
4326 /* level 257 SMB_ */
4327 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4328 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4329 T2_FFIRST_RSP_PARMS *parms;
4331 int bytes_returned = 0;
4332 int name_len, remap;
4333 __u16 params, byte_count;
4334 struct nls_table *nls_codepage;
4336 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4339 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4344 nls_codepage = cifs_sb->local_nls;
4345 remap = cifs_remap(cifs_sb);
4347 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4349 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4350 PATH_MAX, nls_codepage, remap);
4351 /* We can not add the asterik earlier in case
4352 it got remapped to 0xF03A as if it were part of the
4353 directory name instead of a wildcard */
4356 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4357 pSMB->FileName[name_len+1] = 0;
4358 pSMB->FileName[name_len+2] = '*';
4359 pSMB->FileName[name_len+3] = 0;
4360 name_len += 4; /* now the trailing null */
4361 /* null terminate just in case */
4362 pSMB->FileName[name_len] = 0;
4363 pSMB->FileName[name_len+1] = 0;
4367 name_len = copy_path_name(pSMB->FileName, searchName);
4369 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4370 name_len = PATH_MAX-2;
4371 /* overwrite nul byte */
4372 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4373 pSMB->FileName[name_len] = '*';
4374 pSMB->FileName[name_len+1] = 0;
4379 params = 12 + name_len /* includes null */ ;
4380 pSMB->TotalDataCount = 0; /* no EAs */
4381 pSMB->MaxParameterCount = cpu_to_le16(10);
4382 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4383 pSMB->MaxSetupCount = 0;
4387 pSMB->Reserved2 = 0;
4388 byte_count = params + 1 /* pad */ ;
4389 pSMB->TotalParameterCount = cpu_to_le16(params);
4390 pSMB->ParameterCount = pSMB->TotalParameterCount;
4391 pSMB->ParameterOffset = cpu_to_le16(
4392 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4394 pSMB->DataCount = 0;
4395 pSMB->DataOffset = 0;
4396 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4397 pSMB->Reserved3 = 0;
4398 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4399 pSMB->SearchAttributes =
4400 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4402 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4403 pSMB->SearchFlags = cpu_to_le16(search_flags);
4404 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4406 /* BB what should we set StorageType to? Does it matter? BB */
4407 pSMB->SearchStorageType = 0;
4408 inc_rfc1001_len(pSMB, byte_count);
4409 pSMB->ByteCount = cpu_to_le16(byte_count);
4411 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4412 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4413 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4415 if (rc) {/* BB add logic to retry regular search if Unix search
4416 rejected unexpectedly by server */
4417 /* BB Add code to handle unsupported level rc */
4418 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4420 cifs_buf_release(pSMB);
4422 /* BB eventually could optimize out free and realloc of buf */
4425 goto findFirstRetry;
4426 } else { /* decode response */
4427 /* BB remember to free buffer if error BB */
4428 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4432 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4433 psrch_inf->unicode = true;
4435 psrch_inf->unicode = false;
4437 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4438 psrch_inf->smallBuf = false;
4439 psrch_inf->srch_entries_start =
4440 (char *) &pSMBr->hdr.Protocol +
4441 le16_to_cpu(pSMBr->t2.DataOffset);
4442 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4443 le16_to_cpu(pSMBr->t2.ParameterOffset));
4445 if (parms->EndofSearch)
4446 psrch_inf->endOfSearch = true;
4448 psrch_inf->endOfSearch = false;
4450 psrch_inf->entries_in_buffer =
4451 le16_to_cpu(parms->SearchCount);
4452 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4453 psrch_inf->entries_in_buffer;
4454 lnoff = le16_to_cpu(parms->LastNameOffset);
4455 if (CIFSMaxBufSize < lnoff) {
4456 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4457 psrch_inf->last_entry = NULL;
4461 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4465 *pnetfid = parms->SearchHandle;
4467 cifs_buf_release(pSMB);
4474 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4475 __u16 searchHandle, __u16 search_flags,
4476 struct cifs_search_info *psrch_inf)
4478 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4479 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4480 T2_FNEXT_RSP_PARMS *parms;
4481 char *response_data;
4484 unsigned int name_len;
4485 __u16 params, byte_count;
4487 cifs_dbg(FYI, "In FindNext\n");
4489 if (psrch_inf->endOfSearch)
4492 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4497 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4499 pSMB->TotalDataCount = 0; /* no EAs */
4500 pSMB->MaxParameterCount = cpu_to_le16(8);
4501 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4502 pSMB->MaxSetupCount = 0;
4506 pSMB->Reserved2 = 0;
4507 pSMB->ParameterOffset = cpu_to_le16(
4508 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4509 pSMB->DataCount = 0;
4510 pSMB->DataOffset = 0;
4511 pSMB->SetupCount = 1;
4512 pSMB->Reserved3 = 0;
4513 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4514 pSMB->SearchHandle = searchHandle; /* always kept as le */
4516 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4517 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4518 pSMB->ResumeKey = psrch_inf->resume_key;
4519 pSMB->SearchFlags = cpu_to_le16(search_flags);
4521 name_len = psrch_inf->resume_name_len;
4523 if (name_len < PATH_MAX) {
4524 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4525 byte_count += name_len;
4526 /* 14 byte parm len above enough for 2 byte null terminator */
4527 pSMB->ResumeFileName[name_len] = 0;
4528 pSMB->ResumeFileName[name_len+1] = 0;
4531 goto FNext2_err_exit;
4533 byte_count = params + 1 /* pad */ ;
4534 pSMB->TotalParameterCount = cpu_to_le16(params);
4535 pSMB->ParameterCount = pSMB->TotalParameterCount;
4536 inc_rfc1001_len(pSMB, byte_count);
4537 pSMB->ByteCount = cpu_to_le16(byte_count);
4539 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4540 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4541 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4544 psrch_inf->endOfSearch = true;
4545 cifs_buf_release(pSMB);
4546 rc = 0; /* search probably was closed at end of search*/
4548 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4549 } else { /* decode response */
4550 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4555 /* BB fixme add lock for file (srch_info) struct here */
4556 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4557 psrch_inf->unicode = true;
4559 psrch_inf->unicode = false;
4560 response_data = (char *) &pSMBr->hdr.Protocol +
4561 le16_to_cpu(pSMBr->t2.ParameterOffset);
4562 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4563 response_data = (char *)&pSMBr->hdr.Protocol +
4564 le16_to_cpu(pSMBr->t2.DataOffset);
4565 if (psrch_inf->smallBuf)
4566 cifs_small_buf_release(
4567 psrch_inf->ntwrk_buf_start);
4569 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4570 psrch_inf->srch_entries_start = response_data;
4571 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4572 psrch_inf->smallBuf = false;
4573 if (parms->EndofSearch)
4574 psrch_inf->endOfSearch = true;
4576 psrch_inf->endOfSearch = false;
4577 psrch_inf->entries_in_buffer =
4578 le16_to_cpu(parms->SearchCount);
4579 psrch_inf->index_of_last_entry +=
4580 psrch_inf->entries_in_buffer;
4581 lnoff = le16_to_cpu(parms->LastNameOffset);
4582 if (CIFSMaxBufSize < lnoff) {
4583 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4584 psrch_inf->last_entry = NULL;
4587 psrch_inf->last_entry =
4588 psrch_inf->srch_entries_start + lnoff;
4590 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4591 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4593 /* BB fixme add unlock here */
4598 /* BB On error, should we leave previous search buf (and count and
4599 last entry fields) intact or free the previous one? */
4601 /* Note: On -EAGAIN error only caller can retry on handle based calls
4602 since file handle passed in no longer valid */
4605 cifs_buf_release(pSMB);
4610 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4611 const __u16 searchHandle)
4614 FINDCLOSE_REQ *pSMB = NULL;
4616 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4617 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4619 /* no sense returning error if session restarted
4620 as file handle has been closed */
4626 pSMB->FileID = searchHandle;
4627 pSMB->ByteCount = 0;
4628 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4629 cifs_small_buf_release(pSMB);
4631 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4633 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4635 /* Since session is dead, search handle closed on server already */
4643 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4644 const char *search_name, __u64 *inode_number,
4645 const struct nls_table *nls_codepage, int remap)
4648 TRANSACTION2_QPI_REQ *pSMB = NULL;
4649 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4650 int name_len, bytes_returned;
4651 __u16 params, byte_count;
4653 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4657 GetInodeNumberRetry:
4658 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4663 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4665 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4666 search_name, PATH_MAX, nls_codepage,
4668 name_len++; /* trailing null */
4671 name_len = copy_path_name(pSMB->FileName, search_name);
4674 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4675 pSMB->TotalDataCount = 0;
4676 pSMB->MaxParameterCount = cpu_to_le16(2);
4677 /* BB find exact max data count below from sess structure BB */
4678 pSMB->MaxDataCount = cpu_to_le16(4000);
4679 pSMB->MaxSetupCount = 0;
4683 pSMB->Reserved2 = 0;
4684 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4685 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4686 pSMB->DataCount = 0;
4687 pSMB->DataOffset = 0;
4688 pSMB->SetupCount = 1;
4689 pSMB->Reserved3 = 0;
4690 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4691 byte_count = params + 1 /* pad */ ;
4692 pSMB->TotalParameterCount = cpu_to_le16(params);
4693 pSMB->ParameterCount = pSMB->TotalParameterCount;
4694 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4695 pSMB->Reserved4 = 0;
4696 inc_rfc1001_len(pSMB, byte_count);
4697 pSMB->ByteCount = cpu_to_le16(byte_count);
4699 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4700 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4702 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4704 /* decode response */
4705 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4706 /* BB also check enough total bytes returned */
4707 if (rc || get_bcc(&pSMBr->hdr) < 2)
4708 /* If rc should we check for EOPNOSUPP and
4709 disable the srvino flag? or in caller? */
4710 rc = -EIO; /* bad smb */
4712 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4713 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4714 struct file_internal_info *pfinfo;
4715 /* BB Do we need a cast or hash here ? */
4717 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4719 goto GetInodeNumOut;
4721 pfinfo = (struct file_internal_info *)
4722 (data_offset + (char *) &pSMBr->hdr.Protocol);
4723 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4727 cifs_buf_release(pSMB);
4729 goto GetInodeNumberRetry;
4734 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4735 const char *search_name, struct dfs_info3_param **target_nodes,
4736 unsigned int *num_of_nodes,
4737 const struct nls_table *nls_codepage, int remap)
4739 /* TRANS2_GET_DFS_REFERRAL */
4740 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4741 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4745 __u16 params, byte_count;
4747 *target_nodes = NULL;
4749 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4750 if (ses == NULL || ses->tcon_ipc == NULL)
4755 * Use smb_init_no_reconnect() instead of smb_init() as
4756 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4757 * causing an infinite recursion.
4759 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4760 (void **)&pSMB, (void **)&pSMBr);
4764 /* server pointer checked in called function,
4765 but should never be null here anyway */
4766 pSMB->hdr.Mid = get_next_mid(ses->server);
4767 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4768 pSMB->hdr.Uid = ses->Suid;
4769 if (ses->capabilities & CAP_STATUS32)
4770 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4771 if (ses->capabilities & CAP_DFS)
4772 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4774 if (ses->capabilities & CAP_UNICODE) {
4775 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4777 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4778 search_name, PATH_MAX, nls_codepage,
4780 name_len++; /* trailing null */
4782 } else { /* BB improve the check for buffer overruns BB */
4783 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4786 if (ses->server->sign)
4787 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4789 pSMB->hdr.Uid = ses->Suid;
4791 params = 2 /* level */ + name_len /*includes null */ ;
4792 pSMB->TotalDataCount = 0;
4793 pSMB->DataCount = 0;
4794 pSMB->DataOffset = 0;
4795 pSMB->MaxParameterCount = 0;
4796 /* BB find exact max SMB PDU from sess structure BB */
4797 pSMB->MaxDataCount = cpu_to_le16(4000);
4798 pSMB->MaxSetupCount = 0;
4802 pSMB->Reserved2 = 0;
4803 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4804 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4805 pSMB->SetupCount = 1;
4806 pSMB->Reserved3 = 0;
4807 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4808 byte_count = params + 3 /* pad */ ;
4809 pSMB->ParameterCount = cpu_to_le16(params);
4810 pSMB->TotalParameterCount = pSMB->ParameterCount;
4811 pSMB->MaxReferralLevel = cpu_to_le16(3);
4812 inc_rfc1001_len(pSMB, byte_count);
4813 pSMB->ByteCount = cpu_to_le16(byte_count);
4815 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4816 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4818 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4821 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4823 /* BB Also check if enough total bytes returned? */
4824 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4825 rc = -EIO; /* bad smb */
4829 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4830 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4832 /* parse returned result into more usable form */
4833 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4834 le16_to_cpu(pSMBr->t2.DataCount),
4835 num_of_nodes, target_nodes, nls_codepage,
4837 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4840 cifs_buf_release(pSMB);
4848 /* Query File System Info such as free space to old servers such as Win 9x */
4850 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4851 struct kstatfs *FSData)
4853 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4854 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4855 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4856 FILE_SYSTEM_ALLOC_INFO *response_data;
4858 int bytes_returned = 0;
4859 __u16 params, byte_count;
4861 cifs_dbg(FYI, "OldQFSInfo\n");
4863 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4868 params = 2; /* level */
4869 pSMB->TotalDataCount = 0;
4870 pSMB->MaxParameterCount = cpu_to_le16(2);
4871 pSMB->MaxDataCount = cpu_to_le16(1000);
4872 pSMB->MaxSetupCount = 0;
4876 pSMB->Reserved2 = 0;
4877 byte_count = params + 1 /* pad */ ;
4878 pSMB->TotalParameterCount = cpu_to_le16(params);
4879 pSMB->ParameterCount = pSMB->TotalParameterCount;
4880 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4881 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4882 pSMB->DataCount = 0;
4883 pSMB->DataOffset = 0;
4884 pSMB->SetupCount = 1;
4885 pSMB->Reserved3 = 0;
4886 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4887 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4888 inc_rfc1001_len(pSMB, byte_count);
4889 pSMB->ByteCount = cpu_to_le16(byte_count);
4891 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4892 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4894 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4895 } else { /* decode response */
4896 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4898 if (rc || get_bcc(&pSMBr->hdr) < 18)
4899 rc = -EIO; /* bad smb */
4901 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4902 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4903 get_bcc(&pSMBr->hdr), data_offset);
4905 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4906 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4908 le16_to_cpu(response_data->BytesPerSector) *
4909 le32_to_cpu(response_data->
4910 SectorsPerAllocationUnit);
4912 * much prefer larger but if server doesn't report
4913 * a valid size than 4K is a reasonable minimum
4915 if (FSData->f_bsize < 512)
4916 FSData->f_bsize = 4096;
4919 le32_to_cpu(response_data->TotalAllocationUnits);
4920 FSData->f_bfree = FSData->f_bavail =
4921 le32_to_cpu(response_data->FreeAllocationUnits);
4922 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4923 (unsigned long long)FSData->f_blocks,
4924 (unsigned long long)FSData->f_bfree,
4928 cifs_buf_release(pSMB);
4931 goto oldQFSInfoRetry;
4937 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4938 struct kstatfs *FSData)
4940 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4941 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4942 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4943 FILE_SYSTEM_INFO *response_data;
4945 int bytes_returned = 0;
4946 __u16 params, byte_count;
4948 cifs_dbg(FYI, "In QFSInfo\n");
4950 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4955 params = 2; /* level */
4956 pSMB->TotalDataCount = 0;
4957 pSMB->MaxParameterCount = cpu_to_le16(2);
4958 pSMB->MaxDataCount = cpu_to_le16(1000);
4959 pSMB->MaxSetupCount = 0;
4963 pSMB->Reserved2 = 0;
4964 byte_count = params + 1 /* pad */ ;
4965 pSMB->TotalParameterCount = cpu_to_le16(params);
4966 pSMB->ParameterCount = pSMB->TotalParameterCount;
4967 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4968 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4969 pSMB->DataCount = 0;
4970 pSMB->DataOffset = 0;
4971 pSMB->SetupCount = 1;
4972 pSMB->Reserved3 = 0;
4973 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4974 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4975 inc_rfc1001_len(pSMB, byte_count);
4976 pSMB->ByteCount = cpu_to_le16(byte_count);
4978 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4979 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4981 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4982 } else { /* decode response */
4983 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4985 if (rc || get_bcc(&pSMBr->hdr) < 24)
4986 rc = -EIO; /* bad smb */
4988 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4992 *) (((char *) &pSMBr->hdr.Protocol) +
4995 le32_to_cpu(response_data->BytesPerSector) *
4996 le32_to_cpu(response_data->
4997 SectorsPerAllocationUnit);
4999 * much prefer larger but if server doesn't report
5000 * a valid size than 4K is a reasonable minimum
5002 if (FSData->f_bsize < 512)
5003 FSData->f_bsize = 4096;
5006 le64_to_cpu(response_data->TotalAllocationUnits);
5007 FSData->f_bfree = FSData->f_bavail =
5008 le64_to_cpu(response_data->FreeAllocationUnits);
5009 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5010 (unsigned long long)FSData->f_blocks,
5011 (unsigned long long)FSData->f_bfree,
5015 cifs_buf_release(pSMB);
5024 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5026 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5027 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5028 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5029 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5031 int bytes_returned = 0;
5032 __u16 params, byte_count;
5034 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5036 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5041 params = 2; /* level */
5042 pSMB->TotalDataCount = 0;
5043 pSMB->MaxParameterCount = cpu_to_le16(2);
5044 /* BB find exact max SMB PDU from sess structure BB */
5045 pSMB->MaxDataCount = cpu_to_le16(1000);
5046 pSMB->MaxSetupCount = 0;
5050 pSMB->Reserved2 = 0;
5051 byte_count = params + 1 /* pad */ ;
5052 pSMB->TotalParameterCount = cpu_to_le16(params);
5053 pSMB->ParameterCount = pSMB->TotalParameterCount;
5054 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5055 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5056 pSMB->DataCount = 0;
5057 pSMB->DataOffset = 0;
5058 pSMB->SetupCount = 1;
5059 pSMB->Reserved3 = 0;
5060 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5061 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5062 inc_rfc1001_len(pSMB, byte_count);
5063 pSMB->ByteCount = cpu_to_le16(byte_count);
5065 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5066 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5068 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5069 } else { /* decode response */
5070 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5072 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5073 /* BB also check if enough bytes returned */
5074 rc = -EIO; /* bad smb */
5076 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5078 (FILE_SYSTEM_ATTRIBUTE_INFO
5079 *) (((char *) &pSMBr->hdr.Protocol) +
5081 memcpy(&tcon->fsAttrInfo, response_data,
5082 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5085 cifs_buf_release(pSMB);
5088 goto QFSAttributeRetry;
5094 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5096 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5097 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5098 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5099 FILE_SYSTEM_DEVICE_INFO *response_data;
5101 int bytes_returned = 0;
5102 __u16 params, byte_count;
5104 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5106 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5111 params = 2; /* level */
5112 pSMB->TotalDataCount = 0;
5113 pSMB->MaxParameterCount = cpu_to_le16(2);
5114 /* BB find exact max SMB PDU from sess structure BB */
5115 pSMB->MaxDataCount = cpu_to_le16(1000);
5116 pSMB->MaxSetupCount = 0;
5120 pSMB->Reserved2 = 0;
5121 byte_count = params + 1 /* pad */ ;
5122 pSMB->TotalParameterCount = cpu_to_le16(params);
5123 pSMB->ParameterCount = pSMB->TotalParameterCount;
5124 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5125 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5127 pSMB->DataCount = 0;
5128 pSMB->DataOffset = 0;
5129 pSMB->SetupCount = 1;
5130 pSMB->Reserved3 = 0;
5131 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5132 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5133 inc_rfc1001_len(pSMB, byte_count);
5134 pSMB->ByteCount = cpu_to_le16(byte_count);
5136 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5137 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5139 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5140 } else { /* decode response */
5141 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5143 if (rc || get_bcc(&pSMBr->hdr) <
5144 sizeof(FILE_SYSTEM_DEVICE_INFO))
5145 rc = -EIO; /* bad smb */
5147 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5149 (FILE_SYSTEM_DEVICE_INFO *)
5150 (((char *) &pSMBr->hdr.Protocol) +
5152 memcpy(&tcon->fsDevInfo, response_data,
5153 sizeof(FILE_SYSTEM_DEVICE_INFO));
5156 cifs_buf_release(pSMB);
5159 goto QFSDeviceRetry;
5165 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5167 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5168 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5169 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5170 FILE_SYSTEM_UNIX_INFO *response_data;
5172 int bytes_returned = 0;
5173 __u16 params, byte_count;
5175 cifs_dbg(FYI, "In QFSUnixInfo\n");
5177 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5178 (void **) &pSMB, (void **) &pSMBr);
5182 params = 2; /* level */
5183 pSMB->TotalDataCount = 0;
5184 pSMB->DataCount = 0;
5185 pSMB->DataOffset = 0;
5186 pSMB->MaxParameterCount = cpu_to_le16(2);
5187 /* BB find exact max SMB PDU from sess structure BB */
5188 pSMB->MaxDataCount = cpu_to_le16(100);
5189 pSMB->MaxSetupCount = 0;
5193 pSMB->Reserved2 = 0;
5194 byte_count = params + 1 /* pad */ ;
5195 pSMB->ParameterCount = cpu_to_le16(params);
5196 pSMB->TotalParameterCount = pSMB->ParameterCount;
5197 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5198 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5199 pSMB->SetupCount = 1;
5200 pSMB->Reserved3 = 0;
5201 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5202 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5203 inc_rfc1001_len(pSMB, byte_count);
5204 pSMB->ByteCount = cpu_to_le16(byte_count);
5206 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5207 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5209 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5210 } else { /* decode response */
5211 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5213 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5214 rc = -EIO; /* bad smb */
5216 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5218 (FILE_SYSTEM_UNIX_INFO
5219 *) (((char *) &pSMBr->hdr.Protocol) +
5221 memcpy(&tcon->fsUnixInfo, response_data,
5222 sizeof(FILE_SYSTEM_UNIX_INFO));
5225 cifs_buf_release(pSMB);
5235 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5237 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5238 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5239 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5241 int bytes_returned = 0;
5242 __u16 params, param_offset, offset, byte_count;
5244 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5246 /* BB switch to small buf init to save memory */
5247 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5248 (void **) &pSMB, (void **) &pSMBr);
5252 params = 4; /* 2 bytes zero followed by info level. */
5253 pSMB->MaxSetupCount = 0;
5257 pSMB->Reserved2 = 0;
5258 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5260 offset = param_offset + params;
5262 pSMB->MaxParameterCount = cpu_to_le16(4);
5263 /* BB find exact max SMB PDU from sess structure BB */
5264 pSMB->MaxDataCount = cpu_to_le16(100);
5265 pSMB->SetupCount = 1;
5266 pSMB->Reserved3 = 0;
5267 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5268 byte_count = 1 /* pad */ + params + 12;
5270 pSMB->DataCount = cpu_to_le16(12);
5271 pSMB->ParameterCount = cpu_to_le16(params);
5272 pSMB->TotalDataCount = pSMB->DataCount;
5273 pSMB->TotalParameterCount = pSMB->ParameterCount;
5274 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5275 pSMB->DataOffset = cpu_to_le16(offset);
5279 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5282 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5283 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5284 pSMB->ClientUnixCap = cpu_to_le64(cap);
5286 inc_rfc1001_len(pSMB, byte_count);
5287 pSMB->ByteCount = cpu_to_le16(byte_count);
5289 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5290 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5292 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5293 } else { /* decode response */
5294 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5296 rc = -EIO; /* bad smb */
5298 cifs_buf_release(pSMB);
5301 goto SETFSUnixRetry;
5309 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5310 struct kstatfs *FSData)
5312 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5313 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5314 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5315 FILE_SYSTEM_POSIX_INFO *response_data;
5317 int bytes_returned = 0;
5318 __u16 params, byte_count;
5320 cifs_dbg(FYI, "In QFSPosixInfo\n");
5322 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5327 params = 2; /* level */
5328 pSMB->TotalDataCount = 0;
5329 pSMB->DataCount = 0;
5330 pSMB->DataOffset = 0;
5331 pSMB->MaxParameterCount = cpu_to_le16(2);
5332 /* BB find exact max SMB PDU from sess structure BB */
5333 pSMB->MaxDataCount = cpu_to_le16(100);
5334 pSMB->MaxSetupCount = 0;
5338 pSMB->Reserved2 = 0;
5339 byte_count = params + 1 /* pad */ ;
5340 pSMB->ParameterCount = cpu_to_le16(params);
5341 pSMB->TotalParameterCount = pSMB->ParameterCount;
5342 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5343 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5344 pSMB->SetupCount = 1;
5345 pSMB->Reserved3 = 0;
5346 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5347 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5348 inc_rfc1001_len(pSMB, byte_count);
5349 pSMB->ByteCount = cpu_to_le16(byte_count);
5351 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5352 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5354 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5355 } else { /* decode response */
5356 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5358 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5359 rc = -EIO; /* bad smb */
5361 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5363 (FILE_SYSTEM_POSIX_INFO
5364 *) (((char *) &pSMBr->hdr.Protocol) +
5367 le32_to_cpu(response_data->BlockSize);
5369 * much prefer larger but if server doesn't report
5370 * a valid size than 4K is a reasonable minimum
5372 if (FSData->f_bsize < 512)
5373 FSData->f_bsize = 4096;
5376 le64_to_cpu(response_data->TotalBlocks);
5378 le64_to_cpu(response_data->BlocksAvail);
5379 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5380 FSData->f_bavail = FSData->f_bfree;
5383 le64_to_cpu(response_data->UserBlocksAvail);
5385 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5387 le64_to_cpu(response_data->TotalFileNodes);
5388 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5390 le64_to_cpu(response_data->FreeFileNodes);
5393 cifs_buf_release(pSMB);
5403 * We can not use write of zero bytes trick to set file size due to need for
5404 * large file support. Also note that this SetPathInfo is preferred to
5405 * SetFileInfo based method in next routine which is only needed to work around
5406 * a sharing violation bugin Samba which this routine can run into.
5409 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5410 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5411 bool set_allocation)
5413 struct smb_com_transaction2_spi_req *pSMB = NULL;
5414 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5415 struct file_end_of_file_info *parm_data;
5418 int bytes_returned = 0;
5419 int remap = cifs_remap(cifs_sb);
5421 __u16 params, byte_count, data_count, param_offset, offset;
5423 cifs_dbg(FYI, "In SetEOF\n");
5425 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5430 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5432 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5433 PATH_MAX, cifs_sb->local_nls, remap);
5434 name_len++; /* trailing null */
5437 name_len = copy_path_name(pSMB->FileName, file_name);
5439 params = 6 + name_len;
5440 data_count = sizeof(struct file_end_of_file_info);
5441 pSMB->MaxParameterCount = cpu_to_le16(2);
5442 pSMB->MaxDataCount = cpu_to_le16(4100);
5443 pSMB->MaxSetupCount = 0;
5447 pSMB->Reserved2 = 0;
5448 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5449 InformationLevel) - 4;
5450 offset = param_offset + params;
5451 if (set_allocation) {
5452 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5453 pSMB->InformationLevel =
5454 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5456 pSMB->InformationLevel =
5457 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5458 } else /* Set File Size */ {
5459 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5460 pSMB->InformationLevel =
5461 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5463 pSMB->InformationLevel =
5464 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5468 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5470 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5471 pSMB->DataOffset = cpu_to_le16(offset);
5472 pSMB->SetupCount = 1;
5473 pSMB->Reserved3 = 0;
5474 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5475 byte_count = 3 /* pad */ + params + data_count;
5476 pSMB->DataCount = cpu_to_le16(data_count);
5477 pSMB->TotalDataCount = pSMB->DataCount;
5478 pSMB->ParameterCount = cpu_to_le16(params);
5479 pSMB->TotalParameterCount = pSMB->ParameterCount;
5480 pSMB->Reserved4 = 0;
5481 inc_rfc1001_len(pSMB, byte_count);
5482 parm_data->FileSize = cpu_to_le64(size);
5483 pSMB->ByteCount = cpu_to_le16(byte_count);
5484 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5485 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5487 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5489 cifs_buf_release(pSMB);
5498 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5499 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5501 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5502 struct file_end_of_file_info *parm_data;
5504 __u16 params, param_offset, offset, byte_count, count;
5506 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5508 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5513 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5514 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5517 pSMB->MaxSetupCount = 0;
5521 pSMB->Reserved2 = 0;
5522 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5523 offset = param_offset + params;
5525 count = sizeof(struct file_end_of_file_info);
5526 pSMB->MaxParameterCount = cpu_to_le16(2);
5527 /* BB find exact max SMB PDU from sess structure BB */
5528 pSMB->MaxDataCount = cpu_to_le16(1000);
5529 pSMB->SetupCount = 1;
5530 pSMB->Reserved3 = 0;
5531 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5532 byte_count = 3 /* pad */ + params + count;
5533 pSMB->DataCount = cpu_to_le16(count);
5534 pSMB->ParameterCount = cpu_to_le16(params);
5535 pSMB->TotalDataCount = pSMB->DataCount;
5536 pSMB->TotalParameterCount = pSMB->ParameterCount;
5537 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5538 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5540 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5541 pSMB->DataOffset = cpu_to_le16(offset);
5542 parm_data->FileSize = cpu_to_le64(size);
5543 pSMB->Fid = cfile->fid.netfid;
5544 if (set_allocation) {
5545 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5546 pSMB->InformationLevel =
5547 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5549 pSMB->InformationLevel =
5550 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5551 } else /* Set File Size */ {
5552 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5553 pSMB->InformationLevel =
5554 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5556 pSMB->InformationLevel =
5557 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5559 pSMB->Reserved4 = 0;
5560 inc_rfc1001_len(pSMB, byte_count);
5561 pSMB->ByteCount = cpu_to_le16(byte_count);
5562 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5563 cifs_small_buf_release(pSMB);
5565 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5569 /* Note: On -EAGAIN error only caller can retry on handle based calls
5570 since file handle passed in no longer valid */
5575 /* Some legacy servers such as NT4 require that the file times be set on
5576 an open handle, rather than by pathname - this is awkward due to
5577 potential access conflicts on the open, but it is unavoidable for these
5578 old servers since the only other choice is to go from 100 nanosecond DCE
5579 time and resort to the original setpathinfo level which takes the ancient
5580 DOS time format with 2 second granularity */
5582 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5583 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5585 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5588 __u16 params, param_offset, offset, byte_count, count;
5590 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5591 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5596 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5597 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5600 pSMB->MaxSetupCount = 0;
5604 pSMB->Reserved2 = 0;
5605 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5606 offset = param_offset + params;
5608 data_offset = (char *)pSMB +
5609 offsetof(struct smb_hdr, Protocol) + offset;
5611 count = sizeof(FILE_BASIC_INFO);
5612 pSMB->MaxParameterCount = cpu_to_le16(2);
5613 /* BB find max SMB PDU from sess */
5614 pSMB->MaxDataCount = cpu_to_le16(1000);
5615 pSMB->SetupCount = 1;
5616 pSMB->Reserved3 = 0;
5617 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5618 byte_count = 3 /* pad */ + params + count;
5619 pSMB->DataCount = cpu_to_le16(count);
5620 pSMB->ParameterCount = cpu_to_le16(params);
5621 pSMB->TotalDataCount = pSMB->DataCount;
5622 pSMB->TotalParameterCount = pSMB->ParameterCount;
5623 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5624 pSMB->DataOffset = cpu_to_le16(offset);
5626 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5627 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5629 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5630 pSMB->Reserved4 = 0;
5631 inc_rfc1001_len(pSMB, byte_count);
5632 pSMB->ByteCount = cpu_to_le16(byte_count);
5633 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5634 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5635 cifs_small_buf_release(pSMB);
5637 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5640 /* Note: On -EAGAIN error only caller can retry on handle based calls
5641 since file handle passed in no longer valid */
5647 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5648 bool delete_file, __u16 fid, __u32 pid_of_opener)
5650 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5653 __u16 params, param_offset, offset, byte_count, count;
5655 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5656 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5661 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5662 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5665 pSMB->MaxSetupCount = 0;
5669 pSMB->Reserved2 = 0;
5670 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5671 offset = param_offset + params;
5673 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5674 data_offset = (char *)(pSMB) + offset + 4;
5677 pSMB->MaxParameterCount = cpu_to_le16(2);
5678 /* BB find max SMB PDU from sess */
5679 pSMB->MaxDataCount = cpu_to_le16(1000);
5680 pSMB->SetupCount = 1;
5681 pSMB->Reserved3 = 0;
5682 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5683 byte_count = 3 /* pad */ + params + count;
5684 pSMB->DataCount = cpu_to_le16(count);
5685 pSMB->ParameterCount = cpu_to_le16(params);
5686 pSMB->TotalDataCount = pSMB->DataCount;
5687 pSMB->TotalParameterCount = pSMB->ParameterCount;
5688 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5689 pSMB->DataOffset = cpu_to_le16(offset);
5691 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5692 pSMB->Reserved4 = 0;
5693 inc_rfc1001_len(pSMB, byte_count);
5694 pSMB->ByteCount = cpu_to_le16(byte_count);
5695 *data_offset = delete_file ? 1 : 0;
5696 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5697 cifs_small_buf_release(pSMB);
5699 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5705 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5706 const char *fileName, const FILE_BASIC_INFO *data,
5707 const struct nls_table *nls_codepage,
5708 struct cifs_sb_info *cifs_sb)
5711 struct cifs_open_parms oparms;
5712 struct cifs_fid fid;
5716 oparms.cifs_sb = cifs_sb;
5717 oparms.desired_access = GENERIC_WRITE;
5718 oparms.create_options = cifs_create_options(cifs_sb, 0);
5719 oparms.disposition = FILE_OPEN;
5720 oparms.path = fileName;
5722 oparms.reconnect = false;
5724 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5728 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5729 CIFSSMBClose(xid, tcon, fid.netfid);
5736 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5737 const char *fileName, const FILE_BASIC_INFO *data,
5738 const struct nls_table *nls_codepage,
5739 struct cifs_sb_info *cifs_sb)
5741 TRANSACTION2_SPI_REQ *pSMB = NULL;
5742 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5745 int bytes_returned = 0;
5747 __u16 params, param_offset, offset, byte_count, count;
5748 int remap = cifs_remap(cifs_sb);
5750 cifs_dbg(FYI, "In SetTimes\n");
5753 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5758 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5760 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5761 PATH_MAX, nls_codepage, remap);
5762 name_len++; /* trailing null */
5765 name_len = copy_path_name(pSMB->FileName, fileName);
5768 params = 6 + name_len;
5769 count = sizeof(FILE_BASIC_INFO);
5770 pSMB->MaxParameterCount = cpu_to_le16(2);
5771 /* BB find max SMB PDU from sess structure BB */
5772 pSMB->MaxDataCount = cpu_to_le16(1000);
5773 pSMB->MaxSetupCount = 0;
5777 pSMB->Reserved2 = 0;
5778 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5779 InformationLevel) - 4;
5780 offset = param_offset + params;
5781 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5782 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5783 pSMB->DataOffset = cpu_to_le16(offset);
5784 pSMB->SetupCount = 1;
5785 pSMB->Reserved3 = 0;
5786 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5787 byte_count = 3 /* pad */ + params + count;
5789 pSMB->DataCount = cpu_to_le16(count);
5790 pSMB->ParameterCount = cpu_to_le16(params);
5791 pSMB->TotalDataCount = pSMB->DataCount;
5792 pSMB->TotalParameterCount = pSMB->ParameterCount;
5793 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5794 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5796 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5797 pSMB->Reserved4 = 0;
5798 inc_rfc1001_len(pSMB, byte_count);
5799 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5800 pSMB->ByteCount = cpu_to_le16(byte_count);
5801 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5802 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5804 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5806 cifs_buf_release(pSMB);
5811 if (rc == -EOPNOTSUPP)
5812 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5813 nls_codepage, cifs_sb);
5819 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5820 const struct cifs_unix_set_info_args *args)
5822 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5823 u64 mode = args->mode;
5825 if (uid_valid(args->uid))
5826 uid = from_kuid(&init_user_ns, args->uid);
5827 if (gid_valid(args->gid))
5828 gid = from_kgid(&init_user_ns, args->gid);
5831 * Samba server ignores set of file size to zero due to bugs in some
5832 * older clients, but we should be precise - we use SetFileSize to
5833 * set file size and do not want to truncate file size to zero
5834 * accidentally as happened on one Samba server beta by putting
5835 * zero instead of -1 here
5837 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5838 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5839 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5840 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5841 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5842 data_offset->Uid = cpu_to_le64(uid);
5843 data_offset->Gid = cpu_to_le64(gid);
5844 /* better to leave device as zero when it is */
5845 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5846 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5847 data_offset->Permissions = cpu_to_le64(mode);
5850 data_offset->Type = cpu_to_le32(UNIX_FILE);
5851 else if (S_ISDIR(mode))
5852 data_offset->Type = cpu_to_le32(UNIX_DIR);
5853 else if (S_ISLNK(mode))
5854 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5855 else if (S_ISCHR(mode))
5856 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5857 else if (S_ISBLK(mode))
5858 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5859 else if (S_ISFIFO(mode))
5860 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5861 else if (S_ISSOCK(mode))
5862 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5866 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5867 const struct cifs_unix_set_info_args *args,
5868 u16 fid, u32 pid_of_opener)
5870 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5873 u16 params, param_offset, offset, byte_count, count;
5875 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5876 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5881 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5882 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5885 pSMB->MaxSetupCount = 0;
5889 pSMB->Reserved2 = 0;
5890 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5891 offset = param_offset + params;
5893 data_offset = (char *)pSMB +
5894 offsetof(struct smb_hdr, Protocol) + offset;
5896 count = sizeof(FILE_UNIX_BASIC_INFO);
5898 pSMB->MaxParameterCount = cpu_to_le16(2);
5899 /* BB find max SMB PDU from sess */
5900 pSMB->MaxDataCount = cpu_to_le16(1000);
5901 pSMB->SetupCount = 1;
5902 pSMB->Reserved3 = 0;
5903 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5904 byte_count = 3 /* pad */ + params + count;
5905 pSMB->DataCount = cpu_to_le16(count);
5906 pSMB->ParameterCount = cpu_to_le16(params);
5907 pSMB->TotalDataCount = pSMB->DataCount;
5908 pSMB->TotalParameterCount = pSMB->ParameterCount;
5909 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5910 pSMB->DataOffset = cpu_to_le16(offset);
5912 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5913 pSMB->Reserved4 = 0;
5914 inc_rfc1001_len(pSMB, byte_count);
5915 pSMB->ByteCount = cpu_to_le16(byte_count);
5917 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5919 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5920 cifs_small_buf_release(pSMB);
5922 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5925 /* Note: On -EAGAIN error only caller can retry on handle based calls
5926 since file handle passed in no longer valid */
5932 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5933 const char *file_name,
5934 const struct cifs_unix_set_info_args *args,
5935 const struct nls_table *nls_codepage, int remap)
5937 TRANSACTION2_SPI_REQ *pSMB = NULL;
5938 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5941 int bytes_returned = 0;
5942 FILE_UNIX_BASIC_INFO *data_offset;
5943 __u16 params, param_offset, offset, count, byte_count;
5945 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5947 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5952 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5954 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5955 PATH_MAX, nls_codepage, remap);
5956 name_len++; /* trailing null */
5959 name_len = copy_path_name(pSMB->FileName, file_name);
5962 params = 6 + name_len;
5963 count = sizeof(FILE_UNIX_BASIC_INFO);
5964 pSMB->MaxParameterCount = cpu_to_le16(2);
5965 /* BB find max SMB PDU from sess structure BB */
5966 pSMB->MaxDataCount = cpu_to_le16(1000);
5967 pSMB->MaxSetupCount = 0;
5971 pSMB->Reserved2 = 0;
5972 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5973 InformationLevel) - 4;
5974 offset = param_offset + params;
5975 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5976 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
5977 memset(data_offset, 0, count);
5978 pSMB->DataOffset = cpu_to_le16(offset);
5979 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5980 pSMB->SetupCount = 1;
5981 pSMB->Reserved3 = 0;
5982 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5983 byte_count = 3 /* pad */ + params + count;
5984 pSMB->ParameterCount = cpu_to_le16(params);
5985 pSMB->DataCount = cpu_to_le16(count);
5986 pSMB->TotalParameterCount = pSMB->ParameterCount;
5987 pSMB->TotalDataCount = pSMB->DataCount;
5988 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5989 pSMB->Reserved4 = 0;
5990 inc_rfc1001_len(pSMB, byte_count);
5992 cifs_fill_unix_set_info(data_offset, args);
5994 pSMB->ByteCount = cpu_to_le16(byte_count);
5995 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5996 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5998 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6000 cifs_buf_release(pSMB);
6006 #ifdef CONFIG_CIFS_XATTR
6008 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6009 * function used by listxattr and getxattr type calls. When ea_name is set,
6010 * it looks for that attribute name and stuffs that value into the EAData
6011 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6012 * buffer. In both cases, the return value is either the length of the
6013 * resulting data or a negative error code. If EAData is a NULL pointer then
6014 * the data isn't copied to it, but the length is returned.
6017 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6018 const unsigned char *searchName, const unsigned char *ea_name,
6019 char *EAData, size_t buf_size,
6020 struct cifs_sb_info *cifs_sb)
6022 /* BB assumes one setup word */
6023 TRANSACTION2_QPI_REQ *pSMB = NULL;
6024 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6025 int remap = cifs_remap(cifs_sb);
6026 struct nls_table *nls_codepage = cifs_sb->local_nls;
6030 struct fealist *ea_response_data;
6031 struct fea *temp_fea;
6034 __u16 params, byte_count, data_offset;
6035 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6037 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6039 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6044 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6046 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6047 PATH_MAX, nls_codepage, remap);
6048 list_len++; /* trailing null */
6051 list_len = copy_path_name(pSMB->FileName, searchName);
6054 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6055 pSMB->TotalDataCount = 0;
6056 pSMB->MaxParameterCount = cpu_to_le16(2);
6057 /* BB find exact max SMB PDU from sess structure BB */
6058 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6059 pSMB->MaxSetupCount = 0;
6063 pSMB->Reserved2 = 0;
6064 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6065 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6066 pSMB->DataCount = 0;
6067 pSMB->DataOffset = 0;
6068 pSMB->SetupCount = 1;
6069 pSMB->Reserved3 = 0;
6070 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6071 byte_count = params + 1 /* pad */ ;
6072 pSMB->TotalParameterCount = cpu_to_le16(params);
6073 pSMB->ParameterCount = pSMB->TotalParameterCount;
6074 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6075 pSMB->Reserved4 = 0;
6076 inc_rfc1001_len(pSMB, byte_count);
6077 pSMB->ByteCount = cpu_to_le16(byte_count);
6079 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6080 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6082 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6087 /* BB also check enough total bytes returned */
6088 /* BB we need to improve the validity checking
6089 of these trans2 responses */
6091 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6092 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6093 rc = -EIO; /* bad smb */
6097 /* check that length of list is not more than bcc */
6098 /* check that each entry does not go beyond length
6100 /* check that each element of each entry does not
6101 go beyond end of list */
6102 /* validate_trans2_offsets() */
6103 /* BB check if start of smb + data_offset > &bcc+ bcc */
6105 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6106 ea_response_data = (struct fealist *)
6107 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6109 list_len = le32_to_cpu(ea_response_data->list_len);
6110 cifs_dbg(FYI, "ea length %d\n", list_len);
6111 if (list_len <= 8) {
6112 cifs_dbg(FYI, "empty EA list returned from server\n");
6113 /* didn't find the named attribute */
6119 /* make sure list_len doesn't go past end of SMB */
6120 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6121 if ((char *)ea_response_data + list_len > end_of_smb) {
6122 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6127 /* account for ea list len */
6129 temp_fea = ea_response_data->list;
6130 temp_ptr = (char *)temp_fea;
6131 while (list_len > 0) {
6132 unsigned int name_len;
6137 /* make sure we can read name_len and value_len */
6139 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6144 name_len = temp_fea->name_len;
6145 value_len = le16_to_cpu(temp_fea->value_len);
6146 list_len -= name_len + 1 + value_len;
6148 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6154 if (ea_name_len == name_len &&
6155 memcmp(ea_name, temp_ptr, name_len) == 0) {
6156 temp_ptr += name_len + 1;
6160 if ((size_t)value_len > buf_size) {
6164 memcpy(EAData, temp_ptr, value_len);
6168 /* account for prefix user. and trailing null */
6169 rc += (5 + 1 + name_len);
6170 if (rc < (int) buf_size) {
6171 memcpy(EAData, "user.", 5);
6173 memcpy(EAData, temp_ptr, name_len);
6175 /* null terminate name */
6178 } else if (buf_size == 0) {
6179 /* skip copy - calc size only */
6181 /* stop before overrun buffer */
6186 temp_ptr += name_len + 1 + value_len;
6187 temp_fea = (struct fea *)temp_ptr;
6190 /* didn't find the named attribute */
6195 cifs_buf_release(pSMB);
6203 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6204 const char *fileName, const char *ea_name, const void *ea_value,
6205 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6206 struct cifs_sb_info *cifs_sb)
6208 struct smb_com_transaction2_spi_req *pSMB = NULL;
6209 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6210 struct fealist *parm_data;
6213 int bytes_returned = 0;
6214 __u16 params, param_offset, byte_count, offset, count;
6215 int remap = cifs_remap(cifs_sb);
6217 cifs_dbg(FYI, "In SetEA\n");
6219 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6224 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6226 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6227 PATH_MAX, nls_codepage, remap);
6228 name_len++; /* trailing null */
6231 name_len = copy_path_name(pSMB->FileName, fileName);
6234 params = 6 + name_len;
6236 /* done calculating parms using name_len of file name,
6237 now use name_len to calculate length of ea name
6238 we are going to create in the inode xattrs */
6239 if (ea_name == NULL)
6242 name_len = strnlen(ea_name, 255);
6244 count = sizeof(*parm_data) + ea_value_len + name_len;
6245 pSMB->MaxParameterCount = cpu_to_le16(2);
6246 /* BB find max SMB PDU from sess */
6247 pSMB->MaxDataCount = cpu_to_le16(1000);
6248 pSMB->MaxSetupCount = 0;
6252 pSMB->Reserved2 = 0;
6253 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6254 InformationLevel) - 4;
6255 offset = param_offset + params;
6256 pSMB->InformationLevel =
6257 cpu_to_le16(SMB_SET_FILE_EA);
6259 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6260 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6261 pSMB->DataOffset = cpu_to_le16(offset);
6262 pSMB->SetupCount = 1;
6263 pSMB->Reserved3 = 0;
6264 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6265 byte_count = 3 /* pad */ + params + count;
6266 pSMB->DataCount = cpu_to_le16(count);
6267 parm_data->list_len = cpu_to_le32(count);
6268 parm_data->list[0].EA_flags = 0;
6269 /* we checked above that name len is less than 255 */
6270 parm_data->list[0].name_len = (__u8)name_len;
6271 /* EA names are always ASCII */
6273 strncpy(parm_data->list[0].name, ea_name, name_len);
6274 parm_data->list[0].name[name_len] = 0;
6275 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6276 /* caller ensures that ea_value_len is less than 64K but
6277 we need to ensure that it fits within the smb */
6279 /*BB add length check to see if it would fit in
6280 negotiated SMB buffer size BB */
6281 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6283 memcpy(parm_data->list[0].name+name_len+1,
6284 ea_value, ea_value_len);
6286 pSMB->TotalDataCount = pSMB->DataCount;
6287 pSMB->ParameterCount = cpu_to_le16(params);
6288 pSMB->TotalParameterCount = pSMB->ParameterCount;
6289 pSMB->Reserved4 = 0;
6290 inc_rfc1001_len(pSMB, byte_count);
6291 pSMB->ByteCount = cpu_to_le16(byte_count);
6292 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6293 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6295 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6297 cifs_buf_release(pSMB);