1 // SPDX-License-Identifier: LGPL-2.1
4 * Copyright (C) International Business Machines Corp., 2002,2010
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for constructing the SMB PDUs themselves
11 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
12 /* These are mostly routines that operate on a pathname, or on a tree id */
13 /* (mounted volume), but there are eight handle based routines which must be */
14 /* treated slightly differently for reconnection purposes since we never */
15 /* want to reuse a stale file handle and only the caller knows the file info */
18 #include <linux/kernel.h>
19 #include <linux/vfs.h>
20 #include <linux/slab.h>
21 #include <linux/posix_acl_xattr.h>
22 #include <linux/pagemap.h>
23 #include <linux/swap.h>
24 #include <linux/task_io_accounting_ops.h>
25 #include <linux/uaccess.h>
29 #include "cifsproto.h"
30 #include "cifs_unicode.h"
31 #include "cifs_debug.h"
32 #include "smb2proto.h"
34 #include "smbdirect.h"
35 #ifdef CONFIG_CIFS_DFS_UPCALL
36 #include "dfs_cache.h"
39 #ifdef CONFIG_CIFS_POSIX
44 {CIFS_PROT, "\2NT LM 0.12"},
45 {POSIX_PROT, "\2POSIX 2"},
53 {CIFS_PROT, "\2NT LM 0.12"},
58 /* define the number of elements in the cifs dialect array */
59 #ifdef CONFIG_CIFS_POSIX
60 #define CIFS_NUM_PROT 2
62 #define CIFS_NUM_PROT 1
63 #endif /* CIFS_POSIX */
66 * Mark as invalid, all open files on tree connections since they
67 * were closed when session to server was lost.
70 cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
72 struct cifsFileInfo *open_file = NULL;
73 struct list_head *tmp;
74 struct list_head *tmp1;
76 /* list all files open on tree connection and mark them invalid */
77 spin_lock(&tcon->open_file_lock);
78 list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
79 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
80 open_file->invalidHandle = true;
81 open_file->oplock_break_cancelled = true;
83 spin_unlock(&tcon->open_file_lock);
85 mutex_lock(&tcon->crfid.fid_mutex);
86 tcon->crfid.is_valid = false;
87 /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
88 close_cached_dir_lease_locked(&tcon->crfid);
89 memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
90 mutex_unlock(&tcon->crfid.fid_mutex);
93 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
98 /* reconnect the socket, tcon, and smb session if needed */
100 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
103 struct cifs_ses *ses;
104 struct TCP_Server_Info *server;
105 struct nls_table *nls_codepage;
109 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
110 * tcp and smb session status done differently for those three - in the
117 server = ses->server;
120 * only tree disconnect, open, and write, (and ulogoff which does not
121 * have tcon) are allowed as we start force umount
123 if (tcon->tidStatus == CifsExiting) {
124 if (smb_command != SMB_COM_WRITE_ANDX &&
125 smb_command != SMB_COM_OPEN_ANDX &&
126 smb_command != SMB_COM_TREE_DISCONNECT) {
127 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
133 retries = server->nr_targets;
136 * Give demultiplex thread up to 10 seconds to each target available for
137 * reconnect -- should be greater than cifs socket timeout which is 7
140 while (server->tcpStatus == CifsNeedReconnect) {
141 rc = wait_event_interruptible_timeout(server->response_q,
142 (server->tcpStatus != CifsNeedReconnect),
145 cifs_dbg(FYI, "%s: aborting reconnect due to a received signal by the process\n",
150 /* are we still trying to reconnect? */
151 if (server->tcpStatus != CifsNeedReconnect)
154 if (retries && --retries)
158 * on "soft" mounts we wait once. Hard mounts keep
159 * retrying until process is killed or server comes
163 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
166 retries = server->nr_targets;
169 spin_lock(&ses->chan_lock);
170 if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
171 spin_unlock(&ses->chan_lock);
174 spin_unlock(&ses->chan_lock);
176 nls_codepage = load_nls_default();
179 * need to prevent multiple threads trying to simultaneously
180 * reconnect the same SMB session
182 mutex_lock(&ses->session_mutex);
185 * Recheck after acquire mutex. If another thread is negotiating
186 * and the server never sends an answer the socket will be closed
187 * and tcpStatus set to reconnect.
189 if (server->tcpStatus == CifsNeedReconnect) {
191 mutex_unlock(&ses->session_mutex);
196 * need to prevent multiple threads trying to simultaneously
197 * reconnect the same SMB session
199 spin_lock(&ses->chan_lock);
200 if (!cifs_chan_needs_reconnect(ses, server)) {
201 spin_unlock(&ses->chan_lock);
203 /* this means that we only need to tree connect */
204 if (tcon->need_reconnect)
205 goto skip_sess_setup;
208 mutex_unlock(&ses->session_mutex);
211 spin_unlock(&ses->chan_lock);
213 rc = cifs_negotiate_protocol(0, ses, server);
215 rc = cifs_setup_session(0, ses, server, nls_codepage);
217 /* do we need to reconnect tcon? */
218 if (rc || !tcon->need_reconnect) {
219 mutex_unlock(&ses->session_mutex);
224 cifs_mark_open_files_invalid(tcon);
225 rc = cifs_tree_connect(0, tcon, nls_codepage);
226 mutex_unlock(&ses->session_mutex);
227 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
230 pr_warn_once("reconnect tcon failed rc = %d\n", rc);
234 atomic_inc(&tconInfoReconnectCount);
236 /* tell server Unix caps we support */
238 reset_cifs_unix_caps(0, tcon, NULL, NULL);
241 * Removed call to reopen open files here. It is safer (and faster) to
242 * reopen files one at a time as needed in read and write.
244 * FIXME: what about file locks? don't we need to reclaim them ASAP?
249 * Check if handle based operation so we know whether we can continue
250 * or not without returning to caller to reset file handle
252 switch (smb_command) {
253 case SMB_COM_READ_ANDX:
254 case SMB_COM_WRITE_ANDX:
256 case SMB_COM_FIND_CLOSE2:
257 case SMB_COM_LOCKING_ANDX:
261 unload_nls(nls_codepage);
265 /* Allocate and return pointer to an SMB request buffer, and set basic
266 SMB information in the SMB header. If the return code is zero, this
267 function must have filled in request_buf pointer */
269 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
274 rc = cifs_reconnect_tcon(tcon, smb_command);
278 *request_buf = cifs_small_buf_get();
279 if (*request_buf == NULL) {
280 /* BB should we add a retry in here if not a writepage? */
284 header_assemble((struct smb_hdr *) *request_buf, smb_command,
288 cifs_stats_inc(&tcon->num_smbs_sent);
294 small_smb_init_no_tc(const int smb_command, const int wct,
295 struct cifs_ses *ses, void **request_buf)
298 struct smb_hdr *buffer;
300 rc = small_smb_init(smb_command, wct, NULL, request_buf);
304 buffer = (struct smb_hdr *)*request_buf;
305 buffer->Mid = get_next_mid(ses->server);
306 if (ses->capabilities & CAP_UNICODE)
307 buffer->Flags2 |= SMBFLG2_UNICODE;
308 if (ses->capabilities & CAP_STATUS32)
309 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
311 /* uid, tid can stay at zero as set in header assemble */
313 /* BB add support for turning on the signing when
314 this function is used after 1st of session setup requests */
319 /* If the return code is zero, this function must fill in request_buf pointer */
321 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
322 void **request_buf, void **response_buf)
324 *request_buf = cifs_buf_get();
325 if (*request_buf == NULL) {
326 /* BB should we add a retry in here if not a writepage? */
329 /* Although the original thought was we needed the response buf for */
330 /* potential retries of smb operations it turns out we can determine */
331 /* from the mid flags when the request buffer can be resent without */
332 /* having to use a second distinct buffer for the response */
334 *response_buf = *request_buf;
336 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
340 cifs_stats_inc(&tcon->num_smbs_sent);
345 /* If the return code is zero, this function must fill in request_buf pointer */
347 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
348 void **request_buf, void **response_buf)
352 rc = cifs_reconnect_tcon(tcon, smb_command);
356 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
360 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
361 void **request_buf, void **response_buf)
363 spin_lock(&tcon->ses->chan_lock);
364 if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) ||
365 tcon->need_reconnect) {
366 spin_unlock(&tcon->ses->chan_lock);
369 spin_unlock(&tcon->ses->chan_lock);
371 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
374 static int validate_t2(struct smb_t2_rsp *pSMB)
376 unsigned int total_size;
378 /* check for plausible wct */
379 if (pSMB->hdr.WordCount < 10)
382 /* check for parm and data offset going beyond end of smb */
383 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
384 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
387 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
388 if (total_size >= 512)
391 /* check that bcc is at least as big as parms + data, and that it is
392 * less than negotiated smb buffer
394 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
395 if (total_size > get_bcc(&pSMB->hdr) ||
396 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
401 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
402 sizeof(struct smb_t2_rsp) + 16);
407 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
411 char *guid = pSMBr->u.extended_response.GUID;
412 struct TCP_Server_Info *server = ses->server;
414 count = get_bcc(&pSMBr->hdr);
415 if (count < SMB1_CLIENT_GUID_SIZE)
418 spin_lock(&cifs_tcp_ses_lock);
419 if (server->srv_count > 1) {
420 spin_unlock(&cifs_tcp_ses_lock);
421 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
422 cifs_dbg(FYI, "server UID changed\n");
423 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
426 spin_unlock(&cifs_tcp_ses_lock);
427 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
430 if (count == SMB1_CLIENT_GUID_SIZE) {
431 server->sec_ntlmssp = true;
433 count -= SMB1_CLIENT_GUID_SIZE;
434 rc = decode_negTokenInit(
435 pSMBr->u.extended_response.SecurityBlob, count, server);
444 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
446 bool srv_sign_required = server->sec_mode & server->vals->signing_required;
447 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
448 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
451 * Is signing required by mnt options? If not then check
452 * global_secflags to see if it is there.
454 if (!mnt_sign_required)
455 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
459 * If signing is required then it's automatically enabled too,
460 * otherwise, check to see if the secflags allow it.
462 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
463 (global_secflags & CIFSSEC_MAY_SIGN);
465 /* If server requires signing, does client allow it? */
466 if (srv_sign_required) {
467 if (!mnt_sign_enabled) {
468 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!\n");
474 /* If client requires signing, does server allow it? */
475 if (mnt_sign_required) {
476 if (!srv_sign_enabled) {
477 cifs_dbg(VFS, "Server does not support signing!\n");
483 if (cifs_rdma_enabled(server) && server->sign)
484 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled\n");
490 should_set_ext_sec_flag(enum securityEnum sectype)
497 if (global_secflags &
498 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
507 CIFSSMBNegotiate(const unsigned int xid,
508 struct cifs_ses *ses,
509 struct TCP_Server_Info *server)
512 NEGOTIATE_RSP *pSMBr;
519 WARN(1, "%s: server is NULL!\n", __func__);
523 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
524 (void **) &pSMB, (void **) &pSMBr);
528 pSMB->hdr.Mid = get_next_mid(server);
529 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
531 if (should_set_ext_sec_flag(ses->sectype)) {
532 cifs_dbg(FYI, "Requesting extended security\n");
533 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
538 * We know that all the name entries in the protocols array
539 * are short (< 16 bytes anyway) and are NUL terminated.
541 for (i = 0; i < CIFS_NUM_PROT; i++) {
542 size_t len = strlen(protocols[i].name) + 1;
544 memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
547 inc_rfc1001_len(pSMB, count);
548 pSMB->ByteCount = cpu_to_le16(count);
550 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
551 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
555 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
556 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
557 /* Check wct = 1 error case */
558 if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
559 /* core returns wct = 1, but we do not ask for core - otherwise
560 small wct just comes when dialect index is -1 indicating we
561 could not negotiate a common dialect */
564 } else if (pSMBr->hdr.WordCount != 17) {
569 /* else wct == 17, NTLM or better */
571 server->sec_mode = pSMBr->SecurityMode;
572 if ((server->sec_mode & SECMODE_USER) == 0)
573 cifs_dbg(FYI, "share mode security\n");
575 /* one byte, so no need to convert this or EncryptionKeyLen from
577 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
579 set_credits(server, server->maxReq);
580 /* probably no need to store and check maxvcs */
581 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
582 /* set up max_read for readpages check */
583 server->max_read = server->maxBuf;
584 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
585 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
586 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
587 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
588 server->timeAdj *= 60;
590 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
591 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
592 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
593 CIFS_CRYPTO_KEY_SIZE);
594 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
595 server->capabilities & CAP_EXTENDED_SECURITY) {
596 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
597 rc = decode_ext_sec_blob(ses, pSMBr);
598 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
599 rc = -EIO; /* no crypt key only if plain text pwd */
601 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
602 server->capabilities &= ~CAP_EXTENDED_SECURITY;
606 rc = cifs_enable_signing(server, ses->sign);
608 cifs_buf_release(pSMB);
610 cifs_dbg(FYI, "negprot rc %d\n", rc);
615 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
617 struct smb_hdr *smb_buffer;
620 cifs_dbg(FYI, "In tree disconnect\n");
622 /* BB: do we need to check this? These should never be NULL. */
623 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
627 * No need to return error on this operation if tid invalidated and
628 * closed on server already e.g. due to tcp session crashing. Also,
629 * the tcon is no longer on the list, so no need to take lock before
632 spin_lock(&tcon->ses->chan_lock);
633 if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
634 spin_unlock(&tcon->ses->chan_lock);
637 spin_unlock(&tcon->ses->chan_lock);
639 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
640 (void **)&smb_buffer);
644 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
645 cifs_small_buf_release(smb_buffer);
647 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
649 /* No need to return error on this operation if tid invalidated and
650 closed on server already e.g. due to tcp session crashing */
658 * This is a no-op for now. We're not really interested in the reply, but
659 * rather in the fact that the server sent one and that server->lstrp
662 * FIXME: maybe we should consider checking that the reply matches request?
665 cifs_echo_callback(struct mid_q_entry *mid)
667 struct TCP_Server_Info *server = mid->callback_data;
668 struct cifs_credits credits = { .value = 1, .instance = 0 };
670 DeleteMidQEntry(mid);
671 add_credits(server, &credits, CIFS_ECHO_OP);
675 CIFSSMBEcho(struct TCP_Server_Info *server)
680 struct smb_rqst rqst = { .rq_iov = iov,
683 cifs_dbg(FYI, "In echo request\n");
685 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
689 if (server->capabilities & CAP_UNICODE)
690 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
692 /* set up echo request */
693 smb->hdr.Tid = 0xffff;
694 smb->hdr.WordCount = 1;
695 put_unaligned_le16(1, &smb->EchoCount);
696 put_bcc(1, &smb->hdr);
698 inc_rfc1001_len(smb, 3);
701 iov[0].iov_base = smb;
702 iov[1].iov_len = get_rfc1002_length(smb);
703 iov[1].iov_base = (char *)smb + 4;
705 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
706 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
708 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
710 cifs_small_buf_release(smb);
716 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
718 LOGOFF_ANDX_REQ *pSMB;
721 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
724 * BB: do we need to check validity of ses and server? They should
725 * always be valid since we have an active reference. If not, that
726 * should probably be a BUG()
728 if (!ses || !ses->server)
731 mutex_lock(&ses->session_mutex);
732 spin_lock(&ses->chan_lock);
733 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
734 spin_unlock(&ses->chan_lock);
735 goto session_already_dead; /* no need to send SMBlogoff if uid
736 already closed due to reconnect */
738 spin_unlock(&ses->chan_lock);
740 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
742 mutex_unlock(&ses->session_mutex);
746 pSMB->hdr.Mid = get_next_mid(ses->server);
748 if (ses->server->sign)
749 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
751 pSMB->hdr.Uid = ses->Suid;
753 pSMB->AndXCommand = 0xFF;
754 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
755 cifs_small_buf_release(pSMB);
756 session_already_dead:
757 mutex_unlock(&ses->session_mutex);
759 /* if session dead then we do not need to do ulogoff,
760 since server closed smb session, no sense reporting
768 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
769 const char *fileName, __u16 type,
770 const struct nls_table *nls_codepage, int remap)
772 TRANSACTION2_SPI_REQ *pSMB = NULL;
773 TRANSACTION2_SPI_RSP *pSMBr = NULL;
774 struct unlink_psx_rq *pRqD;
777 int bytes_returned = 0;
778 __u16 params, param_offset, offset, byte_count;
780 cifs_dbg(FYI, "In POSIX delete\n");
782 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
787 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
789 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
790 PATH_MAX, nls_codepage, remap);
791 name_len++; /* trailing null */
794 name_len = copy_path_name(pSMB->FileName, fileName);
797 params = 6 + name_len;
798 pSMB->MaxParameterCount = cpu_to_le16(2);
799 pSMB->MaxDataCount = 0; /* BB double check this with jra */
800 pSMB->MaxSetupCount = 0;
805 param_offset = offsetof(struct smb_com_transaction2_spi_req,
806 InformationLevel) - 4;
807 offset = param_offset + params;
809 /* Setup pointer to Request Data (inode type).
810 * Note that SMB offsets are from the beginning of SMB which is 4 bytes
811 * in, after RFC1001 field
813 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
814 pRqD->type = cpu_to_le16(type);
815 pSMB->ParameterOffset = cpu_to_le16(param_offset);
816 pSMB->DataOffset = cpu_to_le16(offset);
817 pSMB->SetupCount = 1;
819 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
820 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
822 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
823 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
824 pSMB->ParameterCount = cpu_to_le16(params);
825 pSMB->TotalParameterCount = pSMB->ParameterCount;
826 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
828 inc_rfc1001_len(pSMB, byte_count);
829 pSMB->ByteCount = cpu_to_le16(byte_count);
830 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
831 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
833 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
834 cifs_buf_release(pSMB);
836 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
845 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
846 struct cifs_sb_info *cifs_sb)
848 DELETE_FILE_REQ *pSMB = NULL;
849 DELETE_FILE_RSP *pSMBr = NULL;
853 int remap = cifs_remap(cifs_sb);
856 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
861 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
862 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
863 PATH_MAX, cifs_sb->local_nls,
865 name_len++; /* trailing null */
868 name_len = copy_path_name(pSMB->fileName, name);
870 pSMB->SearchAttributes =
871 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
872 pSMB->BufferFormat = 0x04;
873 inc_rfc1001_len(pSMB, name_len + 1);
874 pSMB->ByteCount = cpu_to_le16(name_len + 1);
875 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
876 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
877 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
879 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
881 cifs_buf_release(pSMB);
889 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
890 struct cifs_sb_info *cifs_sb)
892 DELETE_DIRECTORY_REQ *pSMB = NULL;
893 DELETE_DIRECTORY_RSP *pSMBr = NULL;
897 int remap = cifs_remap(cifs_sb);
899 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
901 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
906 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
907 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
908 PATH_MAX, cifs_sb->local_nls,
910 name_len++; /* trailing null */
913 name_len = copy_path_name(pSMB->DirName, name);
916 pSMB->BufferFormat = 0x04;
917 inc_rfc1001_len(pSMB, name_len + 1);
918 pSMB->ByteCount = cpu_to_le16(name_len + 1);
919 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
920 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
921 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
923 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
925 cifs_buf_release(pSMB);
932 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
933 struct cifs_tcon *tcon, const char *name,
934 struct cifs_sb_info *cifs_sb)
937 CREATE_DIRECTORY_REQ *pSMB = NULL;
938 CREATE_DIRECTORY_RSP *pSMBr = NULL;
941 int remap = cifs_remap(cifs_sb);
943 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
945 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
950 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
951 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
952 PATH_MAX, cifs_sb->local_nls,
954 name_len++; /* trailing null */
957 name_len = copy_path_name(pSMB->DirName, name);
960 pSMB->BufferFormat = 0x04;
961 inc_rfc1001_len(pSMB, name_len + 1);
962 pSMB->ByteCount = cpu_to_le16(name_len + 1);
963 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
964 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
965 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
967 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
969 cifs_buf_release(pSMB);
976 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
977 __u32 posix_flags, __u64 mode, __u16 *netfid,
978 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
979 const char *name, const struct nls_table *nls_codepage,
982 TRANSACTION2_SPI_REQ *pSMB = NULL;
983 TRANSACTION2_SPI_RSP *pSMBr = NULL;
986 int bytes_returned = 0;
987 __u16 params, param_offset, offset, byte_count, count;
989 OPEN_PSX_RSP *psx_rsp;
991 cifs_dbg(FYI, "In POSIX Create\n");
993 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
998 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1000 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1001 PATH_MAX, nls_codepage, remap);
1002 name_len++; /* trailing null */
1005 name_len = copy_path_name(pSMB->FileName, name);
1008 params = 6 + name_len;
1009 count = sizeof(OPEN_PSX_REQ);
1010 pSMB->MaxParameterCount = cpu_to_le16(2);
1011 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1012 pSMB->MaxSetupCount = 0;
1016 pSMB->Reserved2 = 0;
1017 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1018 InformationLevel) - 4;
1019 offset = param_offset + params;
1020 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
1021 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
1022 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1023 pdata->Permissions = cpu_to_le64(mode);
1024 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1025 pdata->OpenFlags = cpu_to_le32(*pOplock);
1026 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1027 pSMB->DataOffset = cpu_to_le16(offset);
1028 pSMB->SetupCount = 1;
1029 pSMB->Reserved3 = 0;
1030 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1031 byte_count = 3 /* pad */ + params + count;
1033 pSMB->DataCount = cpu_to_le16(count);
1034 pSMB->ParameterCount = cpu_to_le16(params);
1035 pSMB->TotalDataCount = pSMB->DataCount;
1036 pSMB->TotalParameterCount = pSMB->ParameterCount;
1037 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1038 pSMB->Reserved4 = 0;
1039 inc_rfc1001_len(pSMB, byte_count);
1040 pSMB->ByteCount = cpu_to_le16(byte_count);
1041 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1042 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1044 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1045 goto psx_create_err;
1048 cifs_dbg(FYI, "copying inode info\n");
1049 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1051 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1052 rc = -EIO; /* bad smb */
1053 goto psx_create_err;
1056 /* copy return information to pRetData */
1057 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1058 + le16_to_cpu(pSMBr->t2.DataOffset));
1060 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1062 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1063 /* Let caller know file was created so we can set the mode. */
1064 /* Do we care about the CreateAction in any other cases? */
1065 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1066 *pOplock |= CIFS_CREATE_ACTION;
1067 /* check to make sure response data is there */
1068 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1069 pRetData->Type = cpu_to_le32(-1); /* unknown */
1070 cifs_dbg(NOISY, "unknown type\n");
1072 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1073 + sizeof(FILE_UNIX_BASIC_INFO)) {
1074 cifs_dbg(VFS, "Open response data too small\n");
1075 pRetData->Type = cpu_to_le32(-1);
1076 goto psx_create_err;
1078 memcpy((char *) pRetData,
1079 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1080 sizeof(FILE_UNIX_BASIC_INFO));
1084 cifs_buf_release(pSMB);
1086 if (posix_flags & SMB_O_DIRECTORY)
1087 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1089 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1097 static __u16 convert_disposition(int disposition)
1101 switch (disposition) {
1102 case FILE_SUPERSEDE:
1103 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1106 ofun = SMBOPEN_OAPPEND;
1109 ofun = SMBOPEN_OCREATE;
1112 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1114 case FILE_OVERWRITE:
1115 ofun = SMBOPEN_OTRUNC;
1117 case FILE_OVERWRITE_IF:
1118 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1121 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1122 ofun = SMBOPEN_OAPPEND; /* regular open */
1128 access_flags_to_smbopen_mode(const int access_flags)
1130 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1132 if (masked_flags == GENERIC_READ)
1133 return SMBOPEN_READ;
1134 else if (masked_flags == GENERIC_WRITE)
1135 return SMBOPEN_WRITE;
1137 /* just go for read/write */
1138 return SMBOPEN_READWRITE;
1142 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1143 const char *fileName, const int openDisposition,
1144 const int access_flags, const int create_options, __u16 *netfid,
1145 int *pOplock, FILE_ALL_INFO *pfile_info,
1146 const struct nls_table *nls_codepage, int remap)
1149 OPENX_REQ *pSMB = NULL;
1150 OPENX_RSP *pSMBr = NULL;
1156 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1161 pSMB->AndXCommand = 0xFF; /* none */
1163 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1164 count = 1; /* account for one byte pad to word boundary */
1166 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1167 fileName, PATH_MAX, nls_codepage, remap);
1168 name_len++; /* trailing null */
1171 count = 0; /* no pad */
1172 name_len = copy_path_name(pSMB->fileName, fileName);
1174 if (*pOplock & REQ_OPLOCK)
1175 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1176 else if (*pOplock & REQ_BATCHOPLOCK)
1177 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1179 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1180 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1181 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1182 /* set file as system file if special file such
1183 as fifo and server expecting SFU style and
1184 no Unix extensions */
1186 if (create_options & CREATE_OPTION_SPECIAL)
1187 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1188 else /* BB FIXME BB */
1189 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1191 if (create_options & CREATE_OPTION_READONLY)
1192 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1195 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1196 CREATE_OPTIONS_MASK); */
1197 /* BB FIXME END BB */
1199 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1200 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1202 inc_rfc1001_len(pSMB, count);
1204 pSMB->ByteCount = cpu_to_le16(count);
1205 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1206 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1207 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1209 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1211 /* BB verify if wct == 15 */
1213 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1215 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1216 /* Let caller know file was created so we can set the mode. */
1217 /* Do we care about the CreateAction in any other cases? */
1219 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1220 *pOplock |= CIFS_CREATE_ACTION; */
1224 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1225 pfile_info->LastAccessTime = 0; /* BB fixme */
1226 pfile_info->LastWriteTime = 0; /* BB fixme */
1227 pfile_info->ChangeTime = 0; /* BB fixme */
1228 pfile_info->Attributes =
1229 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1230 /* the file_info buf is endian converted by caller */
1231 pfile_info->AllocationSize =
1232 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1233 pfile_info->EndOfFile = pfile_info->AllocationSize;
1234 pfile_info->NumberOfLinks = cpu_to_le32(1);
1235 pfile_info->DeletePending = 0;
1239 cifs_buf_release(pSMB);
1246 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1250 OPEN_REQ *req = NULL;
1251 OPEN_RSP *rsp = NULL;
1255 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1256 struct cifs_tcon *tcon = oparms->tcon;
1257 int remap = cifs_remap(cifs_sb);
1258 const struct nls_table *nls = cifs_sb->local_nls;
1259 int create_options = oparms->create_options;
1260 int desired_access = oparms->desired_access;
1261 int disposition = oparms->disposition;
1262 const char *path = oparms->path;
1265 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1270 /* no commands go after this */
1271 req->AndXCommand = 0xFF;
1273 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1274 /* account for one byte pad to word boundary */
1276 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1277 path, PATH_MAX, nls, remap);
1281 req->NameLength = cpu_to_le16(name_len);
1283 /* BB improve check for buffer overruns BB */
1286 name_len = copy_path_name(req->fileName, path);
1287 req->NameLength = cpu_to_le16(name_len);
1290 if (*oplock & REQ_OPLOCK)
1291 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1292 else if (*oplock & REQ_BATCHOPLOCK)
1293 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1295 req->DesiredAccess = cpu_to_le32(desired_access);
1296 req->AllocationSize = 0;
1299 * Set file as system file if special file such as fifo and server
1300 * expecting SFU style and no Unix extensions.
1302 if (create_options & CREATE_OPTION_SPECIAL)
1303 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1305 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1308 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1309 * sensitive checks for other servers such as Samba.
1311 if (tcon->ses->capabilities & CAP_UNIX)
1312 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1314 if (create_options & CREATE_OPTION_READONLY)
1315 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1317 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1318 req->CreateDisposition = cpu_to_le32(disposition);
1319 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1321 /* BB Expirement with various impersonation levels and verify */
1322 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1323 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1326 inc_rfc1001_len(req, count);
1328 req->ByteCount = cpu_to_le16(count);
1329 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1330 (struct smb_hdr *)rsp, &bytes_returned, 0);
1331 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1333 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1334 cifs_buf_release(req);
1340 /* 1 byte no need to le_to_cpu */
1341 *oplock = rsp->OplockLevel;
1342 /* cifs fid stays in le */
1343 oparms->fid->netfid = rsp->Fid;
1344 oparms->fid->access = desired_access;
1346 /* Let caller know file was created so we can set the mode. */
1347 /* Do we care about the CreateAction in any other cases? */
1348 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1349 *oplock |= CIFS_CREATE_ACTION;
1352 /* copy from CreationTime to Attributes */
1353 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1354 /* the file_info buf is endian converted by caller */
1355 buf->AllocationSize = rsp->AllocationSize;
1356 buf->EndOfFile = rsp->EndOfFile;
1357 buf->NumberOfLinks = cpu_to_le32(1);
1358 buf->DeletePending = 0;
1361 cifs_buf_release(req);
1366 * Discard any remaining data in the current SMB. To do this, we borrow the
1370 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1372 unsigned int rfclen = server->pdu_size;
1373 int remaining = rfclen + server->vals->header_preamble_size -
1376 while (remaining > 0) {
1379 length = cifs_discard_from_socket(server,
1380 min_t(size_t, remaining,
1381 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1384 server->total_read += length;
1385 remaining -= length;
1392 __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
1397 length = cifs_discard_remaining_data(server);
1398 dequeue_mid(mid, malformed);
1399 mid->resp_buf = server->smallbuf;
1400 server->smallbuf = NULL;
1405 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1407 struct cifs_readdata *rdata = mid->callback_data;
1409 return __cifs_readv_discard(server, mid, rdata->result);
1413 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1416 unsigned int data_offset, data_len;
1417 struct cifs_readdata *rdata = mid->callback_data;
1418 char *buf = server->smallbuf;
1419 unsigned int buflen = server->pdu_size +
1420 server->vals->header_preamble_size;
1421 bool use_rdma_mr = false;
1423 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1424 __func__, mid->mid, rdata->offset, rdata->bytes);
1427 * read the rest of READ_RSP header (sans Data array), or whatever we
1428 * can if there's not enough data. At this point, we've read down to
1431 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1432 HEADER_SIZE(server) + 1;
1434 length = cifs_read_from_socket(server,
1435 buf + HEADER_SIZE(server) - 1, len);
1438 server->total_read += length;
1440 if (server->ops->is_session_expired &&
1441 server->ops->is_session_expired(buf)) {
1442 cifs_reconnect(server);
1446 if (server->ops->is_status_pending &&
1447 server->ops->is_status_pending(buf, server)) {
1448 cifs_discard_remaining_data(server);
1452 /* set up first two iov for signature check and to get credits */
1453 rdata->iov[0].iov_base = buf;
1454 rdata->iov[0].iov_len = server->vals->header_preamble_size;
1455 rdata->iov[1].iov_base = buf + server->vals->header_preamble_size;
1456 rdata->iov[1].iov_len =
1457 server->total_read - server->vals->header_preamble_size;
1458 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1459 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1460 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
1461 rdata->iov[1].iov_base, rdata->iov[1].iov_len);
1463 /* Was the SMB read successful? */
1464 rdata->result = server->ops->map_error(buf, false);
1465 if (rdata->result != 0) {
1466 cifs_dbg(FYI, "%s: server returned error %d\n",
1467 __func__, rdata->result);
1468 /* normal error on read response */
1469 return __cifs_readv_discard(server, mid, false);
1472 /* Is there enough to get to the rest of the READ_RSP header? */
1473 if (server->total_read < server->vals->read_rsp_size) {
1474 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1475 __func__, server->total_read,
1476 server->vals->read_rsp_size);
1477 rdata->result = -EIO;
1478 return cifs_readv_discard(server, mid);
1481 data_offset = server->ops->read_data_offset(buf) +
1482 server->vals->header_preamble_size;
1483 if (data_offset < server->total_read) {
1485 * win2k8 sometimes sends an offset of 0 when the read
1486 * is beyond the EOF. Treat it as if the data starts just after
1489 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1490 __func__, data_offset);
1491 data_offset = server->total_read;
1492 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1493 /* data_offset is beyond the end of smallbuf */
1494 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1495 __func__, data_offset);
1496 rdata->result = -EIO;
1497 return cifs_readv_discard(server, mid);
1500 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1501 __func__, server->total_read, data_offset);
1503 len = data_offset - server->total_read;
1505 /* read any junk before data into the rest of smallbuf */
1506 length = cifs_read_from_socket(server,
1507 buf + server->total_read, len);
1510 server->total_read += length;
1513 /* how much data is in the response? */
1514 #ifdef CONFIG_CIFS_SMB_DIRECT
1515 use_rdma_mr = rdata->mr;
1517 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1518 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1519 /* data_len is corrupt -- discard frame */
1520 rdata->result = -EIO;
1521 return cifs_readv_discard(server, mid);
1524 length = rdata->read_into_pages(server, rdata, data_len);
1528 server->total_read += length;
1530 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1531 server->total_read, buflen, data_len);
1533 /* discard anything left over */
1534 if (server->total_read < buflen)
1535 return cifs_readv_discard(server, mid);
1537 dequeue_mid(mid, false);
1538 mid->resp_buf = server->smallbuf;
1539 server->smallbuf = NULL;
1544 cifs_readv_callback(struct mid_q_entry *mid)
1546 struct cifs_readdata *rdata = mid->callback_data;
1547 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1548 struct TCP_Server_Info *server = tcon->ses->server;
1549 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1551 .rq_pages = rdata->pages,
1552 .rq_offset = rdata->page_offset,
1553 .rq_npages = rdata->nr_pages,
1554 .rq_pagesz = rdata->pagesz,
1555 .rq_tailsz = rdata->tailsz };
1556 struct cifs_credits credits = { .value = 1, .instance = 0 };
1558 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1559 __func__, mid->mid, mid->mid_state, rdata->result,
1562 switch (mid->mid_state) {
1563 case MID_RESPONSE_RECEIVED:
1564 /* result already set, check signature */
1568 rc = cifs_verify_signature(&rqst, server,
1569 mid->sequence_number);
1571 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1574 /* FIXME: should this be counted toward the initiating task? */
1575 task_io_account_read(rdata->got_bytes);
1576 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1578 case MID_REQUEST_SUBMITTED:
1579 case MID_RETRY_NEEDED:
1580 rdata->result = -EAGAIN;
1581 if (server->sign && rdata->got_bytes)
1582 /* reset bytes number since we can not check a sign */
1583 rdata->got_bytes = 0;
1584 /* FIXME: should this be counted toward the initiating task? */
1585 task_io_account_read(rdata->got_bytes);
1586 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1589 rdata->result = -EIO;
1592 queue_work(cifsiod_wq, &rdata->work);
1593 DeleteMidQEntry(mid);
1594 add_credits(server, &credits, 0);
1597 /* cifs_async_readv - send an async write, and set up mid to handle result */
1599 cifs_async_readv(struct cifs_readdata *rdata)
1602 READ_REQ *smb = NULL;
1604 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1605 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1608 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1609 __func__, rdata->offset, rdata->bytes);
1611 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1614 wct = 10; /* old style read */
1615 if ((rdata->offset >> 32) > 0) {
1616 /* can not handle this big offset for old */
1621 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1625 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1626 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1628 smb->AndXCommand = 0xFF; /* none */
1629 smb->Fid = rdata->cfile->fid.netfid;
1630 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1632 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1634 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1635 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1639 /* old style read */
1640 struct smb_com_readx_req *smbr =
1641 (struct smb_com_readx_req *)smb;
1642 smbr->ByteCount = 0;
1645 /* 4 for RFC1001 length + 1 for BCC */
1646 rdata->iov[0].iov_base = smb;
1647 rdata->iov[0].iov_len = 4;
1648 rdata->iov[1].iov_base = (char *)smb + 4;
1649 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1651 kref_get(&rdata->refcount);
1652 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1653 cifs_readv_callback, NULL, rdata, 0, NULL);
1656 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1658 kref_put(&rdata->refcount, cifs_readdata_release);
1660 cifs_small_buf_release(smb);
1665 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1666 unsigned int *nbytes, char **buf, int *pbuf_type)
1669 READ_REQ *pSMB = NULL;
1670 READ_RSP *pSMBr = NULL;
1671 char *pReadData = NULL;
1673 int resp_buf_type = 0;
1675 struct kvec rsp_iov;
1676 __u32 pid = io_parms->pid;
1677 __u16 netfid = io_parms->netfid;
1678 __u64 offset = io_parms->offset;
1679 struct cifs_tcon *tcon = io_parms->tcon;
1680 unsigned int count = io_parms->length;
1682 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1683 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1686 wct = 10; /* old style read */
1687 if ((offset >> 32) > 0) {
1688 /* can not handle this big offset for old */
1694 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1698 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1699 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1701 /* tcon and ses pointer are checked in smb_init */
1702 if (tcon->ses->server == NULL)
1703 return -ECONNABORTED;
1705 pSMB->AndXCommand = 0xFF; /* none */
1707 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1709 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1711 pSMB->Remaining = 0;
1712 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1713 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1715 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1717 /* old style read */
1718 struct smb_com_readx_req *pSMBW =
1719 (struct smb_com_readx_req *)pSMB;
1720 pSMBW->ByteCount = 0;
1723 iov[0].iov_base = (char *)pSMB;
1724 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1725 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1726 CIFS_LOG_ERROR, &rsp_iov);
1727 cifs_small_buf_release(pSMB);
1728 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1729 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1731 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1733 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1734 data_length = data_length << 16;
1735 data_length += le16_to_cpu(pSMBr->DataLength);
1736 *nbytes = data_length;
1738 /*check that DataLength would not go beyond end of SMB */
1739 if ((data_length > CIFSMaxBufSize)
1740 || (data_length > count)) {
1741 cifs_dbg(FYI, "bad length %d for count %d\n",
1742 data_length, count);
1746 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1747 le16_to_cpu(pSMBr->DataOffset);
1748 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1749 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1751 }*/ /* can not use copy_to_user when using page cache*/
1753 memcpy(*buf, pReadData, data_length);
1758 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1759 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1760 /* return buffer to caller to free */
1761 *buf = rsp_iov.iov_base;
1762 if (resp_buf_type == CIFS_SMALL_BUFFER)
1763 *pbuf_type = CIFS_SMALL_BUFFER;
1764 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1765 *pbuf_type = CIFS_LARGE_BUFFER;
1766 } /* else no valid buffer on return - leave as null */
1768 /* Note: On -EAGAIN error only caller can retry on handle based calls
1769 since file handle passed in no longer valid */
1775 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1776 unsigned int *nbytes, const char *buf)
1779 WRITE_REQ *pSMB = NULL;
1780 WRITE_RSP *pSMBr = NULL;
1781 int bytes_returned, wct;
1784 __u32 pid = io_parms->pid;
1785 __u16 netfid = io_parms->netfid;
1786 __u64 offset = io_parms->offset;
1787 struct cifs_tcon *tcon = io_parms->tcon;
1788 unsigned int count = io_parms->length;
1792 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1793 if (tcon->ses == NULL)
1794 return -ECONNABORTED;
1796 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1800 if ((offset >> 32) > 0) {
1801 /* can not handle big offset for old srv */
1806 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1811 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1812 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1814 /* tcon and ses pointer are checked in smb_init */
1815 if (tcon->ses->server == NULL)
1816 return -ECONNABORTED;
1818 pSMB->AndXCommand = 0xFF; /* none */
1820 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1822 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1824 pSMB->Reserved = 0xFFFFFFFF;
1825 pSMB->WriteMode = 0;
1826 pSMB->Remaining = 0;
1828 /* Can increase buffer size if buffer is big enough in some cases ie we
1829 can send more if LARGE_WRITE_X capability returned by the server and if
1830 our buffer is big enough or if we convert to iovecs on socket writes
1831 and eliminate the copy to the CIFS buffer */
1832 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1833 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1835 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1839 if (bytes_sent > count)
1842 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1844 memcpy(pSMB->Data, buf, bytes_sent);
1845 else if (count != 0) {
1847 cifs_buf_release(pSMB);
1849 } /* else setting file size with write of zero bytes */
1851 byte_count = bytes_sent + 1; /* pad */
1852 else /* wct == 12 */
1853 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1855 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1856 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1857 inc_rfc1001_len(pSMB, byte_count);
1860 pSMB->ByteCount = cpu_to_le16(byte_count);
1861 else { /* old style write has byte count 4 bytes earlier
1863 struct smb_com_writex_req *pSMBW =
1864 (struct smb_com_writex_req *)pSMB;
1865 pSMBW->ByteCount = cpu_to_le16(byte_count);
1868 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1869 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1870 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1872 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1874 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1875 *nbytes = (*nbytes) << 16;
1876 *nbytes += le16_to_cpu(pSMBr->Count);
1879 * Mask off high 16 bits when bytes written as returned by the
1880 * server is greater than bytes requested by the client. Some
1881 * OS/2 servers are known to set incorrect CountHigh values.
1883 if (*nbytes > count)
1887 cifs_buf_release(pSMB);
1889 /* Note: On -EAGAIN error only caller can retry on handle based calls
1890 since file handle passed in no longer valid */
1896 cifs_writedata_release(struct kref *refcount)
1898 struct cifs_writedata *wdata = container_of(refcount,
1899 struct cifs_writedata, refcount);
1900 #ifdef CONFIG_CIFS_SMB_DIRECT
1902 smbd_deregister_mr(wdata->mr);
1908 cifsFileInfo_put(wdata->cfile);
1910 kvfree(wdata->pages);
1915 * Write failed with a retryable error. Resend the write request. It's also
1916 * possible that the page was redirtied so re-clean the page.
1919 cifs_writev_requeue(struct cifs_writedata *wdata)
1922 struct inode *inode = d_inode(wdata->cfile->dentry);
1923 struct TCP_Server_Info *server;
1924 unsigned int rest_len;
1926 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1928 rest_len = wdata->bytes;
1930 struct cifs_writedata *wdata2;
1931 unsigned int j, nr_pages, wsize, tailsz, cur_len;
1933 wsize = server->ops->wp_retry_size(inode);
1934 if (wsize < rest_len) {
1935 nr_pages = wsize / PAGE_SIZE;
1940 cur_len = nr_pages * PAGE_SIZE;
1943 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
1945 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
1948 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
1954 for (j = 0; j < nr_pages; j++) {
1955 wdata2->pages[j] = wdata->pages[i + j];
1956 lock_page(wdata2->pages[j]);
1957 clear_page_dirty_for_io(wdata2->pages[j]);
1960 wdata2->sync_mode = wdata->sync_mode;
1961 wdata2->nr_pages = nr_pages;
1962 wdata2->offset = page_offset(wdata2->pages[0]);
1963 wdata2->pagesz = PAGE_SIZE;
1964 wdata2->tailsz = tailsz;
1965 wdata2->bytes = cur_len;
1967 rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
1969 if (!wdata2->cfile) {
1970 cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
1972 if (!is_retryable_error(rc))
1975 wdata2->pid = wdata2->cfile->pid;
1976 rc = server->ops->async_writev(wdata2,
1977 cifs_writedata_release);
1980 for (j = 0; j < nr_pages; j++) {
1981 unlock_page(wdata2->pages[j]);
1982 if (rc != 0 && !is_retryable_error(rc)) {
1983 SetPageError(wdata2->pages[j]);
1984 end_page_writeback(wdata2->pages[j]);
1985 put_page(wdata2->pages[j]);
1989 kref_put(&wdata2->refcount, cifs_writedata_release);
1991 if (is_retryable_error(rc))
1997 rest_len -= cur_len;
1999 } while (i < wdata->nr_pages);
2001 /* cleanup remaining pages from the original wdata */
2002 for (; i < wdata->nr_pages; i++) {
2003 SetPageError(wdata->pages[i]);
2004 end_page_writeback(wdata->pages[i]);
2005 put_page(wdata->pages[i]);
2008 if (rc != 0 && !is_retryable_error(rc))
2009 mapping_set_error(inode->i_mapping, rc);
2010 kref_put(&wdata->refcount, cifs_writedata_release);
2014 cifs_writev_complete(struct work_struct *work)
2016 struct cifs_writedata *wdata = container_of(work,
2017 struct cifs_writedata, work);
2018 struct inode *inode = d_inode(wdata->cfile->dentry);
2021 if (wdata->result == 0) {
2022 spin_lock(&inode->i_lock);
2023 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2024 spin_unlock(&inode->i_lock);
2025 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2027 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2028 return cifs_writev_requeue(wdata);
2030 for (i = 0; i < wdata->nr_pages; i++) {
2031 struct page *page = wdata->pages[i];
2032 if (wdata->result == -EAGAIN)
2033 __set_page_dirty_nobuffers(page);
2034 else if (wdata->result < 0)
2036 end_page_writeback(page);
2037 cifs_readpage_to_fscache(inode, page);
2040 if (wdata->result != -EAGAIN)
2041 mapping_set_error(inode->i_mapping, wdata->result);
2042 kref_put(&wdata->refcount, cifs_writedata_release);
2045 struct cifs_writedata *
2046 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2048 struct page **pages =
2049 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2051 return cifs_writedata_direct_alloc(pages, complete);
2056 struct cifs_writedata *
2057 cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2059 struct cifs_writedata *wdata;
2061 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2062 if (wdata != NULL) {
2063 wdata->pages = pages;
2064 kref_init(&wdata->refcount);
2065 INIT_LIST_HEAD(&wdata->list);
2066 init_completion(&wdata->done);
2067 INIT_WORK(&wdata->work, complete);
2073 * Check the mid_state and signature on received buffer (if any), and queue the
2074 * workqueue completion task.
2077 cifs_writev_callback(struct mid_q_entry *mid)
2079 struct cifs_writedata *wdata = mid->callback_data;
2080 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2081 unsigned int written;
2082 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2083 struct cifs_credits credits = { .value = 1, .instance = 0 };
2085 switch (mid->mid_state) {
2086 case MID_RESPONSE_RECEIVED:
2087 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2088 if (wdata->result != 0)
2091 written = le16_to_cpu(smb->CountHigh);
2093 written += le16_to_cpu(smb->Count);
2095 * Mask off high 16 bits when bytes written as returned
2096 * by the server is greater than bytes requested by the
2097 * client. OS/2 servers are known to set incorrect
2100 if (written > wdata->bytes)
2103 if (written < wdata->bytes)
2104 wdata->result = -ENOSPC;
2106 wdata->bytes = written;
2108 case MID_REQUEST_SUBMITTED:
2109 case MID_RETRY_NEEDED:
2110 wdata->result = -EAGAIN;
2113 wdata->result = -EIO;
2117 queue_work(cifsiod_wq, &wdata->work);
2118 DeleteMidQEntry(mid);
2119 add_credits(tcon->ses->server, &credits, 0);
2122 /* cifs_async_writev - send an async write, and set up mid to handle result */
2124 cifs_async_writev(struct cifs_writedata *wdata,
2125 void (*release)(struct kref *kref))
2128 WRITE_REQ *smb = NULL;
2130 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2132 struct smb_rqst rqst = { };
2134 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2138 if (wdata->offset >> 32 > 0) {
2139 /* can not handle big offset for old srv */
2144 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2146 goto async_writev_out;
2148 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2149 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2151 smb->AndXCommand = 0xFF; /* none */
2152 smb->Fid = wdata->cfile->fid.netfid;
2153 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2155 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2156 smb->Reserved = 0xFFFFFFFF;
2161 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2163 /* 4 for RFC1001 length + 1 for BCC */
2165 iov[0].iov_base = smb;
2166 iov[1].iov_len = get_rfc1002_length(smb) + 1;
2167 iov[1].iov_base = (char *)smb + 4;
2171 rqst.rq_pages = wdata->pages;
2172 rqst.rq_offset = wdata->page_offset;
2173 rqst.rq_npages = wdata->nr_pages;
2174 rqst.rq_pagesz = wdata->pagesz;
2175 rqst.rq_tailsz = wdata->tailsz;
2177 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2178 wdata->offset, wdata->bytes);
2180 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2181 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2184 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2185 put_bcc(wdata->bytes + 1, &smb->hdr);
2188 struct smb_com_writex_req *smbw =
2189 (struct smb_com_writex_req *)smb;
2190 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2191 put_bcc(wdata->bytes + 5, &smbw->hdr);
2192 iov[1].iov_len += 4; /* pad bigger by four bytes */
2195 kref_get(&wdata->refcount);
2196 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2197 cifs_writev_callback, NULL, wdata, 0, NULL);
2200 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2202 kref_put(&wdata->refcount, release);
2205 cifs_small_buf_release(smb);
2210 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2211 unsigned int *nbytes, struct kvec *iov, int n_vec)
2214 WRITE_REQ *pSMB = NULL;
2217 int resp_buf_type = 0;
2218 __u32 pid = io_parms->pid;
2219 __u16 netfid = io_parms->netfid;
2220 __u64 offset = io_parms->offset;
2221 struct cifs_tcon *tcon = io_parms->tcon;
2222 unsigned int count = io_parms->length;
2223 struct kvec rsp_iov;
2227 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2229 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2233 if ((offset >> 32) > 0) {
2234 /* can not handle big offset for old srv */
2238 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2242 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2243 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2245 /* tcon and ses pointer are checked in smb_init */
2246 if (tcon->ses->server == NULL)
2247 return -ECONNABORTED;
2249 pSMB->AndXCommand = 0xFF; /* none */
2251 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2253 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2254 pSMB->Reserved = 0xFFFFFFFF;
2255 pSMB->WriteMode = 0;
2256 pSMB->Remaining = 0;
2259 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2261 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2262 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2263 /* header + 1 byte pad */
2264 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2266 inc_rfc1001_len(pSMB, count + 1);
2267 else /* wct == 12 */
2268 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2270 pSMB->ByteCount = cpu_to_le16(count + 1);
2271 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2272 struct smb_com_writex_req *pSMBW =
2273 (struct smb_com_writex_req *)pSMB;
2274 pSMBW->ByteCount = cpu_to_le16(count + 5);
2276 iov[0].iov_base = pSMB;
2278 iov[0].iov_len = smb_hdr_len + 4;
2279 else /* wct == 12 pad bigger by four bytes */
2280 iov[0].iov_len = smb_hdr_len + 8;
2282 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2284 cifs_small_buf_release(pSMB);
2285 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2287 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2288 } else if (resp_buf_type == 0) {
2289 /* presumably this can not happen, but best to be safe */
2292 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2293 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2294 *nbytes = (*nbytes) << 16;
2295 *nbytes += le16_to_cpu(pSMBr->Count);
2298 * Mask off high 16 bits when bytes written as returned by the
2299 * server is greater than bytes requested by the client. OS/2
2300 * servers are known to set incorrect CountHigh values.
2302 if (*nbytes > count)
2306 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2308 /* Note: On -EAGAIN error only caller can retry on handle based calls
2309 since file handle passed in no longer valid */
2314 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2315 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2316 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2319 LOCK_REQ *pSMB = NULL;
2321 struct kvec rsp_iov;
2325 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2326 num_lock, num_unlock);
2328 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2333 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2334 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2335 pSMB->LockType = lock_type;
2336 pSMB->AndXCommand = 0xFF; /* none */
2337 pSMB->Fid = netfid; /* netfid stays le */
2339 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2340 inc_rfc1001_len(pSMB, count);
2341 pSMB->ByteCount = cpu_to_le16(count);
2343 iov[0].iov_base = (char *)pSMB;
2344 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2345 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2346 iov[1].iov_base = (char *)buf;
2347 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2349 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2350 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
2351 CIFS_NO_RSP_BUF, &rsp_iov);
2352 cifs_small_buf_release(pSMB);
2354 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2360 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2361 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2362 const __u64 offset, const __u32 numUnlock,
2363 const __u32 numLock, const __u8 lockType,
2364 const bool waitFlag, const __u8 oplock_level)
2367 LOCK_REQ *pSMB = NULL;
2368 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2373 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2374 (int)waitFlag, numLock);
2375 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2380 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2381 /* no response expected */
2382 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
2384 } else if (waitFlag) {
2385 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2386 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2391 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2392 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2393 pSMB->LockType = lockType;
2394 pSMB->OplockLevel = oplock_level;
2395 pSMB->AndXCommand = 0xFF; /* none */
2396 pSMB->Fid = smb_file_id; /* netfid stays le */
2398 if ((numLock != 0) || (numUnlock != 0)) {
2399 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2400 /* BB where to store pid high? */
2401 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2402 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2403 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2404 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2405 count = sizeof(LOCKING_ANDX_RANGE);
2410 inc_rfc1001_len(pSMB, count);
2411 pSMB->ByteCount = cpu_to_le16(count);
2414 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2415 (struct smb_hdr *) pSMB, &bytes_returned);
2417 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2418 cifs_small_buf_release(pSMB);
2419 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2421 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2423 /* Note: On -EAGAIN error only caller can retry on handle based calls
2424 since file handle passed in no longer valid */
2429 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2430 const __u16 smb_file_id, const __u32 netpid,
2431 const loff_t start_offset, const __u64 len,
2432 struct file_lock *pLockData, const __u16 lock_type,
2433 const bool waitFlag)
2435 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2436 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2437 struct cifs_posix_lock *parm_data;
2440 int bytes_returned = 0;
2441 int resp_buf_type = 0;
2442 __u16 params, param_offset, offset, byte_count, count;
2444 struct kvec rsp_iov;
2446 cifs_dbg(FYI, "Posix Lock\n");
2448 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2453 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2456 pSMB->MaxSetupCount = 0;
2459 pSMB->Reserved2 = 0;
2460 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2461 offset = param_offset + params;
2463 count = sizeof(struct cifs_posix_lock);
2464 pSMB->MaxParameterCount = cpu_to_le16(2);
2465 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2466 pSMB->SetupCount = 1;
2467 pSMB->Reserved3 = 0;
2469 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2471 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2472 byte_count = 3 /* pad */ + params + count;
2473 pSMB->DataCount = cpu_to_le16(count);
2474 pSMB->ParameterCount = cpu_to_le16(params);
2475 pSMB->TotalDataCount = pSMB->DataCount;
2476 pSMB->TotalParameterCount = pSMB->ParameterCount;
2477 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2478 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2479 parm_data = (struct cifs_posix_lock *)
2480 (((char *)pSMB) + offset + 4);
2482 parm_data->lock_type = cpu_to_le16(lock_type);
2484 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2485 parm_data->lock_flags = cpu_to_le16(1);
2486 pSMB->Timeout = cpu_to_le32(-1);
2490 parm_data->pid = cpu_to_le32(netpid);
2491 parm_data->start = cpu_to_le64(start_offset);
2492 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2494 pSMB->DataOffset = cpu_to_le16(offset);
2495 pSMB->Fid = smb_file_id;
2496 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2497 pSMB->Reserved4 = 0;
2498 inc_rfc1001_len(pSMB, byte_count);
2499 pSMB->ByteCount = cpu_to_le16(byte_count);
2501 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2502 (struct smb_hdr *) pSMBr, &bytes_returned);
2504 iov[0].iov_base = (char *)pSMB;
2505 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2506 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2507 &resp_buf_type, timeout, &rsp_iov);
2508 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2510 cifs_small_buf_release(pSMB);
2513 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2514 } else if (pLockData) {
2515 /* lock structure can be returned on get */
2518 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2520 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2521 rc = -EIO; /* bad smb */
2524 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2525 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2526 if (data_count < sizeof(struct cifs_posix_lock)) {
2530 parm_data = (struct cifs_posix_lock *)
2531 ((char *)&pSMBr->hdr.Protocol + data_offset);
2532 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2533 pLockData->fl_type = F_UNLCK;
2535 if (parm_data->lock_type ==
2536 cpu_to_le16(CIFS_RDLCK))
2537 pLockData->fl_type = F_RDLCK;
2538 else if (parm_data->lock_type ==
2539 cpu_to_le16(CIFS_WRLCK))
2540 pLockData->fl_type = F_WRLCK;
2542 pLockData->fl_start = le64_to_cpu(parm_data->start);
2543 pLockData->fl_end = pLockData->fl_start +
2544 le64_to_cpu(parm_data->length) - 1;
2545 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2550 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2552 /* Note: On -EAGAIN error only caller can retry on handle based calls
2553 since file handle passed in no longer valid */
2560 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2563 CLOSE_REQ *pSMB = NULL;
2564 cifs_dbg(FYI, "In CIFSSMBClose\n");
2566 /* do not retry on dead session on close */
2567 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2573 pSMB->FileID = (__u16) smb_file_id;
2574 pSMB->LastWriteTime = 0xFFFFFFFF;
2575 pSMB->ByteCount = 0;
2576 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2577 cifs_small_buf_release(pSMB);
2578 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2581 /* EINTR is expected when user ctl-c to kill app */
2582 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2586 /* Since session is dead, file will be closed on server already */
2594 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2597 FLUSH_REQ *pSMB = NULL;
2598 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2600 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2604 pSMB->FileID = (__u16) smb_file_id;
2605 pSMB->ByteCount = 0;
2606 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2607 cifs_small_buf_release(pSMB);
2608 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2610 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2616 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2617 const char *from_name, const char *to_name,
2618 struct cifs_sb_info *cifs_sb)
2621 RENAME_REQ *pSMB = NULL;
2622 RENAME_RSP *pSMBr = NULL;
2624 int name_len, name_len2;
2626 int remap = cifs_remap(cifs_sb);
2628 cifs_dbg(FYI, "In CIFSSMBRename\n");
2630 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2635 pSMB->BufferFormat = 0x04;
2636 pSMB->SearchAttributes =
2637 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2640 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2641 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2642 from_name, PATH_MAX,
2643 cifs_sb->local_nls, remap);
2644 name_len++; /* trailing null */
2646 pSMB->OldFileName[name_len] = 0x04; /* pad */
2647 /* protocol requires ASCII signature byte on Unicode string */
2648 pSMB->OldFileName[name_len + 1] = 0x00;
2650 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2651 to_name, PATH_MAX, cifs_sb->local_nls,
2653 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2654 name_len2 *= 2; /* convert to bytes */
2656 name_len = copy_path_name(pSMB->OldFileName, from_name);
2657 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2658 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2659 name_len2++; /* signature byte */
2662 count = 1 /* 1st signature byte */ + name_len + name_len2;
2663 inc_rfc1001_len(pSMB, count);
2664 pSMB->ByteCount = cpu_to_le16(count);
2666 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2667 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2668 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2670 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2672 cifs_buf_release(pSMB);
2680 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2681 int netfid, const char *target_name,
2682 const struct nls_table *nls_codepage, int remap)
2684 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2685 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2686 struct set_file_rename *rename_info;
2688 char dummy_string[30];
2690 int bytes_returned = 0;
2692 __u16 params, param_offset, offset, count, byte_count;
2694 cifs_dbg(FYI, "Rename to File by handle\n");
2695 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2701 pSMB->MaxSetupCount = 0;
2705 pSMB->Reserved2 = 0;
2706 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2707 offset = param_offset + params;
2709 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2710 data_offset = (char *)(pSMB) + offset + 4;
2711 rename_info = (struct set_file_rename *) data_offset;
2712 pSMB->MaxParameterCount = cpu_to_le16(2);
2713 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2714 pSMB->SetupCount = 1;
2715 pSMB->Reserved3 = 0;
2716 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2717 byte_count = 3 /* pad */ + params;
2718 pSMB->ParameterCount = cpu_to_le16(params);
2719 pSMB->TotalParameterCount = pSMB->ParameterCount;
2720 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2721 pSMB->DataOffset = cpu_to_le16(offset);
2722 /* construct random name ".cifs_tmp<inodenum><mid>" */
2723 rename_info->overwrite = cpu_to_le32(1);
2724 rename_info->root_fid = 0;
2725 /* unicode only call */
2726 if (target_name == NULL) {
2727 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2729 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2730 dummy_string, 24, nls_codepage, remap);
2733 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2734 target_name, PATH_MAX, nls_codepage,
2737 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2738 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2739 byte_count += count;
2740 pSMB->DataCount = cpu_to_le16(count);
2741 pSMB->TotalDataCount = pSMB->DataCount;
2743 pSMB->InformationLevel =
2744 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2745 pSMB->Reserved4 = 0;
2746 inc_rfc1001_len(pSMB, byte_count);
2747 pSMB->ByteCount = cpu_to_le16(byte_count);
2748 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2749 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2750 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2752 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2755 cifs_buf_release(pSMB);
2757 /* Note: On -EAGAIN error only caller can retry on handle based calls
2758 since file handle passed in no longer valid */
2764 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2765 const char *fromName, const __u16 target_tid, const char *toName,
2766 const int flags, const struct nls_table *nls_codepage, int remap)
2769 COPY_REQ *pSMB = NULL;
2770 COPY_RSP *pSMBr = NULL;
2772 int name_len, name_len2;
2775 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2777 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2782 pSMB->BufferFormat = 0x04;
2783 pSMB->Tid2 = target_tid;
2785 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2787 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2788 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2789 fromName, PATH_MAX, nls_codepage,
2791 name_len++; /* trailing null */
2793 pSMB->OldFileName[name_len] = 0x04; /* pad */
2794 /* protocol requires ASCII signature byte on Unicode string */
2795 pSMB->OldFileName[name_len + 1] = 0x00;
2797 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2798 toName, PATH_MAX, nls_codepage, remap);
2799 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2800 name_len2 *= 2; /* convert to bytes */
2802 name_len = copy_path_name(pSMB->OldFileName, fromName);
2803 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2804 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2805 name_len2++; /* signature byte */
2808 count = 1 /* 1st signature byte */ + name_len + name_len2;
2809 inc_rfc1001_len(pSMB, count);
2810 pSMB->ByteCount = cpu_to_le16(count);
2812 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2813 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2815 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2816 rc, le16_to_cpu(pSMBr->CopyCount));
2818 cifs_buf_release(pSMB);
2827 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2828 const char *fromName, const char *toName,
2829 const struct nls_table *nls_codepage, int remap)
2831 TRANSACTION2_SPI_REQ *pSMB = NULL;
2832 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2835 int name_len_target;
2837 int bytes_returned = 0;
2838 __u16 params, param_offset, offset, byte_count;
2840 cifs_dbg(FYI, "In Symlink Unix style\n");
2842 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2847 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2849 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2850 /* find define for this maxpathcomponent */
2851 PATH_MAX, nls_codepage, remap);
2852 name_len++; /* trailing null */
2856 name_len = copy_path_name(pSMB->FileName, fromName);
2858 params = 6 + name_len;
2859 pSMB->MaxSetupCount = 0;
2863 pSMB->Reserved2 = 0;
2864 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2865 InformationLevel) - 4;
2866 offset = param_offset + params;
2868 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2869 data_offset = (char *)pSMB + offset + 4;
2870 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2872 cifsConvertToUTF16((__le16 *) data_offset, toName,
2873 /* find define for this maxpathcomponent */
2874 PATH_MAX, nls_codepage, remap);
2875 name_len_target++; /* trailing null */
2876 name_len_target *= 2;
2878 name_len_target = copy_path_name(data_offset, toName);
2881 pSMB->MaxParameterCount = cpu_to_le16(2);
2882 /* BB find exact max on data count below from sess */
2883 pSMB->MaxDataCount = cpu_to_le16(1000);
2884 pSMB->SetupCount = 1;
2885 pSMB->Reserved3 = 0;
2886 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2887 byte_count = 3 /* pad */ + params + name_len_target;
2888 pSMB->DataCount = cpu_to_le16(name_len_target);
2889 pSMB->ParameterCount = cpu_to_le16(params);
2890 pSMB->TotalDataCount = pSMB->DataCount;
2891 pSMB->TotalParameterCount = pSMB->ParameterCount;
2892 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2893 pSMB->DataOffset = cpu_to_le16(offset);
2894 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2895 pSMB->Reserved4 = 0;
2896 inc_rfc1001_len(pSMB, byte_count);
2897 pSMB->ByteCount = cpu_to_le16(byte_count);
2898 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2899 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2900 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2902 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2905 cifs_buf_release(pSMB);
2908 goto createSymLinkRetry;
2914 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2915 const char *fromName, const char *toName,
2916 const struct nls_table *nls_codepage, int remap)
2918 TRANSACTION2_SPI_REQ *pSMB = NULL;
2919 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2922 int name_len_target;
2924 int bytes_returned = 0;
2925 __u16 params, param_offset, offset, byte_count;
2927 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2928 createHardLinkRetry:
2929 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2934 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2935 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2936 PATH_MAX, nls_codepage, remap);
2937 name_len++; /* trailing null */
2941 name_len = copy_path_name(pSMB->FileName, toName);
2943 params = 6 + name_len;
2944 pSMB->MaxSetupCount = 0;
2948 pSMB->Reserved2 = 0;
2949 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2950 InformationLevel) - 4;
2951 offset = param_offset + params;
2953 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2954 data_offset = (char *)pSMB + offset + 4;
2955 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2957 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2958 PATH_MAX, nls_codepage, remap);
2959 name_len_target++; /* trailing null */
2960 name_len_target *= 2;
2962 name_len_target = copy_path_name(data_offset, fromName);
2965 pSMB->MaxParameterCount = cpu_to_le16(2);
2966 /* BB find exact max on data count below from sess*/
2967 pSMB->MaxDataCount = cpu_to_le16(1000);
2968 pSMB->SetupCount = 1;
2969 pSMB->Reserved3 = 0;
2970 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2971 byte_count = 3 /* pad */ + params + name_len_target;
2972 pSMB->ParameterCount = cpu_to_le16(params);
2973 pSMB->TotalParameterCount = pSMB->ParameterCount;
2974 pSMB->DataCount = cpu_to_le16(name_len_target);
2975 pSMB->TotalDataCount = pSMB->DataCount;
2976 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2977 pSMB->DataOffset = cpu_to_le16(offset);
2978 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2979 pSMB->Reserved4 = 0;
2980 inc_rfc1001_len(pSMB, byte_count);
2981 pSMB->ByteCount = cpu_to_le16(byte_count);
2982 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2983 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2984 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2986 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2989 cifs_buf_release(pSMB);
2991 goto createHardLinkRetry;
2997 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2998 const char *from_name, const char *to_name,
2999 struct cifs_sb_info *cifs_sb)
3002 NT_RENAME_REQ *pSMB = NULL;
3003 RENAME_RSP *pSMBr = NULL;
3005 int name_len, name_len2;
3007 int remap = cifs_remap(cifs_sb);
3009 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3010 winCreateHardLinkRetry:
3012 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3017 pSMB->SearchAttributes =
3018 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3020 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3021 pSMB->ClusterCount = 0;
3023 pSMB->BufferFormat = 0x04;
3025 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3027 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3028 PATH_MAX, cifs_sb->local_nls, remap);
3029 name_len++; /* trailing null */
3032 /* protocol specifies ASCII buffer format (0x04) for unicode */
3033 pSMB->OldFileName[name_len] = 0x04;
3034 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3036 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3037 to_name, PATH_MAX, cifs_sb->local_nls,
3039 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3040 name_len2 *= 2; /* convert to bytes */
3042 name_len = copy_path_name(pSMB->OldFileName, from_name);
3043 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3044 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
3045 name_len2++; /* signature byte */
3048 count = 1 /* string type byte */ + name_len + name_len2;
3049 inc_rfc1001_len(pSMB, count);
3050 pSMB->ByteCount = cpu_to_le16(count);
3052 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3053 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3054 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3056 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3058 cifs_buf_release(pSMB);
3060 goto winCreateHardLinkRetry;
3066 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3067 const unsigned char *searchName, char **symlinkinfo,
3068 const struct nls_table *nls_codepage, int remap)
3070 /* SMB_QUERY_FILE_UNIX_LINK */
3071 TRANSACTION2_QPI_REQ *pSMB = NULL;
3072 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3076 __u16 params, byte_count;
3079 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3082 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3087 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3089 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3090 searchName, PATH_MAX, nls_codepage,
3092 name_len++; /* trailing null */
3095 name_len = copy_path_name(pSMB->FileName, searchName);
3098 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3099 pSMB->TotalDataCount = 0;
3100 pSMB->MaxParameterCount = cpu_to_le16(2);
3101 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3102 pSMB->MaxSetupCount = 0;
3106 pSMB->Reserved2 = 0;
3107 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3108 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3109 pSMB->DataCount = 0;
3110 pSMB->DataOffset = 0;
3111 pSMB->SetupCount = 1;
3112 pSMB->Reserved3 = 0;
3113 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3114 byte_count = params + 1 /* pad */ ;
3115 pSMB->TotalParameterCount = cpu_to_le16(params);
3116 pSMB->ParameterCount = pSMB->TotalParameterCount;
3117 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3118 pSMB->Reserved4 = 0;
3119 inc_rfc1001_len(pSMB, byte_count);
3120 pSMB->ByteCount = cpu_to_le16(byte_count);
3122 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3123 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3125 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3127 /* decode response */
3129 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3130 /* BB also check enough total bytes returned */
3131 if (rc || get_bcc(&pSMBr->hdr) < 2)
3135 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3137 data_start = ((char *) &pSMBr->hdr.Protocol) +
3138 le16_to_cpu(pSMBr->t2.DataOffset);
3140 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3145 /* BB FIXME investigate remapping reserved chars here */
3146 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3147 count, is_unicode, nls_codepage);
3152 cifs_buf_release(pSMB);
3154 goto querySymLinkRetry;
3159 * Recent Windows versions now create symlinks more frequently
3160 * and they use the "reparse point" mechanism below. We can of course
3161 * do symlinks nicely to Samba and other servers which support the
3162 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3163 * "MF" symlinks optionally, but for recent Windows we really need to
3164 * reenable the code below and fix the cifs_symlink callers to handle this.
3165 * In the interim this code has been moved to its own config option so
3166 * it is not compiled in by default until callers fixed up and more tested.
3169 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3170 __u16 fid, char **symlinkinfo,
3171 const struct nls_table *nls_codepage)
3175 struct smb_com_transaction_ioctl_req *pSMB;
3176 struct smb_com_transaction_ioctl_rsp *pSMBr;
3178 unsigned int sub_len;
3180 struct reparse_symlink_data *reparse_buf;
3181 struct reparse_posix_data *posix_buf;
3182 __u32 data_offset, data_count;
3185 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3186 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3191 pSMB->TotalParameterCount = 0 ;
3192 pSMB->TotalDataCount = 0;
3193 pSMB->MaxParameterCount = cpu_to_le32(2);
3194 /* BB find exact data count max from sess structure BB */
3195 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3196 pSMB->MaxSetupCount = 4;
3198 pSMB->ParameterOffset = 0;
3199 pSMB->DataCount = 0;
3200 pSMB->DataOffset = 0;
3201 pSMB->SetupCount = 4;
3202 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3203 pSMB->ParameterCount = pSMB->TotalParameterCount;
3204 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3205 pSMB->IsFsctl = 1; /* FSCTL */
3206 pSMB->IsRootFlag = 0;
3207 pSMB->Fid = fid; /* file handle always le */
3208 pSMB->ByteCount = 0;
3210 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3211 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3213 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3217 data_offset = le32_to_cpu(pSMBr->DataOffset);
3218 data_count = le32_to_cpu(pSMBr->DataCount);
3219 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3220 /* BB also check enough total bytes returned */
3221 rc = -EIO; /* bad smb */
3224 if (!data_count || (data_count > 2048)) {
3226 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3229 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3230 reparse_buf = (struct reparse_symlink_data *)
3231 ((char *)&pSMBr->hdr.Protocol + data_offset);
3232 if ((char *)reparse_buf >= end_of_smb) {
3236 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3237 cifs_dbg(FYI, "NFS style reparse tag\n");
3238 posix_buf = (struct reparse_posix_data *)reparse_buf;
3240 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3241 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3242 le64_to_cpu(posix_buf->InodeType));
3247 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3248 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3249 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3253 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3254 sub_len, is_unicode, nls_codepage);
3256 } else if (reparse_buf->ReparseTag !=
3257 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3262 /* Reparse tag is NTFS symlink */
3263 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3264 reparse_buf->PathBuffer;
3265 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3266 if (sub_start + sub_len > end_of_smb) {
3267 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3271 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3276 /* BB FIXME investigate remapping reserved chars here */
3277 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3282 cifs_buf_release(pSMB);
3285 * Note: On -EAGAIN error only caller can retry on handle based calls
3286 * since file handle passed in no longer valid.
3292 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3297 struct smb_com_transaction_compr_ioctl_req *pSMB;
3298 struct smb_com_transaction_ioctl_rsp *pSMBr;
3300 cifs_dbg(FYI, "Set compression for %u\n", fid);
3301 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3306 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3308 pSMB->TotalParameterCount = 0;
3309 pSMB->TotalDataCount = cpu_to_le32(2);
3310 pSMB->MaxParameterCount = 0;
3311 pSMB->MaxDataCount = 0;
3312 pSMB->MaxSetupCount = 4;
3314 pSMB->ParameterOffset = 0;
3315 pSMB->DataCount = cpu_to_le32(2);
3317 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3318 compression_state) - 4); /* 84 */
3319 pSMB->SetupCount = 4;
3320 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3321 pSMB->ParameterCount = 0;
3322 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3323 pSMB->IsFsctl = 1; /* FSCTL */
3324 pSMB->IsRootFlag = 0;
3325 pSMB->Fid = fid; /* file handle always le */
3326 /* 3 byte pad, followed by 2 byte compress state */
3327 pSMB->ByteCount = cpu_to_le16(5);
3328 inc_rfc1001_len(pSMB, 5);
3330 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3331 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3333 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3335 cifs_buf_release(pSMB);
3338 * Note: On -EAGAIN error only caller can retry on handle based calls
3339 * since file handle passed in no longer valid.
3345 #ifdef CONFIG_CIFS_POSIX
3347 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3348 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3349 struct cifs_posix_ace *cifs_ace)
3351 /* u8 cifs fields do not need le conversion */
3352 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3353 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3354 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3356 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3357 ace->e_perm, ace->e_tag, ace->e_id);
3363 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3364 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3365 const int acl_type, const int size_of_data_area)
3370 struct cifs_posix_ace *pACE;
3371 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3372 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3374 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3377 if (acl_type == ACL_TYPE_ACCESS) {
3378 count = le16_to_cpu(cifs_acl->access_entry_count);
3379 pACE = &cifs_acl->ace_array[0];
3380 size = sizeof(struct cifs_posix_acl);
3381 size += sizeof(struct cifs_posix_ace) * count;
3382 /* check if we would go beyond end of SMB */
3383 if (size_of_data_area < size) {
3384 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3385 size_of_data_area, size);
3388 } else if (acl_type == ACL_TYPE_DEFAULT) {
3389 count = le16_to_cpu(cifs_acl->access_entry_count);
3390 size = sizeof(struct cifs_posix_acl);
3391 size += sizeof(struct cifs_posix_ace) * count;
3392 /* skip past access ACEs to get to default ACEs */
3393 pACE = &cifs_acl->ace_array[count];
3394 count = le16_to_cpu(cifs_acl->default_entry_count);
3395 size += sizeof(struct cifs_posix_ace) * count;
3396 /* check if we would go beyond end of SMB */
3397 if (size_of_data_area < size)
3404 size = posix_acl_xattr_size(count);
3405 if ((buflen == 0) || (local_acl == NULL)) {
3406 /* used to query ACL EA size */
3407 } else if (size > buflen) {
3409 } else /* buffer big enough */ {
3410 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3412 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3413 for (i = 0; i < count ; i++) {
3414 cifs_convert_ace(&ace[i], pACE);
3421 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3422 const struct posix_acl_xattr_entry *local_ace)
3424 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3425 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3426 /* BB is there a better way to handle the large uid? */
3427 if (local_ace->e_id == cpu_to_le32(-1)) {
3428 /* Probably no need to le convert -1 on any arch but can not hurt */
3429 cifs_ace->cifs_uid = cpu_to_le64(-1);
3431 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3433 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3434 ace->e_perm, ace->e_tag, ace->e_id);
3438 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3439 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3440 const int buflen, const int acl_type)
3443 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3444 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3445 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3449 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3452 count = posix_acl_xattr_count((size_t)buflen);
3453 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3454 count, buflen, le32_to_cpu(local_acl->a_version));
3455 if (le32_to_cpu(local_acl->a_version) != 2) {
3456 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3457 le32_to_cpu(local_acl->a_version));
3460 cifs_acl->version = cpu_to_le16(1);
3461 if (acl_type == ACL_TYPE_ACCESS) {
3462 cifs_acl->access_entry_count = cpu_to_le16(count);
3463 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3464 } else if (acl_type == ACL_TYPE_DEFAULT) {
3465 cifs_acl->default_entry_count = cpu_to_le16(count);
3466 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3468 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3471 for (i = 0; i < count; i++)
3472 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3474 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3475 rc += sizeof(struct cifs_posix_acl);
3476 /* BB add check to make sure ACL does not overflow SMB */
3482 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3483 const unsigned char *searchName,
3484 char *acl_inf, const int buflen, const int acl_type,
3485 const struct nls_table *nls_codepage, int remap)
3487 /* SMB_QUERY_POSIX_ACL */
3488 TRANSACTION2_QPI_REQ *pSMB = NULL;
3489 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3493 __u16 params, byte_count;
3495 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3498 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3503 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3505 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3506 searchName, PATH_MAX, nls_codepage,
3508 name_len++; /* trailing null */
3510 pSMB->FileName[name_len] = 0;
3511 pSMB->FileName[name_len+1] = 0;
3513 name_len = copy_path_name(pSMB->FileName, searchName);
3516 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3517 pSMB->TotalDataCount = 0;
3518 pSMB->MaxParameterCount = cpu_to_le16(2);
3519 /* BB find exact max data count below from sess structure BB */
3520 pSMB->MaxDataCount = cpu_to_le16(4000);
3521 pSMB->MaxSetupCount = 0;
3525 pSMB->Reserved2 = 0;
3526 pSMB->ParameterOffset = cpu_to_le16(
3527 offsetof(struct smb_com_transaction2_qpi_req,
3528 InformationLevel) - 4);
3529 pSMB->DataCount = 0;
3530 pSMB->DataOffset = 0;
3531 pSMB->SetupCount = 1;
3532 pSMB->Reserved3 = 0;
3533 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3534 byte_count = params + 1 /* pad */ ;
3535 pSMB->TotalParameterCount = cpu_to_le16(params);
3536 pSMB->ParameterCount = pSMB->TotalParameterCount;
3537 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3538 pSMB->Reserved4 = 0;
3539 inc_rfc1001_len(pSMB, byte_count);
3540 pSMB->ByteCount = cpu_to_le16(byte_count);
3542 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3543 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3544 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3546 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3548 /* decode response */
3550 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3551 /* BB also check enough total bytes returned */
3552 if (rc || get_bcc(&pSMBr->hdr) < 2)
3553 rc = -EIO; /* bad smb */
3555 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3556 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3557 rc = cifs_copy_posix_acl(acl_inf,
3558 (char *)&pSMBr->hdr.Protocol+data_offset,
3559 buflen, acl_type, count);
3562 cifs_buf_release(pSMB);
3569 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3570 const unsigned char *fileName,
3571 const char *local_acl, const int buflen,
3573 const struct nls_table *nls_codepage, int remap)
3575 struct smb_com_transaction2_spi_req *pSMB = NULL;
3576 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3580 int bytes_returned = 0;
3581 __u16 params, byte_count, data_count, param_offset, offset;
3583 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3585 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3589 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3591 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3592 PATH_MAX, nls_codepage, remap);
3593 name_len++; /* trailing null */
3596 name_len = copy_path_name(pSMB->FileName, fileName);
3598 params = 6 + name_len;
3599 pSMB->MaxParameterCount = cpu_to_le16(2);
3600 /* BB find max SMB size from sess */
3601 pSMB->MaxDataCount = cpu_to_le16(1000);
3602 pSMB->MaxSetupCount = 0;
3606 pSMB->Reserved2 = 0;
3607 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3608 InformationLevel) - 4;
3609 offset = param_offset + params;
3610 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3611 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3613 /* convert to on the wire format for POSIX ACL */
3614 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3616 if (data_count == 0) {
3618 goto setACLerrorExit;
3620 pSMB->DataOffset = cpu_to_le16(offset);
3621 pSMB->SetupCount = 1;
3622 pSMB->Reserved3 = 0;
3623 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3624 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3625 byte_count = 3 /* pad */ + params + data_count;
3626 pSMB->DataCount = cpu_to_le16(data_count);
3627 pSMB->TotalDataCount = pSMB->DataCount;
3628 pSMB->ParameterCount = cpu_to_le16(params);
3629 pSMB->TotalParameterCount = pSMB->ParameterCount;
3630 pSMB->Reserved4 = 0;
3631 inc_rfc1001_len(pSMB, byte_count);
3632 pSMB->ByteCount = cpu_to_le16(byte_count);
3633 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3634 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3636 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3639 cifs_buf_release(pSMB);
3645 /* BB fix tabs in this function FIXME BB */
3647 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3648 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3651 struct smb_t2_qfi_req *pSMB = NULL;
3652 struct smb_t2_qfi_rsp *pSMBr = NULL;
3654 __u16 params, byte_count;
3656 cifs_dbg(FYI, "In GetExtAttr\n");
3661 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3666 params = 2 /* level */ + 2 /* fid */;
3667 pSMB->t2.TotalDataCount = 0;
3668 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3669 /* BB find exact max data count below from sess structure BB */
3670 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3671 pSMB->t2.MaxSetupCount = 0;
3672 pSMB->t2.Reserved = 0;
3674 pSMB->t2.Timeout = 0;
3675 pSMB->t2.Reserved2 = 0;
3676 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3678 pSMB->t2.DataCount = 0;
3679 pSMB->t2.DataOffset = 0;
3680 pSMB->t2.SetupCount = 1;
3681 pSMB->t2.Reserved3 = 0;
3682 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3683 byte_count = params + 1 /* pad */ ;
3684 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3685 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3686 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3689 inc_rfc1001_len(pSMB, byte_count);
3690 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3692 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3693 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3695 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3697 /* decode response */
3698 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3699 /* BB also check enough total bytes returned */
3700 if (rc || get_bcc(&pSMBr->hdr) < 2)
3701 /* If rc should we check for EOPNOSUPP and
3702 disable the srvino flag? or in caller? */
3703 rc = -EIO; /* bad smb */
3705 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3706 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3707 struct file_chattr_info *pfinfo;
3708 /* BB Do we need a cast or hash here ? */
3710 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3714 pfinfo = (struct file_chattr_info *)
3715 (data_offset + (char *) &pSMBr->hdr.Protocol);
3716 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3717 *pMask = le64_to_cpu(pfinfo->mask);
3721 cifs_buf_release(pSMB);
3723 goto GetExtAttrRetry;
3727 #endif /* CONFIG_POSIX */
3730 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3731 * all NT TRANSACTS that we init here have total parm and data under about 400
3732 * bytes (to fit in small cifs buffer size), which is the case so far, it
3733 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3734 * returned setup area) and MaxParameterCount (returned parms size) must be set
3738 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3739 const int parm_len, struct cifs_tcon *tcon,
3744 struct smb_com_ntransact_req *pSMB;
3746 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3750 *ret_buf = (void *)pSMB;
3752 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3753 pSMB->TotalDataCount = 0;
3754 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3755 pSMB->ParameterCount = pSMB->TotalParameterCount;
3756 pSMB->DataCount = pSMB->TotalDataCount;
3757 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3758 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3759 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3760 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3761 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3762 pSMB->SubCommand = cpu_to_le16(sub_command);
3767 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3768 __u32 *pparmlen, __u32 *pdatalen)
3771 __u32 data_count, data_offset, parm_count, parm_offset;
3772 struct smb_com_ntransact_rsp *pSMBr;
3781 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3783 bcc = get_bcc(&pSMBr->hdr);
3784 end_of_smb = 2 /* sizeof byte count */ + bcc +
3785 (char *)&pSMBr->ByteCount;
3787 data_offset = le32_to_cpu(pSMBr->DataOffset);
3788 data_count = le32_to_cpu(pSMBr->DataCount);
3789 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3790 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3792 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3793 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3795 /* should we also check that parm and data areas do not overlap? */
3796 if (*ppparm > end_of_smb) {
3797 cifs_dbg(FYI, "parms start after end of smb\n");
3799 } else if (parm_count + *ppparm > end_of_smb) {
3800 cifs_dbg(FYI, "parm end after end of smb\n");
3802 } else if (*ppdata > end_of_smb) {
3803 cifs_dbg(FYI, "data starts after end of smb\n");
3805 } else if (data_count + *ppdata > end_of_smb) {
3806 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3807 *ppdata, data_count, (data_count + *ppdata),
3810 } else if (parm_count + data_count > bcc) {
3811 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3814 *pdatalen = data_count;
3815 *pparmlen = parm_count;
3819 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3821 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3822 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3826 QUERY_SEC_DESC_REQ *pSMB;
3828 struct kvec rsp_iov;
3830 cifs_dbg(FYI, "GetCifsACL\n");
3835 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3836 8 /* parm len */, tcon, (void **) &pSMB);
3840 pSMB->MaxParameterCount = cpu_to_le32(4);
3841 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3842 pSMB->MaxSetupCount = 0;
3843 pSMB->Fid = fid; /* file handle always le */
3844 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3846 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3847 inc_rfc1001_len(pSMB, 11);
3848 iov[0].iov_base = (char *)pSMB;
3849 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3851 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3853 cifs_small_buf_release(pSMB);
3854 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3856 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3857 } else { /* decode response */
3861 struct smb_com_ntransact_rsp *pSMBr;
3864 /* validate_nttransact */
3865 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3866 &pdata, &parm_len, pbuflen);
3869 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3871 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3872 pSMBr, parm, *acl_inf);
3874 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3875 rc = -EIO; /* bad smb */
3880 /* BB check that data area is minimum length and as big as acl_len */
3882 acl_len = le32_to_cpu(*parm);
3883 if (acl_len != *pbuflen) {
3884 cifs_dbg(VFS, "acl length %d does not match %d\n",
3886 if (*pbuflen > acl_len)
3890 /* check if buffer is big enough for the acl
3891 header followed by the smallest SID */
3892 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3893 (*pbuflen >= 64 * 1024)) {
3894 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3898 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3899 if (*acl_inf == NULL) {
3906 free_rsp_buf(buf_type, rsp_iov.iov_base);
3911 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3912 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3914 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3916 int bytes_returned = 0;
3917 SET_SEC_DESC_REQ *pSMB = NULL;
3921 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3925 pSMB->MaxSetupCount = 0;
3929 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3930 data_count = acllen;
3931 data_offset = param_offset + param_count;
3932 byte_count = 3 /* pad */ + param_count;
3934 pSMB->DataCount = cpu_to_le32(data_count);
3935 pSMB->TotalDataCount = pSMB->DataCount;
3936 pSMB->MaxParameterCount = cpu_to_le32(4);
3937 pSMB->MaxDataCount = cpu_to_le32(16384);
3938 pSMB->ParameterCount = cpu_to_le32(param_count);
3939 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3940 pSMB->TotalParameterCount = pSMB->ParameterCount;
3941 pSMB->DataOffset = cpu_to_le32(data_offset);
3942 pSMB->SetupCount = 0;
3943 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3944 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3946 pSMB->Fid = fid; /* file handle always le */
3947 pSMB->Reserved2 = 0;
3948 pSMB->AclFlags = cpu_to_le32(aclflag);
3950 if (pntsd && acllen) {
3951 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3952 data_offset, pntsd, acllen);
3953 inc_rfc1001_len(pSMB, byte_count + data_count);
3955 inc_rfc1001_len(pSMB, byte_count);
3957 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3958 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3960 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3961 bytes_returned, rc);
3963 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3964 cifs_buf_release(pSMB);
3967 goto setCifsAclRetry;
3973 /* Legacy Query Path Information call for lookup to old servers such
3976 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3977 const char *search_name, FILE_ALL_INFO *data,
3978 const struct nls_table *nls_codepage, int remap)
3980 QUERY_INFORMATION_REQ *pSMB;
3981 QUERY_INFORMATION_RSP *pSMBr;
3986 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3988 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3993 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3995 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3996 search_name, PATH_MAX, nls_codepage,
3998 name_len++; /* trailing null */
4001 name_len = copy_path_name(pSMB->FileName, search_name);
4003 pSMB->BufferFormat = 0x04;
4004 name_len++; /* account for buffer type byte */
4005 inc_rfc1001_len(pSMB, (__u16)name_len);
4006 pSMB->ByteCount = cpu_to_le16(name_len);
4008 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4009 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4011 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4013 struct timespec64 ts;
4014 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4016 /* decode response */
4017 /* BB FIXME - add time zone adjustment BB */
4018 memset(data, 0, sizeof(FILE_ALL_INFO));
4021 /* decode time fields */
4022 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4023 data->LastWriteTime = data->ChangeTime;
4024 data->LastAccessTime = 0;
4025 data->AllocationSize =
4026 cpu_to_le64(le32_to_cpu(pSMBr->size));
4027 data->EndOfFile = data->AllocationSize;
4029 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4031 rc = -EIO; /* bad buffer passed in */
4033 cifs_buf_release(pSMB);
4042 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4043 u16 netfid, FILE_ALL_INFO *pFindData)
4045 struct smb_t2_qfi_req *pSMB = NULL;
4046 struct smb_t2_qfi_rsp *pSMBr = NULL;
4049 __u16 params, byte_count;
4052 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4057 params = 2 /* level */ + 2 /* fid */;
4058 pSMB->t2.TotalDataCount = 0;
4059 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4060 /* BB find exact max data count below from sess structure BB */
4061 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4062 pSMB->t2.MaxSetupCount = 0;
4063 pSMB->t2.Reserved = 0;
4065 pSMB->t2.Timeout = 0;
4066 pSMB->t2.Reserved2 = 0;
4067 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4069 pSMB->t2.DataCount = 0;
4070 pSMB->t2.DataOffset = 0;
4071 pSMB->t2.SetupCount = 1;
4072 pSMB->t2.Reserved3 = 0;
4073 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4074 byte_count = params + 1 /* pad */ ;
4075 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4076 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4077 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4080 inc_rfc1001_len(pSMB, byte_count);
4081 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4083 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4084 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4086 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
4087 } else { /* decode response */
4088 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4090 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4092 else if (get_bcc(&pSMBr->hdr) < 40)
4093 rc = -EIO; /* bad smb */
4094 else if (pFindData) {
4095 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4096 memcpy((char *) pFindData,
4097 (char *) &pSMBr->hdr.Protocol +
4098 data_offset, sizeof(FILE_ALL_INFO));
4102 cifs_buf_release(pSMB);
4104 goto QFileInfoRetry;
4110 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4111 const char *search_name, FILE_ALL_INFO *data,
4112 int legacy /* old style infolevel */,
4113 const struct nls_table *nls_codepage, int remap)
4115 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4116 TRANSACTION2_QPI_REQ *pSMB = NULL;
4117 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4121 __u16 params, byte_count;
4123 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4125 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4130 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4132 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4133 PATH_MAX, nls_codepage, remap);
4134 name_len++; /* trailing null */
4137 name_len = copy_path_name(pSMB->FileName, search_name);
4140 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4141 pSMB->TotalDataCount = 0;
4142 pSMB->MaxParameterCount = cpu_to_le16(2);
4143 /* BB find exact max SMB PDU from sess structure BB */
4144 pSMB->MaxDataCount = cpu_to_le16(4000);
4145 pSMB->MaxSetupCount = 0;
4149 pSMB->Reserved2 = 0;
4150 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4151 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4152 pSMB->DataCount = 0;
4153 pSMB->DataOffset = 0;
4154 pSMB->SetupCount = 1;
4155 pSMB->Reserved3 = 0;
4156 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4157 byte_count = params + 1 /* pad */ ;
4158 pSMB->TotalParameterCount = cpu_to_le16(params);
4159 pSMB->ParameterCount = pSMB->TotalParameterCount;
4161 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4163 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4164 pSMB->Reserved4 = 0;
4165 inc_rfc1001_len(pSMB, byte_count);
4166 pSMB->ByteCount = cpu_to_le16(byte_count);
4168 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4169 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4171 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4172 } else { /* decode response */
4173 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4175 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4177 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4178 rc = -EIO; /* bad smb */
4179 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4180 rc = -EIO; /* 24 or 26 expected but we do not read
4184 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4187 * On legacy responses we do not read the last field,
4188 * EAsize, fortunately since it varies by subdialect and
4189 * also note it differs on Set vs Get, ie two bytes or 4
4190 * bytes depending but we don't care here.
4193 size = sizeof(FILE_INFO_STANDARD);
4195 size = sizeof(FILE_ALL_INFO);
4196 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4201 cifs_buf_release(pSMB);
4203 goto QPathInfoRetry;
4209 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4210 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4212 struct smb_t2_qfi_req *pSMB = NULL;
4213 struct smb_t2_qfi_rsp *pSMBr = NULL;
4216 __u16 params, byte_count;
4219 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4224 params = 2 /* level */ + 2 /* fid */;
4225 pSMB->t2.TotalDataCount = 0;
4226 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4227 /* BB find exact max data count below from sess structure BB */
4228 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4229 pSMB->t2.MaxSetupCount = 0;
4230 pSMB->t2.Reserved = 0;
4232 pSMB->t2.Timeout = 0;
4233 pSMB->t2.Reserved2 = 0;
4234 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4236 pSMB->t2.DataCount = 0;
4237 pSMB->t2.DataOffset = 0;
4238 pSMB->t2.SetupCount = 1;
4239 pSMB->t2.Reserved3 = 0;
4240 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4241 byte_count = params + 1 /* pad */ ;
4242 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4243 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4244 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4247 inc_rfc1001_len(pSMB, byte_count);
4248 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4250 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4251 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4253 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
4254 } else { /* decode response */
4255 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4257 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4258 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4259 rc = -EIO; /* bad smb */
4261 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4262 memcpy((char *) pFindData,
4263 (char *) &pSMBr->hdr.Protocol +
4265 sizeof(FILE_UNIX_BASIC_INFO));
4269 cifs_buf_release(pSMB);
4271 goto UnixQFileInfoRetry;
4277 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4278 const unsigned char *searchName,
4279 FILE_UNIX_BASIC_INFO *pFindData,
4280 const struct nls_table *nls_codepage, int remap)
4282 /* SMB_QUERY_FILE_UNIX_BASIC */
4283 TRANSACTION2_QPI_REQ *pSMB = NULL;
4284 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4286 int bytes_returned = 0;
4288 __u16 params, byte_count;
4290 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4292 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4297 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4299 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4300 PATH_MAX, nls_codepage, remap);
4301 name_len++; /* trailing null */
4304 name_len = copy_path_name(pSMB->FileName, searchName);
4307 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4308 pSMB->TotalDataCount = 0;
4309 pSMB->MaxParameterCount = cpu_to_le16(2);
4310 /* BB find exact max SMB PDU from sess structure BB */
4311 pSMB->MaxDataCount = cpu_to_le16(4000);
4312 pSMB->MaxSetupCount = 0;
4316 pSMB->Reserved2 = 0;
4317 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4318 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4319 pSMB->DataCount = 0;
4320 pSMB->DataOffset = 0;
4321 pSMB->SetupCount = 1;
4322 pSMB->Reserved3 = 0;
4323 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4324 byte_count = params + 1 /* pad */ ;
4325 pSMB->TotalParameterCount = cpu_to_le16(params);
4326 pSMB->ParameterCount = pSMB->TotalParameterCount;
4327 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4328 pSMB->Reserved4 = 0;
4329 inc_rfc1001_len(pSMB, byte_count);
4330 pSMB->ByteCount = cpu_to_le16(byte_count);
4332 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4333 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4335 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
4336 } else { /* decode response */
4337 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4339 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4340 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4341 rc = -EIO; /* bad smb */
4343 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4344 memcpy((char *) pFindData,
4345 (char *) &pSMBr->hdr.Protocol +
4347 sizeof(FILE_UNIX_BASIC_INFO));
4350 cifs_buf_release(pSMB);
4352 goto UnixQPathInfoRetry;
4357 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4359 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4360 const char *searchName, struct cifs_sb_info *cifs_sb,
4361 __u16 *pnetfid, __u16 search_flags,
4362 struct cifs_search_info *psrch_inf, bool msearch)
4364 /* level 257 SMB_ */
4365 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4366 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4367 T2_FFIRST_RSP_PARMS *parms;
4369 int bytes_returned = 0;
4370 int name_len, remap;
4371 __u16 params, byte_count;
4372 struct nls_table *nls_codepage;
4374 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4377 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4382 nls_codepage = cifs_sb->local_nls;
4383 remap = cifs_remap(cifs_sb);
4385 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4387 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4388 PATH_MAX, nls_codepage, remap);
4389 /* We can not add the asterik earlier in case
4390 it got remapped to 0xF03A as if it were part of the
4391 directory name instead of a wildcard */
4394 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4395 pSMB->FileName[name_len+1] = 0;
4396 pSMB->FileName[name_len+2] = '*';
4397 pSMB->FileName[name_len+3] = 0;
4398 name_len += 4; /* now the trailing null */
4399 /* null terminate just in case */
4400 pSMB->FileName[name_len] = 0;
4401 pSMB->FileName[name_len+1] = 0;
4405 name_len = copy_path_name(pSMB->FileName, searchName);
4407 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4408 name_len = PATH_MAX-2;
4409 /* overwrite nul byte */
4410 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4411 pSMB->FileName[name_len] = '*';
4412 pSMB->FileName[name_len+1] = 0;
4417 params = 12 + name_len /* includes null */ ;
4418 pSMB->TotalDataCount = 0; /* no EAs */
4419 pSMB->MaxParameterCount = cpu_to_le16(10);
4420 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4421 pSMB->MaxSetupCount = 0;
4425 pSMB->Reserved2 = 0;
4426 byte_count = params + 1 /* pad */ ;
4427 pSMB->TotalParameterCount = cpu_to_le16(params);
4428 pSMB->ParameterCount = pSMB->TotalParameterCount;
4429 pSMB->ParameterOffset = cpu_to_le16(
4430 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4432 pSMB->DataCount = 0;
4433 pSMB->DataOffset = 0;
4434 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4435 pSMB->Reserved3 = 0;
4436 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4437 pSMB->SearchAttributes =
4438 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4440 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4441 pSMB->SearchFlags = cpu_to_le16(search_flags);
4442 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4444 /* BB what should we set StorageType to? Does it matter? BB */
4445 pSMB->SearchStorageType = 0;
4446 inc_rfc1001_len(pSMB, byte_count);
4447 pSMB->ByteCount = cpu_to_le16(byte_count);
4449 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4450 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4451 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4453 if (rc) {/* BB add logic to retry regular search if Unix search
4454 rejected unexpectedly by server */
4455 /* BB Add code to handle unsupported level rc */
4456 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4458 cifs_buf_release(pSMB);
4460 /* BB eventually could optimize out free and realloc of buf */
4463 goto findFirstRetry;
4464 } else { /* decode response */
4465 /* BB remember to free buffer if error BB */
4466 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4470 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4471 psrch_inf->unicode = true;
4473 psrch_inf->unicode = false;
4475 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4476 psrch_inf->smallBuf = false;
4477 psrch_inf->srch_entries_start =
4478 (char *) &pSMBr->hdr.Protocol +
4479 le16_to_cpu(pSMBr->t2.DataOffset);
4480 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4481 le16_to_cpu(pSMBr->t2.ParameterOffset));
4483 if (parms->EndofSearch)
4484 psrch_inf->endOfSearch = true;
4486 psrch_inf->endOfSearch = false;
4488 psrch_inf->entries_in_buffer =
4489 le16_to_cpu(parms->SearchCount);
4490 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4491 psrch_inf->entries_in_buffer;
4492 lnoff = le16_to_cpu(parms->LastNameOffset);
4493 if (CIFSMaxBufSize < lnoff) {
4494 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4495 psrch_inf->last_entry = NULL;
4499 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4503 *pnetfid = parms->SearchHandle;
4505 cifs_buf_release(pSMB);
4512 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4513 __u16 searchHandle, __u16 search_flags,
4514 struct cifs_search_info *psrch_inf)
4516 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4517 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4518 T2_FNEXT_RSP_PARMS *parms;
4519 char *response_data;
4522 unsigned int name_len;
4523 __u16 params, byte_count;
4525 cifs_dbg(FYI, "In FindNext\n");
4527 if (psrch_inf->endOfSearch)
4530 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4535 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4537 pSMB->TotalDataCount = 0; /* no EAs */
4538 pSMB->MaxParameterCount = cpu_to_le16(8);
4539 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4540 pSMB->MaxSetupCount = 0;
4544 pSMB->Reserved2 = 0;
4545 pSMB->ParameterOffset = cpu_to_le16(
4546 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4547 pSMB->DataCount = 0;
4548 pSMB->DataOffset = 0;
4549 pSMB->SetupCount = 1;
4550 pSMB->Reserved3 = 0;
4551 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4552 pSMB->SearchHandle = searchHandle; /* always kept as le */
4554 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4555 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4556 pSMB->ResumeKey = psrch_inf->resume_key;
4557 pSMB->SearchFlags = cpu_to_le16(search_flags);
4559 name_len = psrch_inf->resume_name_len;
4561 if (name_len < PATH_MAX) {
4562 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4563 byte_count += name_len;
4564 /* 14 byte parm len above enough for 2 byte null terminator */
4565 pSMB->ResumeFileName[name_len] = 0;
4566 pSMB->ResumeFileName[name_len+1] = 0;
4569 goto FNext2_err_exit;
4571 byte_count = params + 1 /* pad */ ;
4572 pSMB->TotalParameterCount = cpu_to_le16(params);
4573 pSMB->ParameterCount = pSMB->TotalParameterCount;
4574 inc_rfc1001_len(pSMB, byte_count);
4575 pSMB->ByteCount = cpu_to_le16(byte_count);
4577 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4578 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4579 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4582 psrch_inf->endOfSearch = true;
4583 cifs_buf_release(pSMB);
4584 rc = 0; /* search probably was closed at end of search*/
4586 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4587 } else { /* decode response */
4588 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4593 /* BB fixme add lock for file (srch_info) struct here */
4594 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4595 psrch_inf->unicode = true;
4597 psrch_inf->unicode = false;
4598 response_data = (char *) &pSMBr->hdr.Protocol +
4599 le16_to_cpu(pSMBr->t2.ParameterOffset);
4600 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4601 response_data = (char *)&pSMBr->hdr.Protocol +
4602 le16_to_cpu(pSMBr->t2.DataOffset);
4603 if (psrch_inf->smallBuf)
4604 cifs_small_buf_release(
4605 psrch_inf->ntwrk_buf_start);
4607 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4608 psrch_inf->srch_entries_start = response_data;
4609 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4610 psrch_inf->smallBuf = false;
4611 if (parms->EndofSearch)
4612 psrch_inf->endOfSearch = true;
4614 psrch_inf->endOfSearch = false;
4615 psrch_inf->entries_in_buffer =
4616 le16_to_cpu(parms->SearchCount);
4617 psrch_inf->index_of_last_entry +=
4618 psrch_inf->entries_in_buffer;
4619 lnoff = le16_to_cpu(parms->LastNameOffset);
4620 if (CIFSMaxBufSize < lnoff) {
4621 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4622 psrch_inf->last_entry = NULL;
4625 psrch_inf->last_entry =
4626 psrch_inf->srch_entries_start + lnoff;
4628 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4629 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4631 /* BB fixme add unlock here */
4636 /* BB On error, should we leave previous search buf (and count and
4637 last entry fields) intact or free the previous one? */
4639 /* Note: On -EAGAIN error only caller can retry on handle based calls
4640 since file handle passed in no longer valid */
4643 cifs_buf_release(pSMB);
4648 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4649 const __u16 searchHandle)
4652 FINDCLOSE_REQ *pSMB = NULL;
4654 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4655 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4657 /* no sense returning error if session restarted
4658 as file handle has been closed */
4664 pSMB->FileID = searchHandle;
4665 pSMB->ByteCount = 0;
4666 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4667 cifs_small_buf_release(pSMB);
4669 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4671 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4673 /* Since session is dead, search handle closed on server already */
4681 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4682 const char *search_name, __u64 *inode_number,
4683 const struct nls_table *nls_codepage, int remap)
4686 TRANSACTION2_QPI_REQ *pSMB = NULL;
4687 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4688 int name_len, bytes_returned;
4689 __u16 params, byte_count;
4691 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4695 GetInodeNumberRetry:
4696 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4701 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4703 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4704 search_name, PATH_MAX, nls_codepage,
4706 name_len++; /* trailing null */
4709 name_len = copy_path_name(pSMB->FileName, search_name);
4712 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4713 pSMB->TotalDataCount = 0;
4714 pSMB->MaxParameterCount = cpu_to_le16(2);
4715 /* BB find exact max data count below from sess structure BB */
4716 pSMB->MaxDataCount = cpu_to_le16(4000);
4717 pSMB->MaxSetupCount = 0;
4721 pSMB->Reserved2 = 0;
4722 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4723 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4724 pSMB->DataCount = 0;
4725 pSMB->DataOffset = 0;
4726 pSMB->SetupCount = 1;
4727 pSMB->Reserved3 = 0;
4728 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4729 byte_count = params + 1 /* pad */ ;
4730 pSMB->TotalParameterCount = cpu_to_le16(params);
4731 pSMB->ParameterCount = pSMB->TotalParameterCount;
4732 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4733 pSMB->Reserved4 = 0;
4734 inc_rfc1001_len(pSMB, byte_count);
4735 pSMB->ByteCount = cpu_to_le16(byte_count);
4737 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4738 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4740 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4742 /* decode response */
4743 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4744 /* BB also check enough total bytes returned */
4745 if (rc || get_bcc(&pSMBr->hdr) < 2)
4746 /* If rc should we check for EOPNOSUPP and
4747 disable the srvino flag? or in caller? */
4748 rc = -EIO; /* bad smb */
4750 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4751 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4752 struct file_internal_info *pfinfo;
4753 /* BB Do we need a cast or hash here ? */
4755 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4757 goto GetInodeNumOut;
4759 pfinfo = (struct file_internal_info *)
4760 (data_offset + (char *) &pSMBr->hdr.Protocol);
4761 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4765 cifs_buf_release(pSMB);
4767 goto GetInodeNumberRetry;
4772 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4773 const char *search_name, struct dfs_info3_param **target_nodes,
4774 unsigned int *num_of_nodes,
4775 const struct nls_table *nls_codepage, int remap)
4777 /* TRANS2_GET_DFS_REFERRAL */
4778 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4779 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4783 __u16 params, byte_count;
4785 *target_nodes = NULL;
4787 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4788 if (ses == NULL || ses->tcon_ipc == NULL)
4792 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4797 /* server pointer checked in called function,
4798 but should never be null here anyway */
4799 pSMB->hdr.Mid = get_next_mid(ses->server);
4800 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4801 pSMB->hdr.Uid = ses->Suid;
4802 if (ses->capabilities & CAP_STATUS32)
4803 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4804 if (ses->capabilities & CAP_DFS)
4805 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4807 if (ses->capabilities & CAP_UNICODE) {
4808 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4810 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4811 search_name, PATH_MAX, nls_codepage,
4813 name_len++; /* trailing null */
4815 } else { /* BB improve the check for buffer overruns BB */
4816 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4819 if (ses->server->sign)
4820 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4822 pSMB->hdr.Uid = ses->Suid;
4824 params = 2 /* level */ + name_len /*includes null */ ;
4825 pSMB->TotalDataCount = 0;
4826 pSMB->DataCount = 0;
4827 pSMB->DataOffset = 0;
4828 pSMB->MaxParameterCount = 0;
4829 /* BB find exact max SMB PDU from sess structure BB */
4830 pSMB->MaxDataCount = cpu_to_le16(4000);
4831 pSMB->MaxSetupCount = 0;
4835 pSMB->Reserved2 = 0;
4836 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4837 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4838 pSMB->SetupCount = 1;
4839 pSMB->Reserved3 = 0;
4840 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4841 byte_count = params + 3 /* pad */ ;
4842 pSMB->ParameterCount = cpu_to_le16(params);
4843 pSMB->TotalParameterCount = pSMB->ParameterCount;
4844 pSMB->MaxReferralLevel = cpu_to_le16(3);
4845 inc_rfc1001_len(pSMB, byte_count);
4846 pSMB->ByteCount = cpu_to_le16(byte_count);
4848 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4849 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4851 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4854 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4856 /* BB Also check if enough total bytes returned? */
4857 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4858 rc = -EIO; /* bad smb */
4862 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4863 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4865 /* parse returned result into more usable form */
4866 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4867 le16_to_cpu(pSMBr->t2.DataCount),
4868 num_of_nodes, target_nodes, nls_codepage,
4870 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4873 cifs_buf_release(pSMB);
4881 /* Query File System Info such as free space to old servers such as Win 9x */
4883 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4884 struct kstatfs *FSData)
4886 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4887 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4888 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4889 FILE_SYSTEM_ALLOC_INFO *response_data;
4891 int bytes_returned = 0;
4892 __u16 params, byte_count;
4894 cifs_dbg(FYI, "OldQFSInfo\n");
4896 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4901 params = 2; /* level */
4902 pSMB->TotalDataCount = 0;
4903 pSMB->MaxParameterCount = cpu_to_le16(2);
4904 pSMB->MaxDataCount = cpu_to_le16(1000);
4905 pSMB->MaxSetupCount = 0;
4909 pSMB->Reserved2 = 0;
4910 byte_count = params + 1 /* pad */ ;
4911 pSMB->TotalParameterCount = cpu_to_le16(params);
4912 pSMB->ParameterCount = pSMB->TotalParameterCount;
4913 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4914 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4915 pSMB->DataCount = 0;
4916 pSMB->DataOffset = 0;
4917 pSMB->SetupCount = 1;
4918 pSMB->Reserved3 = 0;
4919 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4920 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4921 inc_rfc1001_len(pSMB, byte_count);
4922 pSMB->ByteCount = cpu_to_le16(byte_count);
4924 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4925 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4927 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4928 } else { /* decode response */
4929 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4931 if (rc || get_bcc(&pSMBr->hdr) < 18)
4932 rc = -EIO; /* bad smb */
4934 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4935 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4936 get_bcc(&pSMBr->hdr), data_offset);
4938 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4939 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4941 le16_to_cpu(response_data->BytesPerSector) *
4942 le32_to_cpu(response_data->
4943 SectorsPerAllocationUnit);
4945 * much prefer larger but if server doesn't report
4946 * a valid size than 4K is a reasonable minimum
4948 if (FSData->f_bsize < 512)
4949 FSData->f_bsize = 4096;
4952 le32_to_cpu(response_data->TotalAllocationUnits);
4953 FSData->f_bfree = FSData->f_bavail =
4954 le32_to_cpu(response_data->FreeAllocationUnits);
4955 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4956 (unsigned long long)FSData->f_blocks,
4957 (unsigned long long)FSData->f_bfree,
4961 cifs_buf_release(pSMB);
4964 goto oldQFSInfoRetry;
4970 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4971 struct kstatfs *FSData)
4973 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4974 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4975 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4976 FILE_SYSTEM_INFO *response_data;
4978 int bytes_returned = 0;
4979 __u16 params, byte_count;
4981 cifs_dbg(FYI, "In QFSInfo\n");
4983 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4988 params = 2; /* level */
4989 pSMB->TotalDataCount = 0;
4990 pSMB->MaxParameterCount = cpu_to_le16(2);
4991 pSMB->MaxDataCount = cpu_to_le16(1000);
4992 pSMB->MaxSetupCount = 0;
4996 pSMB->Reserved2 = 0;
4997 byte_count = params + 1 /* pad */ ;
4998 pSMB->TotalParameterCount = cpu_to_le16(params);
4999 pSMB->ParameterCount = pSMB->TotalParameterCount;
5000 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5001 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5002 pSMB->DataCount = 0;
5003 pSMB->DataOffset = 0;
5004 pSMB->SetupCount = 1;
5005 pSMB->Reserved3 = 0;
5006 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5007 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5008 inc_rfc1001_len(pSMB, byte_count);
5009 pSMB->ByteCount = cpu_to_le16(byte_count);
5011 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5012 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5014 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5015 } else { /* decode response */
5016 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5018 if (rc || get_bcc(&pSMBr->hdr) < 24)
5019 rc = -EIO; /* bad smb */
5021 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5025 *) (((char *) &pSMBr->hdr.Protocol) +
5028 le32_to_cpu(response_data->BytesPerSector) *
5029 le32_to_cpu(response_data->
5030 SectorsPerAllocationUnit);
5032 * much prefer larger but if server doesn't report
5033 * a valid size than 4K is a reasonable minimum
5035 if (FSData->f_bsize < 512)
5036 FSData->f_bsize = 4096;
5039 le64_to_cpu(response_data->TotalAllocationUnits);
5040 FSData->f_bfree = FSData->f_bavail =
5041 le64_to_cpu(response_data->FreeAllocationUnits);
5042 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5043 (unsigned long long)FSData->f_blocks,
5044 (unsigned long long)FSData->f_bfree,
5048 cifs_buf_release(pSMB);
5057 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5059 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5060 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5061 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5062 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5064 int bytes_returned = 0;
5065 __u16 params, byte_count;
5067 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5069 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5074 params = 2; /* level */
5075 pSMB->TotalDataCount = 0;
5076 pSMB->MaxParameterCount = cpu_to_le16(2);
5077 /* BB find exact max SMB PDU from sess structure BB */
5078 pSMB->MaxDataCount = cpu_to_le16(1000);
5079 pSMB->MaxSetupCount = 0;
5083 pSMB->Reserved2 = 0;
5084 byte_count = params + 1 /* pad */ ;
5085 pSMB->TotalParameterCount = cpu_to_le16(params);
5086 pSMB->ParameterCount = pSMB->TotalParameterCount;
5087 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5088 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5089 pSMB->DataCount = 0;
5090 pSMB->DataOffset = 0;
5091 pSMB->SetupCount = 1;
5092 pSMB->Reserved3 = 0;
5093 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5094 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5095 inc_rfc1001_len(pSMB, byte_count);
5096 pSMB->ByteCount = cpu_to_le16(byte_count);
5098 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5099 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5101 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5102 } else { /* decode response */
5103 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5105 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5106 /* BB also check if enough bytes returned */
5107 rc = -EIO; /* bad smb */
5109 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5111 (FILE_SYSTEM_ATTRIBUTE_INFO
5112 *) (((char *) &pSMBr->hdr.Protocol) +
5114 memcpy(&tcon->fsAttrInfo, response_data,
5115 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5118 cifs_buf_release(pSMB);
5121 goto QFSAttributeRetry;
5127 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5129 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5130 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5131 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5132 FILE_SYSTEM_DEVICE_INFO *response_data;
5134 int bytes_returned = 0;
5135 __u16 params, byte_count;
5137 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5139 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5144 params = 2; /* level */
5145 pSMB->TotalDataCount = 0;
5146 pSMB->MaxParameterCount = cpu_to_le16(2);
5147 /* BB find exact max SMB PDU from sess structure BB */
5148 pSMB->MaxDataCount = cpu_to_le16(1000);
5149 pSMB->MaxSetupCount = 0;
5153 pSMB->Reserved2 = 0;
5154 byte_count = params + 1 /* pad */ ;
5155 pSMB->TotalParameterCount = cpu_to_le16(params);
5156 pSMB->ParameterCount = pSMB->TotalParameterCount;
5157 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5158 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5160 pSMB->DataCount = 0;
5161 pSMB->DataOffset = 0;
5162 pSMB->SetupCount = 1;
5163 pSMB->Reserved3 = 0;
5164 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5165 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5166 inc_rfc1001_len(pSMB, byte_count);
5167 pSMB->ByteCount = cpu_to_le16(byte_count);
5169 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5170 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5172 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5173 } else { /* decode response */
5174 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5176 if (rc || get_bcc(&pSMBr->hdr) <
5177 sizeof(FILE_SYSTEM_DEVICE_INFO))
5178 rc = -EIO; /* bad smb */
5180 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5182 (FILE_SYSTEM_DEVICE_INFO *)
5183 (((char *) &pSMBr->hdr.Protocol) +
5185 memcpy(&tcon->fsDevInfo, response_data,
5186 sizeof(FILE_SYSTEM_DEVICE_INFO));
5189 cifs_buf_release(pSMB);
5192 goto QFSDeviceRetry;
5198 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5200 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5201 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5202 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5203 FILE_SYSTEM_UNIX_INFO *response_data;
5205 int bytes_returned = 0;
5206 __u16 params, byte_count;
5208 cifs_dbg(FYI, "In QFSUnixInfo\n");
5210 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5211 (void **) &pSMB, (void **) &pSMBr);
5215 params = 2; /* level */
5216 pSMB->TotalDataCount = 0;
5217 pSMB->DataCount = 0;
5218 pSMB->DataOffset = 0;
5219 pSMB->MaxParameterCount = cpu_to_le16(2);
5220 /* BB find exact max SMB PDU from sess structure BB */
5221 pSMB->MaxDataCount = cpu_to_le16(100);
5222 pSMB->MaxSetupCount = 0;
5226 pSMB->Reserved2 = 0;
5227 byte_count = params + 1 /* pad */ ;
5228 pSMB->ParameterCount = cpu_to_le16(params);
5229 pSMB->TotalParameterCount = pSMB->ParameterCount;
5230 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5231 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5232 pSMB->SetupCount = 1;
5233 pSMB->Reserved3 = 0;
5234 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5235 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5236 inc_rfc1001_len(pSMB, byte_count);
5237 pSMB->ByteCount = cpu_to_le16(byte_count);
5239 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5240 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5242 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5243 } else { /* decode response */
5244 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5246 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5247 rc = -EIO; /* bad smb */
5249 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5251 (FILE_SYSTEM_UNIX_INFO
5252 *) (((char *) &pSMBr->hdr.Protocol) +
5254 memcpy(&tcon->fsUnixInfo, response_data,
5255 sizeof(FILE_SYSTEM_UNIX_INFO));
5258 cifs_buf_release(pSMB);
5268 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5270 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5271 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5272 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5274 int bytes_returned = 0;
5275 __u16 params, param_offset, offset, byte_count;
5277 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5279 /* BB switch to small buf init to save memory */
5280 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5281 (void **) &pSMB, (void **) &pSMBr);
5285 params = 4; /* 2 bytes zero followed by info level. */
5286 pSMB->MaxSetupCount = 0;
5290 pSMB->Reserved2 = 0;
5291 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5293 offset = param_offset + params;
5295 pSMB->MaxParameterCount = cpu_to_le16(4);
5296 /* BB find exact max SMB PDU from sess structure BB */
5297 pSMB->MaxDataCount = cpu_to_le16(100);
5298 pSMB->SetupCount = 1;
5299 pSMB->Reserved3 = 0;
5300 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5301 byte_count = 1 /* pad */ + params + 12;
5303 pSMB->DataCount = cpu_to_le16(12);
5304 pSMB->ParameterCount = cpu_to_le16(params);
5305 pSMB->TotalDataCount = pSMB->DataCount;
5306 pSMB->TotalParameterCount = pSMB->ParameterCount;
5307 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5308 pSMB->DataOffset = cpu_to_le16(offset);
5312 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5315 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5316 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5317 pSMB->ClientUnixCap = cpu_to_le64(cap);
5319 inc_rfc1001_len(pSMB, byte_count);
5320 pSMB->ByteCount = cpu_to_le16(byte_count);
5322 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5323 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5325 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5326 } else { /* decode response */
5327 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5329 rc = -EIO; /* bad smb */
5331 cifs_buf_release(pSMB);
5334 goto SETFSUnixRetry;
5342 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5343 struct kstatfs *FSData)
5345 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5346 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5347 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5348 FILE_SYSTEM_POSIX_INFO *response_data;
5350 int bytes_returned = 0;
5351 __u16 params, byte_count;
5353 cifs_dbg(FYI, "In QFSPosixInfo\n");
5355 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5360 params = 2; /* level */
5361 pSMB->TotalDataCount = 0;
5362 pSMB->DataCount = 0;
5363 pSMB->DataOffset = 0;
5364 pSMB->MaxParameterCount = cpu_to_le16(2);
5365 /* BB find exact max SMB PDU from sess structure BB */
5366 pSMB->MaxDataCount = cpu_to_le16(100);
5367 pSMB->MaxSetupCount = 0;
5371 pSMB->Reserved2 = 0;
5372 byte_count = params + 1 /* pad */ ;
5373 pSMB->ParameterCount = cpu_to_le16(params);
5374 pSMB->TotalParameterCount = pSMB->ParameterCount;
5375 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5376 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5377 pSMB->SetupCount = 1;
5378 pSMB->Reserved3 = 0;
5379 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5380 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5381 inc_rfc1001_len(pSMB, byte_count);
5382 pSMB->ByteCount = cpu_to_le16(byte_count);
5384 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5385 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5387 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5388 } else { /* decode response */
5389 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5391 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5392 rc = -EIO; /* bad smb */
5394 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5396 (FILE_SYSTEM_POSIX_INFO
5397 *) (((char *) &pSMBr->hdr.Protocol) +
5400 le32_to_cpu(response_data->BlockSize);
5402 * much prefer larger but if server doesn't report
5403 * a valid size than 4K is a reasonable minimum
5405 if (FSData->f_bsize < 512)
5406 FSData->f_bsize = 4096;
5409 le64_to_cpu(response_data->TotalBlocks);
5411 le64_to_cpu(response_data->BlocksAvail);
5412 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5413 FSData->f_bavail = FSData->f_bfree;
5416 le64_to_cpu(response_data->UserBlocksAvail);
5418 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5420 le64_to_cpu(response_data->TotalFileNodes);
5421 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5423 le64_to_cpu(response_data->FreeFileNodes);
5426 cifs_buf_release(pSMB);
5436 * We can not use write of zero bytes trick to set file size due to need for
5437 * large file support. Also note that this SetPathInfo is preferred to
5438 * SetFileInfo based method in next routine which is only needed to work around
5439 * a sharing violation bugin Samba which this routine can run into.
5442 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5443 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5444 bool set_allocation)
5446 struct smb_com_transaction2_spi_req *pSMB = NULL;
5447 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5448 struct file_end_of_file_info *parm_data;
5451 int bytes_returned = 0;
5452 int remap = cifs_remap(cifs_sb);
5454 __u16 params, byte_count, data_count, param_offset, offset;
5456 cifs_dbg(FYI, "In SetEOF\n");
5458 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5463 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5465 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5466 PATH_MAX, cifs_sb->local_nls, remap);
5467 name_len++; /* trailing null */
5470 name_len = copy_path_name(pSMB->FileName, file_name);
5472 params = 6 + name_len;
5473 data_count = sizeof(struct file_end_of_file_info);
5474 pSMB->MaxParameterCount = cpu_to_le16(2);
5475 pSMB->MaxDataCount = cpu_to_le16(4100);
5476 pSMB->MaxSetupCount = 0;
5480 pSMB->Reserved2 = 0;
5481 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5482 InformationLevel) - 4;
5483 offset = param_offset + params;
5484 if (set_allocation) {
5485 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5486 pSMB->InformationLevel =
5487 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5489 pSMB->InformationLevel =
5490 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5491 } else /* Set File Size */ {
5492 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5493 pSMB->InformationLevel =
5494 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5496 pSMB->InformationLevel =
5497 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5501 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5503 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5504 pSMB->DataOffset = cpu_to_le16(offset);
5505 pSMB->SetupCount = 1;
5506 pSMB->Reserved3 = 0;
5507 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5508 byte_count = 3 /* pad */ + params + data_count;
5509 pSMB->DataCount = cpu_to_le16(data_count);
5510 pSMB->TotalDataCount = pSMB->DataCount;
5511 pSMB->ParameterCount = cpu_to_le16(params);
5512 pSMB->TotalParameterCount = pSMB->ParameterCount;
5513 pSMB->Reserved4 = 0;
5514 inc_rfc1001_len(pSMB, byte_count);
5515 parm_data->FileSize = cpu_to_le64(size);
5516 pSMB->ByteCount = cpu_to_le16(byte_count);
5517 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5518 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5520 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5522 cifs_buf_release(pSMB);
5531 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5532 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5534 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5535 struct file_end_of_file_info *parm_data;
5537 __u16 params, param_offset, offset, byte_count, count;
5539 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5541 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5546 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5547 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5550 pSMB->MaxSetupCount = 0;
5554 pSMB->Reserved2 = 0;
5555 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5556 offset = param_offset + params;
5558 count = sizeof(struct file_end_of_file_info);
5559 pSMB->MaxParameterCount = cpu_to_le16(2);
5560 /* BB find exact max SMB PDU from sess structure BB */
5561 pSMB->MaxDataCount = cpu_to_le16(1000);
5562 pSMB->SetupCount = 1;
5563 pSMB->Reserved3 = 0;
5564 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5565 byte_count = 3 /* pad */ + params + count;
5566 pSMB->DataCount = cpu_to_le16(count);
5567 pSMB->ParameterCount = cpu_to_le16(params);
5568 pSMB->TotalDataCount = pSMB->DataCount;
5569 pSMB->TotalParameterCount = pSMB->ParameterCount;
5570 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5571 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5573 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5574 pSMB->DataOffset = cpu_to_le16(offset);
5575 parm_data->FileSize = cpu_to_le64(size);
5576 pSMB->Fid = cfile->fid.netfid;
5577 if (set_allocation) {
5578 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5579 pSMB->InformationLevel =
5580 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5582 pSMB->InformationLevel =
5583 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5584 } else /* Set File Size */ {
5585 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5586 pSMB->InformationLevel =
5587 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5589 pSMB->InformationLevel =
5590 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5592 pSMB->Reserved4 = 0;
5593 inc_rfc1001_len(pSMB, byte_count);
5594 pSMB->ByteCount = cpu_to_le16(byte_count);
5595 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5596 cifs_small_buf_release(pSMB);
5598 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5602 /* Note: On -EAGAIN error only caller can retry on handle based calls
5603 since file handle passed in no longer valid */
5608 /* Some legacy servers such as NT4 require that the file times be set on
5609 an open handle, rather than by pathname - this is awkward due to
5610 potential access conflicts on the open, but it is unavoidable for these
5611 old servers since the only other choice is to go from 100 nanosecond DCE
5612 time and resort to the original setpathinfo level which takes the ancient
5613 DOS time format with 2 second granularity */
5615 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5616 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5618 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5621 __u16 params, param_offset, offset, byte_count, count;
5623 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5624 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5629 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5630 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5633 pSMB->MaxSetupCount = 0;
5637 pSMB->Reserved2 = 0;
5638 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5639 offset = param_offset + params;
5641 data_offset = (char *)pSMB +
5642 offsetof(struct smb_hdr, Protocol) + offset;
5644 count = sizeof(FILE_BASIC_INFO);
5645 pSMB->MaxParameterCount = cpu_to_le16(2);
5646 /* BB find max SMB PDU from sess */
5647 pSMB->MaxDataCount = cpu_to_le16(1000);
5648 pSMB->SetupCount = 1;
5649 pSMB->Reserved3 = 0;
5650 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5651 byte_count = 3 /* pad */ + params + count;
5652 pSMB->DataCount = cpu_to_le16(count);
5653 pSMB->ParameterCount = cpu_to_le16(params);
5654 pSMB->TotalDataCount = pSMB->DataCount;
5655 pSMB->TotalParameterCount = pSMB->ParameterCount;
5656 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5657 pSMB->DataOffset = cpu_to_le16(offset);
5659 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5660 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5662 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5663 pSMB->Reserved4 = 0;
5664 inc_rfc1001_len(pSMB, byte_count);
5665 pSMB->ByteCount = cpu_to_le16(byte_count);
5666 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5667 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5668 cifs_small_buf_release(pSMB);
5670 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5673 /* Note: On -EAGAIN error only caller can retry on handle based calls
5674 since file handle passed in no longer valid */
5680 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5681 bool delete_file, __u16 fid, __u32 pid_of_opener)
5683 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5686 __u16 params, param_offset, offset, byte_count, count;
5688 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5689 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5694 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5695 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5698 pSMB->MaxSetupCount = 0;
5702 pSMB->Reserved2 = 0;
5703 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5704 offset = param_offset + params;
5706 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5707 data_offset = (char *)(pSMB) + offset + 4;
5710 pSMB->MaxParameterCount = cpu_to_le16(2);
5711 /* BB find max SMB PDU from sess */
5712 pSMB->MaxDataCount = cpu_to_le16(1000);
5713 pSMB->SetupCount = 1;
5714 pSMB->Reserved3 = 0;
5715 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5716 byte_count = 3 /* pad */ + params + count;
5717 pSMB->DataCount = cpu_to_le16(count);
5718 pSMB->ParameterCount = cpu_to_le16(params);
5719 pSMB->TotalDataCount = pSMB->DataCount;
5720 pSMB->TotalParameterCount = pSMB->ParameterCount;
5721 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5722 pSMB->DataOffset = cpu_to_le16(offset);
5724 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5725 pSMB->Reserved4 = 0;
5726 inc_rfc1001_len(pSMB, byte_count);
5727 pSMB->ByteCount = cpu_to_le16(byte_count);
5728 *data_offset = delete_file ? 1 : 0;
5729 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5730 cifs_small_buf_release(pSMB);
5732 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5738 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5739 const char *fileName, const FILE_BASIC_INFO *data,
5740 const struct nls_table *nls_codepage,
5741 struct cifs_sb_info *cifs_sb)
5744 struct cifs_open_parms oparms;
5745 struct cifs_fid fid;
5749 oparms.cifs_sb = cifs_sb;
5750 oparms.desired_access = GENERIC_WRITE;
5751 oparms.create_options = cifs_create_options(cifs_sb, 0);
5752 oparms.disposition = FILE_OPEN;
5753 oparms.path = fileName;
5755 oparms.reconnect = false;
5757 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5761 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5762 CIFSSMBClose(xid, tcon, fid.netfid);
5769 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5770 const char *fileName, const FILE_BASIC_INFO *data,
5771 const struct nls_table *nls_codepage,
5772 struct cifs_sb_info *cifs_sb)
5774 TRANSACTION2_SPI_REQ *pSMB = NULL;
5775 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5778 int bytes_returned = 0;
5780 __u16 params, param_offset, offset, byte_count, count;
5781 int remap = cifs_remap(cifs_sb);
5783 cifs_dbg(FYI, "In SetTimes\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;
5802 count = sizeof(FILE_BASIC_INFO);
5803 pSMB->MaxParameterCount = cpu_to_le16(2);
5804 /* BB find max SMB PDU from sess structure BB */
5805 pSMB->MaxDataCount = cpu_to_le16(1000);
5806 pSMB->MaxSetupCount = 0;
5810 pSMB->Reserved2 = 0;
5811 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5812 InformationLevel) - 4;
5813 offset = param_offset + params;
5814 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5815 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5816 pSMB->DataOffset = cpu_to_le16(offset);
5817 pSMB->SetupCount = 1;
5818 pSMB->Reserved3 = 0;
5819 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5820 byte_count = 3 /* pad */ + params + count;
5822 pSMB->DataCount = cpu_to_le16(count);
5823 pSMB->ParameterCount = cpu_to_le16(params);
5824 pSMB->TotalDataCount = pSMB->DataCount;
5825 pSMB->TotalParameterCount = pSMB->ParameterCount;
5826 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5827 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5829 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5830 pSMB->Reserved4 = 0;
5831 inc_rfc1001_len(pSMB, byte_count);
5832 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5833 pSMB->ByteCount = cpu_to_le16(byte_count);
5834 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5835 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5837 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5839 cifs_buf_release(pSMB);
5844 if (rc == -EOPNOTSUPP)
5845 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5846 nls_codepage, cifs_sb);
5852 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5853 const struct cifs_unix_set_info_args *args)
5855 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5856 u64 mode = args->mode;
5858 if (uid_valid(args->uid))
5859 uid = from_kuid(&init_user_ns, args->uid);
5860 if (gid_valid(args->gid))
5861 gid = from_kgid(&init_user_ns, args->gid);
5864 * Samba server ignores set of file size to zero due to bugs in some
5865 * older clients, but we should be precise - we use SetFileSize to
5866 * set file size and do not want to truncate file size to zero
5867 * accidentally as happened on one Samba server beta by putting
5868 * zero instead of -1 here
5870 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5871 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5872 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5873 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5874 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5875 data_offset->Uid = cpu_to_le64(uid);
5876 data_offset->Gid = cpu_to_le64(gid);
5877 /* better to leave device as zero when it is */
5878 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5879 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5880 data_offset->Permissions = cpu_to_le64(mode);
5883 data_offset->Type = cpu_to_le32(UNIX_FILE);
5884 else if (S_ISDIR(mode))
5885 data_offset->Type = cpu_to_le32(UNIX_DIR);
5886 else if (S_ISLNK(mode))
5887 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5888 else if (S_ISCHR(mode))
5889 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5890 else if (S_ISBLK(mode))
5891 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5892 else if (S_ISFIFO(mode))
5893 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5894 else if (S_ISSOCK(mode))
5895 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5899 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5900 const struct cifs_unix_set_info_args *args,
5901 u16 fid, u32 pid_of_opener)
5903 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5906 u16 params, param_offset, offset, byte_count, count;
5908 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5909 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5914 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5915 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5918 pSMB->MaxSetupCount = 0;
5922 pSMB->Reserved2 = 0;
5923 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5924 offset = param_offset + params;
5926 data_offset = (char *)pSMB +
5927 offsetof(struct smb_hdr, Protocol) + offset;
5929 count = sizeof(FILE_UNIX_BASIC_INFO);
5931 pSMB->MaxParameterCount = cpu_to_le16(2);
5932 /* BB find max SMB PDU from sess */
5933 pSMB->MaxDataCount = cpu_to_le16(1000);
5934 pSMB->SetupCount = 1;
5935 pSMB->Reserved3 = 0;
5936 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5937 byte_count = 3 /* pad */ + params + count;
5938 pSMB->DataCount = cpu_to_le16(count);
5939 pSMB->ParameterCount = cpu_to_le16(params);
5940 pSMB->TotalDataCount = pSMB->DataCount;
5941 pSMB->TotalParameterCount = pSMB->ParameterCount;
5942 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5943 pSMB->DataOffset = cpu_to_le16(offset);
5945 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5946 pSMB->Reserved4 = 0;
5947 inc_rfc1001_len(pSMB, byte_count);
5948 pSMB->ByteCount = cpu_to_le16(byte_count);
5950 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5952 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5953 cifs_small_buf_release(pSMB);
5955 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5958 /* Note: On -EAGAIN error only caller can retry on handle based calls
5959 since file handle passed in no longer valid */
5965 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5966 const char *file_name,
5967 const struct cifs_unix_set_info_args *args,
5968 const struct nls_table *nls_codepage, int remap)
5970 TRANSACTION2_SPI_REQ *pSMB = NULL;
5971 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5974 int bytes_returned = 0;
5975 FILE_UNIX_BASIC_INFO *data_offset;
5976 __u16 params, param_offset, offset, count, byte_count;
5978 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5980 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5985 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5987 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5988 PATH_MAX, nls_codepage, remap);
5989 name_len++; /* trailing null */
5992 name_len = copy_path_name(pSMB->FileName, file_name);
5995 params = 6 + name_len;
5996 count = sizeof(FILE_UNIX_BASIC_INFO);
5997 pSMB->MaxParameterCount = cpu_to_le16(2);
5998 /* BB find max SMB PDU from sess structure BB */
5999 pSMB->MaxDataCount = cpu_to_le16(1000);
6000 pSMB->MaxSetupCount = 0;
6004 pSMB->Reserved2 = 0;
6005 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6006 InformationLevel) - 4;
6007 offset = param_offset + params;
6008 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
6009 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
6010 memset(data_offset, 0, count);
6011 pSMB->DataOffset = cpu_to_le16(offset);
6012 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6013 pSMB->SetupCount = 1;
6014 pSMB->Reserved3 = 0;
6015 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6016 byte_count = 3 /* pad */ + params + count;
6017 pSMB->ParameterCount = cpu_to_le16(params);
6018 pSMB->DataCount = cpu_to_le16(count);
6019 pSMB->TotalParameterCount = pSMB->ParameterCount;
6020 pSMB->TotalDataCount = pSMB->DataCount;
6021 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6022 pSMB->Reserved4 = 0;
6023 inc_rfc1001_len(pSMB, byte_count);
6025 cifs_fill_unix_set_info(data_offset, args);
6027 pSMB->ByteCount = cpu_to_le16(byte_count);
6028 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6029 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6031 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6033 cifs_buf_release(pSMB);
6039 #ifdef CONFIG_CIFS_XATTR
6041 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6042 * function used by listxattr and getxattr type calls. When ea_name is set,
6043 * it looks for that attribute name and stuffs that value into the EAData
6044 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6045 * buffer. In both cases, the return value is either the length of the
6046 * resulting data or a negative error code. If EAData is a NULL pointer then
6047 * the data isn't copied to it, but the length is returned.
6050 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6051 const unsigned char *searchName, const unsigned char *ea_name,
6052 char *EAData, size_t buf_size,
6053 struct cifs_sb_info *cifs_sb)
6055 /* BB assumes one setup word */
6056 TRANSACTION2_QPI_REQ *pSMB = NULL;
6057 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6058 int remap = cifs_remap(cifs_sb);
6059 struct nls_table *nls_codepage = cifs_sb->local_nls;
6063 struct fealist *ea_response_data;
6064 struct fea *temp_fea;
6067 __u16 params, byte_count, data_offset;
6068 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6070 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6072 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6077 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6079 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6080 PATH_MAX, nls_codepage, remap);
6081 list_len++; /* trailing null */
6084 list_len = copy_path_name(pSMB->FileName, searchName);
6087 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6088 pSMB->TotalDataCount = 0;
6089 pSMB->MaxParameterCount = cpu_to_le16(2);
6090 /* BB find exact max SMB PDU from sess structure BB */
6091 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6092 pSMB->MaxSetupCount = 0;
6096 pSMB->Reserved2 = 0;
6097 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6098 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6099 pSMB->DataCount = 0;
6100 pSMB->DataOffset = 0;
6101 pSMB->SetupCount = 1;
6102 pSMB->Reserved3 = 0;
6103 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6104 byte_count = params + 1 /* pad */ ;
6105 pSMB->TotalParameterCount = cpu_to_le16(params);
6106 pSMB->ParameterCount = pSMB->TotalParameterCount;
6107 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6108 pSMB->Reserved4 = 0;
6109 inc_rfc1001_len(pSMB, byte_count);
6110 pSMB->ByteCount = cpu_to_le16(byte_count);
6112 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6113 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6115 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6120 /* BB also check enough total bytes returned */
6121 /* BB we need to improve the validity checking
6122 of these trans2 responses */
6124 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6125 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6126 rc = -EIO; /* bad smb */
6130 /* check that length of list is not more than bcc */
6131 /* check that each entry does not go beyond length
6133 /* check that each element of each entry does not
6134 go beyond end of list */
6135 /* validate_trans2_offsets() */
6136 /* BB check if start of smb + data_offset > &bcc+ bcc */
6138 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6139 ea_response_data = (struct fealist *)
6140 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6142 list_len = le32_to_cpu(ea_response_data->list_len);
6143 cifs_dbg(FYI, "ea length %d\n", list_len);
6144 if (list_len <= 8) {
6145 cifs_dbg(FYI, "empty EA list returned from server\n");
6146 /* didn't find the named attribute */
6152 /* make sure list_len doesn't go past end of SMB */
6153 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6154 if ((char *)ea_response_data + list_len > end_of_smb) {
6155 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6160 /* account for ea list len */
6162 temp_fea = ea_response_data->list;
6163 temp_ptr = (char *)temp_fea;
6164 while (list_len > 0) {
6165 unsigned int name_len;
6170 /* make sure we can read name_len and value_len */
6172 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6177 name_len = temp_fea->name_len;
6178 value_len = le16_to_cpu(temp_fea->value_len);
6179 list_len -= name_len + 1 + value_len;
6181 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6187 if (ea_name_len == name_len &&
6188 memcmp(ea_name, temp_ptr, name_len) == 0) {
6189 temp_ptr += name_len + 1;
6193 if ((size_t)value_len > buf_size) {
6197 memcpy(EAData, temp_ptr, value_len);
6201 /* account for prefix user. and trailing null */
6202 rc += (5 + 1 + name_len);
6203 if (rc < (int) buf_size) {
6204 memcpy(EAData, "user.", 5);
6206 memcpy(EAData, temp_ptr, name_len);
6208 /* null terminate name */
6211 } else if (buf_size == 0) {
6212 /* skip copy - calc size only */
6214 /* stop before overrun buffer */
6219 temp_ptr += name_len + 1 + value_len;
6220 temp_fea = (struct fea *)temp_ptr;
6223 /* didn't find the named attribute */
6228 cifs_buf_release(pSMB);
6236 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6237 const char *fileName, const char *ea_name, const void *ea_value,
6238 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6239 struct cifs_sb_info *cifs_sb)
6241 struct smb_com_transaction2_spi_req *pSMB = NULL;
6242 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6243 struct fealist *parm_data;
6246 int bytes_returned = 0;
6247 __u16 params, param_offset, byte_count, offset, count;
6248 int remap = cifs_remap(cifs_sb);
6250 cifs_dbg(FYI, "In SetEA\n");
6252 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6257 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6259 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6260 PATH_MAX, nls_codepage, remap);
6261 name_len++; /* trailing null */
6264 name_len = copy_path_name(pSMB->FileName, fileName);
6267 params = 6 + name_len;
6269 /* done calculating parms using name_len of file name,
6270 now use name_len to calculate length of ea name
6271 we are going to create in the inode xattrs */
6272 if (ea_name == NULL)
6275 name_len = strnlen(ea_name, 255);
6277 count = sizeof(*parm_data) + ea_value_len + name_len;
6278 pSMB->MaxParameterCount = cpu_to_le16(2);
6279 /* BB find max SMB PDU from sess */
6280 pSMB->MaxDataCount = cpu_to_le16(1000);
6281 pSMB->MaxSetupCount = 0;
6285 pSMB->Reserved2 = 0;
6286 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6287 InformationLevel) - 4;
6288 offset = param_offset + params;
6289 pSMB->InformationLevel =
6290 cpu_to_le16(SMB_SET_FILE_EA);
6292 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6293 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6294 pSMB->DataOffset = cpu_to_le16(offset);
6295 pSMB->SetupCount = 1;
6296 pSMB->Reserved3 = 0;
6297 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6298 byte_count = 3 /* pad */ + params + count;
6299 pSMB->DataCount = cpu_to_le16(count);
6300 parm_data->list_len = cpu_to_le32(count);
6301 parm_data->list[0].EA_flags = 0;
6302 /* we checked above that name len is less than 255 */
6303 parm_data->list[0].name_len = (__u8)name_len;
6304 /* EA names are always ASCII */
6306 strncpy(parm_data->list[0].name, ea_name, name_len);
6307 parm_data->list[0].name[name_len] = 0;
6308 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6309 /* caller ensures that ea_value_len is less than 64K but
6310 we need to ensure that it fits within the smb */
6312 /*BB add length check to see if it would fit in
6313 negotiated SMB buffer size BB */
6314 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6316 memcpy(parm_data->list[0].name+name_len+1,
6317 ea_value, ea_value_len);
6319 pSMB->TotalDataCount = pSMB->DataCount;
6320 pSMB->ParameterCount = cpu_to_le16(params);
6321 pSMB->TotalParameterCount = pSMB->ParameterCount;
6322 pSMB->Reserved4 = 0;
6323 inc_rfc1001_len(pSMB, byte_count);
6324 pSMB->ByteCount = cpu_to_le16(byte_count);
6325 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6326 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6328 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6330 cifs_buf_release(pSMB);