1 // SPDX-License-Identifier: LGPL-2.1
4 * Copyright (C) International Business Machines Corp., 2002,2010
7 * Contains the routines for constructing the SMB PDUs themselves
11 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
12 /* These are mostly routines that operate on a pathname, or on a tree id */
13 /* (mounted volume), but there are eight handle based routines which must be */
14 /* treated slightly differently for reconnection purposes since we never */
15 /* want to reuse a stale file handle and only the caller knows the file info */
18 #include <linux/filelock.h>
19 #include <linux/kernel.h>
20 #include <linux/vfs.h>
21 #include <linux/slab.h>
22 #include <linux/posix_acl_xattr.h>
23 #include <linux/pagemap.h>
24 #include <linux/swap.h>
25 #include <linux/task_io_accounting_ops.h>
26 #include <linux/uaccess.h>
27 #include <linux/netfs.h>
28 #include <trace/events/netfs.h>
33 #include "cifsproto.h"
34 #include "cifs_unicode.h"
35 #include "cifs_debug.h"
37 #include "smbdirect.h"
38 #ifdef CONFIG_CIFS_DFS_UPCALL
39 #include "dfs_cache.h"
42 #ifdef CONFIG_CIFS_POSIX
47 {CIFS_PROT, "\2NT LM 0.12"},
48 {POSIX_PROT, "\2POSIX 2"},
56 {CIFS_PROT, "\2NT LM 0.12"},
61 /* define the number of elements in the cifs dialect array */
62 #ifdef CONFIG_CIFS_POSIX
63 #define CIFS_NUM_PROT 2
65 #define CIFS_NUM_PROT 1
66 #endif /* CIFS_POSIX */
69 /* reconnect the socket, tcon, and smb session if needed */
71 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
73 struct TCP_Server_Info *server;
78 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
79 * tcp and smb session status done differently for those three - in the
89 * only tree disconnect, open, and write, (and ulogoff which does not
90 * have tcon) are allowed as we start umount
92 spin_lock(&tcon->tc_lock);
93 if (tcon->status == TID_EXITING) {
94 if (smb_command != SMB_COM_TREE_DISCONNECT) {
95 spin_unlock(&tcon->tc_lock);
96 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
101 spin_unlock(&tcon->tc_lock);
104 rc = cifs_wait_for_server_reconnect(server, tcon->retry);
108 spin_lock(&ses->chan_lock);
109 if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
110 spin_unlock(&ses->chan_lock);
113 spin_unlock(&ses->chan_lock);
115 mutex_lock(&ses->session_mutex);
117 * Recheck after acquire mutex. If another thread is negotiating
118 * and the server never sends an answer the socket will be closed
119 * and tcpStatus set to reconnect.
121 spin_lock(&server->srv_lock);
122 if (server->tcpStatus == CifsNeedReconnect) {
123 spin_unlock(&server->srv_lock);
124 mutex_unlock(&ses->session_mutex);
131 spin_unlock(&server->srv_lock);
134 * need to prevent multiple threads trying to simultaneously
135 * reconnect the same SMB session
137 spin_lock(&ses->ses_lock);
138 spin_lock(&ses->chan_lock);
139 if (!cifs_chan_needs_reconnect(ses, server) &&
140 ses->ses_status == SES_GOOD) {
141 spin_unlock(&ses->chan_lock);
142 spin_unlock(&ses->ses_lock);
144 /* this means that we only need to tree connect */
145 if (tcon->need_reconnect)
146 goto skip_sess_setup;
148 mutex_unlock(&ses->session_mutex);
151 spin_unlock(&ses->chan_lock);
152 spin_unlock(&ses->ses_lock);
154 rc = cifs_negotiate_protocol(0, ses, server);
156 rc = cifs_setup_session(0, ses, server, ses->local_nls);
158 /* do we need to reconnect tcon? */
159 if (rc || !tcon->need_reconnect) {
160 mutex_unlock(&ses->session_mutex);
165 cifs_mark_open_files_invalid(tcon);
166 rc = cifs_tree_connect(0, tcon);
167 mutex_unlock(&ses->session_mutex);
168 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
171 pr_warn_once("reconnect tcon failed rc = %d\n", rc);
175 atomic_inc(&tconInfoReconnectCount);
177 /* tell server Unix caps we support */
179 reset_cifs_unix_caps(0, tcon, NULL, NULL);
182 * Removed call to reopen open files here. It is safer (and faster) to
183 * reopen files one at a time as needed in read and write.
185 * FIXME: what about file locks? don't we need to reclaim them ASAP?
190 * Check if handle based operation so we know whether we can continue
191 * or not without returning to caller to reset file handle
193 switch (smb_command) {
194 case SMB_COM_READ_ANDX:
195 case SMB_COM_WRITE_ANDX:
197 case SMB_COM_FIND_CLOSE2:
198 case SMB_COM_LOCKING_ANDX:
205 /* Allocate and return pointer to an SMB request buffer, and set basic
206 SMB information in the SMB header. If the return code is zero, this
207 function must have filled in request_buf pointer */
209 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
214 rc = cifs_reconnect_tcon(tcon, smb_command);
218 *request_buf = cifs_small_buf_get();
219 if (*request_buf == NULL) {
220 /* BB should we add a retry in here if not a writepage? */
224 header_assemble((struct smb_hdr *) *request_buf, smb_command,
228 cifs_stats_inc(&tcon->num_smbs_sent);
234 small_smb_init_no_tc(const int smb_command, const int wct,
235 struct cifs_ses *ses, void **request_buf)
238 struct smb_hdr *buffer;
240 rc = small_smb_init(smb_command, wct, NULL, request_buf);
244 buffer = (struct smb_hdr *)*request_buf;
245 buffer->Mid = get_next_mid(ses->server);
246 if (ses->capabilities & CAP_UNICODE)
247 buffer->Flags2 |= SMBFLG2_UNICODE;
248 if (ses->capabilities & CAP_STATUS32)
249 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
251 /* uid, tid can stay at zero as set in header assemble */
253 /* BB add support for turning on the signing when
254 this function is used after 1st of session setup requests */
259 /* If the return code is zero, this function must fill in request_buf pointer */
261 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
262 void **request_buf, void **response_buf)
264 *request_buf = cifs_buf_get();
265 if (*request_buf == NULL) {
266 /* BB should we add a retry in here if not a writepage? */
269 /* Although the original thought was we needed the response buf for */
270 /* potential retries of smb operations it turns out we can determine */
271 /* from the mid flags when the request buffer can be resent without */
272 /* having to use a second distinct buffer for the response */
274 *response_buf = *request_buf;
276 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
280 cifs_stats_inc(&tcon->num_smbs_sent);
285 /* If the return code is zero, this function must fill in request_buf pointer */
287 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
288 void **request_buf, void **response_buf)
292 rc = cifs_reconnect_tcon(tcon, smb_command);
296 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
300 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
301 void **request_buf, void **response_buf)
303 spin_lock(&tcon->ses->chan_lock);
304 if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) ||
305 tcon->need_reconnect) {
306 spin_unlock(&tcon->ses->chan_lock);
309 spin_unlock(&tcon->ses->chan_lock);
311 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
314 static int validate_t2(struct smb_t2_rsp *pSMB)
316 unsigned int total_size;
318 /* check for plausible wct */
319 if (pSMB->hdr.WordCount < 10)
322 /* check for parm and data offset going beyond end of smb */
323 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
324 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
327 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
328 if (total_size >= 512)
331 /* check that bcc is at least as big as parms + data, and that it is
332 * less than negotiated smb buffer
334 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
335 if (total_size > get_bcc(&pSMB->hdr) ||
336 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
341 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
342 sizeof(struct smb_t2_rsp) + 16);
347 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
351 char *guid = pSMBr->u.extended_response.GUID;
352 struct TCP_Server_Info *server = ses->server;
354 count = get_bcc(&pSMBr->hdr);
355 if (count < SMB1_CLIENT_GUID_SIZE)
358 spin_lock(&cifs_tcp_ses_lock);
359 if (server->srv_count > 1) {
360 spin_unlock(&cifs_tcp_ses_lock);
361 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
362 cifs_dbg(FYI, "server UID changed\n");
363 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
366 spin_unlock(&cifs_tcp_ses_lock);
367 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
370 if (count == SMB1_CLIENT_GUID_SIZE) {
371 server->sec_ntlmssp = true;
373 count -= SMB1_CLIENT_GUID_SIZE;
374 rc = decode_negTokenInit(
375 pSMBr->u.extended_response.SecurityBlob, count, server);
384 should_set_ext_sec_flag(enum securityEnum sectype)
391 if (global_secflags &
392 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
401 CIFSSMBNegotiate(const unsigned int xid,
402 struct cifs_ses *ses,
403 struct TCP_Server_Info *server)
406 NEGOTIATE_RSP *pSMBr;
413 WARN(1, "%s: server is NULL!\n", __func__);
417 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
418 (void **) &pSMB, (void **) &pSMBr);
422 pSMB->hdr.Mid = get_next_mid(server);
423 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
425 if (should_set_ext_sec_flag(ses->sectype)) {
426 cifs_dbg(FYI, "Requesting extended security\n");
427 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
432 * We know that all the name entries in the protocols array
433 * are short (< 16 bytes anyway) and are NUL terminated.
435 for (i = 0; i < CIFS_NUM_PROT; i++) {
436 size_t len = strlen(protocols[i].name) + 1;
438 memcpy(&pSMB->DialectsArray[count], protocols[i].name, len);
441 inc_rfc1001_len(pSMB, count);
442 pSMB->ByteCount = cpu_to_le16(count);
444 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
445 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
449 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
450 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
451 /* Check wct = 1 error case */
452 if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
453 /* core returns wct = 1, but we do not ask for core - otherwise
454 small wct just comes when dialect index is -1 indicating we
455 could not negotiate a common dialect */
458 } else if (pSMBr->hdr.WordCount != 17) {
463 /* else wct == 17, NTLM or better */
465 server->sec_mode = pSMBr->SecurityMode;
466 if ((server->sec_mode & SECMODE_USER) == 0)
467 cifs_dbg(FYI, "share mode security\n");
469 /* one byte, so no need to convert this or EncryptionKeyLen from
471 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
473 set_credits(server, server->maxReq);
474 /* probably no need to store and check maxvcs */
475 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
476 /* set up max_read for readahead check */
477 server->max_read = server->maxBuf;
478 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
479 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
480 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
481 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
482 server->timeAdj *= 60;
484 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
485 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
486 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
487 CIFS_CRYPTO_KEY_SIZE);
488 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
489 server->capabilities & CAP_EXTENDED_SECURITY) {
490 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
491 rc = decode_ext_sec_blob(ses, pSMBr);
492 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
493 rc = -EIO; /* no crypt key only if plain text pwd */
495 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
496 server->capabilities &= ~CAP_EXTENDED_SECURITY;
500 rc = cifs_enable_signing(server, ses->sign);
502 cifs_buf_release(pSMB);
504 cifs_dbg(FYI, "negprot rc %d\n", rc);
509 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
511 struct smb_hdr *smb_buffer;
514 cifs_dbg(FYI, "In tree disconnect\n");
516 /* BB: do we need to check this? These should never be NULL. */
517 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
521 * No need to return error on this operation if tid invalidated and
522 * closed on server already e.g. due to tcp session crashing. Also,
523 * the tcon is no longer on the list, so no need to take lock before
526 spin_lock(&tcon->ses->chan_lock);
527 if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
528 spin_unlock(&tcon->ses->chan_lock);
531 spin_unlock(&tcon->ses->chan_lock);
533 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
534 (void **)&smb_buffer);
538 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
539 cifs_small_buf_release(smb_buffer);
541 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
543 /* No need to return error on this operation if tid invalidated and
544 closed on server already e.g. due to tcp session crashing */
552 * This is a no-op for now. We're not really interested in the reply, but
553 * rather in the fact that the server sent one and that server->lstrp
556 * FIXME: maybe we should consider checking that the reply matches request?
559 cifs_echo_callback(struct mid_q_entry *mid)
561 struct TCP_Server_Info *server = mid->callback_data;
562 struct cifs_credits credits = { .value = 1, .instance = 0 };
565 add_credits(server, &credits, CIFS_ECHO_OP);
569 CIFSSMBEcho(struct TCP_Server_Info *server)
574 struct smb_rqst rqst = { .rq_iov = iov,
577 cifs_dbg(FYI, "In echo request\n");
579 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
583 if (server->capabilities & CAP_UNICODE)
584 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
586 /* set up echo request */
587 smb->hdr.Tid = 0xffff;
588 smb->hdr.WordCount = 1;
589 put_unaligned_le16(1, &smb->EchoCount);
590 put_bcc(1, &smb->hdr);
592 inc_rfc1001_len(smb, 3);
595 iov[0].iov_base = smb;
596 iov[1].iov_len = get_rfc1002_length(smb);
597 iov[1].iov_base = (char *)smb + 4;
599 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
600 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
602 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
604 cifs_small_buf_release(smb);
610 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
612 LOGOFF_ANDX_REQ *pSMB;
615 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
618 * BB: do we need to check validity of ses and server? They should
619 * always be valid since we have an active reference. If not, that
620 * should probably be a BUG()
622 if (!ses || !ses->server)
625 mutex_lock(&ses->session_mutex);
626 spin_lock(&ses->chan_lock);
627 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
628 spin_unlock(&ses->chan_lock);
629 goto session_already_dead; /* no need to send SMBlogoff if uid
630 already closed due to reconnect */
632 spin_unlock(&ses->chan_lock);
634 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
636 mutex_unlock(&ses->session_mutex);
640 pSMB->hdr.Mid = get_next_mid(ses->server);
642 if (ses->server->sign)
643 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
645 pSMB->hdr.Uid = ses->Suid;
647 pSMB->AndXCommand = 0xFF;
648 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
649 cifs_small_buf_release(pSMB);
650 session_already_dead:
651 mutex_unlock(&ses->session_mutex);
653 /* if session dead then we do not need to do ulogoff,
654 since server closed smb session, no sense reporting
662 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
663 const char *fileName, __u16 type,
664 const struct nls_table *nls_codepage, int remap)
666 TRANSACTION2_SPI_REQ *pSMB = NULL;
667 TRANSACTION2_SPI_RSP *pSMBr = NULL;
668 struct unlink_psx_rq *pRqD;
671 int bytes_returned = 0;
672 __u16 params, param_offset, offset, byte_count;
674 cifs_dbg(FYI, "In POSIX delete\n");
676 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
681 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
683 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
684 PATH_MAX, nls_codepage, remap);
685 name_len++; /* trailing null */
688 name_len = copy_path_name(pSMB->FileName, fileName);
691 params = 6 + name_len;
692 pSMB->MaxParameterCount = cpu_to_le16(2);
693 pSMB->MaxDataCount = 0; /* BB double check this with jra */
694 pSMB->MaxSetupCount = 0;
699 param_offset = offsetof(struct smb_com_transaction2_spi_req,
700 InformationLevel) - 4;
701 offset = param_offset + params;
703 /* Setup pointer to Request Data (inode type).
704 * Note that SMB offsets are from the beginning of SMB which is 4 bytes
705 * in, after RFC1001 field
707 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
708 pRqD->type = cpu_to_le16(type);
709 pSMB->ParameterOffset = cpu_to_le16(param_offset);
710 pSMB->DataOffset = cpu_to_le16(offset);
711 pSMB->SetupCount = 1;
713 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
714 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
716 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
717 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
718 pSMB->ParameterCount = cpu_to_le16(params);
719 pSMB->TotalParameterCount = pSMB->ParameterCount;
720 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
722 inc_rfc1001_len(pSMB, byte_count);
723 pSMB->ByteCount = cpu_to_le16(byte_count);
724 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
725 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
727 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
728 cifs_buf_release(pSMB);
730 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
739 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
740 struct cifs_sb_info *cifs_sb, struct dentry *dentry)
742 DELETE_FILE_REQ *pSMB = NULL;
743 DELETE_FILE_RSP *pSMBr = NULL;
747 int remap = cifs_remap(cifs_sb);
750 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
755 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
756 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
757 PATH_MAX, cifs_sb->local_nls,
759 name_len++; /* trailing null */
762 name_len = copy_path_name(pSMB->fileName, name);
764 pSMB->SearchAttributes =
765 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
766 pSMB->BufferFormat = 0x04;
767 inc_rfc1001_len(pSMB, name_len + 1);
768 pSMB->ByteCount = cpu_to_le16(name_len + 1);
769 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
770 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
771 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
773 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
775 cifs_buf_release(pSMB);
783 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
784 struct cifs_sb_info *cifs_sb)
786 DELETE_DIRECTORY_REQ *pSMB = NULL;
787 DELETE_DIRECTORY_RSP *pSMBr = NULL;
791 int remap = cifs_remap(cifs_sb);
793 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
795 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
800 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
801 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
802 PATH_MAX, cifs_sb->local_nls,
804 name_len++; /* trailing null */
807 name_len = copy_path_name(pSMB->DirName, name);
810 pSMB->BufferFormat = 0x04;
811 inc_rfc1001_len(pSMB, name_len + 1);
812 pSMB->ByteCount = cpu_to_le16(name_len + 1);
813 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
814 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
815 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
817 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
819 cifs_buf_release(pSMB);
826 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
827 struct cifs_tcon *tcon, const char *name,
828 struct cifs_sb_info *cifs_sb)
831 CREATE_DIRECTORY_REQ *pSMB = NULL;
832 CREATE_DIRECTORY_RSP *pSMBr = NULL;
835 int remap = cifs_remap(cifs_sb);
837 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
839 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
844 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
845 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
846 PATH_MAX, cifs_sb->local_nls,
848 name_len++; /* trailing null */
851 name_len = copy_path_name(pSMB->DirName, name);
854 pSMB->BufferFormat = 0x04;
855 inc_rfc1001_len(pSMB, name_len + 1);
856 pSMB->ByteCount = cpu_to_le16(name_len + 1);
857 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
858 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
859 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
861 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
863 cifs_buf_release(pSMB);
870 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
871 __u32 posix_flags, __u64 mode, __u16 *netfid,
872 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
873 const char *name, const struct nls_table *nls_codepage,
876 TRANSACTION2_SPI_REQ *pSMB = NULL;
877 TRANSACTION2_SPI_RSP *pSMBr = NULL;
880 int bytes_returned = 0;
881 __u16 params, param_offset, offset, byte_count, count;
883 OPEN_PSX_RSP *psx_rsp;
885 cifs_dbg(FYI, "In POSIX Create\n");
887 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
892 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
894 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
895 PATH_MAX, nls_codepage, remap);
896 name_len++; /* trailing null */
899 name_len = copy_path_name(pSMB->FileName, name);
902 params = 6 + name_len;
903 count = sizeof(OPEN_PSX_REQ);
904 pSMB->MaxParameterCount = cpu_to_le16(2);
905 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
906 pSMB->MaxSetupCount = 0;
911 param_offset = offsetof(struct smb_com_transaction2_spi_req,
912 InformationLevel) - 4;
913 offset = param_offset + params;
914 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
915 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
916 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
917 pdata->Permissions = cpu_to_le64(mode);
918 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
919 pdata->OpenFlags = cpu_to_le32(*pOplock);
920 pSMB->ParameterOffset = cpu_to_le16(param_offset);
921 pSMB->DataOffset = cpu_to_le16(offset);
922 pSMB->SetupCount = 1;
924 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
925 byte_count = 3 /* pad */ + params + count;
927 pSMB->DataCount = cpu_to_le16(count);
928 pSMB->ParameterCount = cpu_to_le16(params);
929 pSMB->TotalDataCount = pSMB->DataCount;
930 pSMB->TotalParameterCount = pSMB->ParameterCount;
931 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
933 inc_rfc1001_len(pSMB, byte_count);
934 pSMB->ByteCount = cpu_to_le16(byte_count);
935 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
936 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
938 cifs_dbg(FYI, "Posix create returned %d\n", rc);
942 cifs_dbg(FYI, "copying inode info\n");
943 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
945 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
946 rc = -EIO; /* bad smb */
950 /* copy return information to pRetData */
951 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
952 + le16_to_cpu(pSMBr->t2.DataOffset));
954 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
956 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
957 /* Let caller know file was created so we can set the mode. */
958 /* Do we care about the CreateAction in any other cases? */
959 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
960 *pOplock |= CIFS_CREATE_ACTION;
961 /* check to make sure response data is there */
962 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
963 pRetData->Type = cpu_to_le32(-1); /* unknown */
964 cifs_dbg(NOISY, "unknown type\n");
966 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
967 + sizeof(FILE_UNIX_BASIC_INFO)) {
968 cifs_dbg(VFS, "Open response data too small\n");
969 pRetData->Type = cpu_to_le32(-1);
972 memcpy((char *) pRetData,
973 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
974 sizeof(FILE_UNIX_BASIC_INFO));
978 cifs_buf_release(pSMB);
980 if (posix_flags & SMB_O_DIRECTORY)
981 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
983 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
991 static __u16 convert_disposition(int disposition)
995 switch (disposition) {
997 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1000 ofun = SMBOPEN_OAPPEND;
1003 ofun = SMBOPEN_OCREATE;
1006 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1008 case FILE_OVERWRITE:
1009 ofun = SMBOPEN_OTRUNC;
1011 case FILE_OVERWRITE_IF:
1012 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1015 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1016 ofun = SMBOPEN_OAPPEND; /* regular open */
1022 access_flags_to_smbopen_mode(const int access_flags)
1024 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1026 if (masked_flags == GENERIC_READ)
1027 return SMBOPEN_READ;
1028 else if (masked_flags == GENERIC_WRITE)
1029 return SMBOPEN_WRITE;
1031 /* just go for read/write */
1032 return SMBOPEN_READWRITE;
1036 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1037 const char *fileName, const int openDisposition,
1038 const int access_flags, const int create_options, __u16 *netfid,
1039 int *pOplock, FILE_ALL_INFO *pfile_info,
1040 const struct nls_table *nls_codepage, int remap)
1043 OPENX_REQ *pSMB = NULL;
1044 OPENX_RSP *pSMBr = NULL;
1050 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1055 pSMB->AndXCommand = 0xFF; /* none */
1057 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1058 count = 1; /* account for one byte pad to word boundary */
1060 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1061 fileName, PATH_MAX, nls_codepage, remap);
1062 name_len++; /* trailing null */
1065 count = 0; /* no pad */
1066 name_len = copy_path_name(pSMB->fileName, fileName);
1068 if (*pOplock & REQ_OPLOCK)
1069 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1070 else if (*pOplock & REQ_BATCHOPLOCK)
1071 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1073 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1074 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1075 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1076 /* set file as system file if special file such as fifo,
1077 * socket, char or block and server expecting SFU style and
1078 no Unix extensions */
1080 if (create_options & CREATE_OPTION_SPECIAL)
1081 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1082 else /* BB FIXME BB */
1083 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1085 if (create_options & CREATE_OPTION_READONLY)
1086 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1089 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1090 CREATE_OPTIONS_MASK); */
1091 /* BB FIXME END BB */
1093 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1094 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1096 inc_rfc1001_len(pSMB, count);
1098 pSMB->ByteCount = cpu_to_le16(count);
1099 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1100 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1101 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1103 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1105 /* BB verify if wct == 15 */
1107 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1109 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1110 /* Let caller know file was created so we can set the mode. */
1111 /* Do we care about the CreateAction in any other cases? */
1113 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1114 *pOplock |= CIFS_CREATE_ACTION; */
1118 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1119 pfile_info->LastAccessTime = 0; /* BB fixme */
1120 pfile_info->LastWriteTime = 0; /* BB fixme */
1121 pfile_info->ChangeTime = 0; /* BB fixme */
1122 pfile_info->Attributes =
1123 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1124 /* the file_info buf is endian converted by caller */
1125 pfile_info->AllocationSize =
1126 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1127 pfile_info->EndOfFile = pfile_info->AllocationSize;
1128 pfile_info->NumberOfLinks = cpu_to_le32(1);
1129 pfile_info->DeletePending = 0;
1133 cifs_buf_release(pSMB);
1140 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1144 OPEN_REQ *req = NULL;
1145 OPEN_RSP *rsp = NULL;
1149 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1150 struct cifs_tcon *tcon = oparms->tcon;
1151 int remap = cifs_remap(cifs_sb);
1152 const struct nls_table *nls = cifs_sb->local_nls;
1153 int create_options = oparms->create_options;
1154 int desired_access = oparms->desired_access;
1155 int disposition = oparms->disposition;
1156 const char *path = oparms->path;
1159 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1164 /* no commands go after this */
1165 req->AndXCommand = 0xFF;
1167 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1168 /* account for one byte pad to word boundary */
1170 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1171 path, PATH_MAX, nls, remap);
1175 req->NameLength = cpu_to_le16(name_len);
1177 /* BB improve check for buffer overruns BB */
1180 name_len = copy_path_name(req->fileName, path);
1181 req->NameLength = cpu_to_le16(name_len);
1184 if (*oplock & REQ_OPLOCK)
1185 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1186 else if (*oplock & REQ_BATCHOPLOCK)
1187 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1189 req->DesiredAccess = cpu_to_le32(desired_access);
1190 req->AllocationSize = 0;
1193 * Set file as system file if special file such as fifo, socket, char
1194 * or block and server expecting SFU style and no Unix extensions.
1196 if (create_options & CREATE_OPTION_SPECIAL)
1197 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1199 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1202 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1203 * sensitive checks for other servers such as Samba.
1205 if (tcon->ses->capabilities & CAP_UNIX)
1206 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1208 if (create_options & CREATE_OPTION_READONLY)
1209 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1211 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1212 req->CreateDisposition = cpu_to_le32(disposition);
1213 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1215 /* BB Experiment with various impersonation levels and verify */
1216 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1217 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1220 inc_rfc1001_len(req, count);
1222 req->ByteCount = cpu_to_le16(count);
1223 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1224 (struct smb_hdr *)rsp, &bytes_returned, 0);
1225 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1227 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1228 cifs_buf_release(req);
1234 /* 1 byte no need to le_to_cpu */
1235 *oplock = rsp->OplockLevel;
1236 /* cifs fid stays in le */
1237 oparms->fid->netfid = rsp->Fid;
1238 oparms->fid->access = desired_access;
1240 /* Let caller know file was created so we can set the mode. */
1241 /* Do we care about the CreateAction in any other cases? */
1242 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1243 *oplock |= CIFS_CREATE_ACTION;
1246 /* copy commonly used attributes */
1247 memcpy(&buf->common_attributes,
1248 &rsp->common_attributes,
1249 sizeof(buf->common_attributes));
1250 /* the file_info buf is endian converted by caller */
1251 buf->AllocationSize = rsp->AllocationSize;
1252 buf->EndOfFile = rsp->EndOfFile;
1253 buf->NumberOfLinks = cpu_to_le32(1);
1254 buf->DeletePending = 0;
1257 cifs_buf_release(req);
1261 static void cifs_readv_worker(struct work_struct *work)
1263 struct cifs_io_subrequest *rdata =
1264 container_of(work, struct cifs_io_subrequest, subreq.work);
1266 netfs_read_subreq_terminated(&rdata->subreq, rdata->result, false);
1270 cifs_readv_callback(struct mid_q_entry *mid)
1272 struct cifs_io_subrequest *rdata = mid->callback_data;
1273 struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode);
1274 struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
1275 struct TCP_Server_Info *server = tcon->ses->server;
1276 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1278 .rq_iter = rdata->subreq.io_iter };
1279 struct cifs_credits credits = {
1282 .rreq_debug_id = rdata->rreq->debug_id,
1283 .rreq_debug_index = rdata->subreq.debug_index,
1286 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n",
1287 __func__, mid->mid, mid->mid_state, rdata->result,
1290 switch (mid->mid_state) {
1291 case MID_RESPONSE_RECEIVED:
1292 /* result already set, check signature */
1296 iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes);
1297 rc = cifs_verify_signature(&rqst, server,
1298 mid->sequence_number);
1300 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1303 /* FIXME: should this be counted toward the initiating task? */
1304 task_io_account_read(rdata->got_bytes);
1305 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1307 case MID_REQUEST_SUBMITTED:
1308 case MID_RETRY_NEEDED:
1309 rdata->result = -EAGAIN;
1310 if (server->sign && rdata->got_bytes)
1311 /* reset bytes number since we can not check a sign */
1312 rdata->got_bytes = 0;
1313 /* FIXME: should this be counted toward the initiating task? */
1314 task_io_account_read(rdata->got_bytes);
1315 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1318 rdata->result = -EIO;
1321 if (rdata->result == -ENODATA) {
1323 __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
1325 size_t trans = rdata->subreq.transferred + rdata->got_bytes;
1326 if (trans < rdata->subreq.len &&
1327 rdata->subreq.start + trans == ictx->remote_i_size) {
1329 __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
1330 } else if (rdata->got_bytes > 0) {
1331 __set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags);
1335 rdata->credits.value = 0;
1336 rdata->subreq.transferred += rdata->got_bytes;
1337 INIT_WORK(&rdata->subreq.work, cifs_readv_worker);
1338 queue_work(cifsiod_wq, &rdata->subreq.work);
1340 add_credits(server, &credits, 0);
1343 /* cifs_async_readv - send an async write, and set up mid to handle result */
1345 cifs_async_readv(struct cifs_io_subrequest *rdata)
1348 READ_REQ *smb = NULL;
1350 struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
1351 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1354 cifs_dbg(FYI, "%s: offset=%llu bytes=%zu\n",
1355 __func__, rdata->subreq.start, rdata->subreq.len);
1357 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1360 wct = 10; /* old style read */
1361 if ((rdata->subreq.start >> 32) > 0) {
1362 /* can not handle this big offset for old */
1367 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1371 smb->hdr.Pid = cpu_to_le16((__u16)rdata->req->pid);
1372 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->req->pid >> 16));
1374 smb->AndXCommand = 0xFF; /* none */
1375 smb->Fid = rdata->req->cfile->fid.netfid;
1376 smb->OffsetLow = cpu_to_le32(rdata->subreq.start & 0xFFFFFFFF);
1378 smb->OffsetHigh = cpu_to_le32(rdata->subreq.start >> 32);
1380 smb->MaxCount = cpu_to_le16(rdata->subreq.len & 0xFFFF);
1381 smb->MaxCountHigh = cpu_to_le32(rdata->subreq.len >> 16);
1385 /* old style read */
1386 struct smb_com_readx_req *smbr =
1387 (struct smb_com_readx_req *)smb;
1388 smbr->ByteCount = 0;
1391 /* 4 for RFC1001 length + 1 for BCC */
1392 rdata->iov[0].iov_base = smb;
1393 rdata->iov[0].iov_len = 4;
1394 rdata->iov[1].iov_base = (char *)smb + 4;
1395 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1397 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1398 cifs_readv_callback, NULL, rdata, 0, NULL);
1401 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1402 cifs_small_buf_release(smb);
1407 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1408 unsigned int *nbytes, char **buf, int *pbuf_type)
1411 READ_REQ *pSMB = NULL;
1412 READ_RSP *pSMBr = NULL;
1413 char *pReadData = NULL;
1415 int resp_buf_type = 0;
1417 struct kvec rsp_iov;
1418 __u32 pid = io_parms->pid;
1419 __u16 netfid = io_parms->netfid;
1420 __u64 offset = io_parms->offset;
1421 struct cifs_tcon *tcon = io_parms->tcon;
1422 unsigned int count = io_parms->length;
1424 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1425 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1428 wct = 10; /* old style read */
1429 if ((offset >> 32) > 0) {
1430 /* can not handle this big offset for old */
1436 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1440 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1441 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1443 /* tcon and ses pointer are checked in smb_init */
1444 if (tcon->ses->server == NULL)
1445 return -ECONNABORTED;
1447 pSMB->AndXCommand = 0xFF; /* none */
1449 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1451 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1453 pSMB->Remaining = 0;
1454 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1455 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1457 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1459 /* old style read */
1460 struct smb_com_readx_req *pSMBW =
1461 (struct smb_com_readx_req *)pSMB;
1462 pSMBW->ByteCount = 0;
1465 iov[0].iov_base = (char *)pSMB;
1466 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1467 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1468 CIFS_LOG_ERROR, &rsp_iov);
1469 cifs_small_buf_release(pSMB);
1470 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1471 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1473 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1475 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1476 data_length = data_length << 16;
1477 data_length += le16_to_cpu(pSMBr->DataLength);
1478 *nbytes = data_length;
1480 /*check that DataLength would not go beyond end of SMB */
1481 if ((data_length > CIFSMaxBufSize)
1482 || (data_length > count)) {
1483 cifs_dbg(FYI, "bad length %d for count %d\n",
1484 data_length, count);
1488 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1489 le16_to_cpu(pSMBr->DataOffset);
1490 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1491 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1493 }*/ /* can not use copy_to_user when using page cache*/
1495 memcpy(*buf, pReadData, data_length);
1500 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1501 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1502 /* return buffer to caller to free */
1503 *buf = rsp_iov.iov_base;
1504 if (resp_buf_type == CIFS_SMALL_BUFFER)
1505 *pbuf_type = CIFS_SMALL_BUFFER;
1506 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1507 *pbuf_type = CIFS_LARGE_BUFFER;
1508 } /* else no valid buffer on return - leave as null */
1510 /* Note: On -EAGAIN error only caller can retry on handle based calls
1511 since file handle passed in no longer valid */
1517 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1518 unsigned int *nbytes, const char *buf)
1521 WRITE_REQ *pSMB = NULL;
1522 WRITE_RSP *pSMBr = NULL;
1523 int bytes_returned, wct;
1526 __u32 pid = io_parms->pid;
1527 __u16 netfid = io_parms->netfid;
1528 __u64 offset = io_parms->offset;
1529 struct cifs_tcon *tcon = io_parms->tcon;
1530 unsigned int count = io_parms->length;
1534 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1535 if (tcon->ses == NULL)
1536 return -ECONNABORTED;
1538 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1542 if ((offset >> 32) > 0) {
1543 /* can not handle big offset for old srv */
1548 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1553 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1554 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1556 /* tcon and ses pointer are checked in smb_init */
1557 if (tcon->ses->server == NULL)
1558 return -ECONNABORTED;
1560 pSMB->AndXCommand = 0xFF; /* none */
1562 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1564 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1566 pSMB->Reserved = 0xFFFFFFFF;
1567 pSMB->WriteMode = 0;
1568 pSMB->Remaining = 0;
1570 /* Can increase buffer size if buffer is big enough in some cases ie we
1571 can send more if LARGE_WRITE_X capability returned by the server and if
1572 our buffer is big enough or if we convert to iovecs on socket writes
1573 and eliminate the copy to the CIFS buffer */
1574 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1575 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1577 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1581 if (bytes_sent > count)
1584 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1586 memcpy(pSMB->Data, buf, bytes_sent);
1587 else if (count != 0) {
1589 cifs_buf_release(pSMB);
1591 } /* else setting file size with write of zero bytes */
1593 byte_count = bytes_sent + 1; /* pad */
1594 else /* wct == 12 */
1595 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1597 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1598 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1599 inc_rfc1001_len(pSMB, byte_count);
1602 pSMB->ByteCount = cpu_to_le16(byte_count);
1603 else { /* old style write has byte count 4 bytes earlier
1605 struct smb_com_writex_req *pSMBW =
1606 (struct smb_com_writex_req *)pSMB;
1607 pSMBW->ByteCount = cpu_to_le16(byte_count);
1610 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1611 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1612 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1614 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1616 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1617 *nbytes = (*nbytes) << 16;
1618 *nbytes += le16_to_cpu(pSMBr->Count);
1621 * Mask off high 16 bits when bytes written as returned by the
1622 * server is greater than bytes requested by the client. Some
1623 * OS/2 servers are known to set incorrect CountHigh values.
1625 if (*nbytes > count)
1629 cifs_buf_release(pSMB);
1631 /* Note: On -EAGAIN error only caller can retry on handle based calls
1632 since file handle passed in no longer valid */
1638 * Check the mid_state and signature on received buffer (if any), and queue the
1639 * workqueue completion task.
1642 cifs_writev_callback(struct mid_q_entry *mid)
1644 struct cifs_io_subrequest *wdata = mid->callback_data;
1645 struct TCP_Server_Info *server = wdata->server;
1646 struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
1647 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1648 struct cifs_credits credits = {
1651 .rreq_debug_id = wdata->rreq->debug_id,
1652 .rreq_debug_index = wdata->subreq.debug_index,
1657 switch (mid->mid_state) {
1658 case MID_RESPONSE_RECEIVED:
1659 result = cifs_check_receive(mid, tcon->ses->server, 0);
1663 written = le16_to_cpu(smb->CountHigh);
1665 written += le16_to_cpu(smb->Count);
1667 * Mask off high 16 bits when bytes written as returned
1668 * by the server is greater than bytes requested by the
1669 * client. OS/2 servers are known to set incorrect
1672 if (written > wdata->subreq.len)
1675 if (written < wdata->subreq.len) {
1680 __set_bit(NETFS_SREQ_MADE_PROGRESS, &wdata->subreq.flags);
1683 case MID_REQUEST_SUBMITTED:
1684 case MID_RETRY_NEEDED:
1692 trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index,
1693 wdata->credits.value,
1694 server->credits, server->in_flight,
1695 0, cifs_trace_rw_credits_write_response_clear);
1696 wdata->credits.value = 0;
1697 cifs_write_subrequest_terminated(wdata, result, true);
1699 trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0,
1700 server->credits, server->in_flight,
1701 credits.value, cifs_trace_rw_credits_write_response_add);
1702 add_credits(tcon->ses->server, &credits, 0);
1705 /* cifs_async_writev - send an async write, and set up mid to handle result */
1707 cifs_async_writev(struct cifs_io_subrequest *wdata)
1710 WRITE_REQ *smb = NULL;
1712 struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
1714 struct smb_rqst rqst = { };
1716 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1720 if (wdata->subreq.start >> 32 > 0) {
1721 /* can not handle big offset for old srv */
1727 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
1729 goto async_writev_out;
1731 smb->hdr.Pid = cpu_to_le16((__u16)wdata->req->pid);
1732 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->req->pid >> 16));
1734 smb->AndXCommand = 0xFF; /* none */
1735 smb->Fid = wdata->req->cfile->fid.netfid;
1736 smb->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF);
1738 smb->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32);
1739 smb->Reserved = 0xFFFFFFFF;
1744 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1746 /* 4 for RFC1001 length + 1 for BCC */
1748 iov[0].iov_base = smb;
1749 iov[1].iov_len = get_rfc1002_length(smb) + 1;
1750 iov[1].iov_base = (char *)smb + 4;
1754 rqst.rq_iter = wdata->subreq.io_iter;
1756 cifs_dbg(FYI, "async write at %llu %zu bytes\n",
1757 wdata->subreq.start, wdata->subreq.len);
1759 smb->DataLengthLow = cpu_to_le16(wdata->subreq.len & 0xFFFF);
1760 smb->DataLengthHigh = cpu_to_le16(wdata->subreq.len >> 16);
1763 inc_rfc1001_len(&smb->hdr, wdata->subreq.len + 1);
1764 put_bcc(wdata->subreq.len + 1, &smb->hdr);
1767 struct smb_com_writex_req *smbw =
1768 (struct smb_com_writex_req *)smb;
1769 inc_rfc1001_len(&smbw->hdr, wdata->subreq.len + 5);
1770 put_bcc(wdata->subreq.len + 5, &smbw->hdr);
1771 iov[1].iov_len += 4; /* pad bigger by four bytes */
1774 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
1775 cifs_writev_callback, NULL, wdata, 0, NULL);
1776 /* Can't touch wdata if rc == 0 */
1778 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1781 cifs_small_buf_release(smb);
1784 add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
1785 cifs_write_subrequest_terminated(wdata, rc, false);
1790 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
1791 unsigned int *nbytes, struct kvec *iov, int n_vec)
1794 WRITE_REQ *pSMB = NULL;
1797 int resp_buf_type = 0;
1798 __u32 pid = io_parms->pid;
1799 __u16 netfid = io_parms->netfid;
1800 __u64 offset = io_parms->offset;
1801 struct cifs_tcon *tcon = io_parms->tcon;
1802 unsigned int count = io_parms->length;
1803 struct kvec rsp_iov;
1807 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
1809 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1813 if ((offset >> 32) > 0) {
1814 /* can not handle big offset for old srv */
1818 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
1822 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1823 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1825 /* tcon and ses pointer are checked in smb_init */
1826 if (tcon->ses->server == NULL)
1827 return -ECONNABORTED;
1829 pSMB->AndXCommand = 0xFF; /* none */
1831 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1833 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1834 pSMB->Reserved = 0xFFFFFFFF;
1835 pSMB->WriteMode = 0;
1836 pSMB->Remaining = 0;
1839 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1841 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1842 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1843 /* header + 1 byte pad */
1844 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
1846 inc_rfc1001_len(pSMB, count + 1);
1847 else /* wct == 12 */
1848 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
1850 pSMB->ByteCount = cpu_to_le16(count + 1);
1851 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1852 struct smb_com_writex_req *pSMBW =
1853 (struct smb_com_writex_req *)pSMB;
1854 pSMBW->ByteCount = cpu_to_le16(count + 5);
1856 iov[0].iov_base = pSMB;
1858 iov[0].iov_len = smb_hdr_len + 4;
1859 else /* wct == 12 pad bigger by four bytes */
1860 iov[0].iov_len = smb_hdr_len + 8;
1862 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
1864 cifs_small_buf_release(pSMB);
1865 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1867 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
1868 } else if (resp_buf_type == 0) {
1869 /* presumably this can not happen, but best to be safe */
1872 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
1873 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1874 *nbytes = (*nbytes) << 16;
1875 *nbytes += le16_to_cpu(pSMBr->Count);
1878 * Mask off high 16 bits when bytes written as returned by the
1879 * server is greater than bytes requested by the client. OS/2
1880 * servers are known to set incorrect CountHigh values.
1882 if (*nbytes > count)
1886 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1888 /* Note: On -EAGAIN error only caller can retry on handle based calls
1889 since file handle passed in no longer valid */
1894 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
1895 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
1896 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
1899 LOCK_REQ *pSMB = NULL;
1901 struct kvec rsp_iov;
1905 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
1906 num_lock, num_unlock);
1908 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1913 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
1914 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
1915 pSMB->LockType = lock_type;
1916 pSMB->AndXCommand = 0xFF; /* none */
1917 pSMB->Fid = netfid; /* netfid stays le */
1919 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1920 inc_rfc1001_len(pSMB, count);
1921 pSMB->ByteCount = cpu_to_le16(count);
1923 iov[0].iov_base = (char *)pSMB;
1924 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
1925 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1926 iov[1].iov_base = (char *)buf;
1927 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1929 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1930 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
1931 CIFS_NO_RSP_BUF, &rsp_iov);
1932 cifs_small_buf_release(pSMB);
1934 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
1940 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
1941 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
1942 const __u64 offset, const __u32 numUnlock,
1943 const __u32 numLock, const __u8 lockType,
1944 const bool waitFlag, const __u8 oplock_level)
1947 LOCK_REQ *pSMB = NULL;
1948 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
1953 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
1954 (int)waitFlag, numLock);
1955 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1960 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1961 /* no response expected */
1962 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
1964 } else if (waitFlag) {
1965 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1966 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
1971 pSMB->NumberOfLocks = cpu_to_le16(numLock);
1972 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
1973 pSMB->LockType = lockType;
1974 pSMB->OplockLevel = oplock_level;
1975 pSMB->AndXCommand = 0xFF; /* none */
1976 pSMB->Fid = smb_file_id; /* netfid stays le */
1978 if ((numLock != 0) || (numUnlock != 0)) {
1979 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
1980 /* BB where to store pid high? */
1981 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
1982 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
1983 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
1984 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
1985 count = sizeof(LOCKING_ANDX_RANGE);
1990 inc_rfc1001_len(pSMB, count);
1991 pSMB->ByteCount = cpu_to_le16(count);
1994 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1995 (struct smb_hdr *) pSMB, &bytes_returned);
1997 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
1998 cifs_small_buf_release(pSMB);
1999 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2001 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2003 /* Note: On -EAGAIN error only caller can retry on handle based calls
2004 since file handle passed in no longer valid */
2009 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2010 const __u16 smb_file_id, const __u32 netpid,
2011 const loff_t start_offset, const __u64 len,
2012 struct file_lock *pLockData, const __u16 lock_type,
2013 const bool waitFlag)
2015 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2016 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2017 struct cifs_posix_lock *parm_data;
2020 int bytes_returned = 0;
2021 int resp_buf_type = 0;
2022 __u16 params, param_offset, offset, byte_count, count;
2024 struct kvec rsp_iov;
2026 cifs_dbg(FYI, "Posix Lock\n");
2028 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2033 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2036 pSMB->MaxSetupCount = 0;
2039 pSMB->Reserved2 = 0;
2040 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2041 offset = param_offset + params;
2043 count = sizeof(struct cifs_posix_lock);
2044 pSMB->MaxParameterCount = cpu_to_le16(2);
2045 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2046 pSMB->SetupCount = 1;
2047 pSMB->Reserved3 = 0;
2049 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2051 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2052 byte_count = 3 /* pad */ + params + count;
2053 pSMB->DataCount = cpu_to_le16(count);
2054 pSMB->ParameterCount = cpu_to_le16(params);
2055 pSMB->TotalDataCount = pSMB->DataCount;
2056 pSMB->TotalParameterCount = pSMB->ParameterCount;
2057 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2058 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2059 parm_data = (struct cifs_posix_lock *)
2060 (((char *)pSMB) + offset + 4);
2062 parm_data->lock_type = cpu_to_le16(lock_type);
2064 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2065 parm_data->lock_flags = cpu_to_le16(1);
2066 pSMB->Timeout = cpu_to_le32(-1);
2070 parm_data->pid = cpu_to_le32(netpid);
2071 parm_data->start = cpu_to_le64(start_offset);
2072 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2074 pSMB->DataOffset = cpu_to_le16(offset);
2075 pSMB->Fid = smb_file_id;
2076 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2077 pSMB->Reserved4 = 0;
2078 inc_rfc1001_len(pSMB, byte_count);
2079 pSMB->ByteCount = cpu_to_le16(byte_count);
2081 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2082 (struct smb_hdr *) pSMBr, &bytes_returned);
2084 iov[0].iov_base = (char *)pSMB;
2085 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2086 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2087 &resp_buf_type, timeout, &rsp_iov);
2088 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2090 cifs_small_buf_release(pSMB);
2093 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2094 } else if (pLockData) {
2095 /* lock structure can be returned on get */
2098 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2100 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2101 rc = -EIO; /* bad smb */
2104 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2105 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2106 if (data_count < sizeof(struct cifs_posix_lock)) {
2110 parm_data = (struct cifs_posix_lock *)
2111 ((char *)&pSMBr->hdr.Protocol + data_offset);
2112 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2113 pLockData->c.flc_type = F_UNLCK;
2115 if (parm_data->lock_type ==
2116 cpu_to_le16(CIFS_RDLCK))
2117 pLockData->c.flc_type = F_RDLCK;
2118 else if (parm_data->lock_type ==
2119 cpu_to_le16(CIFS_WRLCK))
2120 pLockData->c.flc_type = F_WRLCK;
2122 pLockData->fl_start = le64_to_cpu(parm_data->start);
2123 pLockData->fl_end = pLockData->fl_start +
2124 (le64_to_cpu(parm_data->length) ?
2125 le64_to_cpu(parm_data->length) - 1 : 0);
2126 pLockData->c.flc_pid = -le32_to_cpu(parm_data->pid);
2131 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2133 /* Note: On -EAGAIN error only caller can retry on handle based calls
2134 since file handle passed in no longer valid */
2141 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2144 CLOSE_REQ *pSMB = NULL;
2145 cifs_dbg(FYI, "In CIFSSMBClose\n");
2147 /* do not retry on dead session on close */
2148 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2154 pSMB->FileID = (__u16) smb_file_id;
2155 pSMB->LastWriteTime = 0xFFFFFFFF;
2156 pSMB->ByteCount = 0;
2157 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2158 cifs_small_buf_release(pSMB);
2159 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2162 /* EINTR is expected when user ctl-c to kill app */
2163 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2167 /* Since session is dead, file will be closed on server already */
2175 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2178 FLUSH_REQ *pSMB = NULL;
2179 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2181 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2185 pSMB->FileID = (__u16) smb_file_id;
2186 pSMB->ByteCount = 0;
2187 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2188 cifs_small_buf_release(pSMB);
2189 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2191 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2196 int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2197 struct dentry *source_dentry,
2198 const char *from_name, const char *to_name,
2199 struct cifs_sb_info *cifs_sb)
2202 RENAME_REQ *pSMB = NULL;
2203 RENAME_RSP *pSMBr = NULL;
2205 int name_len, name_len2;
2207 int remap = cifs_remap(cifs_sb);
2209 cifs_dbg(FYI, "In CIFSSMBRename\n");
2211 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2216 pSMB->BufferFormat = 0x04;
2217 pSMB->SearchAttributes =
2218 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2221 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2222 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2223 from_name, PATH_MAX,
2224 cifs_sb->local_nls, remap);
2225 name_len++; /* trailing null */
2227 pSMB->OldFileName[name_len] = 0x04; /* pad */
2228 /* protocol requires ASCII signature byte on Unicode string */
2229 pSMB->OldFileName[name_len + 1] = 0x00;
2231 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2232 to_name, PATH_MAX, cifs_sb->local_nls,
2234 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2235 name_len2 *= 2; /* convert to bytes */
2237 name_len = copy_path_name(pSMB->OldFileName, from_name);
2238 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2239 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2240 name_len2++; /* signature byte */
2243 count = 1 /* 1st signature byte */ + name_len + name_len2;
2244 inc_rfc1001_len(pSMB, count);
2245 pSMB->ByteCount = cpu_to_le16(count);
2247 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2248 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2249 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2251 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2253 cifs_buf_release(pSMB);
2261 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2262 int netfid, const char *target_name,
2263 const struct nls_table *nls_codepage, int remap)
2265 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2266 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2267 struct set_file_rename *rename_info;
2269 char dummy_string[30];
2271 int bytes_returned = 0;
2273 __u16 params, param_offset, offset, count, byte_count;
2275 cifs_dbg(FYI, "Rename to File by handle\n");
2276 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2282 pSMB->MaxSetupCount = 0;
2286 pSMB->Reserved2 = 0;
2287 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2288 offset = param_offset + params;
2290 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2291 data_offset = (char *)(pSMB) + offset + 4;
2292 rename_info = (struct set_file_rename *) data_offset;
2293 pSMB->MaxParameterCount = cpu_to_le16(2);
2294 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2295 pSMB->SetupCount = 1;
2296 pSMB->Reserved3 = 0;
2297 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2298 byte_count = 3 /* pad */ + params;
2299 pSMB->ParameterCount = cpu_to_le16(params);
2300 pSMB->TotalParameterCount = pSMB->ParameterCount;
2301 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2302 pSMB->DataOffset = cpu_to_le16(offset);
2303 /* construct random name ".cifs_tmp<inodenum><mid>" */
2304 rename_info->overwrite = cpu_to_le32(1);
2305 rename_info->root_fid = 0;
2306 /* unicode only call */
2307 if (target_name == NULL) {
2308 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2310 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2311 dummy_string, 24, nls_codepage, remap);
2314 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2315 target_name, PATH_MAX, nls_codepage,
2318 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2319 count = sizeof(struct set_file_rename) + (2 * len_of_str);
2320 byte_count += count;
2321 pSMB->DataCount = cpu_to_le16(count);
2322 pSMB->TotalDataCount = pSMB->DataCount;
2324 pSMB->InformationLevel =
2325 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2326 pSMB->Reserved4 = 0;
2327 inc_rfc1001_len(pSMB, byte_count);
2328 pSMB->ByteCount = cpu_to_le16(byte_count);
2329 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2330 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2331 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2333 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2336 cifs_buf_release(pSMB);
2338 /* Note: On -EAGAIN error only caller can retry on handle based calls
2339 since file handle passed in no longer valid */
2345 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2346 const char *fromName, const char *toName,
2347 const struct nls_table *nls_codepage, int remap)
2349 TRANSACTION2_SPI_REQ *pSMB = NULL;
2350 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2353 int name_len_target;
2355 int bytes_returned = 0;
2356 __u16 params, param_offset, offset, byte_count;
2358 cifs_dbg(FYI, "In Symlink Unix style\n");
2360 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2365 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2367 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2368 /* find define for this maxpathcomponent */
2369 PATH_MAX, nls_codepage, remap);
2370 name_len++; /* trailing null */
2374 name_len = copy_path_name(pSMB->FileName, fromName);
2376 params = 6 + name_len;
2377 pSMB->MaxSetupCount = 0;
2381 pSMB->Reserved2 = 0;
2382 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2383 InformationLevel) - 4;
2384 offset = param_offset + params;
2386 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2387 data_offset = (char *)pSMB + offset + 4;
2388 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2390 cifsConvertToUTF16((__le16 *) data_offset, toName,
2391 /* find define for this maxpathcomponent */
2392 PATH_MAX, nls_codepage, remap);
2393 name_len_target++; /* trailing null */
2394 name_len_target *= 2;
2396 name_len_target = copy_path_name(data_offset, toName);
2399 pSMB->MaxParameterCount = cpu_to_le16(2);
2400 /* BB find exact max on data count below from sess */
2401 pSMB->MaxDataCount = cpu_to_le16(1000);
2402 pSMB->SetupCount = 1;
2403 pSMB->Reserved3 = 0;
2404 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2405 byte_count = 3 /* pad */ + params + name_len_target;
2406 pSMB->DataCount = cpu_to_le16(name_len_target);
2407 pSMB->ParameterCount = cpu_to_le16(params);
2408 pSMB->TotalDataCount = pSMB->DataCount;
2409 pSMB->TotalParameterCount = pSMB->ParameterCount;
2410 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2411 pSMB->DataOffset = cpu_to_le16(offset);
2412 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2413 pSMB->Reserved4 = 0;
2414 inc_rfc1001_len(pSMB, byte_count);
2415 pSMB->ByteCount = cpu_to_le16(byte_count);
2416 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2417 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2418 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2420 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2423 cifs_buf_release(pSMB);
2426 goto createSymLinkRetry;
2432 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2433 const char *fromName, const char *toName,
2434 const struct nls_table *nls_codepage, int remap)
2436 TRANSACTION2_SPI_REQ *pSMB = NULL;
2437 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2440 int name_len_target;
2442 int bytes_returned = 0;
2443 __u16 params, param_offset, offset, byte_count;
2445 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2446 createHardLinkRetry:
2447 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2452 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2453 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2454 PATH_MAX, nls_codepage, remap);
2455 name_len++; /* trailing null */
2459 name_len = copy_path_name(pSMB->FileName, toName);
2461 params = 6 + name_len;
2462 pSMB->MaxSetupCount = 0;
2466 pSMB->Reserved2 = 0;
2467 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2468 InformationLevel) - 4;
2469 offset = param_offset + params;
2471 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2472 data_offset = (char *)pSMB + offset + 4;
2473 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2475 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2476 PATH_MAX, nls_codepage, remap);
2477 name_len_target++; /* trailing null */
2478 name_len_target *= 2;
2480 name_len_target = copy_path_name(data_offset, fromName);
2483 pSMB->MaxParameterCount = cpu_to_le16(2);
2484 /* BB find exact max on data count below from sess*/
2485 pSMB->MaxDataCount = cpu_to_le16(1000);
2486 pSMB->SetupCount = 1;
2487 pSMB->Reserved3 = 0;
2488 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2489 byte_count = 3 /* pad */ + params + name_len_target;
2490 pSMB->ParameterCount = cpu_to_le16(params);
2491 pSMB->TotalParameterCount = pSMB->ParameterCount;
2492 pSMB->DataCount = cpu_to_le16(name_len_target);
2493 pSMB->TotalDataCount = pSMB->DataCount;
2494 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2495 pSMB->DataOffset = cpu_to_le16(offset);
2496 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2497 pSMB->Reserved4 = 0;
2498 inc_rfc1001_len(pSMB, byte_count);
2499 pSMB->ByteCount = cpu_to_le16(byte_count);
2500 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2501 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2502 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2504 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2507 cifs_buf_release(pSMB);
2509 goto createHardLinkRetry;
2514 int CIFSCreateHardLink(const unsigned int xid,
2515 struct cifs_tcon *tcon,
2516 struct dentry *source_dentry,
2517 const char *from_name, const char *to_name,
2518 struct cifs_sb_info *cifs_sb)
2521 NT_RENAME_REQ *pSMB = NULL;
2522 RENAME_RSP *pSMBr = NULL;
2524 int name_len, name_len2;
2526 int remap = cifs_remap(cifs_sb);
2528 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2529 winCreateHardLinkRetry:
2531 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2536 pSMB->SearchAttributes =
2537 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2539 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2540 pSMB->ClusterCount = 0;
2542 pSMB->BufferFormat = 0x04;
2544 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2546 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2547 PATH_MAX, cifs_sb->local_nls, remap);
2548 name_len++; /* trailing null */
2551 /* protocol specifies ASCII buffer format (0x04) for unicode */
2552 pSMB->OldFileName[name_len] = 0x04;
2553 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2555 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2556 to_name, PATH_MAX, cifs_sb->local_nls,
2558 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2559 name_len2 *= 2; /* convert to bytes */
2561 name_len = copy_path_name(pSMB->OldFileName, from_name);
2562 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2563 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2564 name_len2++; /* signature byte */
2567 count = 1 /* string type byte */ + name_len + name_len2;
2568 inc_rfc1001_len(pSMB, count);
2569 pSMB->ByteCount = cpu_to_le16(count);
2571 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2572 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2573 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2575 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2577 cifs_buf_release(pSMB);
2579 goto winCreateHardLinkRetry;
2585 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2586 const unsigned char *searchName, char **symlinkinfo,
2587 const struct nls_table *nls_codepage, int remap)
2589 /* SMB_QUERY_FILE_UNIX_LINK */
2590 TRANSACTION2_QPI_REQ *pSMB = NULL;
2591 TRANSACTION2_QPI_RSP *pSMBr = NULL;
2595 __u16 params, byte_count;
2598 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
2601 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2606 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2608 cifsConvertToUTF16((__le16 *) pSMB->FileName,
2609 searchName, PATH_MAX, nls_codepage,
2611 name_len++; /* trailing null */
2614 name_len = copy_path_name(pSMB->FileName, searchName);
2617 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
2618 pSMB->TotalDataCount = 0;
2619 pSMB->MaxParameterCount = cpu_to_le16(2);
2620 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2621 pSMB->MaxSetupCount = 0;
2625 pSMB->Reserved2 = 0;
2626 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2627 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
2628 pSMB->DataCount = 0;
2629 pSMB->DataOffset = 0;
2630 pSMB->SetupCount = 1;
2631 pSMB->Reserved3 = 0;
2632 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2633 byte_count = params + 1 /* pad */ ;
2634 pSMB->TotalParameterCount = cpu_to_le16(params);
2635 pSMB->ParameterCount = pSMB->TotalParameterCount;
2636 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2637 pSMB->Reserved4 = 0;
2638 inc_rfc1001_len(pSMB, byte_count);
2639 pSMB->ByteCount = cpu_to_le16(byte_count);
2641 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2642 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2644 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
2646 /* decode response */
2648 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2649 /* BB also check enough total bytes returned */
2650 if (rc || get_bcc(&pSMBr->hdr) < 2)
2654 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2656 data_start = ((char *) &pSMBr->hdr.Protocol) +
2657 le16_to_cpu(pSMBr->t2.DataOffset);
2659 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2664 /* BB FIXME investigate remapping reserved chars here */
2665 *symlinkinfo = cifs_strndup_from_utf16(data_start,
2666 count, is_unicode, nls_codepage);
2671 cifs_buf_release(pSMB);
2673 goto querySymLinkRetry;
2677 int cifs_query_reparse_point(const unsigned int xid,
2678 struct cifs_tcon *tcon,
2679 struct cifs_sb_info *cifs_sb,
2680 const char *full_path,
2681 u32 *tag, struct kvec *rsp,
2684 struct reparse_data_buffer *buf;
2685 struct cifs_open_parms oparms;
2686 TRANSACT_IOCTL_REQ *io_req = NULL;
2687 TRANSACT_IOCTL_RSP *io_rsp = NULL;
2688 struct cifs_fid fid;
2689 __u32 data_offset, data_count, len;
2695 cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
2697 if (cap_unix(tcon->ses))
2700 oparms = (struct cifs_open_parms) {
2703 .desired_access = FILE_READ_ATTRIBUTES,
2704 .create_options = cifs_create_options(cifs_sb,
2705 OPEN_REPARSE_POINT),
2706 .disposition = FILE_OPEN,
2711 rc = CIFS_open(xid, &oparms, &oplock, NULL);
2715 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon,
2716 (void **)&io_req, (void **)&io_rsp);
2720 io_req->TotalParameterCount = 0;
2721 io_req->TotalDataCount = 0;
2722 io_req->MaxParameterCount = cpu_to_le32(2);
2723 /* BB find exact data count max from sess structure BB */
2724 io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
2725 io_req->MaxSetupCount = 4;
2726 io_req->Reserved = 0;
2727 io_req->ParameterOffset = 0;
2728 io_req->DataCount = 0;
2729 io_req->DataOffset = 0;
2730 io_req->SetupCount = 4;
2731 io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2732 io_req->ParameterCount = io_req->TotalParameterCount;
2733 io_req->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
2734 io_req->IsFsctl = 1;
2735 io_req->IsRootFlag = 0;
2736 io_req->Fid = fid.netfid;
2737 io_req->ByteCount = 0;
2739 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req,
2740 (struct smb_hdr *)io_rsp, &io_rsp_len, 0);
2744 data_offset = le32_to_cpu(io_rsp->DataOffset);
2745 data_count = le32_to_cpu(io_rsp->DataCount);
2746 if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 ||
2747 !data_count || data_count > 2048) {
2752 end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
2753 start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
2759 data_count = le16_to_cpu(io_rsp->ByteCount);
2760 buf = (struct reparse_data_buffer *)start;
2762 if (data_count < len ||
2763 data_count < le16_to_cpu(buf->ReparseDataLength) + len) {
2768 *tag = le32_to_cpu(buf->ReparseTag);
2769 rsp->iov_base = io_rsp;
2770 rsp->iov_len = io_rsp_len;
2771 *rsp_buftype = CIFS_LARGE_BUFFER;
2772 CIFSSMBClose(xid, tcon, fid.netfid);
2776 cifs_buf_release(io_req);
2777 CIFSSMBClose(xid, tcon, fid.netfid);
2782 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
2787 struct smb_com_transaction_compr_ioctl_req *pSMB;
2788 struct smb_com_transaction_ioctl_rsp *pSMBr;
2790 cifs_dbg(FYI, "Set compression for %u\n", fid);
2791 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2796 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
2798 pSMB->TotalParameterCount = 0;
2799 pSMB->TotalDataCount = cpu_to_le32(2);
2800 pSMB->MaxParameterCount = 0;
2801 pSMB->MaxDataCount = 0;
2802 pSMB->MaxSetupCount = 4;
2804 pSMB->ParameterOffset = 0;
2805 pSMB->DataCount = cpu_to_le32(2);
2807 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
2808 compression_state) - 4); /* 84 */
2809 pSMB->SetupCount = 4;
2810 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2811 pSMB->ParameterCount = 0;
2812 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
2813 pSMB->IsFsctl = 1; /* FSCTL */
2814 pSMB->IsRootFlag = 0;
2815 pSMB->Fid = fid; /* file handle always le */
2816 /* 3 byte pad, followed by 2 byte compress state */
2817 pSMB->ByteCount = cpu_to_le16(5);
2818 inc_rfc1001_len(pSMB, 5);
2820 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2821 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2823 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
2825 cifs_buf_release(pSMB);
2828 * Note: On -EAGAIN error only caller can retry on handle based calls
2829 * since file handle passed in no longer valid.
2835 #ifdef CONFIG_CIFS_POSIX
2837 #ifdef CONFIG_FS_POSIX_ACL
2839 * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format
2840 * @ace: POSIX ACL entry to store converted ACL into
2841 * @cifs_ace: ACL in cifs format
2843 * Convert an Access Control Entry from wire format to local POSIX xattr
2846 * Note that the @cifs_uid member is used to store both {g,u}id_t.
2848 static void cifs_init_posix_acl(struct posix_acl_entry *ace,
2849 struct cifs_posix_ace *cifs_ace)
2851 /* u8 cifs fields do not need le conversion */
2852 ace->e_perm = cifs_ace->cifs_e_perm;
2853 ace->e_tag = cifs_ace->cifs_e_tag;
2855 switch (ace->e_tag) {
2857 ace->e_uid = make_kuid(&init_user_ns,
2858 le64_to_cpu(cifs_ace->cifs_uid));
2861 ace->e_gid = make_kgid(&init_user_ns,
2862 le64_to_cpu(cifs_ace->cifs_uid));
2869 * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format
2870 * @acl: ACLs returned in POSIX ACL format
2871 * @src: ACLs in cifs format
2872 * @acl_type: type of POSIX ACL requested
2873 * @size_of_data_area: size of SMB we got
2875 * This function converts ACLs from cifs format to POSIX ACL format.
2876 * If @acl is NULL then the size of the buffer required to store POSIX ACLs in
2877 * their uapi format is returned.
2879 static int cifs_to_posix_acl(struct posix_acl **acl, char *src,
2880 const int acl_type, const int size_of_data_area)
2884 struct cifs_posix_ace *pACE;
2885 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
2886 struct posix_acl *kacl = NULL;
2887 struct posix_acl_entry *pa, *pe;
2889 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
2892 if (acl_type == ACL_TYPE_ACCESS) {
2893 count = le16_to_cpu(cifs_acl->access_entry_count);
2894 pACE = &cifs_acl->ace_array[0];
2895 size = sizeof(struct cifs_posix_acl);
2896 size += sizeof(struct cifs_posix_ace) * count;
2897 /* check if we would go beyond end of SMB */
2898 if (size_of_data_area < size) {
2899 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
2900 size_of_data_area, size);
2903 } else if (acl_type == ACL_TYPE_DEFAULT) {
2904 count = le16_to_cpu(cifs_acl->access_entry_count);
2905 size = sizeof(struct cifs_posix_acl);
2906 size += sizeof(struct cifs_posix_ace) * count;
2907 /* skip past access ACEs to get to default ACEs */
2908 pACE = &cifs_acl->ace_array[count];
2909 count = le16_to_cpu(cifs_acl->default_entry_count);
2910 size += sizeof(struct cifs_posix_ace) * count;
2911 /* check if we would go beyond end of SMB */
2912 if (size_of_data_area < size)
2919 /* Allocate number of POSIX ACLs to store in VFS format. */
2920 kacl = posix_acl_alloc(count, GFP_NOFS);
2924 FOREACH_ACL_ENTRY(pa, kacl, pe) {
2925 cifs_init_posix_acl(pa, pACE);
2934 * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format
2935 * @cifs_ace: the cifs ACL entry to store into
2936 * @local_ace: the POSIX ACL entry to convert
2938 static void cifs_init_ace(struct cifs_posix_ace *cifs_ace,
2939 const struct posix_acl_entry *local_ace)
2941 cifs_ace->cifs_e_perm = local_ace->e_perm;
2942 cifs_ace->cifs_e_tag = local_ace->e_tag;
2944 switch (local_ace->e_tag) {
2946 cifs_ace->cifs_uid =
2947 cpu_to_le64(from_kuid(&init_user_ns, local_ace->e_uid));
2950 cifs_ace->cifs_uid =
2951 cpu_to_le64(from_kgid(&init_user_ns, local_ace->e_gid));
2954 cifs_ace->cifs_uid = cpu_to_le64(-1);
2959 * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format
2960 * @parm_data: ACLs in cifs format to convert to
2961 * @acl: ACLs in POSIX ACL format to convert from
2962 * @acl_type: the type of POSIX ACLs stored in @acl
2964 * Return: the number cifs ACL entries after conversion
2966 static __u16 posix_acl_to_cifs(char *parm_data, const struct posix_acl *acl,
2970 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
2971 const struct posix_acl_entry *pa, *pe;
2975 if ((acl == NULL) || (cifs_acl == NULL))
2978 count = acl->a_count;
2979 cifs_dbg(FYI, "setting acl with %d entries\n", count);
2982 * Note that the uapi POSIX ACL version is verified by the VFS and is
2983 * independent of the cifs ACL version. Changing the POSIX ACL version
2984 * is a uapi change and if it's changed we will pass down the POSIX ACL
2985 * version in struct posix_acl from the VFS. For now there's really
2986 * only one that all filesystems know how to deal with.
2988 cifs_acl->version = cpu_to_le16(1);
2989 if (acl_type == ACL_TYPE_ACCESS) {
2990 cifs_acl->access_entry_count = cpu_to_le16(count);
2991 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
2992 } else if (acl_type == ACL_TYPE_DEFAULT) {
2993 cifs_acl->default_entry_count = cpu_to_le16(count);
2994 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
2996 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
2999 FOREACH_ACL_ENTRY(pa, acl, pe) {
3000 cifs_init_ace(&cifs_acl->ace_array[i++], pa);
3003 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3004 rc += sizeof(struct cifs_posix_acl);
3005 /* BB add check to make sure ACL does not overflow SMB */
3010 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3011 const unsigned char *searchName, struct posix_acl **acl,
3012 const int acl_type, const struct nls_table *nls_codepage,
3015 /* SMB_QUERY_POSIX_ACL */
3016 TRANSACTION2_QPI_REQ *pSMB = NULL;
3017 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3021 __u16 params, byte_count;
3023 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3026 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3031 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3033 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3034 searchName, PATH_MAX, nls_codepage,
3036 name_len++; /* trailing null */
3038 pSMB->FileName[name_len] = 0;
3039 pSMB->FileName[name_len+1] = 0;
3041 name_len = copy_path_name(pSMB->FileName, searchName);
3044 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3045 pSMB->TotalDataCount = 0;
3046 pSMB->MaxParameterCount = cpu_to_le16(2);
3047 /* BB find exact max data count below from sess structure BB */
3048 pSMB->MaxDataCount = cpu_to_le16(4000);
3049 pSMB->MaxSetupCount = 0;
3053 pSMB->Reserved2 = 0;
3054 pSMB->ParameterOffset = cpu_to_le16(
3055 offsetof(struct smb_com_transaction2_qpi_req,
3056 InformationLevel) - 4);
3057 pSMB->DataCount = 0;
3058 pSMB->DataOffset = 0;
3059 pSMB->SetupCount = 1;
3060 pSMB->Reserved3 = 0;
3061 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3062 byte_count = params + 1 /* pad */ ;
3063 pSMB->TotalParameterCount = cpu_to_le16(params);
3064 pSMB->ParameterCount = pSMB->TotalParameterCount;
3065 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3066 pSMB->Reserved4 = 0;
3067 inc_rfc1001_len(pSMB, byte_count);
3068 pSMB->ByteCount = cpu_to_le16(byte_count);
3070 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3071 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3072 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3074 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3076 /* decode response */
3078 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3079 /* BB also check enough total bytes returned */
3080 if (rc || get_bcc(&pSMBr->hdr) < 2)
3081 rc = -EIO; /* bad smb */
3083 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3084 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3085 rc = cifs_to_posix_acl(acl,
3086 (char *)&pSMBr->hdr.Protocol+data_offset,
3090 cifs_buf_release(pSMB);
3092 * The else branch after SendReceive() doesn't return EAGAIN so if we
3093 * allocated @acl in cifs_to_posix_acl() we are guaranteed to return
3094 * here and don't leak POSIX ACLs.
3101 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3102 const unsigned char *fileName, const struct posix_acl *acl,
3103 const int acl_type, const struct nls_table *nls_codepage,
3106 struct smb_com_transaction2_spi_req *pSMB = NULL;
3107 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3111 int bytes_returned = 0;
3112 __u16 params, byte_count, data_count, param_offset, offset;
3114 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3116 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3120 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3122 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3123 PATH_MAX, nls_codepage, remap);
3124 name_len++; /* trailing null */
3127 name_len = copy_path_name(pSMB->FileName, fileName);
3129 params = 6 + name_len;
3130 pSMB->MaxParameterCount = cpu_to_le16(2);
3131 /* BB find max SMB size from sess */
3132 pSMB->MaxDataCount = cpu_to_le16(1000);
3133 pSMB->MaxSetupCount = 0;
3137 pSMB->Reserved2 = 0;
3138 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3139 InformationLevel) - 4;
3140 offset = param_offset + params;
3141 parm_data = ((char *)pSMB) + sizeof(pSMB->hdr.smb_buf_length) + offset;
3142 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3144 /* convert to on the wire format for POSIX ACL */
3145 data_count = posix_acl_to_cifs(parm_data, acl, acl_type);
3147 if (data_count == 0) {
3149 goto setACLerrorExit;
3151 pSMB->DataOffset = cpu_to_le16(offset);
3152 pSMB->SetupCount = 1;
3153 pSMB->Reserved3 = 0;
3154 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3155 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3156 byte_count = 3 /* pad */ + params + data_count;
3157 pSMB->DataCount = cpu_to_le16(data_count);
3158 pSMB->TotalDataCount = pSMB->DataCount;
3159 pSMB->ParameterCount = cpu_to_le16(params);
3160 pSMB->TotalParameterCount = pSMB->ParameterCount;
3161 pSMB->Reserved4 = 0;
3162 inc_rfc1001_len(pSMB, byte_count);
3163 pSMB->ByteCount = cpu_to_le16(byte_count);
3164 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3165 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3167 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3170 cifs_buf_release(pSMB);
3176 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3177 const unsigned char *searchName, struct posix_acl **acl,
3178 const int acl_type, const struct nls_table *nls_codepage,
3184 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3185 const unsigned char *fileName, const struct posix_acl *acl,
3186 const int acl_type, const struct nls_table *nls_codepage,
3191 #endif /* CONFIG_FS_POSIX_ACL */
3194 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3195 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3198 struct smb_t2_qfi_req *pSMB = NULL;
3199 struct smb_t2_qfi_rsp *pSMBr = NULL;
3201 __u16 params, byte_count;
3203 cifs_dbg(FYI, "In GetExtAttr\n");
3208 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3213 params = 2 /* level */ + 2 /* fid */;
3214 pSMB->t2.TotalDataCount = 0;
3215 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3216 /* BB find exact max data count below from sess structure BB */
3217 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3218 pSMB->t2.MaxSetupCount = 0;
3219 pSMB->t2.Reserved = 0;
3221 pSMB->t2.Timeout = 0;
3222 pSMB->t2.Reserved2 = 0;
3223 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3225 pSMB->t2.DataCount = 0;
3226 pSMB->t2.DataOffset = 0;
3227 pSMB->t2.SetupCount = 1;
3228 pSMB->t2.Reserved3 = 0;
3229 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3230 byte_count = params + 1 /* pad */ ;
3231 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3232 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3233 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3236 inc_rfc1001_len(pSMB, byte_count);
3237 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3239 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3240 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3242 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3244 /* decode response */
3245 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3246 /* BB also check enough total bytes returned */
3247 if (rc || get_bcc(&pSMBr->hdr) < 2)
3248 /* If rc should we check for EOPNOSUPP and
3249 disable the srvino flag? or in caller? */
3250 rc = -EIO; /* bad smb */
3252 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3253 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3254 struct file_chattr_info *pfinfo;
3257 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3261 pfinfo = (struct file_chattr_info *)
3262 (data_offset + (char *) &pSMBr->hdr.Protocol);
3263 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3264 *pMask = le64_to_cpu(pfinfo->mask);
3268 cifs_buf_release(pSMB);
3270 goto GetExtAttrRetry;
3274 #endif /* CONFIG_POSIX */
3277 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3278 * all NT TRANSACTS that we init here have total parm and data under about 400
3279 * bytes (to fit in small cifs buffer size), which is the case so far, it
3280 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3281 * returned setup area) and MaxParameterCount (returned parms size) must be set
3285 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3286 const int parm_len, struct cifs_tcon *tcon,
3291 struct smb_com_ntransact_req *pSMB;
3293 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3297 *ret_buf = (void *)pSMB;
3299 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3300 pSMB->TotalDataCount = 0;
3301 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3302 pSMB->ParameterCount = pSMB->TotalParameterCount;
3303 pSMB->DataCount = pSMB->TotalDataCount;
3304 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3305 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3306 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3307 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3308 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3309 pSMB->SubCommand = cpu_to_le16(sub_command);
3314 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3315 __u32 *pparmlen, __u32 *pdatalen)
3318 __u32 data_count, data_offset, parm_count, parm_offset;
3319 struct smb_com_ntransact_rsp *pSMBr;
3328 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3330 bcc = get_bcc(&pSMBr->hdr);
3331 end_of_smb = 2 /* sizeof byte count */ + bcc +
3332 (char *)&pSMBr->ByteCount;
3334 data_offset = le32_to_cpu(pSMBr->DataOffset);
3335 data_count = le32_to_cpu(pSMBr->DataCount);
3336 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3337 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3339 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3340 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3342 /* should we also check that parm and data areas do not overlap? */
3343 if (*ppparm > end_of_smb) {
3344 cifs_dbg(FYI, "parms start after end of smb\n");
3346 } else if (parm_count + *ppparm > end_of_smb) {
3347 cifs_dbg(FYI, "parm end after end of smb\n");
3349 } else if (*ppdata > end_of_smb) {
3350 cifs_dbg(FYI, "data starts after end of smb\n");
3352 } else if (data_count + *ppdata > end_of_smb) {
3353 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3354 *ppdata, data_count, (data_count + *ppdata),
3357 } else if (parm_count + data_count > bcc) {
3358 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3361 *pdatalen = data_count;
3362 *pparmlen = parm_count;
3366 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3368 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3369 struct smb_ntsd **acl_inf, __u32 *pbuflen)
3373 QUERY_SEC_DESC_REQ *pSMB;
3375 struct kvec rsp_iov;
3377 cifs_dbg(FYI, "GetCifsACL\n");
3382 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3383 8 /* parm len */, tcon, (void **) &pSMB);
3387 pSMB->MaxParameterCount = cpu_to_le32(4);
3388 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3389 pSMB->MaxSetupCount = 0;
3390 pSMB->Fid = fid; /* file handle always le */
3391 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3393 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3394 inc_rfc1001_len(pSMB, 11);
3395 iov[0].iov_base = (char *)pSMB;
3396 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3398 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3400 cifs_small_buf_release(pSMB);
3401 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3403 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3404 } else { /* decode response */
3408 struct smb_com_ntransact_rsp *pSMBr;
3411 /* validate_nttransact */
3412 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3413 &pdata, &parm_len, pbuflen);
3416 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3418 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3419 pSMBr, parm, *acl_inf);
3421 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3422 rc = -EIO; /* bad smb */
3427 /* BB check that data area is minimum length and as big as acl_len */
3429 acl_len = le32_to_cpu(*parm);
3430 if (acl_len != *pbuflen) {
3431 cifs_dbg(VFS, "acl length %d does not match %d\n",
3433 if (*pbuflen > acl_len)
3437 /* check if buffer is big enough for the acl
3438 header followed by the smallest SID */
3439 if ((*pbuflen < sizeof(struct smb_ntsd) + 8) ||
3440 (*pbuflen >= 64 * 1024)) {
3441 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3445 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3446 if (*acl_inf == NULL) {
3453 free_rsp_buf(buf_type, rsp_iov.iov_base);
3458 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3459 struct smb_ntsd *pntsd, __u32 acllen, int aclflag)
3461 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3463 int bytes_returned = 0;
3464 SET_SEC_DESC_REQ *pSMB = NULL;
3468 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3472 pSMB->MaxSetupCount = 0;
3476 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3477 data_count = acllen;
3478 data_offset = param_offset + param_count;
3479 byte_count = 3 /* pad */ + param_count;
3481 pSMB->DataCount = cpu_to_le32(data_count);
3482 pSMB->TotalDataCount = pSMB->DataCount;
3483 pSMB->MaxParameterCount = cpu_to_le32(4);
3484 pSMB->MaxDataCount = cpu_to_le32(16384);
3485 pSMB->ParameterCount = cpu_to_le32(param_count);
3486 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3487 pSMB->TotalParameterCount = pSMB->ParameterCount;
3488 pSMB->DataOffset = cpu_to_le32(data_offset);
3489 pSMB->SetupCount = 0;
3490 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3491 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3493 pSMB->Fid = fid; /* file handle always le */
3494 pSMB->Reserved2 = 0;
3495 pSMB->AclFlags = cpu_to_le32(aclflag);
3497 if (pntsd && acllen) {
3498 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3499 data_offset, pntsd, acllen);
3500 inc_rfc1001_len(pSMB, byte_count + data_count);
3502 inc_rfc1001_len(pSMB, byte_count);
3504 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3505 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3507 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3508 bytes_returned, rc);
3510 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3511 cifs_buf_release(pSMB);
3514 goto setCifsAclRetry;
3520 /* Legacy Query Path Information call for lookup to old servers such
3523 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3524 const char *search_name, FILE_ALL_INFO *data,
3525 const struct nls_table *nls_codepage, int remap)
3527 QUERY_INFORMATION_REQ *pSMB;
3528 QUERY_INFORMATION_RSP *pSMBr;
3533 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3535 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3540 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3542 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3543 search_name, PATH_MAX, nls_codepage,
3545 name_len++; /* trailing null */
3548 name_len = copy_path_name(pSMB->FileName, search_name);
3550 pSMB->BufferFormat = 0x04;
3551 name_len++; /* account for buffer type byte */
3552 inc_rfc1001_len(pSMB, (__u16)name_len);
3553 pSMB->ByteCount = cpu_to_le16(name_len);
3555 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3556 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3558 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3560 struct timespec64 ts;
3561 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3563 /* decode response */
3564 /* BB FIXME - add time zone adjustment BB */
3565 memset(data, 0, sizeof(FILE_ALL_INFO));
3568 /* decode time fields */
3569 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3570 data->LastWriteTime = data->ChangeTime;
3571 data->LastAccessTime = 0;
3572 data->AllocationSize =
3573 cpu_to_le64(le32_to_cpu(pSMBr->size));
3574 data->EndOfFile = data->AllocationSize;
3576 cpu_to_le32(le16_to_cpu(pSMBr->attr));
3578 rc = -EIO; /* bad buffer passed in */
3580 cifs_buf_release(pSMB);
3589 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3590 u16 netfid, FILE_ALL_INFO *pFindData)
3592 struct smb_t2_qfi_req *pSMB = NULL;
3593 struct smb_t2_qfi_rsp *pSMBr = NULL;
3596 __u16 params, byte_count;
3599 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3604 params = 2 /* level */ + 2 /* fid */;
3605 pSMB->t2.TotalDataCount = 0;
3606 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3607 /* BB find exact max data count below from sess structure BB */
3608 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3609 pSMB->t2.MaxSetupCount = 0;
3610 pSMB->t2.Reserved = 0;
3612 pSMB->t2.Timeout = 0;
3613 pSMB->t2.Reserved2 = 0;
3614 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3616 pSMB->t2.DataCount = 0;
3617 pSMB->t2.DataOffset = 0;
3618 pSMB->t2.SetupCount = 1;
3619 pSMB->t2.Reserved3 = 0;
3620 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3621 byte_count = params + 1 /* pad */ ;
3622 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3623 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3624 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3627 inc_rfc1001_len(pSMB, byte_count);
3628 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3630 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3631 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3633 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
3634 } else { /* decode response */
3635 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3637 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3639 else if (get_bcc(&pSMBr->hdr) < 40)
3640 rc = -EIO; /* bad smb */
3641 else if (pFindData) {
3642 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3643 memcpy((char *) pFindData,
3644 (char *) &pSMBr->hdr.Protocol +
3645 data_offset, sizeof(FILE_ALL_INFO));
3649 cifs_buf_release(pSMB);
3651 goto QFileInfoRetry;
3657 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3658 const char *search_name, FILE_ALL_INFO *data,
3659 int legacy /* old style infolevel */,
3660 const struct nls_table *nls_codepage, int remap)
3662 /* level 263 SMB_QUERY_FILE_ALL_INFO */
3663 TRANSACTION2_QPI_REQ *pSMB = NULL;
3664 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3668 __u16 params, byte_count;
3670 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3672 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3677 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3679 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3680 PATH_MAX, nls_codepage, remap);
3681 name_len++; /* trailing null */
3684 name_len = copy_path_name(pSMB->FileName, search_name);
3687 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3688 pSMB->TotalDataCount = 0;
3689 pSMB->MaxParameterCount = cpu_to_le16(2);
3690 /* BB find exact max SMB PDU from sess structure BB */
3691 pSMB->MaxDataCount = cpu_to_le16(4000);
3692 pSMB->MaxSetupCount = 0;
3696 pSMB->Reserved2 = 0;
3697 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3698 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3699 pSMB->DataCount = 0;
3700 pSMB->DataOffset = 0;
3701 pSMB->SetupCount = 1;
3702 pSMB->Reserved3 = 0;
3703 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3704 byte_count = params + 1 /* pad */ ;
3705 pSMB->TotalParameterCount = cpu_to_le16(params);
3706 pSMB->ParameterCount = pSMB->TotalParameterCount;
3708 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3710 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3711 pSMB->Reserved4 = 0;
3712 inc_rfc1001_len(pSMB, byte_count);
3713 pSMB->ByteCount = cpu_to_le16(byte_count);
3715 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3716 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3718 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3719 } else { /* decode response */
3720 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3722 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3724 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3725 rc = -EIO; /* bad smb */
3726 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3727 rc = -EIO; /* 24 or 26 expected but we do not read
3731 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3734 * On legacy responses we do not read the last field,
3735 * EAsize, fortunately since it varies by subdialect and
3736 * also note it differs on Set vs Get, ie two bytes or 4
3737 * bytes depending but we don't care here.
3740 size = sizeof(FILE_INFO_STANDARD);
3742 size = sizeof(FILE_ALL_INFO);
3743 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
3748 cifs_buf_release(pSMB);
3750 goto QPathInfoRetry;
3756 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3757 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3759 struct smb_t2_qfi_req *pSMB = NULL;
3760 struct smb_t2_qfi_rsp *pSMBr = NULL;
3763 __u16 params, byte_count;
3766 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3771 params = 2 /* level */ + 2 /* fid */;
3772 pSMB->t2.TotalDataCount = 0;
3773 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3774 /* BB find exact max data count below from sess structure BB */
3775 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3776 pSMB->t2.MaxSetupCount = 0;
3777 pSMB->t2.Reserved = 0;
3779 pSMB->t2.Timeout = 0;
3780 pSMB->t2.Reserved2 = 0;
3781 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3783 pSMB->t2.DataCount = 0;
3784 pSMB->t2.DataOffset = 0;
3785 pSMB->t2.SetupCount = 1;
3786 pSMB->t2.Reserved3 = 0;
3787 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3788 byte_count = params + 1 /* pad */ ;
3789 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3790 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3791 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3794 inc_rfc1001_len(pSMB, byte_count);
3795 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3797 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3798 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3800 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
3801 } else { /* decode response */
3802 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3804 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3805 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3806 rc = -EIO; /* bad smb */
3808 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3809 memcpy((char *) pFindData,
3810 (char *) &pSMBr->hdr.Protocol +
3812 sizeof(FILE_UNIX_BASIC_INFO));
3816 cifs_buf_release(pSMB);
3818 goto UnixQFileInfoRetry;
3824 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3825 const unsigned char *searchName,
3826 FILE_UNIX_BASIC_INFO *pFindData,
3827 const struct nls_table *nls_codepage, int remap)
3829 /* SMB_QUERY_FILE_UNIX_BASIC */
3830 TRANSACTION2_QPI_REQ *pSMB = NULL;
3831 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3833 int bytes_returned = 0;
3835 __u16 params, byte_count;
3837 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
3839 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3844 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3846 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3847 PATH_MAX, nls_codepage, remap);
3848 name_len++; /* trailing null */
3851 name_len = copy_path_name(pSMB->FileName, searchName);
3854 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3855 pSMB->TotalDataCount = 0;
3856 pSMB->MaxParameterCount = cpu_to_le16(2);
3857 /* BB find exact max SMB PDU from sess structure BB */
3858 pSMB->MaxDataCount = cpu_to_le16(4000);
3859 pSMB->MaxSetupCount = 0;
3863 pSMB->Reserved2 = 0;
3864 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3865 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3866 pSMB->DataCount = 0;
3867 pSMB->DataOffset = 0;
3868 pSMB->SetupCount = 1;
3869 pSMB->Reserved3 = 0;
3870 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3871 byte_count = params + 1 /* pad */ ;
3872 pSMB->TotalParameterCount = cpu_to_le16(params);
3873 pSMB->ParameterCount = pSMB->TotalParameterCount;
3874 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3875 pSMB->Reserved4 = 0;
3876 inc_rfc1001_len(pSMB, byte_count);
3877 pSMB->ByteCount = cpu_to_le16(byte_count);
3879 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3880 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3882 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
3883 } else { /* decode response */
3884 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3886 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3887 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3888 rc = -EIO; /* bad smb */
3890 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3891 memcpy((char *) pFindData,
3892 (char *) &pSMBr->hdr.Protocol +
3894 sizeof(FILE_UNIX_BASIC_INFO));
3897 cifs_buf_release(pSMB);
3899 goto UnixQPathInfoRetry;
3904 /* xid, tcon, searchName and codepage are input parms, rest are returned */
3906 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
3907 const char *searchName, struct cifs_sb_info *cifs_sb,
3908 __u16 *pnetfid, __u16 search_flags,
3909 struct cifs_search_info *psrch_inf, bool msearch)
3911 /* level 257 SMB_ */
3912 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
3913 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
3914 T2_FFIRST_RSP_PARMS *parms;
3915 struct nls_table *nls_codepage;
3917 __u16 params, byte_count;
3918 int bytes_returned = 0;
3919 int name_len, remap;
3922 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
3925 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3930 nls_codepage = cifs_sb->local_nls;
3931 remap = cifs_remap(cifs_sb);
3933 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3935 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3936 PATH_MAX, nls_codepage, remap);
3937 /* We can not add the asterisk earlier in case
3938 it got remapped to 0xF03A as if it were part of the
3939 directory name instead of a wildcard */
3942 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
3943 pSMB->FileName[name_len+1] = 0;
3944 pSMB->FileName[name_len+2] = '*';
3945 pSMB->FileName[name_len+3] = 0;
3946 name_len += 4; /* now the trailing null */
3947 /* null terminate just in case */
3948 pSMB->FileName[name_len] = 0;
3949 pSMB->FileName[name_len+1] = 0;
3953 name_len = copy_path_name(pSMB->FileName, searchName);
3955 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
3956 name_len = PATH_MAX-2;
3957 /* overwrite nul byte */
3958 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
3959 pSMB->FileName[name_len] = '*';
3960 pSMB->FileName[name_len+1] = 0;
3965 params = 12 + name_len /* includes null */ ;
3966 pSMB->TotalDataCount = 0; /* no EAs */
3967 pSMB->MaxParameterCount = cpu_to_le16(10);
3968 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
3969 pSMB->MaxSetupCount = 0;
3973 pSMB->Reserved2 = 0;
3974 byte_count = params + 1 /* pad */ ;
3975 pSMB->TotalParameterCount = cpu_to_le16(params);
3976 pSMB->ParameterCount = pSMB->TotalParameterCount;
3977 pSMB->ParameterOffset = cpu_to_le16(
3978 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
3980 pSMB->DataCount = 0;
3981 pSMB->DataOffset = 0;
3982 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
3983 pSMB->Reserved3 = 0;
3984 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
3985 pSMB->SearchAttributes =
3986 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3988 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
3989 pSMB->SearchFlags = cpu_to_le16(search_flags);
3990 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
3992 /* BB what should we set StorageType to? Does it matter? BB */
3993 pSMB->SearchStorageType = 0;
3994 inc_rfc1001_len(pSMB, byte_count);
3995 pSMB->ByteCount = cpu_to_le16(byte_count);
3997 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3998 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3999 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4003 * BB: add logic to retry regular search if Unix search rejected
4004 * unexpectedly by server.
4006 /* BB: add code to handle unsupported level rc */
4007 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4008 cifs_buf_release(pSMB);
4010 * BB: eventually could optimize out free and realloc of buf for
4014 goto findFirstRetry;
4017 /* decode response */
4018 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4020 cifs_buf_release(pSMB);
4024 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4025 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4026 psrch_inf->smallBuf = false;
4027 psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol +
4028 le16_to_cpu(pSMBr->t2.DataOffset);
4030 parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol +
4031 le16_to_cpu(pSMBr->t2.ParameterOffset));
4032 psrch_inf->endOfSearch = !!parms->EndofSearch;
4034 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4035 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4036 psrch_inf->entries_in_buffer;
4037 lnoff = le16_to_cpu(parms->LastNameOffset);
4038 if (CIFSMaxBufSize < lnoff) {
4039 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4040 psrch_inf->last_entry = NULL;
4042 psrch_inf->last_entry = psrch_inf->srch_entries_start + lnoff;
4044 *pnetfid = parms->SearchHandle;
4049 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4050 __u16 searchHandle, __u16 search_flags,
4051 struct cifs_search_info *psrch_inf)
4053 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4054 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4055 T2_FNEXT_RSP_PARMS *parms;
4056 unsigned int name_len;
4058 __u16 params, byte_count;
4059 char *response_data;
4063 cifs_dbg(FYI, "In FindNext\n");
4065 if (psrch_inf->endOfSearch)
4068 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4073 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4075 pSMB->TotalDataCount = 0; /* no EAs */
4076 pSMB->MaxParameterCount = cpu_to_le16(8);
4077 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4078 pSMB->MaxSetupCount = 0;
4082 pSMB->Reserved2 = 0;
4083 pSMB->ParameterOffset = cpu_to_le16(
4084 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4085 pSMB->DataCount = 0;
4086 pSMB->DataOffset = 0;
4087 pSMB->SetupCount = 1;
4088 pSMB->Reserved3 = 0;
4089 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4090 pSMB->SearchHandle = searchHandle; /* always kept as le */
4092 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4093 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4094 pSMB->ResumeKey = psrch_inf->resume_key;
4095 pSMB->SearchFlags = cpu_to_le16(search_flags);
4097 name_len = psrch_inf->resume_name_len;
4099 if (name_len < PATH_MAX) {
4100 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4101 byte_count += name_len;
4102 /* 14 byte parm len above enough for 2 byte null terminator */
4103 pSMB->ResumeFileName[name_len] = 0;
4104 pSMB->ResumeFileName[name_len+1] = 0;
4106 cifs_buf_release(pSMB);
4109 byte_count = params + 1 /* pad */ ;
4110 pSMB->TotalParameterCount = cpu_to_le16(params);
4111 pSMB->ParameterCount = pSMB->TotalParameterCount;
4112 inc_rfc1001_len(pSMB, byte_count);
4113 pSMB->ByteCount = cpu_to_le16(byte_count);
4115 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4116 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4117 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4120 cifs_buf_release(pSMB);
4122 psrch_inf->endOfSearch = true;
4123 rc = 0; /* search probably was closed at end of search*/
4125 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4130 /* decode response */
4131 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4133 cifs_buf_release(pSMB);
4136 /* BB fixme add lock for file (srch_info) struct here */
4137 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4138 response_data = (char *)&pSMBr->hdr.Protocol +
4139 le16_to_cpu(pSMBr->t2.ParameterOffset);
4140 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4141 response_data = (char *)&pSMBr->hdr.Protocol +
4142 le16_to_cpu(pSMBr->t2.DataOffset);
4144 if (psrch_inf->smallBuf)
4145 cifs_small_buf_release(psrch_inf->ntwrk_buf_start);
4147 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4149 psrch_inf->srch_entries_start = response_data;
4150 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4151 psrch_inf->smallBuf = false;
4152 psrch_inf->endOfSearch = !!parms->EndofSearch;
4153 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4154 psrch_inf->index_of_last_entry += psrch_inf->entries_in_buffer;
4155 lnoff = le16_to_cpu(parms->LastNameOffset);
4156 if (CIFSMaxBufSize < lnoff) {
4157 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4158 psrch_inf->last_entry = NULL;
4160 psrch_inf->last_entry =
4161 psrch_inf->srch_entries_start + lnoff;
4163 /* BB fixme add unlock here */
4166 * BB: On error, should we leave previous search buf
4167 * (and count and last entry fields) intact or free the previous one?
4169 * Note: On -EAGAIN error only caller can retry on handle based calls
4170 * since file handle passed in no longer valid.
4176 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4177 const __u16 searchHandle)
4180 FINDCLOSE_REQ *pSMB = NULL;
4182 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4183 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4185 /* no sense returning error if session restarted
4186 as file handle has been closed */
4192 pSMB->FileID = searchHandle;
4193 pSMB->ByteCount = 0;
4194 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4195 cifs_small_buf_release(pSMB);
4197 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4199 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4201 /* Since session is dead, search handle closed on server already */
4209 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4210 const char *search_name, __u64 *inode_number,
4211 const struct nls_table *nls_codepage, int remap)
4214 TRANSACTION2_QPI_REQ *pSMB = NULL;
4215 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4216 int name_len, bytes_returned;
4217 __u16 params, byte_count;
4219 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4223 GetInodeNumberRetry:
4224 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4229 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4231 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4232 search_name, PATH_MAX, nls_codepage,
4234 name_len++; /* trailing null */
4237 name_len = copy_path_name(pSMB->FileName, search_name);
4240 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4241 pSMB->TotalDataCount = 0;
4242 pSMB->MaxParameterCount = cpu_to_le16(2);
4243 /* BB find exact max data count below from sess structure BB */
4244 pSMB->MaxDataCount = cpu_to_le16(4000);
4245 pSMB->MaxSetupCount = 0;
4249 pSMB->Reserved2 = 0;
4250 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4251 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4252 pSMB->DataCount = 0;
4253 pSMB->DataOffset = 0;
4254 pSMB->SetupCount = 1;
4255 pSMB->Reserved3 = 0;
4256 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4257 byte_count = params + 1 /* pad */ ;
4258 pSMB->TotalParameterCount = cpu_to_le16(params);
4259 pSMB->ParameterCount = pSMB->TotalParameterCount;
4260 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4261 pSMB->Reserved4 = 0;
4262 inc_rfc1001_len(pSMB, byte_count);
4263 pSMB->ByteCount = cpu_to_le16(byte_count);
4265 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4266 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4268 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4270 /* decode response */
4271 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4272 /* BB also check enough total bytes returned */
4273 if (rc || get_bcc(&pSMBr->hdr) < 2)
4274 /* If rc should we check for EOPNOSUPP and
4275 disable the srvino flag? or in caller? */
4276 rc = -EIO; /* bad smb */
4278 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4279 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4280 struct file_internal_info *pfinfo;
4281 /* BB Do we need a cast or hash here ? */
4283 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4285 goto GetInodeNumOut;
4287 pfinfo = (struct file_internal_info *)
4288 (data_offset + (char *) &pSMBr->hdr.Protocol);
4289 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4293 cifs_buf_release(pSMB);
4295 goto GetInodeNumberRetry;
4300 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4301 const char *search_name, struct dfs_info3_param **target_nodes,
4302 unsigned int *num_of_nodes,
4303 const struct nls_table *nls_codepage, int remap)
4305 /* TRANS2_GET_DFS_REFERRAL */
4306 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4307 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4311 __u16 params, byte_count;
4313 *target_nodes = NULL;
4315 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4316 if (ses == NULL || ses->tcon_ipc == NULL)
4321 * Use smb_init_no_reconnect() instead of smb_init() as
4322 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4323 * causing an infinite recursion.
4325 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4326 (void **)&pSMB, (void **)&pSMBr);
4330 /* server pointer checked in called function,
4331 but should never be null here anyway */
4332 pSMB->hdr.Mid = get_next_mid(ses->server);
4333 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4334 pSMB->hdr.Uid = ses->Suid;
4335 if (ses->capabilities & CAP_STATUS32)
4336 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4337 if (ses->capabilities & CAP_DFS)
4338 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4340 if (ses->capabilities & CAP_UNICODE) {
4341 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4343 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4344 search_name, PATH_MAX, nls_codepage,
4346 name_len++; /* trailing null */
4348 } else { /* BB improve the check for buffer overruns BB */
4349 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4352 if (ses->server->sign)
4353 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4355 pSMB->hdr.Uid = ses->Suid;
4357 params = 2 /* level */ + name_len /*includes null */ ;
4358 pSMB->TotalDataCount = 0;
4359 pSMB->DataCount = 0;
4360 pSMB->DataOffset = 0;
4361 pSMB->MaxParameterCount = 0;
4362 /* BB find exact max SMB PDU from sess structure BB */
4363 pSMB->MaxDataCount = cpu_to_le16(4000);
4364 pSMB->MaxSetupCount = 0;
4368 pSMB->Reserved2 = 0;
4369 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4370 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4371 pSMB->SetupCount = 1;
4372 pSMB->Reserved3 = 0;
4373 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4374 byte_count = params + 3 /* pad */ ;
4375 pSMB->ParameterCount = cpu_to_le16(params);
4376 pSMB->TotalParameterCount = pSMB->ParameterCount;
4377 pSMB->MaxReferralLevel = cpu_to_le16(3);
4378 inc_rfc1001_len(pSMB, byte_count);
4379 pSMB->ByteCount = cpu_to_le16(byte_count);
4381 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4382 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4384 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4387 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4389 /* BB Also check if enough total bytes returned? */
4390 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4391 rc = -EIO; /* bad smb */
4395 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4396 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4398 /* parse returned result into more usable form */
4399 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4400 le16_to_cpu(pSMBr->t2.DataCount),
4401 num_of_nodes, target_nodes, nls_codepage,
4403 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4406 cifs_buf_release(pSMB);
4414 /* Query File System Info such as free space to old servers such as Win 9x */
4416 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4417 struct kstatfs *FSData)
4419 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4420 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4421 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4422 FILE_SYSTEM_ALLOC_INFO *response_data;
4424 int bytes_returned = 0;
4425 __u16 params, byte_count;
4427 cifs_dbg(FYI, "OldQFSInfo\n");
4429 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4434 params = 2; /* level */
4435 pSMB->TotalDataCount = 0;
4436 pSMB->MaxParameterCount = cpu_to_le16(2);
4437 pSMB->MaxDataCount = cpu_to_le16(1000);
4438 pSMB->MaxSetupCount = 0;
4442 pSMB->Reserved2 = 0;
4443 byte_count = params + 1 /* pad */ ;
4444 pSMB->TotalParameterCount = cpu_to_le16(params);
4445 pSMB->ParameterCount = pSMB->TotalParameterCount;
4446 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4447 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4448 pSMB->DataCount = 0;
4449 pSMB->DataOffset = 0;
4450 pSMB->SetupCount = 1;
4451 pSMB->Reserved3 = 0;
4452 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4453 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4454 inc_rfc1001_len(pSMB, byte_count);
4455 pSMB->ByteCount = cpu_to_le16(byte_count);
4457 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4458 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4460 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4461 } else { /* decode response */
4462 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4464 if (rc || get_bcc(&pSMBr->hdr) < 18)
4465 rc = -EIO; /* bad smb */
4467 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4468 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4469 get_bcc(&pSMBr->hdr), data_offset);
4471 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4472 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4474 le16_to_cpu(response_data->BytesPerSector) *
4475 le32_to_cpu(response_data->
4476 SectorsPerAllocationUnit);
4478 * much prefer larger but if server doesn't report
4479 * a valid size than 4K is a reasonable minimum
4481 if (FSData->f_bsize < 512)
4482 FSData->f_bsize = 4096;
4485 le32_to_cpu(response_data->TotalAllocationUnits);
4486 FSData->f_bfree = FSData->f_bavail =
4487 le32_to_cpu(response_data->FreeAllocationUnits);
4488 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4489 (unsigned long long)FSData->f_blocks,
4490 (unsigned long long)FSData->f_bfree,
4494 cifs_buf_release(pSMB);
4497 goto oldQFSInfoRetry;
4503 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4504 struct kstatfs *FSData)
4506 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4507 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4508 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4509 FILE_SYSTEM_INFO *response_data;
4511 int bytes_returned = 0;
4512 __u16 params, byte_count;
4514 cifs_dbg(FYI, "In QFSInfo\n");
4516 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4521 params = 2; /* level */
4522 pSMB->TotalDataCount = 0;
4523 pSMB->MaxParameterCount = cpu_to_le16(2);
4524 pSMB->MaxDataCount = cpu_to_le16(1000);
4525 pSMB->MaxSetupCount = 0;
4529 pSMB->Reserved2 = 0;
4530 byte_count = params + 1 /* pad */ ;
4531 pSMB->TotalParameterCount = cpu_to_le16(params);
4532 pSMB->ParameterCount = pSMB->TotalParameterCount;
4533 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4534 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4535 pSMB->DataCount = 0;
4536 pSMB->DataOffset = 0;
4537 pSMB->SetupCount = 1;
4538 pSMB->Reserved3 = 0;
4539 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4540 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4541 inc_rfc1001_len(pSMB, byte_count);
4542 pSMB->ByteCount = cpu_to_le16(byte_count);
4544 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4545 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4547 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4548 } else { /* decode response */
4549 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4551 if (rc || get_bcc(&pSMBr->hdr) < 24)
4552 rc = -EIO; /* bad smb */
4554 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4558 *) (((char *) &pSMBr->hdr.Protocol) +
4561 le32_to_cpu(response_data->BytesPerSector) *
4562 le32_to_cpu(response_data->
4563 SectorsPerAllocationUnit);
4565 * much prefer larger but if server doesn't report
4566 * a valid size than 4K is a reasonable minimum
4568 if (FSData->f_bsize < 512)
4569 FSData->f_bsize = 4096;
4572 le64_to_cpu(response_data->TotalAllocationUnits);
4573 FSData->f_bfree = FSData->f_bavail =
4574 le64_to_cpu(response_data->FreeAllocationUnits);
4575 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4576 (unsigned long long)FSData->f_blocks,
4577 (unsigned long long)FSData->f_bfree,
4581 cifs_buf_release(pSMB);
4590 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
4592 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
4593 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4594 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4595 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
4597 int bytes_returned = 0;
4598 __u16 params, byte_count;
4600 cifs_dbg(FYI, "In QFSAttributeInfo\n");
4602 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4607 params = 2; /* level */
4608 pSMB->TotalDataCount = 0;
4609 pSMB->MaxParameterCount = cpu_to_le16(2);
4610 /* BB find exact max SMB PDU from sess structure BB */
4611 pSMB->MaxDataCount = cpu_to_le16(1000);
4612 pSMB->MaxSetupCount = 0;
4616 pSMB->Reserved2 = 0;
4617 byte_count = params + 1 /* pad */ ;
4618 pSMB->TotalParameterCount = cpu_to_le16(params);
4619 pSMB->ParameterCount = pSMB->TotalParameterCount;
4620 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4621 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4622 pSMB->DataCount = 0;
4623 pSMB->DataOffset = 0;
4624 pSMB->SetupCount = 1;
4625 pSMB->Reserved3 = 0;
4626 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4627 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4628 inc_rfc1001_len(pSMB, byte_count);
4629 pSMB->ByteCount = cpu_to_le16(byte_count);
4631 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4632 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4634 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
4635 } else { /* decode response */
4636 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4638 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4639 /* BB also check if enough bytes returned */
4640 rc = -EIO; /* bad smb */
4642 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4644 (FILE_SYSTEM_ATTRIBUTE_INFO
4645 *) (((char *) &pSMBr->hdr.Protocol) +
4647 memcpy(&tcon->fsAttrInfo, response_data,
4648 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
4651 cifs_buf_release(pSMB);
4654 goto QFSAttributeRetry;
4660 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
4662 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4663 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4664 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4665 FILE_SYSTEM_DEVICE_INFO *response_data;
4667 int bytes_returned = 0;
4668 __u16 params, byte_count;
4670 cifs_dbg(FYI, "In QFSDeviceInfo\n");
4672 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4677 params = 2; /* level */
4678 pSMB->TotalDataCount = 0;
4679 pSMB->MaxParameterCount = cpu_to_le16(2);
4680 /* BB find exact max SMB PDU from sess structure BB */
4681 pSMB->MaxDataCount = cpu_to_le16(1000);
4682 pSMB->MaxSetupCount = 0;
4686 pSMB->Reserved2 = 0;
4687 byte_count = params + 1 /* pad */ ;
4688 pSMB->TotalParameterCount = cpu_to_le16(params);
4689 pSMB->ParameterCount = pSMB->TotalParameterCount;
4690 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4691 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4693 pSMB->DataCount = 0;
4694 pSMB->DataOffset = 0;
4695 pSMB->SetupCount = 1;
4696 pSMB->Reserved3 = 0;
4697 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4698 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4699 inc_rfc1001_len(pSMB, byte_count);
4700 pSMB->ByteCount = cpu_to_le16(byte_count);
4702 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4703 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4705 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
4706 } else { /* decode response */
4707 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4709 if (rc || get_bcc(&pSMBr->hdr) <
4710 sizeof(FILE_SYSTEM_DEVICE_INFO))
4711 rc = -EIO; /* bad smb */
4713 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4715 (FILE_SYSTEM_DEVICE_INFO *)
4716 (((char *) &pSMBr->hdr.Protocol) +
4718 memcpy(&tcon->fsDevInfo, response_data,
4719 sizeof(FILE_SYSTEM_DEVICE_INFO));
4722 cifs_buf_release(pSMB);
4725 goto QFSDeviceRetry;
4731 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
4733 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
4734 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4735 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4736 FILE_SYSTEM_UNIX_INFO *response_data;
4738 int bytes_returned = 0;
4739 __u16 params, byte_count;
4741 cifs_dbg(FYI, "In QFSUnixInfo\n");
4743 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4744 (void **) &pSMB, (void **) &pSMBr);
4748 params = 2; /* level */
4749 pSMB->TotalDataCount = 0;
4750 pSMB->DataCount = 0;
4751 pSMB->DataOffset = 0;
4752 pSMB->MaxParameterCount = cpu_to_le16(2);
4753 /* BB find exact max SMB PDU from sess structure BB */
4754 pSMB->MaxDataCount = cpu_to_le16(100);
4755 pSMB->MaxSetupCount = 0;
4759 pSMB->Reserved2 = 0;
4760 byte_count = params + 1 /* pad */ ;
4761 pSMB->ParameterCount = cpu_to_le16(params);
4762 pSMB->TotalParameterCount = pSMB->ParameterCount;
4763 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4764 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4765 pSMB->SetupCount = 1;
4766 pSMB->Reserved3 = 0;
4767 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4768 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4769 inc_rfc1001_len(pSMB, byte_count);
4770 pSMB->ByteCount = cpu_to_le16(byte_count);
4772 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4773 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4775 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
4776 } else { /* decode response */
4777 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4779 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4780 rc = -EIO; /* bad smb */
4782 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4784 (FILE_SYSTEM_UNIX_INFO
4785 *) (((char *) &pSMBr->hdr.Protocol) +
4787 memcpy(&tcon->fsUnixInfo, response_data,
4788 sizeof(FILE_SYSTEM_UNIX_INFO));
4791 cifs_buf_release(pSMB);
4801 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
4803 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
4804 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
4805 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
4807 int bytes_returned = 0;
4808 __u16 params, param_offset, offset, byte_count;
4810 cifs_dbg(FYI, "In SETFSUnixInfo\n");
4812 /* BB switch to small buf init to save memory */
4813 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4814 (void **) &pSMB, (void **) &pSMBr);
4818 params = 4; /* 2 bytes zero followed by info level. */
4819 pSMB->MaxSetupCount = 0;
4823 pSMB->Reserved2 = 0;
4824 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
4826 offset = param_offset + params;
4828 pSMB->MaxParameterCount = cpu_to_le16(4);
4829 /* BB find exact max SMB PDU from sess structure BB */
4830 pSMB->MaxDataCount = cpu_to_le16(100);
4831 pSMB->SetupCount = 1;
4832 pSMB->Reserved3 = 0;
4833 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
4834 byte_count = 1 /* pad */ + params + 12;
4836 pSMB->DataCount = cpu_to_le16(12);
4837 pSMB->ParameterCount = cpu_to_le16(params);
4838 pSMB->TotalDataCount = pSMB->DataCount;
4839 pSMB->TotalParameterCount = pSMB->ParameterCount;
4840 pSMB->ParameterOffset = cpu_to_le16(param_offset);
4841 pSMB->DataOffset = cpu_to_le16(offset);
4845 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
4848 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
4849 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4850 pSMB->ClientUnixCap = cpu_to_le64(cap);
4852 inc_rfc1001_len(pSMB, byte_count);
4853 pSMB->ByteCount = cpu_to_le16(byte_count);
4855 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4856 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4858 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
4859 } else { /* decode response */
4860 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4862 rc = -EIO; /* bad smb */
4864 cifs_buf_release(pSMB);
4867 goto SETFSUnixRetry;
4875 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
4876 struct kstatfs *FSData)
4878 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
4879 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4880 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4881 FILE_SYSTEM_POSIX_INFO *response_data;
4883 int bytes_returned = 0;
4884 __u16 params, byte_count;
4886 cifs_dbg(FYI, "In QFSPosixInfo\n");
4888 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4893 params = 2; /* level */
4894 pSMB->TotalDataCount = 0;
4895 pSMB->DataCount = 0;
4896 pSMB->DataOffset = 0;
4897 pSMB->MaxParameterCount = cpu_to_le16(2);
4898 /* BB find exact max SMB PDU from sess structure BB */
4899 pSMB->MaxDataCount = cpu_to_le16(100);
4900 pSMB->MaxSetupCount = 0;
4904 pSMB->Reserved2 = 0;
4905 byte_count = params + 1 /* pad */ ;
4906 pSMB->ParameterCount = cpu_to_le16(params);
4907 pSMB->TotalParameterCount = pSMB->ParameterCount;
4908 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4909 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4910 pSMB->SetupCount = 1;
4911 pSMB->Reserved3 = 0;
4912 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4913 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4914 inc_rfc1001_len(pSMB, byte_count);
4915 pSMB->ByteCount = cpu_to_le16(byte_count);
4917 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4918 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4920 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
4921 } else { /* decode response */
4922 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4924 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4925 rc = -EIO; /* bad smb */
4927 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4929 (FILE_SYSTEM_POSIX_INFO
4930 *) (((char *) &pSMBr->hdr.Protocol) +
4933 le32_to_cpu(response_data->BlockSize);
4935 * much prefer larger but if server doesn't report
4936 * a valid size than 4K is a reasonable minimum
4938 if (FSData->f_bsize < 512)
4939 FSData->f_bsize = 4096;
4942 le64_to_cpu(response_data->TotalBlocks);
4944 le64_to_cpu(response_data->BlocksAvail);
4945 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
4946 FSData->f_bavail = FSData->f_bfree;
4949 le64_to_cpu(response_data->UserBlocksAvail);
4951 if (response_data->TotalFileNodes != cpu_to_le64(-1))
4953 le64_to_cpu(response_data->TotalFileNodes);
4954 if (response_data->FreeFileNodes != cpu_to_le64(-1))
4956 le64_to_cpu(response_data->FreeFileNodes);
4959 cifs_buf_release(pSMB);
4969 * We can not use write of zero bytes trick to set file size due to need for
4970 * large file support. Also note that this SetPathInfo is preferred to
4971 * SetFileInfo based method in next routine which is only needed to work around
4972 * a sharing violation bugin Samba which this routine can run into.
4975 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
4976 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
4977 bool set_allocation, struct dentry *dentry)
4979 struct smb_com_transaction2_spi_req *pSMB = NULL;
4980 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
4981 struct file_end_of_file_info *parm_data;
4984 int bytes_returned = 0;
4985 int remap = cifs_remap(cifs_sb);
4987 __u16 params, byte_count, data_count, param_offset, offset;
4989 cifs_dbg(FYI, "In SetEOF\n");
4991 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4996 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4998 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
4999 PATH_MAX, cifs_sb->local_nls, remap);
5000 name_len++; /* trailing null */
5003 name_len = copy_path_name(pSMB->FileName, file_name);
5005 params = 6 + name_len;
5006 data_count = sizeof(struct file_end_of_file_info);
5007 pSMB->MaxParameterCount = cpu_to_le16(2);
5008 pSMB->MaxDataCount = cpu_to_le16(4100);
5009 pSMB->MaxSetupCount = 0;
5013 pSMB->Reserved2 = 0;
5014 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5015 InformationLevel) - 4;
5016 offset = param_offset + params;
5017 if (set_allocation) {
5018 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5019 pSMB->InformationLevel =
5020 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5022 pSMB->InformationLevel =
5023 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5024 } else /* Set File Size */ {
5025 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5026 pSMB->InformationLevel =
5027 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5029 pSMB->InformationLevel =
5030 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5034 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5036 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5037 pSMB->DataOffset = cpu_to_le16(offset);
5038 pSMB->SetupCount = 1;
5039 pSMB->Reserved3 = 0;
5040 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5041 byte_count = 3 /* pad */ + params + data_count;
5042 pSMB->DataCount = cpu_to_le16(data_count);
5043 pSMB->TotalDataCount = pSMB->DataCount;
5044 pSMB->ParameterCount = cpu_to_le16(params);
5045 pSMB->TotalParameterCount = pSMB->ParameterCount;
5046 pSMB->Reserved4 = 0;
5047 inc_rfc1001_len(pSMB, byte_count);
5048 parm_data->FileSize = cpu_to_le64(size);
5049 pSMB->ByteCount = cpu_to_le16(byte_count);
5050 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5051 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5053 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5055 cifs_buf_release(pSMB);
5064 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5065 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5067 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5068 struct file_end_of_file_info *parm_data;
5070 __u16 params, param_offset, offset, byte_count, count;
5072 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5074 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5079 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5080 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5083 pSMB->MaxSetupCount = 0;
5087 pSMB->Reserved2 = 0;
5088 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5089 offset = param_offset + params;
5091 count = sizeof(struct file_end_of_file_info);
5092 pSMB->MaxParameterCount = cpu_to_le16(2);
5093 /* BB find exact max SMB PDU from sess structure BB */
5094 pSMB->MaxDataCount = cpu_to_le16(1000);
5095 pSMB->SetupCount = 1;
5096 pSMB->Reserved3 = 0;
5097 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5098 byte_count = 3 /* pad */ + params + count;
5099 pSMB->DataCount = cpu_to_le16(count);
5100 pSMB->ParameterCount = cpu_to_le16(params);
5101 pSMB->TotalDataCount = pSMB->DataCount;
5102 pSMB->TotalParameterCount = pSMB->ParameterCount;
5103 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5104 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5106 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5107 pSMB->DataOffset = cpu_to_le16(offset);
5108 parm_data->FileSize = cpu_to_le64(size);
5109 pSMB->Fid = cfile->fid.netfid;
5110 if (set_allocation) {
5111 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5112 pSMB->InformationLevel =
5113 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5115 pSMB->InformationLevel =
5116 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5117 } else /* Set File Size */ {
5118 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5119 pSMB->InformationLevel =
5120 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5122 pSMB->InformationLevel =
5123 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5125 pSMB->Reserved4 = 0;
5126 inc_rfc1001_len(pSMB, byte_count);
5127 pSMB->ByteCount = cpu_to_le16(byte_count);
5128 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5129 cifs_small_buf_release(pSMB);
5131 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5135 /* Note: On -EAGAIN error only caller can retry on handle based calls
5136 since file handle passed in no longer valid */
5141 /* Some legacy servers such as NT4 require that the file times be set on
5142 an open handle, rather than by pathname - this is awkward due to
5143 potential access conflicts on the open, but it is unavoidable for these
5144 old servers since the only other choice is to go from 100 nanosecond DCE
5145 time and resort to the original setpathinfo level which takes the ancient
5146 DOS time format with 2 second granularity */
5148 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5149 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5151 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5154 __u16 params, param_offset, offset, byte_count, count;
5156 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5157 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5162 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5163 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5166 pSMB->MaxSetupCount = 0;
5170 pSMB->Reserved2 = 0;
5171 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5172 offset = param_offset + params;
5174 data_offset = (char *)pSMB +
5175 offsetof(struct smb_hdr, Protocol) + offset;
5177 count = sizeof(FILE_BASIC_INFO);
5178 pSMB->MaxParameterCount = cpu_to_le16(2);
5179 /* BB find max SMB PDU from sess */
5180 pSMB->MaxDataCount = cpu_to_le16(1000);
5181 pSMB->SetupCount = 1;
5182 pSMB->Reserved3 = 0;
5183 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5184 byte_count = 3 /* pad */ + params + count;
5185 pSMB->DataCount = cpu_to_le16(count);
5186 pSMB->ParameterCount = cpu_to_le16(params);
5187 pSMB->TotalDataCount = pSMB->DataCount;
5188 pSMB->TotalParameterCount = pSMB->ParameterCount;
5189 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5190 pSMB->DataOffset = cpu_to_le16(offset);
5192 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5193 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5195 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5196 pSMB->Reserved4 = 0;
5197 inc_rfc1001_len(pSMB, byte_count);
5198 pSMB->ByteCount = cpu_to_le16(byte_count);
5199 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5200 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5201 cifs_small_buf_release(pSMB);
5203 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5206 /* Note: On -EAGAIN error only caller can retry on handle based calls
5207 since file handle passed in no longer valid */
5213 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5214 bool delete_file, __u16 fid, __u32 pid_of_opener)
5216 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5219 __u16 params, param_offset, offset, byte_count, count;
5221 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5222 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5227 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5228 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5231 pSMB->MaxSetupCount = 0;
5235 pSMB->Reserved2 = 0;
5236 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5237 offset = param_offset + params;
5239 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5240 data_offset = (char *)(pSMB) + offset + 4;
5243 pSMB->MaxParameterCount = cpu_to_le16(2);
5244 /* BB find max SMB PDU from sess */
5245 pSMB->MaxDataCount = cpu_to_le16(1000);
5246 pSMB->SetupCount = 1;
5247 pSMB->Reserved3 = 0;
5248 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5249 byte_count = 3 /* pad */ + params + count;
5250 pSMB->DataCount = cpu_to_le16(count);
5251 pSMB->ParameterCount = cpu_to_le16(params);
5252 pSMB->TotalDataCount = pSMB->DataCount;
5253 pSMB->TotalParameterCount = pSMB->ParameterCount;
5254 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5255 pSMB->DataOffset = cpu_to_le16(offset);
5257 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5258 pSMB->Reserved4 = 0;
5259 inc_rfc1001_len(pSMB, byte_count);
5260 pSMB->ByteCount = cpu_to_le16(byte_count);
5261 *data_offset = delete_file ? 1 : 0;
5262 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5263 cifs_small_buf_release(pSMB);
5265 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5271 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5272 const char *fileName, const FILE_BASIC_INFO *data,
5273 const struct nls_table *nls_codepage,
5274 struct cifs_sb_info *cifs_sb)
5277 struct cifs_open_parms oparms;
5278 struct cifs_fid fid;
5281 oparms = (struct cifs_open_parms) {
5284 .desired_access = GENERIC_WRITE,
5285 .create_options = cifs_create_options(cifs_sb, 0),
5286 .disposition = FILE_OPEN,
5291 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5295 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5296 CIFSSMBClose(xid, tcon, fid.netfid);
5303 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5304 const char *fileName, const FILE_BASIC_INFO *data,
5305 const struct nls_table *nls_codepage,
5306 struct cifs_sb_info *cifs_sb)
5308 TRANSACTION2_SPI_REQ *pSMB = NULL;
5309 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5312 int bytes_returned = 0;
5314 __u16 params, param_offset, offset, byte_count, count;
5315 int remap = cifs_remap(cifs_sb);
5317 cifs_dbg(FYI, "In SetTimes\n");
5320 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5325 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5327 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5328 PATH_MAX, nls_codepage, remap);
5329 name_len++; /* trailing null */
5332 name_len = copy_path_name(pSMB->FileName, fileName);
5335 params = 6 + name_len;
5336 count = sizeof(FILE_BASIC_INFO);
5337 pSMB->MaxParameterCount = cpu_to_le16(2);
5338 /* BB find max SMB PDU from sess structure BB */
5339 pSMB->MaxDataCount = cpu_to_le16(1000);
5340 pSMB->MaxSetupCount = 0;
5344 pSMB->Reserved2 = 0;
5345 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5346 InformationLevel) - 4;
5347 offset = param_offset + params;
5348 data_offset = (char *)pSMB + offsetof(typeof(*pSMB), hdr.Protocol) + offset;
5349 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5350 pSMB->DataOffset = cpu_to_le16(offset);
5351 pSMB->SetupCount = 1;
5352 pSMB->Reserved3 = 0;
5353 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5354 byte_count = 3 /* pad */ + params + count;
5356 pSMB->DataCount = cpu_to_le16(count);
5357 pSMB->ParameterCount = cpu_to_le16(params);
5358 pSMB->TotalDataCount = pSMB->DataCount;
5359 pSMB->TotalParameterCount = pSMB->ParameterCount;
5360 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5361 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5363 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5364 pSMB->Reserved4 = 0;
5365 inc_rfc1001_len(pSMB, byte_count);
5366 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5367 pSMB->ByteCount = cpu_to_le16(byte_count);
5368 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5369 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5371 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5373 cifs_buf_release(pSMB);
5378 if (rc == -EOPNOTSUPP)
5379 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5380 nls_codepage, cifs_sb);
5386 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5387 const struct cifs_unix_set_info_args *args)
5389 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5390 u64 mode = args->mode;
5392 if (uid_valid(args->uid))
5393 uid = from_kuid(&init_user_ns, args->uid);
5394 if (gid_valid(args->gid))
5395 gid = from_kgid(&init_user_ns, args->gid);
5398 * Samba server ignores set of file size to zero due to bugs in some
5399 * older clients, but we should be precise - we use SetFileSize to
5400 * set file size and do not want to truncate file size to zero
5401 * accidentally as happened on one Samba server beta by putting
5402 * zero instead of -1 here
5404 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5405 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5406 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5407 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5408 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5409 data_offset->Uid = cpu_to_le64(uid);
5410 data_offset->Gid = cpu_to_le64(gid);
5411 /* better to leave device as zero when it is */
5412 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5413 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5414 data_offset->Permissions = cpu_to_le64(mode);
5417 data_offset->Type = cpu_to_le32(UNIX_FILE);
5418 else if (S_ISDIR(mode))
5419 data_offset->Type = cpu_to_le32(UNIX_DIR);
5420 else if (S_ISLNK(mode))
5421 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5422 else if (S_ISCHR(mode))
5423 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5424 else if (S_ISBLK(mode))
5425 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5426 else if (S_ISFIFO(mode))
5427 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5428 else if (S_ISSOCK(mode))
5429 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5433 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5434 const struct cifs_unix_set_info_args *args,
5435 u16 fid, u32 pid_of_opener)
5437 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5440 u16 params, param_offset, offset, byte_count, count;
5442 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5443 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5448 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5449 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5452 pSMB->MaxSetupCount = 0;
5456 pSMB->Reserved2 = 0;
5457 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5458 offset = param_offset + params;
5460 data_offset = (char *)pSMB +
5461 offsetof(struct smb_hdr, Protocol) + offset;
5463 count = sizeof(FILE_UNIX_BASIC_INFO);
5465 pSMB->MaxParameterCount = cpu_to_le16(2);
5466 /* BB find max SMB PDU from sess */
5467 pSMB->MaxDataCount = cpu_to_le16(1000);
5468 pSMB->SetupCount = 1;
5469 pSMB->Reserved3 = 0;
5470 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5471 byte_count = 3 /* pad */ + params + count;
5472 pSMB->DataCount = cpu_to_le16(count);
5473 pSMB->ParameterCount = cpu_to_le16(params);
5474 pSMB->TotalDataCount = pSMB->DataCount;
5475 pSMB->TotalParameterCount = pSMB->ParameterCount;
5476 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5477 pSMB->DataOffset = cpu_to_le16(offset);
5479 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5480 pSMB->Reserved4 = 0;
5481 inc_rfc1001_len(pSMB, byte_count);
5482 pSMB->ByteCount = cpu_to_le16(byte_count);
5484 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5486 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5487 cifs_small_buf_release(pSMB);
5489 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5492 /* Note: On -EAGAIN error only caller can retry on handle based calls
5493 since file handle passed in no longer valid */
5499 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5500 const char *file_name,
5501 const struct cifs_unix_set_info_args *args,
5502 const struct nls_table *nls_codepage, int remap)
5504 TRANSACTION2_SPI_REQ *pSMB = NULL;
5505 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5508 int bytes_returned = 0;
5509 FILE_UNIX_BASIC_INFO *data_offset;
5510 __u16 params, param_offset, offset, count, byte_count;
5512 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5514 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5519 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5521 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5522 PATH_MAX, nls_codepage, remap);
5523 name_len++; /* trailing null */
5526 name_len = copy_path_name(pSMB->FileName, file_name);
5529 params = 6 + name_len;
5530 count = sizeof(FILE_UNIX_BASIC_INFO);
5531 pSMB->MaxParameterCount = cpu_to_le16(2);
5532 /* BB find max SMB PDU from sess structure BB */
5533 pSMB->MaxDataCount = cpu_to_le16(1000);
5534 pSMB->MaxSetupCount = 0;
5538 pSMB->Reserved2 = 0;
5539 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5540 InformationLevel) - 4;
5541 offset = param_offset + params;
5542 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5543 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
5544 memset(data_offset, 0, count);
5545 pSMB->DataOffset = cpu_to_le16(offset);
5546 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5547 pSMB->SetupCount = 1;
5548 pSMB->Reserved3 = 0;
5549 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5550 byte_count = 3 /* pad */ + params + count;
5551 pSMB->ParameterCount = cpu_to_le16(params);
5552 pSMB->DataCount = cpu_to_le16(count);
5553 pSMB->TotalParameterCount = pSMB->ParameterCount;
5554 pSMB->TotalDataCount = pSMB->DataCount;
5555 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5556 pSMB->Reserved4 = 0;
5557 inc_rfc1001_len(pSMB, byte_count);
5559 cifs_fill_unix_set_info(data_offset, args);
5561 pSMB->ByteCount = cpu_to_le16(byte_count);
5562 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5563 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5565 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
5567 cifs_buf_release(pSMB);
5573 #ifdef CONFIG_CIFS_XATTR
5575 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
5576 * function used by listxattr and getxattr type calls. When ea_name is set,
5577 * it looks for that attribute name and stuffs that value into the EAData
5578 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
5579 * buffer. In both cases, the return value is either the length of the
5580 * resulting data or a negative error code. If EAData is a NULL pointer then
5581 * the data isn't copied to it, but the length is returned.
5584 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
5585 const unsigned char *searchName, const unsigned char *ea_name,
5586 char *EAData, size_t buf_size,
5587 struct cifs_sb_info *cifs_sb)
5589 /* BB assumes one setup word */
5590 TRANSACTION2_QPI_REQ *pSMB = NULL;
5591 TRANSACTION2_QPI_RSP *pSMBr = NULL;
5592 int remap = cifs_remap(cifs_sb);
5593 struct nls_table *nls_codepage = cifs_sb->local_nls;
5597 struct fealist *ea_response_data;
5598 struct fea *temp_fea;
5601 __u16 params, byte_count, data_offset;
5602 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
5604 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
5606 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5611 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5613 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
5614 PATH_MAX, nls_codepage, remap);
5615 list_len++; /* trailing null */
5618 list_len = copy_path_name(pSMB->FileName, searchName);
5621 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
5622 pSMB->TotalDataCount = 0;
5623 pSMB->MaxParameterCount = cpu_to_le16(2);
5624 /* BB find exact max SMB PDU from sess structure BB */
5625 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
5626 pSMB->MaxSetupCount = 0;
5630 pSMB->Reserved2 = 0;
5631 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5632 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5633 pSMB->DataCount = 0;
5634 pSMB->DataOffset = 0;
5635 pSMB->SetupCount = 1;
5636 pSMB->Reserved3 = 0;
5637 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
5638 byte_count = params + 1 /* pad */ ;
5639 pSMB->TotalParameterCount = cpu_to_le16(params);
5640 pSMB->ParameterCount = pSMB->TotalParameterCount;
5641 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5642 pSMB->Reserved4 = 0;
5643 inc_rfc1001_len(pSMB, byte_count);
5644 pSMB->ByteCount = cpu_to_le16(byte_count);
5646 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5647 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5649 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
5654 /* BB also check enough total bytes returned */
5655 /* BB we need to improve the validity checking
5656 of these trans2 responses */
5658 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5659 if (rc || get_bcc(&pSMBr->hdr) < 4) {
5660 rc = -EIO; /* bad smb */
5664 /* check that length of list is not more than bcc */
5665 /* check that each entry does not go beyond length
5667 /* check that each element of each entry does not
5668 go beyond end of list */
5669 /* validate_trans2_offsets() */
5670 /* BB check if start of smb + data_offset > &bcc+ bcc */
5672 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5673 ea_response_data = (struct fealist *)
5674 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5676 list_len = le32_to_cpu(ea_response_data->list_len);
5677 cifs_dbg(FYI, "ea length %d\n", list_len);
5678 if (list_len <= 8) {
5679 cifs_dbg(FYI, "empty EA list returned from server\n");
5680 /* didn't find the named attribute */
5686 /* make sure list_len doesn't go past end of SMB */
5687 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
5688 if ((char *)ea_response_data + list_len > end_of_smb) {
5689 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
5694 /* account for ea list len */
5696 temp_fea = &ea_response_data->list;
5697 temp_ptr = (char *)temp_fea;
5698 while (list_len > 0) {
5699 unsigned int name_len;
5704 /* make sure we can read name_len and value_len */
5706 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5711 name_len = temp_fea->name_len;
5712 value_len = le16_to_cpu(temp_fea->value_len);
5713 list_len -= name_len + 1 + value_len;
5715 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5721 if (ea_name_len == name_len &&
5722 memcmp(ea_name, temp_ptr, name_len) == 0) {
5723 temp_ptr += name_len + 1;
5727 if ((size_t)value_len > buf_size) {
5731 memcpy(EAData, temp_ptr, value_len);
5735 /* account for prefix user. and trailing null */
5736 rc += (5 + 1 + name_len);
5737 if (rc < (int) buf_size) {
5738 memcpy(EAData, "user.", 5);
5740 memcpy(EAData, temp_ptr, name_len);
5742 /* null terminate name */
5745 } else if (buf_size == 0) {
5746 /* skip copy - calc size only */
5748 /* stop before overrun buffer */
5753 temp_ptr += name_len + 1 + value_len;
5754 temp_fea = (struct fea *)temp_ptr;
5757 /* didn't find the named attribute */
5762 cifs_buf_release(pSMB);
5770 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
5771 const char *fileName, const char *ea_name, const void *ea_value,
5772 const __u16 ea_value_len, const struct nls_table *nls_codepage,
5773 struct cifs_sb_info *cifs_sb)
5775 struct smb_com_transaction2_spi_req *pSMB = NULL;
5776 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5777 struct fealist *parm_data;
5780 int bytes_returned = 0;
5781 __u16 params, param_offset, byte_count, offset, count;
5782 int remap = cifs_remap(cifs_sb);
5784 cifs_dbg(FYI, "In SetEA\n");
5786 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5791 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5793 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5794 PATH_MAX, nls_codepage, remap);
5795 name_len++; /* trailing null */
5798 name_len = copy_path_name(pSMB->FileName, fileName);
5801 params = 6 + name_len;
5803 /* done calculating parms using name_len of file name,
5804 now use name_len to calculate length of ea name
5805 we are going to create in the inode xattrs */
5806 if (ea_name == NULL)
5809 name_len = strnlen(ea_name, 255);
5811 count = sizeof(*parm_data) + 1 + ea_value_len + name_len;
5812 pSMB->MaxParameterCount = cpu_to_le16(2);
5813 /* BB find max SMB PDU from sess */
5814 pSMB->MaxDataCount = cpu_to_le16(1000);
5815 pSMB->MaxSetupCount = 0;
5819 pSMB->Reserved2 = 0;
5820 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5821 InformationLevel) - 4;
5822 offset = param_offset + params;
5823 pSMB->InformationLevel =
5824 cpu_to_le16(SMB_SET_FILE_EA);
5826 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
5827 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5828 pSMB->DataOffset = cpu_to_le16(offset);
5829 pSMB->SetupCount = 1;
5830 pSMB->Reserved3 = 0;
5831 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5832 byte_count = 3 /* pad */ + params + count;
5833 pSMB->DataCount = cpu_to_le16(count);
5834 parm_data->list_len = cpu_to_le32(count);
5835 parm_data->list.EA_flags = 0;
5836 /* we checked above that name len is less than 255 */
5837 parm_data->list.name_len = (__u8)name_len;
5838 /* EA names are always ASCII and NUL-terminated */
5839 strscpy(parm_data->list.name, ea_name ?: "", name_len + 1);
5840 parm_data->list.value_len = cpu_to_le16(ea_value_len);
5841 /* caller ensures that ea_value_len is less than 64K but
5842 we need to ensure that it fits within the smb */
5844 /*BB add length check to see if it would fit in
5845 negotiated SMB buffer size BB */
5846 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
5848 memcpy(parm_data->list.name + name_len + 1,
5849 ea_value, ea_value_len);
5851 pSMB->TotalDataCount = pSMB->DataCount;
5852 pSMB->ParameterCount = cpu_to_le16(params);
5853 pSMB->TotalParameterCount = pSMB->ParameterCount;
5854 pSMB->Reserved4 = 0;
5855 inc_rfc1001_len(pSMB, byte_count);
5856 pSMB->ByteCount = cpu_to_le16(byte_count);
5857 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5858 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5860 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
5862 cifs_buf_release(pSMB);