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
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
25 /* These are mostly routines that operate on a pathname, or on a tree id */
26 /* (mounted volume), but there are eight handle based routines which must be */
27 /* treated slightly differently for reconnection purposes since we never */
28 /* want to reuse a stale file handle and only the caller knows the file info */
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <linux/uaccess.h>
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
46 #include "smbdirect.h"
47 #ifdef CONFIG_CIFS_DFS_UPCALL
48 #include "dfs_cache.h"
51 #ifdef CONFIG_CIFS_POSIX
56 #ifdef CONFIG_CIFS_WEAK_PW_HASH
57 {LANMAN_PROT, "\2LM1.2X002"},
58 {LANMAN2_PROT, "\2LANMAN2.1"},
59 #endif /* weak password hashing for legacy clients */
60 {CIFS_PROT, "\2NT LM 0.12"},
61 {POSIX_PROT, "\2POSIX 2"},
69 #ifdef CONFIG_CIFS_WEAK_PW_HASH
70 {LANMAN_PROT, "\2LM1.2X002"},
71 {LANMAN2_PROT, "\2LANMAN2.1"},
72 #endif /* weak password hashing for legacy clients */
73 {CIFS_PROT, "\2NT LM 0.12"},
78 /* define the number of elements in the cifs dialect array */
79 #ifdef CONFIG_CIFS_POSIX
80 #ifdef CONFIG_CIFS_WEAK_PW_HASH
81 #define CIFS_NUM_PROT 4
83 #define CIFS_NUM_PROT 2
84 #endif /* CIFS_WEAK_PW_HASH */
86 #ifdef CONFIG_CIFS_WEAK_PW_HASH
87 #define CIFS_NUM_PROT 3
89 #define CIFS_NUM_PROT 1
90 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
91 #endif /* CIFS_POSIX */
94 * Mark as invalid, all open files on tree connections since they
95 * were closed when session to server was lost.
98 cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
100 struct cifsFileInfo *open_file = NULL;
101 struct list_head *tmp;
102 struct list_head *tmp1;
104 /* list all files open on tree connection and mark them invalid */
105 spin_lock(&tcon->open_file_lock);
106 list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
107 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
108 open_file->invalidHandle = true;
109 open_file->oplock_break_cancelled = true;
111 spin_unlock(&tcon->open_file_lock);
113 mutex_lock(&tcon->crfid.fid_mutex);
114 tcon->crfid.is_valid = false;
115 memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
116 mutex_unlock(&tcon->crfid.fid_mutex);
119 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
124 #ifdef CONFIG_CIFS_DFS_UPCALL
125 static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
126 struct cifs_tcon *tcon)
129 struct dfs_cache_tgt_list tl;
130 struct dfs_cache_tgt_iterator *it = NULL;
132 const char *tcp_host;
134 const char *dfs_host;
137 tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
142 scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
143 tcon->ses->server->hostname);
144 rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
148 if (!tcon->dfs_path) {
149 rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
153 rc = dfs_cache_noreq_find(tcon->dfs_path + 1, NULL, &tl);
157 extract_unc_hostname(tcon->ses->server->hostname, &tcp_host,
160 for (it = dfs_cache_get_tgt_iterator(&tl); it;
161 it = dfs_cache_get_next_tgt(&tl, it)) {
162 const char *tgt = dfs_cache_get_tgt_name(it);
164 extract_unc_hostname(tgt, &dfs_host, &dfs_host_len);
166 if (dfs_host_len != tcp_host_len
167 || strncasecmp(dfs_host, tcp_host, dfs_host_len) != 0) {
168 cifs_dbg(FYI, "%s: skipping %.*s, doesn't match %.*s",
170 (int)dfs_host_len, dfs_host,
171 (int)tcp_host_len, tcp_host);
175 scnprintf(tree, MAX_TREE_SIZE, "\\%s", tgt);
177 rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
186 rc = dfs_cache_noreq_update_tgthint(tcon->dfs_path + 1,
191 dfs_cache_free_tgts(&tl);
197 static inline int __cifs_reconnect_tcon(const struct nls_table *nlsc,
198 struct cifs_tcon *tcon)
200 return CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
204 /* reconnect the socket, tcon, and smb session if needed */
206 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
209 struct cifs_ses *ses;
210 struct TCP_Server_Info *server;
211 struct nls_table *nls_codepage;
215 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
216 * tcp and smb session status done differently for those three - in the
223 server = ses->server;
226 * only tree disconnect, open, and write, (and ulogoff which does not
227 * have tcon) are allowed as we start force umount
229 if (tcon->tidStatus == CifsExiting) {
230 if (smb_command != SMB_COM_WRITE_ANDX &&
231 smb_command != SMB_COM_OPEN_ANDX &&
232 smb_command != SMB_COM_TREE_DISCONNECT) {
233 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
239 retries = server->nr_targets;
242 * Give demultiplex thread up to 10 seconds to each target available for
243 * reconnect -- should be greater than cifs socket timeout which is 7
246 while (server->tcpStatus == CifsNeedReconnect) {
247 rc = wait_event_interruptible_timeout(server->response_q,
248 (server->tcpStatus != CifsNeedReconnect),
251 cifs_dbg(FYI, "%s: aborting reconnect due to a received"
252 " signal by the process\n", __func__);
256 /* are we still trying to reconnect? */
257 if (server->tcpStatus != CifsNeedReconnect)
264 * on "soft" mounts we wait once. Hard mounts keep
265 * retrying until process is killed or server comes
269 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
272 retries = server->nr_targets;
275 if (!ses->need_reconnect && !tcon->need_reconnect)
278 nls_codepage = load_nls_default();
281 * need to prevent multiple threads trying to simultaneously
282 * reconnect the same SMB session
284 mutex_lock(&ses->session_mutex);
287 * Recheck after acquire mutex. If another thread is negotiating
288 * and the server never sends an answer the socket will be closed
289 * and tcpStatus set to reconnect.
291 if (server->tcpStatus == CifsNeedReconnect) {
293 mutex_unlock(&ses->session_mutex);
297 rc = cifs_negotiate_protocol(0, ses);
298 if (rc == 0 && ses->need_reconnect)
299 rc = cifs_setup_session(0, ses, nls_codepage);
301 /* do we need to reconnect tcon? */
302 if (rc || !tcon->need_reconnect) {
303 mutex_unlock(&ses->session_mutex);
307 cifs_mark_open_files_invalid(tcon);
308 rc = __cifs_reconnect_tcon(nls_codepage, tcon);
309 mutex_unlock(&ses->session_mutex);
310 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
313 printk_once(KERN_WARNING "reconnect tcon failed rc = %d\n", rc);
317 atomic_inc(&tconInfoReconnectCount);
319 /* tell server Unix caps we support */
320 if (ses->capabilities & CAP_UNIX)
321 reset_cifs_unix_caps(0, tcon, NULL, NULL);
324 * Removed call to reopen open files here. It is safer (and faster) to
325 * reopen files one at a time as needed in read and write.
327 * FIXME: what about file locks? don't we need to reclaim them ASAP?
332 * Check if handle based operation so we know whether we can continue
333 * or not without returning to caller to reset file handle
335 switch (smb_command) {
336 case SMB_COM_READ_ANDX:
337 case SMB_COM_WRITE_ANDX:
339 case SMB_COM_FIND_CLOSE2:
340 case SMB_COM_LOCKING_ANDX:
344 unload_nls(nls_codepage);
348 /* Allocate and return pointer to an SMB request buffer, and set basic
349 SMB information in the SMB header. If the return code is zero, this
350 function must have filled in request_buf pointer */
352 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
357 rc = cifs_reconnect_tcon(tcon, smb_command);
361 *request_buf = cifs_small_buf_get();
362 if (*request_buf == NULL) {
363 /* BB should we add a retry in here if not a writepage? */
367 header_assemble((struct smb_hdr *) *request_buf, smb_command,
371 cifs_stats_inc(&tcon->num_smbs_sent);
377 small_smb_init_no_tc(const int smb_command, const int wct,
378 struct cifs_ses *ses, void **request_buf)
381 struct smb_hdr *buffer;
383 rc = small_smb_init(smb_command, wct, NULL, request_buf);
387 buffer = (struct smb_hdr *)*request_buf;
388 buffer->Mid = get_next_mid(ses->server);
389 if (ses->capabilities & CAP_UNICODE)
390 buffer->Flags2 |= SMBFLG2_UNICODE;
391 if (ses->capabilities & CAP_STATUS32)
392 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
394 /* uid, tid can stay at zero as set in header assemble */
396 /* BB add support for turning on the signing when
397 this function is used after 1st of session setup requests */
402 /* If the return code is zero, this function must fill in request_buf pointer */
404 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
405 void **request_buf, void **response_buf)
407 *request_buf = cifs_buf_get();
408 if (*request_buf == NULL) {
409 /* BB should we add a retry in here if not a writepage? */
412 /* Although the original thought was we needed the response buf for */
413 /* potential retries of smb operations it turns out we can determine */
414 /* from the mid flags when the request buffer can be resent without */
415 /* having to use a second distinct buffer for the response */
417 *response_buf = *request_buf;
419 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
423 cifs_stats_inc(&tcon->num_smbs_sent);
428 /* If the return code is zero, this function must fill in request_buf pointer */
430 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
431 void **request_buf, void **response_buf)
435 rc = cifs_reconnect_tcon(tcon, smb_command);
439 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
443 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
444 void **request_buf, void **response_buf)
446 if (tcon->ses->need_reconnect || tcon->need_reconnect)
449 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
452 static int validate_t2(struct smb_t2_rsp *pSMB)
454 unsigned int total_size;
456 /* check for plausible wct */
457 if (pSMB->hdr.WordCount < 10)
460 /* check for parm and data offset going beyond end of smb */
461 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
462 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
465 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
466 if (total_size >= 512)
469 /* check that bcc is at least as big as parms + data, and that it is
470 * less than negotiated smb buffer
472 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
473 if (total_size > get_bcc(&pSMB->hdr) ||
474 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
479 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
480 sizeof(struct smb_t2_rsp) + 16);
485 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
489 char *guid = pSMBr->u.extended_response.GUID;
490 struct TCP_Server_Info *server = ses->server;
492 count = get_bcc(&pSMBr->hdr);
493 if (count < SMB1_CLIENT_GUID_SIZE)
496 spin_lock(&cifs_tcp_ses_lock);
497 if (server->srv_count > 1) {
498 spin_unlock(&cifs_tcp_ses_lock);
499 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
500 cifs_dbg(FYI, "server UID changed\n");
501 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
504 spin_unlock(&cifs_tcp_ses_lock);
505 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
508 if (count == SMB1_CLIENT_GUID_SIZE) {
509 server->sec_ntlmssp = true;
511 count -= SMB1_CLIENT_GUID_SIZE;
512 rc = decode_negTokenInit(
513 pSMBr->u.extended_response.SecurityBlob, count, server);
522 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
524 bool srv_sign_required = server->sec_mode & server->vals->signing_required;
525 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
526 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
529 * Is signing required by mnt options? If not then check
530 * global_secflags to see if it is there.
532 if (!mnt_sign_required)
533 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
537 * If signing is required then it's automatically enabled too,
538 * otherwise, check to see if the secflags allow it.
540 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
541 (global_secflags & CIFSSEC_MAY_SIGN);
543 /* If server requires signing, does client allow it? */
544 if (srv_sign_required) {
545 if (!mnt_sign_enabled) {
546 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!");
552 /* If client requires signing, does server allow it? */
553 if (mnt_sign_required) {
554 if (!srv_sign_enabled) {
555 cifs_dbg(VFS, "Server does not support signing!");
561 if (cifs_rdma_enabled(server) && server->sign)
562 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled");
567 #ifdef CONFIG_CIFS_WEAK_PW_HASH
569 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
572 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
574 if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
577 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
578 server->maxReq = min_t(unsigned int,
579 le16_to_cpu(rsp->MaxMpxCount),
581 set_credits(server, server->maxReq);
582 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
583 /* even though we do not use raw we might as well set this
584 accurately, in case we ever find a need for it */
585 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
586 server->max_rw = 0xFF00;
587 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
589 server->max_rw = 0;/* do not need to use raw anyway */
590 server->capabilities = CAP_MPX_MODE;
592 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
594 /* OS/2 often does not set timezone therefore
595 * we must use server time to calc time zone.
596 * Could deviate slightly from the right zone.
597 * Smallest defined timezone difference is 15 minutes
598 * (i.e. Nepal). Rounding up/down is done to match
601 int val, seconds, remain, result;
602 struct timespec64 ts;
603 time64_t utc = ktime_get_real_seconds();
604 ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
605 rsp->SrvTime.Time, 0);
606 cifs_dbg(FYI, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
609 val = (int)(utc - ts.tv_sec);
611 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
612 remain = seconds % MIN_TZ_ADJ;
613 if (remain >= (MIN_TZ_ADJ / 2))
614 result += MIN_TZ_ADJ;
617 server->timeAdj = result;
619 server->timeAdj = (int)tmp;
620 server->timeAdj *= 60; /* also in seconds */
622 cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
625 /* BB get server time for time conversions and add
626 code to use it and timezone since this is not UTC */
628 if (rsp->EncryptionKeyLength ==
629 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
630 memcpy(server->cryptkey, rsp->EncryptionKey,
631 CIFS_CRYPTO_KEY_SIZE);
632 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
633 return -EIO; /* need cryptkey unless plain text */
636 cifs_dbg(FYI, "LANMAN negotiated\n");
641 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
643 cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
649 should_set_ext_sec_flag(enum securityEnum sectype)
656 if (global_secflags &
657 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
666 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
669 NEGOTIATE_RSP *pSMBr;
673 struct TCP_Server_Info *server = ses->server;
677 WARN(1, "%s: server is NULL!\n", __func__);
681 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
682 (void **) &pSMB, (void **) &pSMBr);
686 pSMB->hdr.Mid = get_next_mid(server);
687 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
689 if (should_set_ext_sec_flag(ses->sectype)) {
690 cifs_dbg(FYI, "Requesting extended security.");
691 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
696 * We know that all the name entries in the protocols array
697 * are short (< 16 bytes anyway) and are NUL terminated.
699 for (i = 0; i < CIFS_NUM_PROT; i++) {
700 size_t len = strlen(protocols[i].name) + 1;
702 memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
705 inc_rfc1001_len(pSMB, count);
706 pSMB->ByteCount = cpu_to_le16(count);
708 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
709 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
713 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
714 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
715 /* Check wct = 1 error case */
716 if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
717 /* core returns wct = 1, but we do not ask for core - otherwise
718 small wct just comes when dialect index is -1 indicating we
719 could not negotiate a common dialect */
722 } else if (pSMBr->hdr.WordCount == 13) {
723 server->negflavor = CIFS_NEGFLAVOR_LANMAN;
724 rc = decode_lanman_negprot_rsp(server, pSMBr);
726 } else if (pSMBr->hdr.WordCount != 17) {
731 /* else wct == 17, NTLM or better */
733 server->sec_mode = pSMBr->SecurityMode;
734 if ((server->sec_mode & SECMODE_USER) == 0)
735 cifs_dbg(FYI, "share mode security\n");
737 /* one byte, so no need to convert this or EncryptionKeyLen from
739 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
741 set_credits(server, server->maxReq);
742 /* probably no need to store and check maxvcs */
743 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
744 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
745 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
746 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
747 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
748 server->timeAdj *= 60;
750 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
751 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
752 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
753 CIFS_CRYPTO_KEY_SIZE);
754 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
755 server->capabilities & CAP_EXTENDED_SECURITY) {
756 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
757 rc = decode_ext_sec_blob(ses, pSMBr);
758 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
759 rc = -EIO; /* no crypt key only if plain text pwd */
761 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
762 server->capabilities &= ~CAP_EXTENDED_SECURITY;
767 rc = cifs_enable_signing(server, ses->sign);
769 cifs_buf_release(pSMB);
771 cifs_dbg(FYI, "negprot rc %d\n", rc);
776 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
778 struct smb_hdr *smb_buffer;
781 cifs_dbg(FYI, "In tree disconnect\n");
783 /* BB: do we need to check this? These should never be NULL. */
784 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
788 * No need to return error on this operation if tid invalidated and
789 * closed on server already e.g. due to tcp session crashing. Also,
790 * the tcon is no longer on the list, so no need to take lock before
793 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
796 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
797 (void **)&smb_buffer);
801 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
802 cifs_small_buf_release(smb_buffer);
804 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
806 /* No need to return error on this operation if tid invalidated and
807 closed on server already e.g. due to tcp session crashing */
815 * This is a no-op for now. We're not really interested in the reply, but
816 * rather in the fact that the server sent one and that server->lstrp
819 * FIXME: maybe we should consider checking that the reply matches request?
822 cifs_echo_callback(struct mid_q_entry *mid)
824 struct TCP_Server_Info *server = mid->callback_data;
825 struct cifs_credits credits = { .value = 1, .instance = 0 };
827 DeleteMidQEntry(mid);
828 add_credits(server, &credits, CIFS_ECHO_OP);
832 CIFSSMBEcho(struct TCP_Server_Info *server)
837 struct smb_rqst rqst = { .rq_iov = iov,
840 cifs_dbg(FYI, "In echo request\n");
842 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
846 if (server->capabilities & CAP_UNICODE)
847 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
849 /* set up echo request */
850 smb->hdr.Tid = 0xffff;
851 smb->hdr.WordCount = 1;
852 put_unaligned_le16(1, &smb->EchoCount);
853 put_bcc(1, &smb->hdr);
855 inc_rfc1001_len(smb, 3);
858 iov[0].iov_base = smb;
859 iov[1].iov_len = get_rfc1002_length(smb);
860 iov[1].iov_base = (char *)smb + 4;
862 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
863 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
865 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
867 cifs_small_buf_release(smb);
873 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
875 LOGOFF_ANDX_REQ *pSMB;
878 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
881 * BB: do we need to check validity of ses and server? They should
882 * always be valid since we have an active reference. If not, that
883 * should probably be a BUG()
885 if (!ses || !ses->server)
888 mutex_lock(&ses->session_mutex);
889 if (ses->need_reconnect)
890 goto session_already_dead; /* no need to send SMBlogoff if uid
891 already closed due to reconnect */
892 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
894 mutex_unlock(&ses->session_mutex);
898 pSMB->hdr.Mid = get_next_mid(ses->server);
900 if (ses->server->sign)
901 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
903 pSMB->hdr.Uid = ses->Suid;
905 pSMB->AndXCommand = 0xFF;
906 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
907 cifs_small_buf_release(pSMB);
908 session_already_dead:
909 mutex_unlock(&ses->session_mutex);
911 /* if session dead then we do not need to do ulogoff,
912 since server closed smb session, no sense reporting
920 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
921 const char *fileName, __u16 type,
922 const struct nls_table *nls_codepage, int remap)
924 TRANSACTION2_SPI_REQ *pSMB = NULL;
925 TRANSACTION2_SPI_RSP *pSMBr = NULL;
926 struct unlink_psx_rq *pRqD;
929 int bytes_returned = 0;
930 __u16 params, param_offset, offset, byte_count;
932 cifs_dbg(FYI, "In POSIX delete\n");
934 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
939 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
941 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
942 PATH_MAX, nls_codepage, remap);
943 name_len++; /* trailing null */
946 name_len = copy_path_name(pSMB->FileName, fileName);
949 params = 6 + name_len;
950 pSMB->MaxParameterCount = cpu_to_le16(2);
951 pSMB->MaxDataCount = 0; /* BB double check this with jra */
952 pSMB->MaxSetupCount = 0;
957 param_offset = offsetof(struct smb_com_transaction2_spi_req,
958 InformationLevel) - 4;
959 offset = param_offset + params;
961 /* Setup pointer to Request Data (inode type) */
962 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
963 pRqD->type = cpu_to_le16(type);
964 pSMB->ParameterOffset = cpu_to_le16(param_offset);
965 pSMB->DataOffset = cpu_to_le16(offset);
966 pSMB->SetupCount = 1;
968 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
969 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
971 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
972 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
973 pSMB->ParameterCount = cpu_to_le16(params);
974 pSMB->TotalParameterCount = pSMB->ParameterCount;
975 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
977 inc_rfc1001_len(pSMB, byte_count);
978 pSMB->ByteCount = cpu_to_le16(byte_count);
979 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
980 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
982 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
983 cifs_buf_release(pSMB);
985 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
994 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
995 struct cifs_sb_info *cifs_sb)
997 DELETE_FILE_REQ *pSMB = NULL;
998 DELETE_FILE_RSP *pSMBr = NULL;
1002 int remap = cifs_remap(cifs_sb);
1005 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
1010 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1011 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
1012 PATH_MAX, cifs_sb->local_nls,
1014 name_len++; /* trailing null */
1017 name_len = copy_path_name(pSMB->fileName, name);
1019 pSMB->SearchAttributes =
1020 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
1021 pSMB->BufferFormat = 0x04;
1022 inc_rfc1001_len(pSMB, name_len + 1);
1023 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1024 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1025 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1026 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
1028 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
1030 cifs_buf_release(pSMB);
1038 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
1039 struct cifs_sb_info *cifs_sb)
1041 DELETE_DIRECTORY_REQ *pSMB = NULL;
1042 DELETE_DIRECTORY_RSP *pSMBr = NULL;
1046 int remap = cifs_remap(cifs_sb);
1048 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
1050 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
1055 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1056 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1057 PATH_MAX, cifs_sb->local_nls,
1059 name_len++; /* trailing null */
1062 name_len = copy_path_name(pSMB->DirName, name);
1065 pSMB->BufferFormat = 0x04;
1066 inc_rfc1001_len(pSMB, name_len + 1);
1067 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1068 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1069 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1070 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
1072 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
1074 cifs_buf_release(pSMB);
1081 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
1082 struct cifs_tcon *tcon, const char *name,
1083 struct cifs_sb_info *cifs_sb)
1086 CREATE_DIRECTORY_REQ *pSMB = NULL;
1087 CREATE_DIRECTORY_RSP *pSMBr = NULL;
1090 int remap = cifs_remap(cifs_sb);
1092 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
1094 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
1099 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1100 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1101 PATH_MAX, cifs_sb->local_nls,
1103 name_len++; /* trailing null */
1106 name_len = copy_path_name(pSMB->DirName, name);
1109 pSMB->BufferFormat = 0x04;
1110 inc_rfc1001_len(pSMB, name_len + 1);
1111 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1112 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1113 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1114 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1116 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
1118 cifs_buf_release(pSMB);
1125 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1126 __u32 posix_flags, __u64 mode, __u16 *netfid,
1127 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1128 const char *name, const struct nls_table *nls_codepage,
1131 TRANSACTION2_SPI_REQ *pSMB = NULL;
1132 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1135 int bytes_returned = 0;
1136 __u16 params, param_offset, offset, byte_count, count;
1137 OPEN_PSX_REQ *pdata;
1138 OPEN_PSX_RSP *psx_rsp;
1140 cifs_dbg(FYI, "In POSIX Create\n");
1142 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1147 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1149 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1150 PATH_MAX, nls_codepage, remap);
1151 name_len++; /* trailing null */
1154 name_len = copy_path_name(pSMB->FileName, name);
1157 params = 6 + name_len;
1158 count = sizeof(OPEN_PSX_REQ);
1159 pSMB->MaxParameterCount = cpu_to_le16(2);
1160 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1161 pSMB->MaxSetupCount = 0;
1165 pSMB->Reserved2 = 0;
1166 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1167 InformationLevel) - 4;
1168 offset = param_offset + params;
1169 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1170 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1171 pdata->Permissions = cpu_to_le64(mode);
1172 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1173 pdata->OpenFlags = cpu_to_le32(*pOplock);
1174 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1175 pSMB->DataOffset = cpu_to_le16(offset);
1176 pSMB->SetupCount = 1;
1177 pSMB->Reserved3 = 0;
1178 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1179 byte_count = 3 /* pad */ + params + count;
1181 pSMB->DataCount = cpu_to_le16(count);
1182 pSMB->ParameterCount = cpu_to_le16(params);
1183 pSMB->TotalDataCount = pSMB->DataCount;
1184 pSMB->TotalParameterCount = pSMB->ParameterCount;
1185 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1186 pSMB->Reserved4 = 0;
1187 inc_rfc1001_len(pSMB, byte_count);
1188 pSMB->ByteCount = cpu_to_le16(byte_count);
1189 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1190 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1192 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1193 goto psx_create_err;
1196 cifs_dbg(FYI, "copying inode info\n");
1197 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1199 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1200 rc = -EIO; /* bad smb */
1201 goto psx_create_err;
1204 /* copy return information to pRetData */
1205 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1206 + le16_to_cpu(pSMBr->t2.DataOffset));
1208 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1210 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1211 /* Let caller know file was created so we can set the mode. */
1212 /* Do we care about the CreateAction in any other cases? */
1213 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1214 *pOplock |= CIFS_CREATE_ACTION;
1215 /* check to make sure response data is there */
1216 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1217 pRetData->Type = cpu_to_le32(-1); /* unknown */
1218 cifs_dbg(NOISY, "unknown type\n");
1220 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1221 + sizeof(FILE_UNIX_BASIC_INFO)) {
1222 cifs_dbg(VFS, "Open response data too small\n");
1223 pRetData->Type = cpu_to_le32(-1);
1224 goto psx_create_err;
1226 memcpy((char *) pRetData,
1227 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1228 sizeof(FILE_UNIX_BASIC_INFO));
1232 cifs_buf_release(pSMB);
1234 if (posix_flags & SMB_O_DIRECTORY)
1235 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1237 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1245 static __u16 convert_disposition(int disposition)
1249 switch (disposition) {
1250 case FILE_SUPERSEDE:
1251 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1254 ofun = SMBOPEN_OAPPEND;
1257 ofun = SMBOPEN_OCREATE;
1260 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1262 case FILE_OVERWRITE:
1263 ofun = SMBOPEN_OTRUNC;
1265 case FILE_OVERWRITE_IF:
1266 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1269 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1270 ofun = SMBOPEN_OAPPEND; /* regular open */
1276 access_flags_to_smbopen_mode(const int access_flags)
1278 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1280 if (masked_flags == GENERIC_READ)
1281 return SMBOPEN_READ;
1282 else if (masked_flags == GENERIC_WRITE)
1283 return SMBOPEN_WRITE;
1285 /* just go for read/write */
1286 return SMBOPEN_READWRITE;
1290 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1291 const char *fileName, const int openDisposition,
1292 const int access_flags, const int create_options, __u16 *netfid,
1293 int *pOplock, FILE_ALL_INFO *pfile_info,
1294 const struct nls_table *nls_codepage, int remap)
1297 OPENX_REQ *pSMB = NULL;
1298 OPENX_RSP *pSMBr = NULL;
1304 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1309 pSMB->AndXCommand = 0xFF; /* none */
1311 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1312 count = 1; /* account for one byte pad to word boundary */
1314 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1315 fileName, PATH_MAX, nls_codepage, remap);
1316 name_len++; /* trailing null */
1319 count = 0; /* no pad */
1320 name_len = copy_path_name(pSMB->fileName, fileName);
1322 if (*pOplock & REQ_OPLOCK)
1323 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1324 else if (*pOplock & REQ_BATCHOPLOCK)
1325 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1327 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1328 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1329 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1330 /* set file as system file if special file such
1331 as fifo and server expecting SFU style and
1332 no Unix extensions */
1334 if (create_options & CREATE_OPTION_SPECIAL)
1335 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1336 else /* BB FIXME BB */
1337 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1339 if (create_options & CREATE_OPTION_READONLY)
1340 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1343 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1344 CREATE_OPTIONS_MASK); */
1345 /* BB FIXME END BB */
1347 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1348 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1350 inc_rfc1001_len(pSMB, count);
1352 pSMB->ByteCount = cpu_to_le16(count);
1353 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1354 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1355 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1357 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1359 /* BB verify if wct == 15 */
1361 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1363 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1364 /* Let caller know file was created so we can set the mode. */
1365 /* Do we care about the CreateAction in any other cases? */
1367 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1368 *pOplock |= CIFS_CREATE_ACTION; */
1372 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1373 pfile_info->LastAccessTime = 0; /* BB fixme */
1374 pfile_info->LastWriteTime = 0; /* BB fixme */
1375 pfile_info->ChangeTime = 0; /* BB fixme */
1376 pfile_info->Attributes =
1377 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1378 /* the file_info buf is endian converted by caller */
1379 pfile_info->AllocationSize =
1380 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1381 pfile_info->EndOfFile = pfile_info->AllocationSize;
1382 pfile_info->NumberOfLinks = cpu_to_le32(1);
1383 pfile_info->DeletePending = 0;
1387 cifs_buf_release(pSMB);
1394 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1398 OPEN_REQ *req = NULL;
1399 OPEN_RSP *rsp = NULL;
1403 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1404 struct cifs_tcon *tcon = oparms->tcon;
1405 int remap = cifs_remap(cifs_sb);
1406 const struct nls_table *nls = cifs_sb->local_nls;
1407 int create_options = oparms->create_options;
1408 int desired_access = oparms->desired_access;
1409 int disposition = oparms->disposition;
1410 const char *path = oparms->path;
1413 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1418 /* no commands go after this */
1419 req->AndXCommand = 0xFF;
1421 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1422 /* account for one byte pad to word boundary */
1424 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1425 path, PATH_MAX, nls, remap);
1429 req->NameLength = cpu_to_le16(name_len);
1431 /* BB improve check for buffer overruns BB */
1434 name_len = copy_path_name(req->fileName, path);
1435 req->NameLength = cpu_to_le16(name_len);
1438 if (*oplock & REQ_OPLOCK)
1439 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1440 else if (*oplock & REQ_BATCHOPLOCK)
1441 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1443 req->DesiredAccess = cpu_to_le32(desired_access);
1444 req->AllocationSize = 0;
1447 * Set file as system file if special file such as fifo and server
1448 * expecting SFU style and no Unix extensions.
1450 if (create_options & CREATE_OPTION_SPECIAL)
1451 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1453 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1456 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1457 * sensitive checks for other servers such as Samba.
1459 if (tcon->ses->capabilities & CAP_UNIX)
1460 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1462 if (create_options & CREATE_OPTION_READONLY)
1463 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1465 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1466 req->CreateDisposition = cpu_to_le32(disposition);
1467 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1469 /* BB Expirement with various impersonation levels and verify */
1470 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1471 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1474 inc_rfc1001_len(req, count);
1476 req->ByteCount = cpu_to_le16(count);
1477 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1478 (struct smb_hdr *)rsp, &bytes_returned, 0);
1479 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1481 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1482 cifs_buf_release(req);
1488 /* 1 byte no need to le_to_cpu */
1489 *oplock = rsp->OplockLevel;
1490 /* cifs fid stays in le */
1491 oparms->fid->netfid = rsp->Fid;
1492 oparms->fid->access = desired_access;
1494 /* Let caller know file was created so we can set the mode. */
1495 /* Do we care about the CreateAction in any other cases? */
1496 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1497 *oplock |= CIFS_CREATE_ACTION;
1500 /* copy from CreationTime to Attributes */
1501 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1502 /* the file_info buf is endian converted by caller */
1503 buf->AllocationSize = rsp->AllocationSize;
1504 buf->EndOfFile = rsp->EndOfFile;
1505 buf->NumberOfLinks = cpu_to_le32(1);
1506 buf->DeletePending = 0;
1509 cifs_buf_release(req);
1514 * Discard any remaining data in the current SMB. To do this, we borrow the
1518 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1520 unsigned int rfclen = server->pdu_size;
1521 int remaining = rfclen + server->vals->header_preamble_size -
1524 while (remaining > 0) {
1527 length = cifs_read_from_socket(server, server->bigbuf,
1528 min_t(unsigned int, remaining,
1529 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1532 server->total_read += length;
1533 remaining -= length;
1540 __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
1545 length = cifs_discard_remaining_data(server);
1546 dequeue_mid(mid, malformed);
1547 mid->resp_buf = server->smallbuf;
1548 server->smallbuf = NULL;
1553 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1555 struct cifs_readdata *rdata = mid->callback_data;
1557 return __cifs_readv_discard(server, mid, rdata->result);
1561 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1564 unsigned int data_offset, data_len;
1565 struct cifs_readdata *rdata = mid->callback_data;
1566 char *buf = server->smallbuf;
1567 unsigned int buflen = server->pdu_size +
1568 server->vals->header_preamble_size;
1569 bool use_rdma_mr = false;
1571 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1572 __func__, mid->mid, rdata->offset, rdata->bytes);
1575 * read the rest of READ_RSP header (sans Data array), or whatever we
1576 * can if there's not enough data. At this point, we've read down to
1579 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1580 HEADER_SIZE(server) + 1;
1582 length = cifs_read_from_socket(server,
1583 buf + HEADER_SIZE(server) - 1, len);
1586 server->total_read += length;
1588 if (server->ops->is_session_expired &&
1589 server->ops->is_session_expired(buf)) {
1590 cifs_reconnect(server);
1591 wake_up(&server->response_q);
1595 if (server->ops->is_status_pending &&
1596 server->ops->is_status_pending(buf, server)) {
1597 cifs_discard_remaining_data(server);
1601 /* set up first two iov for signature check and to get credits */
1602 rdata->iov[0].iov_base = buf;
1603 rdata->iov[0].iov_len = server->vals->header_preamble_size;
1604 rdata->iov[1].iov_base = buf + server->vals->header_preamble_size;
1605 rdata->iov[1].iov_len =
1606 server->total_read - server->vals->header_preamble_size;
1607 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1608 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1609 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
1610 rdata->iov[1].iov_base, rdata->iov[1].iov_len);
1612 /* Was the SMB read successful? */
1613 rdata->result = server->ops->map_error(buf, false);
1614 if (rdata->result != 0) {
1615 cifs_dbg(FYI, "%s: server returned error %d\n",
1616 __func__, rdata->result);
1617 /* normal error on read response */
1618 return __cifs_readv_discard(server, mid, false);
1621 /* Is there enough to get to the rest of the READ_RSP header? */
1622 if (server->total_read < server->vals->read_rsp_size) {
1623 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1624 __func__, server->total_read,
1625 server->vals->read_rsp_size);
1626 rdata->result = -EIO;
1627 return cifs_readv_discard(server, mid);
1630 data_offset = server->ops->read_data_offset(buf) +
1631 server->vals->header_preamble_size;
1632 if (data_offset < server->total_read) {
1634 * win2k8 sometimes sends an offset of 0 when the read
1635 * is beyond the EOF. Treat it as if the data starts just after
1638 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1639 __func__, data_offset);
1640 data_offset = server->total_read;
1641 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1642 /* data_offset is beyond the end of smallbuf */
1643 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1644 __func__, data_offset);
1645 rdata->result = -EIO;
1646 return cifs_readv_discard(server, mid);
1649 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1650 __func__, server->total_read, data_offset);
1652 len = data_offset - server->total_read;
1654 /* read any junk before data into the rest of smallbuf */
1655 length = cifs_read_from_socket(server,
1656 buf + server->total_read, len);
1659 server->total_read += length;
1662 /* how much data is in the response? */
1663 #ifdef CONFIG_CIFS_SMB_DIRECT
1664 use_rdma_mr = rdata->mr;
1666 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1667 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1668 /* data_len is corrupt -- discard frame */
1669 rdata->result = -EIO;
1670 return cifs_readv_discard(server, mid);
1673 length = rdata->read_into_pages(server, rdata, data_len);
1677 server->total_read += length;
1679 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1680 server->total_read, buflen, data_len);
1682 /* discard anything left over */
1683 if (server->total_read < buflen)
1684 return cifs_readv_discard(server, mid);
1686 dequeue_mid(mid, false);
1687 mid->resp_buf = server->smallbuf;
1688 server->smallbuf = NULL;
1693 cifs_readv_callback(struct mid_q_entry *mid)
1695 struct cifs_readdata *rdata = mid->callback_data;
1696 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1697 struct TCP_Server_Info *server = tcon->ses->server;
1698 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1700 .rq_pages = rdata->pages,
1701 .rq_offset = rdata->page_offset,
1702 .rq_npages = rdata->nr_pages,
1703 .rq_pagesz = rdata->pagesz,
1704 .rq_tailsz = rdata->tailsz };
1705 struct cifs_credits credits = { .value = 1, .instance = 0 };
1707 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1708 __func__, mid->mid, mid->mid_state, rdata->result,
1711 switch (mid->mid_state) {
1712 case MID_RESPONSE_RECEIVED:
1713 /* result already set, check signature */
1717 rc = cifs_verify_signature(&rqst, server,
1718 mid->sequence_number);
1720 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1723 /* FIXME: should this be counted toward the initiating task? */
1724 task_io_account_read(rdata->got_bytes);
1725 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1727 case MID_REQUEST_SUBMITTED:
1728 case MID_RETRY_NEEDED:
1729 rdata->result = -EAGAIN;
1730 if (server->sign && rdata->got_bytes)
1731 /* reset bytes number since we can not check a sign */
1732 rdata->got_bytes = 0;
1733 /* FIXME: should this be counted toward the initiating task? */
1734 task_io_account_read(rdata->got_bytes);
1735 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1738 rdata->result = -EIO;
1741 queue_work(cifsiod_wq, &rdata->work);
1742 DeleteMidQEntry(mid);
1743 add_credits(server, &credits, 0);
1746 /* cifs_async_readv - send an async write, and set up mid to handle result */
1748 cifs_async_readv(struct cifs_readdata *rdata)
1751 READ_REQ *smb = NULL;
1753 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1754 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1757 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1758 __func__, rdata->offset, rdata->bytes);
1760 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1763 wct = 10; /* old style read */
1764 if ((rdata->offset >> 32) > 0) {
1765 /* can not handle this big offset for old */
1770 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1774 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1775 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1777 smb->AndXCommand = 0xFF; /* none */
1778 smb->Fid = rdata->cfile->fid.netfid;
1779 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1781 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1783 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1784 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1788 /* old style read */
1789 struct smb_com_readx_req *smbr =
1790 (struct smb_com_readx_req *)smb;
1791 smbr->ByteCount = 0;
1794 /* 4 for RFC1001 length + 1 for BCC */
1795 rdata->iov[0].iov_base = smb;
1796 rdata->iov[0].iov_len = 4;
1797 rdata->iov[1].iov_base = (char *)smb + 4;
1798 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1800 kref_get(&rdata->refcount);
1801 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1802 cifs_readv_callback, NULL, rdata, 0, NULL);
1805 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1807 kref_put(&rdata->refcount, cifs_readdata_release);
1809 cifs_small_buf_release(smb);
1814 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1815 unsigned int *nbytes, char **buf, int *pbuf_type)
1818 READ_REQ *pSMB = NULL;
1819 READ_RSP *pSMBr = NULL;
1820 char *pReadData = NULL;
1822 int resp_buf_type = 0;
1824 struct kvec rsp_iov;
1825 __u32 pid = io_parms->pid;
1826 __u16 netfid = io_parms->netfid;
1827 __u64 offset = io_parms->offset;
1828 struct cifs_tcon *tcon = io_parms->tcon;
1829 unsigned int count = io_parms->length;
1831 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1832 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1835 wct = 10; /* old style read */
1836 if ((offset >> 32) > 0) {
1837 /* can not handle this big offset for old */
1843 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1847 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1848 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1850 /* tcon and ses pointer are checked in smb_init */
1851 if (tcon->ses->server == NULL)
1852 return -ECONNABORTED;
1854 pSMB->AndXCommand = 0xFF; /* none */
1856 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1858 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1860 pSMB->Remaining = 0;
1861 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1862 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1864 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1866 /* old style read */
1867 struct smb_com_readx_req *pSMBW =
1868 (struct smb_com_readx_req *)pSMB;
1869 pSMBW->ByteCount = 0;
1872 iov[0].iov_base = (char *)pSMB;
1873 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1874 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1875 CIFS_LOG_ERROR, &rsp_iov);
1876 cifs_small_buf_release(pSMB);
1877 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1878 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1880 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1882 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1883 data_length = data_length << 16;
1884 data_length += le16_to_cpu(pSMBr->DataLength);
1885 *nbytes = data_length;
1887 /*check that DataLength would not go beyond end of SMB */
1888 if ((data_length > CIFSMaxBufSize)
1889 || (data_length > count)) {
1890 cifs_dbg(FYI, "bad length %d for count %d\n",
1891 data_length, count);
1895 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1896 le16_to_cpu(pSMBr->DataOffset);
1897 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1898 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1900 }*/ /* can not use copy_to_user when using page cache*/
1902 memcpy(*buf, pReadData, data_length);
1907 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1908 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1909 /* return buffer to caller to free */
1910 *buf = rsp_iov.iov_base;
1911 if (resp_buf_type == CIFS_SMALL_BUFFER)
1912 *pbuf_type = CIFS_SMALL_BUFFER;
1913 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1914 *pbuf_type = CIFS_LARGE_BUFFER;
1915 } /* else no valid buffer on return - leave as null */
1917 /* Note: On -EAGAIN error only caller can retry on handle based calls
1918 since file handle passed in no longer valid */
1924 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1925 unsigned int *nbytes, const char *buf)
1928 WRITE_REQ *pSMB = NULL;
1929 WRITE_RSP *pSMBr = NULL;
1930 int bytes_returned, wct;
1933 __u32 pid = io_parms->pid;
1934 __u16 netfid = io_parms->netfid;
1935 __u64 offset = io_parms->offset;
1936 struct cifs_tcon *tcon = io_parms->tcon;
1937 unsigned int count = io_parms->length;
1941 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1942 if (tcon->ses == NULL)
1943 return -ECONNABORTED;
1945 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1949 if ((offset >> 32) > 0) {
1950 /* can not handle big offset for old srv */
1955 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1960 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1961 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1963 /* tcon and ses pointer are checked in smb_init */
1964 if (tcon->ses->server == NULL)
1965 return -ECONNABORTED;
1967 pSMB->AndXCommand = 0xFF; /* none */
1969 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1971 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1973 pSMB->Reserved = 0xFFFFFFFF;
1974 pSMB->WriteMode = 0;
1975 pSMB->Remaining = 0;
1977 /* Can increase buffer size if buffer is big enough in some cases ie we
1978 can send more if LARGE_WRITE_X capability returned by the server and if
1979 our buffer is big enough or if we convert to iovecs on socket writes
1980 and eliminate the copy to the CIFS buffer */
1981 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1982 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1984 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1988 if (bytes_sent > count)
1991 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1993 memcpy(pSMB->Data, buf, bytes_sent);
1994 else if (count != 0) {
1996 cifs_buf_release(pSMB);
1998 } /* else setting file size with write of zero bytes */
2000 byte_count = bytes_sent + 1; /* pad */
2001 else /* wct == 12 */
2002 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
2004 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
2005 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
2006 inc_rfc1001_len(pSMB, byte_count);
2009 pSMB->ByteCount = cpu_to_le16(byte_count);
2010 else { /* old style write has byte count 4 bytes earlier
2012 struct smb_com_writex_req *pSMBW =
2013 (struct smb_com_writex_req *)pSMB;
2014 pSMBW->ByteCount = cpu_to_le16(byte_count);
2017 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2018 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2019 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2021 cifs_dbg(FYI, "Send error in write = %d\n", rc);
2023 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2024 *nbytes = (*nbytes) << 16;
2025 *nbytes += le16_to_cpu(pSMBr->Count);
2028 * Mask off high 16 bits when bytes written as returned by the
2029 * server is greater than bytes requested by the client. Some
2030 * OS/2 servers are known to set incorrect CountHigh values.
2032 if (*nbytes > count)
2036 cifs_buf_release(pSMB);
2038 /* Note: On -EAGAIN error only caller can retry on handle based calls
2039 since file handle passed in no longer valid */
2045 cifs_writedata_release(struct kref *refcount)
2047 struct cifs_writedata *wdata = container_of(refcount,
2048 struct cifs_writedata, refcount);
2049 #ifdef CONFIG_CIFS_SMB_DIRECT
2051 smbd_deregister_mr(wdata->mr);
2057 cifsFileInfo_put(wdata->cfile);
2059 kvfree(wdata->pages);
2064 * Write failed with a retryable error. Resend the write request. It's also
2065 * possible that the page was redirtied so re-clean the page.
2068 cifs_writev_requeue(struct cifs_writedata *wdata)
2071 struct inode *inode = d_inode(wdata->cfile->dentry);
2072 struct TCP_Server_Info *server;
2073 unsigned int rest_len;
2075 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
2077 rest_len = wdata->bytes;
2079 struct cifs_writedata *wdata2;
2080 unsigned int j, nr_pages, wsize, tailsz, cur_len;
2082 wsize = server->ops->wp_retry_size(inode);
2083 if (wsize < rest_len) {
2084 nr_pages = wsize / PAGE_SIZE;
2089 cur_len = nr_pages * PAGE_SIZE;
2092 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
2094 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
2097 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
2103 for (j = 0; j < nr_pages; j++) {
2104 wdata2->pages[j] = wdata->pages[i + j];
2105 lock_page(wdata2->pages[j]);
2106 clear_page_dirty_for_io(wdata2->pages[j]);
2109 wdata2->sync_mode = wdata->sync_mode;
2110 wdata2->nr_pages = nr_pages;
2111 wdata2->offset = page_offset(wdata2->pages[0]);
2112 wdata2->pagesz = PAGE_SIZE;
2113 wdata2->tailsz = tailsz;
2114 wdata2->bytes = cur_len;
2116 rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
2118 if (!wdata2->cfile) {
2119 cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
2121 if (!is_retryable_error(rc))
2124 wdata2->pid = wdata2->cfile->pid;
2125 rc = server->ops->async_writev(wdata2,
2126 cifs_writedata_release);
2129 for (j = 0; j < nr_pages; j++) {
2130 unlock_page(wdata2->pages[j]);
2131 if (rc != 0 && !is_retryable_error(rc)) {
2132 SetPageError(wdata2->pages[j]);
2133 end_page_writeback(wdata2->pages[j]);
2134 put_page(wdata2->pages[j]);
2138 kref_put(&wdata2->refcount, cifs_writedata_release);
2140 if (is_retryable_error(rc))
2146 rest_len -= cur_len;
2148 } while (i < wdata->nr_pages);
2150 /* cleanup remaining pages from the original wdata */
2151 for (; i < wdata->nr_pages; i++) {
2152 SetPageError(wdata->pages[i]);
2153 end_page_writeback(wdata->pages[i]);
2154 put_page(wdata->pages[i]);
2157 if (rc != 0 && !is_retryable_error(rc))
2158 mapping_set_error(inode->i_mapping, rc);
2159 kref_put(&wdata->refcount, cifs_writedata_release);
2163 cifs_writev_complete(struct work_struct *work)
2165 struct cifs_writedata *wdata = container_of(work,
2166 struct cifs_writedata, work);
2167 struct inode *inode = d_inode(wdata->cfile->dentry);
2170 if (wdata->result == 0) {
2171 spin_lock(&inode->i_lock);
2172 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2173 spin_unlock(&inode->i_lock);
2174 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2176 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2177 return cifs_writev_requeue(wdata);
2179 for (i = 0; i < wdata->nr_pages; i++) {
2180 struct page *page = wdata->pages[i];
2181 if (wdata->result == -EAGAIN)
2182 __set_page_dirty_nobuffers(page);
2183 else if (wdata->result < 0)
2185 end_page_writeback(page);
2188 if (wdata->result != -EAGAIN)
2189 mapping_set_error(inode->i_mapping, wdata->result);
2190 kref_put(&wdata->refcount, cifs_writedata_release);
2193 struct cifs_writedata *
2194 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2196 struct page **pages =
2197 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2199 return cifs_writedata_direct_alloc(pages, complete);
2204 struct cifs_writedata *
2205 cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2207 struct cifs_writedata *wdata;
2209 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2210 if (wdata != NULL) {
2211 wdata->pages = pages;
2212 kref_init(&wdata->refcount);
2213 INIT_LIST_HEAD(&wdata->list);
2214 init_completion(&wdata->done);
2215 INIT_WORK(&wdata->work, complete);
2221 * Check the mid_state and signature on received buffer (if any), and queue the
2222 * workqueue completion task.
2225 cifs_writev_callback(struct mid_q_entry *mid)
2227 struct cifs_writedata *wdata = mid->callback_data;
2228 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2229 unsigned int written;
2230 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2231 struct cifs_credits credits = { .value = 1, .instance = 0 };
2233 switch (mid->mid_state) {
2234 case MID_RESPONSE_RECEIVED:
2235 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2236 if (wdata->result != 0)
2239 written = le16_to_cpu(smb->CountHigh);
2241 written += le16_to_cpu(smb->Count);
2243 * Mask off high 16 bits when bytes written as returned
2244 * by the server is greater than bytes requested by the
2245 * client. OS/2 servers are known to set incorrect
2248 if (written > wdata->bytes)
2251 if (written < wdata->bytes)
2252 wdata->result = -ENOSPC;
2254 wdata->bytes = written;
2256 case MID_REQUEST_SUBMITTED:
2257 case MID_RETRY_NEEDED:
2258 wdata->result = -EAGAIN;
2261 wdata->result = -EIO;
2265 queue_work(cifsiod_wq, &wdata->work);
2266 DeleteMidQEntry(mid);
2267 add_credits(tcon->ses->server, &credits, 0);
2270 /* cifs_async_writev - send an async write, and set up mid to handle result */
2272 cifs_async_writev(struct cifs_writedata *wdata,
2273 void (*release)(struct kref *kref))
2276 WRITE_REQ *smb = NULL;
2278 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2280 struct smb_rqst rqst = { };
2282 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2286 if (wdata->offset >> 32 > 0) {
2287 /* can not handle big offset for old srv */
2292 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2294 goto async_writev_out;
2296 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2297 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2299 smb->AndXCommand = 0xFF; /* none */
2300 smb->Fid = wdata->cfile->fid.netfid;
2301 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2303 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2304 smb->Reserved = 0xFFFFFFFF;
2309 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2311 /* 4 for RFC1001 length + 1 for BCC */
2313 iov[0].iov_base = smb;
2314 iov[1].iov_len = get_rfc1002_length(smb) + 1;
2315 iov[1].iov_base = (char *)smb + 4;
2319 rqst.rq_pages = wdata->pages;
2320 rqst.rq_offset = wdata->page_offset;
2321 rqst.rq_npages = wdata->nr_pages;
2322 rqst.rq_pagesz = wdata->pagesz;
2323 rqst.rq_tailsz = wdata->tailsz;
2325 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2326 wdata->offset, wdata->bytes);
2328 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2329 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2332 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2333 put_bcc(wdata->bytes + 1, &smb->hdr);
2336 struct smb_com_writex_req *smbw =
2337 (struct smb_com_writex_req *)smb;
2338 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2339 put_bcc(wdata->bytes + 5, &smbw->hdr);
2340 iov[1].iov_len += 4; /* pad bigger by four bytes */
2343 kref_get(&wdata->refcount);
2344 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2345 cifs_writev_callback, NULL, wdata, 0, NULL);
2348 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2350 kref_put(&wdata->refcount, release);
2353 cifs_small_buf_release(smb);
2358 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2359 unsigned int *nbytes, struct kvec *iov, int n_vec)
2362 WRITE_REQ *pSMB = NULL;
2365 int resp_buf_type = 0;
2366 __u32 pid = io_parms->pid;
2367 __u16 netfid = io_parms->netfid;
2368 __u64 offset = io_parms->offset;
2369 struct cifs_tcon *tcon = io_parms->tcon;
2370 unsigned int count = io_parms->length;
2371 struct kvec rsp_iov;
2375 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2377 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2381 if ((offset >> 32) > 0) {
2382 /* can not handle big offset for old srv */
2386 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2390 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2391 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2393 /* tcon and ses pointer are checked in smb_init */
2394 if (tcon->ses->server == NULL)
2395 return -ECONNABORTED;
2397 pSMB->AndXCommand = 0xFF; /* none */
2399 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2401 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2402 pSMB->Reserved = 0xFFFFFFFF;
2403 pSMB->WriteMode = 0;
2404 pSMB->Remaining = 0;
2407 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2409 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2410 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2411 /* header + 1 byte pad */
2412 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2414 inc_rfc1001_len(pSMB, count + 1);
2415 else /* wct == 12 */
2416 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2418 pSMB->ByteCount = cpu_to_le16(count + 1);
2419 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2420 struct smb_com_writex_req *pSMBW =
2421 (struct smb_com_writex_req *)pSMB;
2422 pSMBW->ByteCount = cpu_to_le16(count + 5);
2424 iov[0].iov_base = pSMB;
2426 iov[0].iov_len = smb_hdr_len + 4;
2427 else /* wct == 12 pad bigger by four bytes */
2428 iov[0].iov_len = smb_hdr_len + 8;
2430 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2432 cifs_small_buf_release(pSMB);
2433 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2435 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2436 } else if (resp_buf_type == 0) {
2437 /* presumably this can not happen, but best to be safe */
2440 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2441 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2442 *nbytes = (*nbytes) << 16;
2443 *nbytes += le16_to_cpu(pSMBr->Count);
2446 * Mask off high 16 bits when bytes written as returned by the
2447 * server is greater than bytes requested by the client. OS/2
2448 * servers are known to set incorrect CountHigh values.
2450 if (*nbytes > count)
2454 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2456 /* Note: On -EAGAIN error only caller can retry on handle based calls
2457 since file handle passed in no longer valid */
2462 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2463 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2464 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2467 LOCK_REQ *pSMB = NULL;
2469 struct kvec rsp_iov;
2473 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2474 num_lock, num_unlock);
2476 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2481 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2482 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2483 pSMB->LockType = lock_type;
2484 pSMB->AndXCommand = 0xFF; /* none */
2485 pSMB->Fid = netfid; /* netfid stays le */
2487 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2488 inc_rfc1001_len(pSMB, count);
2489 pSMB->ByteCount = cpu_to_le16(count);
2491 iov[0].iov_base = (char *)pSMB;
2492 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2493 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2494 iov[1].iov_base = (char *)buf;
2495 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2497 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2498 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
2499 CIFS_NO_RSP_BUF, &rsp_iov);
2500 cifs_small_buf_release(pSMB);
2502 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2508 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2509 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2510 const __u64 offset, const __u32 numUnlock,
2511 const __u32 numLock, const __u8 lockType,
2512 const bool waitFlag, const __u8 oplock_level)
2515 LOCK_REQ *pSMB = NULL;
2516 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2521 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2522 (int)waitFlag, numLock);
2523 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2528 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2529 /* no response expected */
2530 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
2532 } else if (waitFlag) {
2533 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2534 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2539 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2540 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2541 pSMB->LockType = lockType;
2542 pSMB->OplockLevel = oplock_level;
2543 pSMB->AndXCommand = 0xFF; /* none */
2544 pSMB->Fid = smb_file_id; /* netfid stays le */
2546 if ((numLock != 0) || (numUnlock != 0)) {
2547 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2548 /* BB where to store pid high? */
2549 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2550 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2551 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2552 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2553 count = sizeof(LOCKING_ANDX_RANGE);
2558 inc_rfc1001_len(pSMB, count);
2559 pSMB->ByteCount = cpu_to_le16(count);
2562 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2563 (struct smb_hdr *) pSMB, &bytes_returned);
2565 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2566 cifs_small_buf_release(pSMB);
2567 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2569 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2571 /* Note: On -EAGAIN error only caller can retry on handle based calls
2572 since file handle passed in no longer valid */
2577 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2578 const __u16 smb_file_id, const __u32 netpid,
2579 const loff_t start_offset, const __u64 len,
2580 struct file_lock *pLockData, const __u16 lock_type,
2581 const bool waitFlag)
2583 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2584 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2585 struct cifs_posix_lock *parm_data;
2588 int bytes_returned = 0;
2589 int resp_buf_type = 0;
2590 __u16 params, param_offset, offset, byte_count, count;
2592 struct kvec rsp_iov;
2594 cifs_dbg(FYI, "Posix Lock\n");
2596 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2601 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2604 pSMB->MaxSetupCount = 0;
2607 pSMB->Reserved2 = 0;
2608 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2609 offset = param_offset + params;
2611 count = sizeof(struct cifs_posix_lock);
2612 pSMB->MaxParameterCount = cpu_to_le16(2);
2613 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2614 pSMB->SetupCount = 1;
2615 pSMB->Reserved3 = 0;
2617 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2619 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2620 byte_count = 3 /* pad */ + params + count;
2621 pSMB->DataCount = cpu_to_le16(count);
2622 pSMB->ParameterCount = cpu_to_le16(params);
2623 pSMB->TotalDataCount = pSMB->DataCount;
2624 pSMB->TotalParameterCount = pSMB->ParameterCount;
2625 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2626 parm_data = (struct cifs_posix_lock *)
2627 (((char *) &pSMB->hdr.Protocol) + offset);
2629 parm_data->lock_type = cpu_to_le16(lock_type);
2631 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2632 parm_data->lock_flags = cpu_to_le16(1);
2633 pSMB->Timeout = cpu_to_le32(-1);
2637 parm_data->pid = cpu_to_le32(netpid);
2638 parm_data->start = cpu_to_le64(start_offset);
2639 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2641 pSMB->DataOffset = cpu_to_le16(offset);
2642 pSMB->Fid = smb_file_id;
2643 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2644 pSMB->Reserved4 = 0;
2645 inc_rfc1001_len(pSMB, byte_count);
2646 pSMB->ByteCount = cpu_to_le16(byte_count);
2648 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2649 (struct smb_hdr *) pSMBr, &bytes_returned);
2651 iov[0].iov_base = (char *)pSMB;
2652 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2653 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2654 &resp_buf_type, timeout, &rsp_iov);
2655 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2657 cifs_small_buf_release(pSMB);
2660 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2661 } else if (pLockData) {
2662 /* lock structure can be returned on get */
2665 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2667 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2668 rc = -EIO; /* bad smb */
2671 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2672 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2673 if (data_count < sizeof(struct cifs_posix_lock)) {
2677 parm_data = (struct cifs_posix_lock *)
2678 ((char *)&pSMBr->hdr.Protocol + data_offset);
2679 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2680 pLockData->fl_type = F_UNLCK;
2682 if (parm_data->lock_type ==
2683 cpu_to_le16(CIFS_RDLCK))
2684 pLockData->fl_type = F_RDLCK;
2685 else if (parm_data->lock_type ==
2686 cpu_to_le16(CIFS_WRLCK))
2687 pLockData->fl_type = F_WRLCK;
2689 pLockData->fl_start = le64_to_cpu(parm_data->start);
2690 pLockData->fl_end = pLockData->fl_start +
2691 le64_to_cpu(parm_data->length) - 1;
2692 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2697 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2699 /* Note: On -EAGAIN error only caller can retry on handle based calls
2700 since file handle passed in no longer valid */
2707 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2710 CLOSE_REQ *pSMB = NULL;
2711 cifs_dbg(FYI, "In CIFSSMBClose\n");
2713 /* do not retry on dead session on close */
2714 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2720 pSMB->FileID = (__u16) smb_file_id;
2721 pSMB->LastWriteTime = 0xFFFFFFFF;
2722 pSMB->ByteCount = 0;
2723 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2724 cifs_small_buf_release(pSMB);
2725 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2728 /* EINTR is expected when user ctl-c to kill app */
2729 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2733 /* Since session is dead, file will be closed on server already */
2741 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2744 FLUSH_REQ *pSMB = NULL;
2745 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2747 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2751 pSMB->FileID = (__u16) smb_file_id;
2752 pSMB->ByteCount = 0;
2753 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2754 cifs_small_buf_release(pSMB);
2755 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2757 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2763 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2764 const char *from_name, const char *to_name,
2765 struct cifs_sb_info *cifs_sb)
2768 RENAME_REQ *pSMB = NULL;
2769 RENAME_RSP *pSMBr = NULL;
2771 int name_len, name_len2;
2773 int remap = cifs_remap(cifs_sb);
2775 cifs_dbg(FYI, "In CIFSSMBRename\n");
2777 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2782 pSMB->BufferFormat = 0x04;
2783 pSMB->SearchAttributes =
2784 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2787 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2788 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2789 from_name, PATH_MAX,
2790 cifs_sb->local_nls, remap);
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 to_name, PATH_MAX, cifs_sb->local_nls,
2800 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2801 name_len2 *= 2; /* convert to bytes */
2803 name_len = copy_path_name(pSMB->OldFileName, from_name);
2804 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2805 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2806 name_len2++; /* signature byte */
2809 count = 1 /* 1st signature byte */ + name_len + name_len2;
2810 inc_rfc1001_len(pSMB, count);
2811 pSMB->ByteCount = cpu_to_le16(count);
2813 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2814 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2815 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2817 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2819 cifs_buf_release(pSMB);
2827 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2828 int netfid, const char *target_name,
2829 const struct nls_table *nls_codepage, int remap)
2831 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2832 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2833 struct set_file_rename *rename_info;
2835 char dummy_string[30];
2837 int bytes_returned = 0;
2839 __u16 params, param_offset, offset, count, byte_count;
2841 cifs_dbg(FYI, "Rename to File by handle\n");
2842 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2848 pSMB->MaxSetupCount = 0;
2852 pSMB->Reserved2 = 0;
2853 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2854 offset = param_offset + params;
2856 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2857 rename_info = (struct set_file_rename *) data_offset;
2858 pSMB->MaxParameterCount = cpu_to_le16(2);
2859 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2860 pSMB->SetupCount = 1;
2861 pSMB->Reserved3 = 0;
2862 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2863 byte_count = 3 /* pad */ + params;
2864 pSMB->ParameterCount = cpu_to_le16(params);
2865 pSMB->TotalParameterCount = pSMB->ParameterCount;
2866 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2867 pSMB->DataOffset = cpu_to_le16(offset);
2868 /* construct random name ".cifs_tmp<inodenum><mid>" */
2869 rename_info->overwrite = cpu_to_le32(1);
2870 rename_info->root_fid = 0;
2871 /* unicode only call */
2872 if (target_name == NULL) {
2873 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2875 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2876 dummy_string, 24, nls_codepage, remap);
2879 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2880 target_name, PATH_MAX, nls_codepage,
2883 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2884 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2885 byte_count += count;
2886 pSMB->DataCount = cpu_to_le16(count);
2887 pSMB->TotalDataCount = pSMB->DataCount;
2889 pSMB->InformationLevel =
2890 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2891 pSMB->Reserved4 = 0;
2892 inc_rfc1001_len(pSMB, byte_count);
2893 pSMB->ByteCount = cpu_to_le16(byte_count);
2894 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2895 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2896 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2898 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2901 cifs_buf_release(pSMB);
2903 /* Note: On -EAGAIN error only caller can retry on handle based calls
2904 since file handle passed in no longer valid */
2910 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2911 const char *fromName, const __u16 target_tid, const char *toName,
2912 const int flags, const struct nls_table *nls_codepage, int remap)
2915 COPY_REQ *pSMB = NULL;
2916 COPY_RSP *pSMBr = NULL;
2918 int name_len, name_len2;
2921 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2923 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2928 pSMB->BufferFormat = 0x04;
2929 pSMB->Tid2 = target_tid;
2931 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2933 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2934 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2935 fromName, PATH_MAX, nls_codepage,
2937 name_len++; /* trailing null */
2939 pSMB->OldFileName[name_len] = 0x04; /* pad */
2940 /* protocol requires ASCII signature byte on Unicode string */
2941 pSMB->OldFileName[name_len + 1] = 0x00;
2943 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2944 toName, PATH_MAX, nls_codepage, remap);
2945 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2946 name_len2 *= 2; /* convert to bytes */
2948 name_len = copy_path_name(pSMB->OldFileName, fromName);
2949 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2950 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2951 name_len2++; /* signature byte */
2954 count = 1 /* 1st signature byte */ + name_len + name_len2;
2955 inc_rfc1001_len(pSMB, count);
2956 pSMB->ByteCount = cpu_to_le16(count);
2958 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2959 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2961 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2962 rc, le16_to_cpu(pSMBr->CopyCount));
2964 cifs_buf_release(pSMB);
2973 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2974 const char *fromName, const char *toName,
2975 const struct nls_table *nls_codepage, int remap)
2977 TRANSACTION2_SPI_REQ *pSMB = NULL;
2978 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2981 int name_len_target;
2983 int bytes_returned = 0;
2984 __u16 params, param_offset, offset, byte_count;
2986 cifs_dbg(FYI, "In Symlink Unix style\n");
2988 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2993 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2995 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2996 /* find define for this maxpathcomponent */
2997 PATH_MAX, nls_codepage, remap);
2998 name_len++; /* trailing null */
3002 name_len = copy_path_name(pSMB->FileName, fromName);
3004 params = 6 + name_len;
3005 pSMB->MaxSetupCount = 0;
3009 pSMB->Reserved2 = 0;
3010 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3011 InformationLevel) - 4;
3012 offset = param_offset + params;
3014 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
3015 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3017 cifsConvertToUTF16((__le16 *) data_offset, toName,
3018 /* find define for this maxpathcomponent */
3019 PATH_MAX, nls_codepage, remap);
3020 name_len_target++; /* trailing null */
3021 name_len_target *= 2;
3023 name_len_target = copy_path_name(data_offset, toName);
3026 pSMB->MaxParameterCount = cpu_to_le16(2);
3027 /* BB find exact max on data count below from sess */
3028 pSMB->MaxDataCount = cpu_to_le16(1000);
3029 pSMB->SetupCount = 1;
3030 pSMB->Reserved3 = 0;
3031 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3032 byte_count = 3 /* pad */ + params + name_len_target;
3033 pSMB->DataCount = cpu_to_le16(name_len_target);
3034 pSMB->ParameterCount = cpu_to_le16(params);
3035 pSMB->TotalDataCount = pSMB->DataCount;
3036 pSMB->TotalParameterCount = pSMB->ParameterCount;
3037 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3038 pSMB->DataOffset = cpu_to_le16(offset);
3039 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
3040 pSMB->Reserved4 = 0;
3041 inc_rfc1001_len(pSMB, byte_count);
3042 pSMB->ByteCount = cpu_to_le16(byte_count);
3043 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3044 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3045 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
3047 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
3050 cifs_buf_release(pSMB);
3053 goto createSymLinkRetry;
3059 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3060 const char *fromName, const char *toName,
3061 const struct nls_table *nls_codepage, int remap)
3063 TRANSACTION2_SPI_REQ *pSMB = NULL;
3064 TRANSACTION2_SPI_RSP *pSMBr = NULL;
3067 int name_len_target;
3069 int bytes_returned = 0;
3070 __u16 params, param_offset, offset, byte_count;
3072 cifs_dbg(FYI, "In Create Hard link Unix style\n");
3073 createHardLinkRetry:
3074 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3079 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3080 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
3081 PATH_MAX, nls_codepage, remap);
3082 name_len++; /* trailing null */
3086 name_len = copy_path_name(pSMB->FileName, toName);
3088 params = 6 + name_len;
3089 pSMB->MaxSetupCount = 0;
3093 pSMB->Reserved2 = 0;
3094 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3095 InformationLevel) - 4;
3096 offset = param_offset + params;
3098 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
3099 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3101 cifsConvertToUTF16((__le16 *) data_offset, fromName,
3102 PATH_MAX, nls_codepage, remap);
3103 name_len_target++; /* trailing null */
3104 name_len_target *= 2;
3106 name_len_target = copy_path_name(data_offset, fromName);
3109 pSMB->MaxParameterCount = cpu_to_le16(2);
3110 /* BB find exact max on data count below from sess*/
3111 pSMB->MaxDataCount = cpu_to_le16(1000);
3112 pSMB->SetupCount = 1;
3113 pSMB->Reserved3 = 0;
3114 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3115 byte_count = 3 /* pad */ + params + name_len_target;
3116 pSMB->ParameterCount = cpu_to_le16(params);
3117 pSMB->TotalParameterCount = pSMB->ParameterCount;
3118 pSMB->DataCount = cpu_to_le16(name_len_target);
3119 pSMB->TotalDataCount = pSMB->DataCount;
3120 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3121 pSMB->DataOffset = cpu_to_le16(offset);
3122 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3123 pSMB->Reserved4 = 0;
3124 inc_rfc1001_len(pSMB, byte_count);
3125 pSMB->ByteCount = cpu_to_le16(byte_count);
3126 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3127 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3128 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3130 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3133 cifs_buf_release(pSMB);
3135 goto createHardLinkRetry;
3141 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3142 const char *from_name, const char *to_name,
3143 struct cifs_sb_info *cifs_sb)
3146 NT_RENAME_REQ *pSMB = NULL;
3147 RENAME_RSP *pSMBr = NULL;
3149 int name_len, name_len2;
3151 int remap = cifs_remap(cifs_sb);
3153 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3154 winCreateHardLinkRetry:
3156 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3161 pSMB->SearchAttributes =
3162 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3164 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3165 pSMB->ClusterCount = 0;
3167 pSMB->BufferFormat = 0x04;
3169 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3171 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3172 PATH_MAX, cifs_sb->local_nls, remap);
3173 name_len++; /* trailing null */
3176 /* protocol specifies ASCII buffer format (0x04) for unicode */
3177 pSMB->OldFileName[name_len] = 0x04;
3178 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3180 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3181 to_name, PATH_MAX, cifs_sb->local_nls,
3183 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3184 name_len2 *= 2; /* convert to bytes */
3186 name_len = copy_path_name(pSMB->OldFileName, from_name);
3187 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3188 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
3189 name_len2++; /* signature byte */
3192 count = 1 /* string type byte */ + name_len + name_len2;
3193 inc_rfc1001_len(pSMB, count);
3194 pSMB->ByteCount = cpu_to_le16(count);
3196 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3197 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3198 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3200 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3202 cifs_buf_release(pSMB);
3204 goto winCreateHardLinkRetry;
3210 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3211 const unsigned char *searchName, char **symlinkinfo,
3212 const struct nls_table *nls_codepage, int remap)
3214 /* SMB_QUERY_FILE_UNIX_LINK */
3215 TRANSACTION2_QPI_REQ *pSMB = NULL;
3216 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3220 __u16 params, byte_count;
3223 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3226 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3231 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3233 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3234 searchName, PATH_MAX, nls_codepage,
3236 name_len++; /* trailing null */
3239 name_len = copy_path_name(pSMB->FileName, searchName);
3242 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3243 pSMB->TotalDataCount = 0;
3244 pSMB->MaxParameterCount = cpu_to_le16(2);
3245 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3246 pSMB->MaxSetupCount = 0;
3250 pSMB->Reserved2 = 0;
3251 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3252 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3253 pSMB->DataCount = 0;
3254 pSMB->DataOffset = 0;
3255 pSMB->SetupCount = 1;
3256 pSMB->Reserved3 = 0;
3257 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3258 byte_count = params + 1 /* pad */ ;
3259 pSMB->TotalParameterCount = cpu_to_le16(params);
3260 pSMB->ParameterCount = pSMB->TotalParameterCount;
3261 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3262 pSMB->Reserved4 = 0;
3263 inc_rfc1001_len(pSMB, byte_count);
3264 pSMB->ByteCount = cpu_to_le16(byte_count);
3266 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3267 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3269 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3271 /* decode response */
3273 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3274 /* BB also check enough total bytes returned */
3275 if (rc || get_bcc(&pSMBr->hdr) < 2)
3279 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3281 data_start = ((char *) &pSMBr->hdr.Protocol) +
3282 le16_to_cpu(pSMBr->t2.DataOffset);
3284 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3289 /* BB FIXME investigate remapping reserved chars here */
3290 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3291 count, is_unicode, nls_codepage);
3296 cifs_buf_release(pSMB);
3298 goto querySymLinkRetry;
3303 * Recent Windows versions now create symlinks more frequently
3304 * and they use the "reparse point" mechanism below. We can of course
3305 * do symlinks nicely to Samba and other servers which support the
3306 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3307 * "MF" symlinks optionally, but for recent Windows we really need to
3308 * reenable the code below and fix the cifs_symlink callers to handle this.
3309 * In the interim this code has been moved to its own config option so
3310 * it is not compiled in by default until callers fixed up and more tested.
3313 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3314 __u16 fid, char **symlinkinfo,
3315 const struct nls_table *nls_codepage)
3319 struct smb_com_transaction_ioctl_req *pSMB;
3320 struct smb_com_transaction_ioctl_rsp *pSMBr;
3322 unsigned int sub_len;
3324 struct reparse_symlink_data *reparse_buf;
3325 struct reparse_posix_data *posix_buf;
3326 __u32 data_offset, data_count;
3329 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3330 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3335 pSMB->TotalParameterCount = 0 ;
3336 pSMB->TotalDataCount = 0;
3337 pSMB->MaxParameterCount = cpu_to_le32(2);
3338 /* BB find exact data count max from sess structure BB */
3339 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3340 pSMB->MaxSetupCount = 4;
3342 pSMB->ParameterOffset = 0;
3343 pSMB->DataCount = 0;
3344 pSMB->DataOffset = 0;
3345 pSMB->SetupCount = 4;
3346 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3347 pSMB->ParameterCount = pSMB->TotalParameterCount;
3348 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3349 pSMB->IsFsctl = 1; /* FSCTL */
3350 pSMB->IsRootFlag = 0;
3351 pSMB->Fid = fid; /* file handle always le */
3352 pSMB->ByteCount = 0;
3354 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3355 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3357 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3361 data_offset = le32_to_cpu(pSMBr->DataOffset);
3362 data_count = le32_to_cpu(pSMBr->DataCount);
3363 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3364 /* BB also check enough total bytes returned */
3365 rc = -EIO; /* bad smb */
3368 if (!data_count || (data_count > 2048)) {
3370 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3373 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3374 reparse_buf = (struct reparse_symlink_data *)
3375 ((char *)&pSMBr->hdr.Protocol + data_offset);
3376 if ((char *)reparse_buf >= end_of_smb) {
3380 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3381 cifs_dbg(FYI, "NFS style reparse tag\n");
3382 posix_buf = (struct reparse_posix_data *)reparse_buf;
3384 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3385 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3386 le64_to_cpu(posix_buf->InodeType));
3391 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3392 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3393 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3397 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3398 sub_len, is_unicode, nls_codepage);
3400 } else if (reparse_buf->ReparseTag !=
3401 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3406 /* Reparse tag is NTFS symlink */
3407 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3408 reparse_buf->PathBuffer;
3409 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3410 if (sub_start + sub_len > end_of_smb) {
3411 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3415 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3420 /* BB FIXME investigate remapping reserved chars here */
3421 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3426 cifs_buf_release(pSMB);
3429 * Note: On -EAGAIN error only caller can retry on handle based calls
3430 * since file handle passed in no longer valid.
3436 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3441 struct smb_com_transaction_compr_ioctl_req *pSMB;
3442 struct smb_com_transaction_ioctl_rsp *pSMBr;
3444 cifs_dbg(FYI, "Set compression for %u\n", fid);
3445 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3450 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3452 pSMB->TotalParameterCount = 0;
3453 pSMB->TotalDataCount = cpu_to_le32(2);
3454 pSMB->MaxParameterCount = 0;
3455 pSMB->MaxDataCount = 0;
3456 pSMB->MaxSetupCount = 4;
3458 pSMB->ParameterOffset = 0;
3459 pSMB->DataCount = cpu_to_le32(2);
3461 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3462 compression_state) - 4); /* 84 */
3463 pSMB->SetupCount = 4;
3464 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3465 pSMB->ParameterCount = 0;
3466 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3467 pSMB->IsFsctl = 1; /* FSCTL */
3468 pSMB->IsRootFlag = 0;
3469 pSMB->Fid = fid; /* file handle always le */
3470 /* 3 byte pad, followed by 2 byte compress state */
3471 pSMB->ByteCount = cpu_to_le16(5);
3472 inc_rfc1001_len(pSMB, 5);
3474 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3475 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3477 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3479 cifs_buf_release(pSMB);
3482 * Note: On -EAGAIN error only caller can retry on handle based calls
3483 * since file handle passed in no longer valid.
3489 #ifdef CONFIG_CIFS_POSIX
3491 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3492 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3493 struct cifs_posix_ace *cifs_ace)
3495 /* u8 cifs fields do not need le conversion */
3496 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3497 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3498 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3500 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3501 ace->e_perm, ace->e_tag, ace->e_id);
3507 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3508 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3509 const int acl_type, const int size_of_data_area)
3514 struct cifs_posix_ace *pACE;
3515 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3516 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3518 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3521 if (acl_type == ACL_TYPE_ACCESS) {
3522 count = le16_to_cpu(cifs_acl->access_entry_count);
3523 pACE = &cifs_acl->ace_array[0];
3524 size = sizeof(struct cifs_posix_acl);
3525 size += sizeof(struct cifs_posix_ace) * count;
3526 /* check if we would go beyond end of SMB */
3527 if (size_of_data_area < size) {
3528 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3529 size_of_data_area, size);
3532 } else if (acl_type == ACL_TYPE_DEFAULT) {
3533 count = le16_to_cpu(cifs_acl->access_entry_count);
3534 size = sizeof(struct cifs_posix_acl);
3535 size += sizeof(struct cifs_posix_ace) * count;
3536 /* skip past access ACEs to get to default ACEs */
3537 pACE = &cifs_acl->ace_array[count];
3538 count = le16_to_cpu(cifs_acl->default_entry_count);
3539 size += sizeof(struct cifs_posix_ace) * count;
3540 /* check if we would go beyond end of SMB */
3541 if (size_of_data_area < size)
3548 size = posix_acl_xattr_size(count);
3549 if ((buflen == 0) || (local_acl == NULL)) {
3550 /* used to query ACL EA size */
3551 } else if (size > buflen) {
3553 } else /* buffer big enough */ {
3554 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3556 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3557 for (i = 0; i < count ; i++) {
3558 cifs_convert_ace(&ace[i], pACE);
3565 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3566 const struct posix_acl_xattr_entry *local_ace)
3568 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3569 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3570 /* BB is there a better way to handle the large uid? */
3571 if (local_ace->e_id == cpu_to_le32(-1)) {
3572 /* Probably no need to le convert -1 on any arch but can not hurt */
3573 cifs_ace->cifs_uid = cpu_to_le64(-1);
3575 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3577 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3578 ace->e_perm, ace->e_tag, ace->e_id);
3582 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3583 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3584 const int buflen, const int acl_type)
3587 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3588 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3589 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3593 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3596 count = posix_acl_xattr_count((size_t)buflen);
3597 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3598 count, buflen, le32_to_cpu(local_acl->a_version));
3599 if (le32_to_cpu(local_acl->a_version) != 2) {
3600 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3601 le32_to_cpu(local_acl->a_version));
3604 cifs_acl->version = cpu_to_le16(1);
3605 if (acl_type == ACL_TYPE_ACCESS) {
3606 cifs_acl->access_entry_count = cpu_to_le16(count);
3607 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3608 } else if (acl_type == ACL_TYPE_DEFAULT) {
3609 cifs_acl->default_entry_count = cpu_to_le16(count);
3610 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3612 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3615 for (i = 0; i < count; i++)
3616 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3618 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3619 rc += sizeof(struct cifs_posix_acl);
3620 /* BB add check to make sure ACL does not overflow SMB */
3626 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3627 const unsigned char *searchName,
3628 char *acl_inf, const int buflen, const int acl_type,
3629 const struct nls_table *nls_codepage, int remap)
3631 /* SMB_QUERY_POSIX_ACL */
3632 TRANSACTION2_QPI_REQ *pSMB = NULL;
3633 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3637 __u16 params, byte_count;
3639 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3642 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3647 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3649 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3650 searchName, PATH_MAX, nls_codepage,
3652 name_len++; /* trailing null */
3654 pSMB->FileName[name_len] = 0;
3655 pSMB->FileName[name_len+1] = 0;
3657 name_len = copy_path_name(pSMB->FileName, searchName);
3660 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3661 pSMB->TotalDataCount = 0;
3662 pSMB->MaxParameterCount = cpu_to_le16(2);
3663 /* BB find exact max data count below from sess structure BB */
3664 pSMB->MaxDataCount = cpu_to_le16(4000);
3665 pSMB->MaxSetupCount = 0;
3669 pSMB->Reserved2 = 0;
3670 pSMB->ParameterOffset = cpu_to_le16(
3671 offsetof(struct smb_com_transaction2_qpi_req,
3672 InformationLevel) - 4);
3673 pSMB->DataCount = 0;
3674 pSMB->DataOffset = 0;
3675 pSMB->SetupCount = 1;
3676 pSMB->Reserved3 = 0;
3677 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3678 byte_count = params + 1 /* pad */ ;
3679 pSMB->TotalParameterCount = cpu_to_le16(params);
3680 pSMB->ParameterCount = pSMB->TotalParameterCount;
3681 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3682 pSMB->Reserved4 = 0;
3683 inc_rfc1001_len(pSMB, byte_count);
3684 pSMB->ByteCount = cpu_to_le16(byte_count);
3686 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3687 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3688 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3690 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3692 /* decode response */
3694 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3695 /* BB also check enough total bytes returned */
3696 if (rc || get_bcc(&pSMBr->hdr) < 2)
3697 rc = -EIO; /* bad smb */
3699 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3700 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3701 rc = cifs_copy_posix_acl(acl_inf,
3702 (char *)&pSMBr->hdr.Protocol+data_offset,
3703 buflen, acl_type, count);
3706 cifs_buf_release(pSMB);
3713 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3714 const unsigned char *fileName,
3715 const char *local_acl, const int buflen,
3717 const struct nls_table *nls_codepage, int remap)
3719 struct smb_com_transaction2_spi_req *pSMB = NULL;
3720 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3724 int bytes_returned = 0;
3725 __u16 params, byte_count, data_count, param_offset, offset;
3727 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3729 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3733 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3735 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3736 PATH_MAX, nls_codepage, remap);
3737 name_len++; /* trailing null */
3740 name_len = copy_path_name(pSMB->FileName, fileName);
3742 params = 6 + name_len;
3743 pSMB->MaxParameterCount = cpu_to_le16(2);
3744 /* BB find max SMB size from sess */
3745 pSMB->MaxDataCount = cpu_to_le16(1000);
3746 pSMB->MaxSetupCount = 0;
3750 pSMB->Reserved2 = 0;
3751 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3752 InformationLevel) - 4;
3753 offset = param_offset + params;
3754 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3755 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3757 /* convert to on the wire format for POSIX ACL */
3758 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3760 if (data_count == 0) {
3762 goto setACLerrorExit;
3764 pSMB->DataOffset = cpu_to_le16(offset);
3765 pSMB->SetupCount = 1;
3766 pSMB->Reserved3 = 0;
3767 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3768 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3769 byte_count = 3 /* pad */ + params + data_count;
3770 pSMB->DataCount = cpu_to_le16(data_count);
3771 pSMB->TotalDataCount = pSMB->DataCount;
3772 pSMB->ParameterCount = cpu_to_le16(params);
3773 pSMB->TotalParameterCount = pSMB->ParameterCount;
3774 pSMB->Reserved4 = 0;
3775 inc_rfc1001_len(pSMB, byte_count);
3776 pSMB->ByteCount = cpu_to_le16(byte_count);
3777 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3778 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3780 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3783 cifs_buf_release(pSMB);
3789 /* BB fix tabs in this function FIXME BB */
3791 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3792 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3795 struct smb_t2_qfi_req *pSMB = NULL;
3796 struct smb_t2_qfi_rsp *pSMBr = NULL;
3798 __u16 params, byte_count;
3800 cifs_dbg(FYI, "In GetExtAttr\n");
3805 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3810 params = 2 /* level */ + 2 /* fid */;
3811 pSMB->t2.TotalDataCount = 0;
3812 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3813 /* BB find exact max data count below from sess structure BB */
3814 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3815 pSMB->t2.MaxSetupCount = 0;
3816 pSMB->t2.Reserved = 0;
3818 pSMB->t2.Timeout = 0;
3819 pSMB->t2.Reserved2 = 0;
3820 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3822 pSMB->t2.DataCount = 0;
3823 pSMB->t2.DataOffset = 0;
3824 pSMB->t2.SetupCount = 1;
3825 pSMB->t2.Reserved3 = 0;
3826 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3827 byte_count = params + 1 /* pad */ ;
3828 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3829 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3830 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3833 inc_rfc1001_len(pSMB, byte_count);
3834 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3836 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3837 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3839 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3841 /* decode response */
3842 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3843 /* BB also check enough total bytes returned */
3844 if (rc || get_bcc(&pSMBr->hdr) < 2)
3845 /* If rc should we check for EOPNOSUPP and
3846 disable the srvino flag? or in caller? */
3847 rc = -EIO; /* bad smb */
3849 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3850 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3851 struct file_chattr_info *pfinfo;
3852 /* BB Do we need a cast or hash here ? */
3854 cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n");
3858 pfinfo = (struct file_chattr_info *)
3859 (data_offset + (char *) &pSMBr->hdr.Protocol);
3860 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3861 *pMask = le64_to_cpu(pfinfo->mask);
3865 cifs_buf_release(pSMB);
3867 goto GetExtAttrRetry;
3871 #endif /* CONFIG_POSIX */
3874 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3875 * all NT TRANSACTS that we init here have total parm and data under about 400
3876 * bytes (to fit in small cifs buffer size), which is the case so far, it
3877 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3878 * returned setup area) and MaxParameterCount (returned parms size) must be set
3882 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3883 const int parm_len, struct cifs_tcon *tcon,
3888 struct smb_com_ntransact_req *pSMB;
3890 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3894 *ret_buf = (void *)pSMB;
3896 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3897 pSMB->TotalDataCount = 0;
3898 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3899 pSMB->ParameterCount = pSMB->TotalParameterCount;
3900 pSMB->DataCount = pSMB->TotalDataCount;
3901 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3902 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3903 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3904 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3905 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3906 pSMB->SubCommand = cpu_to_le16(sub_command);
3911 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3912 __u32 *pparmlen, __u32 *pdatalen)
3915 __u32 data_count, data_offset, parm_count, parm_offset;
3916 struct smb_com_ntransact_rsp *pSMBr;
3925 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3927 bcc = get_bcc(&pSMBr->hdr);
3928 end_of_smb = 2 /* sizeof byte count */ + bcc +
3929 (char *)&pSMBr->ByteCount;
3931 data_offset = le32_to_cpu(pSMBr->DataOffset);
3932 data_count = le32_to_cpu(pSMBr->DataCount);
3933 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3934 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3936 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3937 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3939 /* should we also check that parm and data areas do not overlap? */
3940 if (*ppparm > end_of_smb) {
3941 cifs_dbg(FYI, "parms start after end of smb\n");
3943 } else if (parm_count + *ppparm > end_of_smb) {
3944 cifs_dbg(FYI, "parm end after end of smb\n");
3946 } else if (*ppdata > end_of_smb) {
3947 cifs_dbg(FYI, "data starts after end of smb\n");
3949 } else if (data_count + *ppdata > end_of_smb) {
3950 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3951 *ppdata, data_count, (data_count + *ppdata),
3954 } else if (parm_count + data_count > bcc) {
3955 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3958 *pdatalen = data_count;
3959 *pparmlen = parm_count;
3963 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3965 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3966 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3970 QUERY_SEC_DESC_REQ *pSMB;
3972 struct kvec rsp_iov;
3974 cifs_dbg(FYI, "GetCifsACL\n");
3979 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3980 8 /* parm len */, tcon, (void **) &pSMB);
3984 pSMB->MaxParameterCount = cpu_to_le32(4);
3985 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3986 pSMB->MaxSetupCount = 0;
3987 pSMB->Fid = fid; /* file handle always le */
3988 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3990 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3991 inc_rfc1001_len(pSMB, 11);
3992 iov[0].iov_base = (char *)pSMB;
3993 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3995 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3997 cifs_small_buf_release(pSMB);
3998 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
4000 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
4001 } else { /* decode response */
4005 struct smb_com_ntransact_rsp *pSMBr;
4008 /* validate_nttransact */
4009 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
4010 &pdata, &parm_len, pbuflen);
4013 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
4015 cifs_dbg(FYI, "smb %p parm %p data %p\n",
4016 pSMBr, parm, *acl_inf);
4018 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
4019 rc = -EIO; /* bad smb */
4024 /* BB check that data area is minimum length and as big as acl_len */
4026 acl_len = le32_to_cpu(*parm);
4027 if (acl_len != *pbuflen) {
4028 cifs_dbg(VFS, "acl length %d does not match %d\n",
4030 if (*pbuflen > acl_len)
4034 /* check if buffer is big enough for the acl
4035 header followed by the smallest SID */
4036 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
4037 (*pbuflen >= 64 * 1024)) {
4038 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
4042 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
4043 if (*acl_inf == NULL) {
4050 free_rsp_buf(buf_type, rsp_iov.iov_base);
4055 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
4056 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
4058 __u16 byte_count, param_count, data_count, param_offset, data_offset;
4060 int bytes_returned = 0;
4061 SET_SEC_DESC_REQ *pSMB = NULL;
4065 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
4069 pSMB->MaxSetupCount = 0;
4073 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
4074 data_count = acllen;
4075 data_offset = param_offset + param_count;
4076 byte_count = 3 /* pad */ + param_count;
4078 pSMB->DataCount = cpu_to_le32(data_count);
4079 pSMB->TotalDataCount = pSMB->DataCount;
4080 pSMB->MaxParameterCount = cpu_to_le32(4);
4081 pSMB->MaxDataCount = cpu_to_le32(16384);
4082 pSMB->ParameterCount = cpu_to_le32(param_count);
4083 pSMB->ParameterOffset = cpu_to_le32(param_offset);
4084 pSMB->TotalParameterCount = pSMB->ParameterCount;
4085 pSMB->DataOffset = cpu_to_le32(data_offset);
4086 pSMB->SetupCount = 0;
4087 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
4088 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
4090 pSMB->Fid = fid; /* file handle always le */
4091 pSMB->Reserved2 = 0;
4092 pSMB->AclFlags = cpu_to_le32(aclflag);
4094 if (pntsd && acllen) {
4095 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
4096 data_offset, pntsd, acllen);
4097 inc_rfc1001_len(pSMB, byte_count + data_count);
4099 inc_rfc1001_len(pSMB, byte_count);
4101 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4102 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4104 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4105 bytes_returned, rc);
4107 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
4108 cifs_buf_release(pSMB);
4111 goto setCifsAclRetry;
4117 /* Legacy Query Path Information call for lookup to old servers such
4120 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
4121 const char *search_name, FILE_ALL_INFO *data,
4122 const struct nls_table *nls_codepage, int remap)
4124 QUERY_INFORMATION_REQ *pSMB;
4125 QUERY_INFORMATION_RSP *pSMBr;
4130 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4132 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4137 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4139 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4140 search_name, PATH_MAX, nls_codepage,
4142 name_len++; /* trailing null */
4145 name_len = copy_path_name(pSMB->FileName, search_name);
4147 pSMB->BufferFormat = 0x04;
4148 name_len++; /* account for buffer type byte */
4149 inc_rfc1001_len(pSMB, (__u16)name_len);
4150 pSMB->ByteCount = cpu_to_le16(name_len);
4152 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4153 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4155 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4157 struct timespec64 ts;
4158 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4160 /* decode response */
4161 /* BB FIXME - add time zone adjustment BB */
4162 memset(data, 0, sizeof(FILE_ALL_INFO));
4165 /* decode time fields */
4166 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4167 data->LastWriteTime = data->ChangeTime;
4168 data->LastAccessTime = 0;
4169 data->AllocationSize =
4170 cpu_to_le64(le32_to_cpu(pSMBr->size));
4171 data->EndOfFile = data->AllocationSize;
4173 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4175 rc = -EIO; /* bad buffer passed in */
4177 cifs_buf_release(pSMB);
4186 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4187 u16 netfid, FILE_ALL_INFO *pFindData)
4189 struct smb_t2_qfi_req *pSMB = NULL;
4190 struct smb_t2_qfi_rsp *pSMBr = NULL;
4193 __u16 params, byte_count;
4196 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4201 params = 2 /* level */ + 2 /* fid */;
4202 pSMB->t2.TotalDataCount = 0;
4203 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4204 /* BB find exact max data count below from sess structure BB */
4205 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4206 pSMB->t2.MaxSetupCount = 0;
4207 pSMB->t2.Reserved = 0;
4209 pSMB->t2.Timeout = 0;
4210 pSMB->t2.Reserved2 = 0;
4211 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4213 pSMB->t2.DataCount = 0;
4214 pSMB->t2.DataOffset = 0;
4215 pSMB->t2.SetupCount = 1;
4216 pSMB->t2.Reserved3 = 0;
4217 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4218 byte_count = params + 1 /* pad */ ;
4219 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4220 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4221 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4224 inc_rfc1001_len(pSMB, byte_count);
4225 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4227 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4228 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4230 cifs_dbg(FYI, "Send error in QFileInfo = %d", rc);
4231 } else { /* decode response */
4232 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4234 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4236 else if (get_bcc(&pSMBr->hdr) < 40)
4237 rc = -EIO; /* bad smb */
4238 else if (pFindData) {
4239 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4240 memcpy((char *) pFindData,
4241 (char *) &pSMBr->hdr.Protocol +
4242 data_offset, sizeof(FILE_ALL_INFO));
4246 cifs_buf_release(pSMB);
4248 goto QFileInfoRetry;
4254 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4255 const char *search_name, FILE_ALL_INFO *data,
4256 int legacy /* old style infolevel */,
4257 const struct nls_table *nls_codepage, int remap)
4259 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4260 TRANSACTION2_QPI_REQ *pSMB = NULL;
4261 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4265 __u16 params, byte_count;
4267 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4269 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4274 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4276 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4277 PATH_MAX, nls_codepage, remap);
4278 name_len++; /* trailing null */
4281 name_len = copy_path_name(pSMB->FileName, search_name);
4284 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4285 pSMB->TotalDataCount = 0;
4286 pSMB->MaxParameterCount = cpu_to_le16(2);
4287 /* BB find exact max SMB PDU from sess structure BB */
4288 pSMB->MaxDataCount = cpu_to_le16(4000);
4289 pSMB->MaxSetupCount = 0;
4293 pSMB->Reserved2 = 0;
4294 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4295 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4296 pSMB->DataCount = 0;
4297 pSMB->DataOffset = 0;
4298 pSMB->SetupCount = 1;
4299 pSMB->Reserved3 = 0;
4300 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4301 byte_count = params + 1 /* pad */ ;
4302 pSMB->TotalParameterCount = cpu_to_le16(params);
4303 pSMB->ParameterCount = pSMB->TotalParameterCount;
4305 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4307 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4308 pSMB->Reserved4 = 0;
4309 inc_rfc1001_len(pSMB, byte_count);
4310 pSMB->ByteCount = cpu_to_le16(byte_count);
4312 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4313 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4315 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4316 } else { /* decode response */
4317 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4319 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4321 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4322 rc = -EIO; /* bad smb */
4323 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4324 rc = -EIO; /* 24 or 26 expected but we do not read
4328 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4331 * On legacy responses we do not read the last field,
4332 * EAsize, fortunately since it varies by subdialect and
4333 * also note it differs on Set vs Get, ie two bytes or 4
4334 * bytes depending but we don't care here.
4337 size = sizeof(FILE_INFO_STANDARD);
4339 size = sizeof(FILE_ALL_INFO);
4340 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4345 cifs_buf_release(pSMB);
4347 goto QPathInfoRetry;
4353 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4354 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4356 struct smb_t2_qfi_req *pSMB = NULL;
4357 struct smb_t2_qfi_rsp *pSMBr = NULL;
4360 __u16 params, byte_count;
4363 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4368 params = 2 /* level */ + 2 /* fid */;
4369 pSMB->t2.TotalDataCount = 0;
4370 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4371 /* BB find exact max data count below from sess structure BB */
4372 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4373 pSMB->t2.MaxSetupCount = 0;
4374 pSMB->t2.Reserved = 0;
4376 pSMB->t2.Timeout = 0;
4377 pSMB->t2.Reserved2 = 0;
4378 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4380 pSMB->t2.DataCount = 0;
4381 pSMB->t2.DataOffset = 0;
4382 pSMB->t2.SetupCount = 1;
4383 pSMB->t2.Reserved3 = 0;
4384 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4385 byte_count = params + 1 /* pad */ ;
4386 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4387 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4388 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4391 inc_rfc1001_len(pSMB, byte_count);
4392 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4394 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4395 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4397 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d", rc);
4398 } else { /* decode response */
4399 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4401 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4402 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4403 rc = -EIO; /* bad smb */
4405 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4406 memcpy((char *) pFindData,
4407 (char *) &pSMBr->hdr.Protocol +
4409 sizeof(FILE_UNIX_BASIC_INFO));
4413 cifs_buf_release(pSMB);
4415 goto UnixQFileInfoRetry;
4421 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4422 const unsigned char *searchName,
4423 FILE_UNIX_BASIC_INFO *pFindData,
4424 const struct nls_table *nls_codepage, int remap)
4426 /* SMB_QUERY_FILE_UNIX_BASIC */
4427 TRANSACTION2_QPI_REQ *pSMB = NULL;
4428 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4430 int bytes_returned = 0;
4432 __u16 params, byte_count;
4434 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4436 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4441 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4443 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4444 PATH_MAX, nls_codepage, remap);
4445 name_len++; /* trailing null */
4448 name_len = copy_path_name(pSMB->FileName, searchName);
4451 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4452 pSMB->TotalDataCount = 0;
4453 pSMB->MaxParameterCount = cpu_to_le16(2);
4454 /* BB find exact max SMB PDU from sess structure BB */
4455 pSMB->MaxDataCount = cpu_to_le16(4000);
4456 pSMB->MaxSetupCount = 0;
4460 pSMB->Reserved2 = 0;
4461 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4462 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4463 pSMB->DataCount = 0;
4464 pSMB->DataOffset = 0;
4465 pSMB->SetupCount = 1;
4466 pSMB->Reserved3 = 0;
4467 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4468 byte_count = params + 1 /* pad */ ;
4469 pSMB->TotalParameterCount = cpu_to_le16(params);
4470 pSMB->ParameterCount = pSMB->TotalParameterCount;
4471 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4472 pSMB->Reserved4 = 0;
4473 inc_rfc1001_len(pSMB, byte_count);
4474 pSMB->ByteCount = cpu_to_le16(byte_count);
4476 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4477 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4479 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d", rc);
4480 } else { /* decode response */
4481 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4483 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4484 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4485 rc = -EIO; /* bad smb */
4487 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4488 memcpy((char *) pFindData,
4489 (char *) &pSMBr->hdr.Protocol +
4491 sizeof(FILE_UNIX_BASIC_INFO));
4494 cifs_buf_release(pSMB);
4496 goto UnixQPathInfoRetry;
4501 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4503 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4504 const char *searchName, struct cifs_sb_info *cifs_sb,
4505 __u16 *pnetfid, __u16 search_flags,
4506 struct cifs_search_info *psrch_inf, bool msearch)
4508 /* level 257 SMB_ */
4509 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4510 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4511 T2_FFIRST_RSP_PARMS *parms;
4513 int bytes_returned = 0;
4514 int name_len, remap;
4515 __u16 params, byte_count;
4516 struct nls_table *nls_codepage;
4518 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4521 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4526 nls_codepage = cifs_sb->local_nls;
4527 remap = cifs_remap(cifs_sb);
4529 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4531 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4532 PATH_MAX, nls_codepage, remap);
4533 /* We can not add the asterik earlier in case
4534 it got remapped to 0xF03A as if it were part of the
4535 directory name instead of a wildcard */
4538 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4539 pSMB->FileName[name_len+1] = 0;
4540 pSMB->FileName[name_len+2] = '*';
4541 pSMB->FileName[name_len+3] = 0;
4542 name_len += 4; /* now the trailing null */
4543 /* null terminate just in case */
4544 pSMB->FileName[name_len] = 0;
4545 pSMB->FileName[name_len+1] = 0;
4549 name_len = copy_path_name(pSMB->FileName, searchName);
4551 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4552 name_len = PATH_MAX-2;
4553 /* overwrite nul byte */
4554 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4555 pSMB->FileName[name_len] = '*';
4556 pSMB->FileName[name_len+1] = 0;
4561 params = 12 + name_len /* includes null */ ;
4562 pSMB->TotalDataCount = 0; /* no EAs */
4563 pSMB->MaxParameterCount = cpu_to_le16(10);
4564 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4565 pSMB->MaxSetupCount = 0;
4569 pSMB->Reserved2 = 0;
4570 byte_count = params + 1 /* pad */ ;
4571 pSMB->TotalParameterCount = cpu_to_le16(params);
4572 pSMB->ParameterCount = pSMB->TotalParameterCount;
4573 pSMB->ParameterOffset = cpu_to_le16(
4574 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4576 pSMB->DataCount = 0;
4577 pSMB->DataOffset = 0;
4578 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4579 pSMB->Reserved3 = 0;
4580 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4581 pSMB->SearchAttributes =
4582 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4584 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4585 pSMB->SearchFlags = cpu_to_le16(search_flags);
4586 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4588 /* BB what should we set StorageType to? Does it matter? BB */
4589 pSMB->SearchStorageType = 0;
4590 inc_rfc1001_len(pSMB, byte_count);
4591 pSMB->ByteCount = cpu_to_le16(byte_count);
4593 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4594 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4595 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4597 if (rc) {/* BB add logic to retry regular search if Unix search
4598 rejected unexpectedly by server */
4599 /* BB Add code to handle unsupported level rc */
4600 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4602 cifs_buf_release(pSMB);
4604 /* BB eventually could optimize out free and realloc of buf */
4607 goto findFirstRetry;
4608 } else { /* decode response */
4609 /* BB remember to free buffer if error BB */
4610 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4614 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4615 psrch_inf->unicode = true;
4617 psrch_inf->unicode = false;
4619 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4620 psrch_inf->smallBuf = 0;
4621 psrch_inf->srch_entries_start =
4622 (char *) &pSMBr->hdr.Protocol +
4623 le16_to_cpu(pSMBr->t2.DataOffset);
4624 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4625 le16_to_cpu(pSMBr->t2.ParameterOffset));
4627 if (parms->EndofSearch)
4628 psrch_inf->endOfSearch = true;
4630 psrch_inf->endOfSearch = false;
4632 psrch_inf->entries_in_buffer =
4633 le16_to_cpu(parms->SearchCount);
4634 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4635 psrch_inf->entries_in_buffer;
4636 lnoff = le16_to_cpu(parms->LastNameOffset);
4637 if (CIFSMaxBufSize < lnoff) {
4638 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4639 psrch_inf->last_entry = NULL;
4643 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4647 *pnetfid = parms->SearchHandle;
4649 cifs_buf_release(pSMB);
4656 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4657 __u16 searchHandle, __u16 search_flags,
4658 struct cifs_search_info *psrch_inf)
4660 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4661 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4662 T2_FNEXT_RSP_PARMS *parms;
4663 char *response_data;
4666 unsigned int name_len;
4667 __u16 params, byte_count;
4669 cifs_dbg(FYI, "In FindNext\n");
4671 if (psrch_inf->endOfSearch)
4674 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4679 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4681 pSMB->TotalDataCount = 0; /* no EAs */
4682 pSMB->MaxParameterCount = cpu_to_le16(8);
4683 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4684 pSMB->MaxSetupCount = 0;
4688 pSMB->Reserved2 = 0;
4689 pSMB->ParameterOffset = cpu_to_le16(
4690 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4691 pSMB->DataCount = 0;
4692 pSMB->DataOffset = 0;
4693 pSMB->SetupCount = 1;
4694 pSMB->Reserved3 = 0;
4695 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4696 pSMB->SearchHandle = searchHandle; /* always kept as le */
4698 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4699 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4700 pSMB->ResumeKey = psrch_inf->resume_key;
4701 pSMB->SearchFlags = cpu_to_le16(search_flags);
4703 name_len = psrch_inf->resume_name_len;
4705 if (name_len < PATH_MAX) {
4706 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4707 byte_count += name_len;
4708 /* 14 byte parm len above enough for 2 byte null terminator */
4709 pSMB->ResumeFileName[name_len] = 0;
4710 pSMB->ResumeFileName[name_len+1] = 0;
4713 goto FNext2_err_exit;
4715 byte_count = params + 1 /* pad */ ;
4716 pSMB->TotalParameterCount = cpu_to_le16(params);
4717 pSMB->ParameterCount = pSMB->TotalParameterCount;
4718 inc_rfc1001_len(pSMB, byte_count);
4719 pSMB->ByteCount = cpu_to_le16(byte_count);
4721 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4722 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4723 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4726 psrch_inf->endOfSearch = true;
4727 cifs_buf_release(pSMB);
4728 rc = 0; /* search probably was closed at end of search*/
4730 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4731 } else { /* decode response */
4732 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4737 /* BB fixme add lock for file (srch_info) struct here */
4738 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4739 psrch_inf->unicode = true;
4741 psrch_inf->unicode = false;
4742 response_data = (char *) &pSMBr->hdr.Protocol +
4743 le16_to_cpu(pSMBr->t2.ParameterOffset);
4744 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4745 response_data = (char *)&pSMBr->hdr.Protocol +
4746 le16_to_cpu(pSMBr->t2.DataOffset);
4747 if (psrch_inf->smallBuf)
4748 cifs_small_buf_release(
4749 psrch_inf->ntwrk_buf_start);
4751 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4752 psrch_inf->srch_entries_start = response_data;
4753 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4754 psrch_inf->smallBuf = 0;
4755 if (parms->EndofSearch)
4756 psrch_inf->endOfSearch = true;
4758 psrch_inf->endOfSearch = false;
4759 psrch_inf->entries_in_buffer =
4760 le16_to_cpu(parms->SearchCount);
4761 psrch_inf->index_of_last_entry +=
4762 psrch_inf->entries_in_buffer;
4763 lnoff = le16_to_cpu(parms->LastNameOffset);
4764 if (CIFSMaxBufSize < lnoff) {
4765 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4766 psrch_inf->last_entry = NULL;
4769 psrch_inf->last_entry =
4770 psrch_inf->srch_entries_start + lnoff;
4772 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4773 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4775 /* BB fixme add unlock here */
4780 /* BB On error, should we leave previous search buf (and count and
4781 last entry fields) intact or free the previous one? */
4783 /* Note: On -EAGAIN error only caller can retry on handle based calls
4784 since file handle passed in no longer valid */
4787 cifs_buf_release(pSMB);
4792 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4793 const __u16 searchHandle)
4796 FINDCLOSE_REQ *pSMB = NULL;
4798 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4799 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4801 /* no sense returning error if session restarted
4802 as file handle has been closed */
4808 pSMB->FileID = searchHandle;
4809 pSMB->ByteCount = 0;
4810 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4811 cifs_small_buf_release(pSMB);
4813 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4815 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4817 /* Since session is dead, search handle closed on server already */
4825 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4826 const char *search_name, __u64 *inode_number,
4827 const struct nls_table *nls_codepage, int remap)
4830 TRANSACTION2_QPI_REQ *pSMB = NULL;
4831 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4832 int name_len, bytes_returned;
4833 __u16 params, byte_count;
4835 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4839 GetInodeNumberRetry:
4840 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4845 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4847 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4848 search_name, PATH_MAX, nls_codepage,
4850 name_len++; /* trailing null */
4853 name_len = copy_path_name(pSMB->FileName, search_name);
4856 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4857 pSMB->TotalDataCount = 0;
4858 pSMB->MaxParameterCount = cpu_to_le16(2);
4859 /* BB find exact max data count below from sess structure BB */
4860 pSMB->MaxDataCount = cpu_to_le16(4000);
4861 pSMB->MaxSetupCount = 0;
4865 pSMB->Reserved2 = 0;
4866 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4867 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4868 pSMB->DataCount = 0;
4869 pSMB->DataOffset = 0;
4870 pSMB->SetupCount = 1;
4871 pSMB->Reserved3 = 0;
4872 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4873 byte_count = params + 1 /* pad */ ;
4874 pSMB->TotalParameterCount = cpu_to_le16(params);
4875 pSMB->ParameterCount = pSMB->TotalParameterCount;
4876 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4877 pSMB->Reserved4 = 0;
4878 inc_rfc1001_len(pSMB, byte_count);
4879 pSMB->ByteCount = cpu_to_le16(byte_count);
4881 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4882 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4884 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4886 /* decode response */
4887 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4888 /* BB also check enough total bytes returned */
4889 if (rc || get_bcc(&pSMBr->hdr) < 2)
4890 /* If rc should we check for EOPNOSUPP and
4891 disable the srvino flag? or in caller? */
4892 rc = -EIO; /* bad smb */
4894 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4895 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4896 struct file_internal_info *pfinfo;
4897 /* BB Do we need a cast or hash here ? */
4899 cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n");
4901 goto GetInodeNumOut;
4903 pfinfo = (struct file_internal_info *)
4904 (data_offset + (char *) &pSMBr->hdr.Protocol);
4905 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4909 cifs_buf_release(pSMB);
4911 goto GetInodeNumberRetry;
4916 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4917 const char *search_name, struct dfs_info3_param **target_nodes,
4918 unsigned int *num_of_nodes,
4919 const struct nls_table *nls_codepage, int remap)
4921 /* TRANS2_GET_DFS_REFERRAL */
4922 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4923 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4927 __u16 params, byte_count;
4929 *target_nodes = NULL;
4931 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4932 if (ses == NULL || ses->tcon_ipc == NULL)
4937 * Use smb_init_no_reconnect() instead of smb_init() as
4938 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4939 * causing an infinite recursion.
4941 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4942 (void **)&pSMB, (void **)&pSMBr);
4946 /* server pointer checked in called function,
4947 but should never be null here anyway */
4948 pSMB->hdr.Mid = get_next_mid(ses->server);
4949 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4950 pSMB->hdr.Uid = ses->Suid;
4951 if (ses->capabilities & CAP_STATUS32)
4952 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4953 if (ses->capabilities & CAP_DFS)
4954 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4956 if (ses->capabilities & CAP_UNICODE) {
4957 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4959 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4960 search_name, PATH_MAX, nls_codepage,
4962 name_len++; /* trailing null */
4964 } else { /* BB improve the check for buffer overruns BB */
4965 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4968 if (ses->server->sign)
4969 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4971 pSMB->hdr.Uid = ses->Suid;
4973 params = 2 /* level */ + name_len /*includes null */ ;
4974 pSMB->TotalDataCount = 0;
4975 pSMB->DataCount = 0;
4976 pSMB->DataOffset = 0;
4977 pSMB->MaxParameterCount = 0;
4978 /* BB find exact max SMB PDU from sess structure BB */
4979 pSMB->MaxDataCount = cpu_to_le16(4000);
4980 pSMB->MaxSetupCount = 0;
4984 pSMB->Reserved2 = 0;
4985 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4986 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4987 pSMB->SetupCount = 1;
4988 pSMB->Reserved3 = 0;
4989 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4990 byte_count = params + 3 /* pad */ ;
4991 pSMB->ParameterCount = cpu_to_le16(params);
4992 pSMB->TotalParameterCount = pSMB->ParameterCount;
4993 pSMB->MaxReferralLevel = cpu_to_le16(3);
4994 inc_rfc1001_len(pSMB, byte_count);
4995 pSMB->ByteCount = cpu_to_le16(byte_count);
4997 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4998 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5000 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
5003 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5005 /* BB Also check if enough total bytes returned? */
5006 if (rc || get_bcc(&pSMBr->hdr) < 17) {
5007 rc = -EIO; /* bad smb */
5011 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
5012 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
5014 /* parse returned result into more usable form */
5015 rc = parse_dfs_referrals(&pSMBr->dfs_data,
5016 le16_to_cpu(pSMBr->t2.DataCount),
5017 num_of_nodes, target_nodes, nls_codepage,
5019 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
5022 cifs_buf_release(pSMB);
5030 /* Query File System Info such as free space to old servers such as Win 9x */
5032 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
5033 struct kstatfs *FSData)
5035 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
5036 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5037 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5038 FILE_SYSTEM_ALLOC_INFO *response_data;
5040 int bytes_returned = 0;
5041 __u16 params, byte_count;
5043 cifs_dbg(FYI, "OldQFSInfo\n");
5045 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5050 params = 2; /* level */
5051 pSMB->TotalDataCount = 0;
5052 pSMB->MaxParameterCount = cpu_to_le16(2);
5053 pSMB->MaxDataCount = cpu_to_le16(1000);
5054 pSMB->MaxSetupCount = 0;
5058 pSMB->Reserved2 = 0;
5059 byte_count = params + 1 /* pad */ ;
5060 pSMB->TotalParameterCount = cpu_to_le16(params);
5061 pSMB->ParameterCount = pSMB->TotalParameterCount;
5062 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5063 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5064 pSMB->DataCount = 0;
5065 pSMB->DataOffset = 0;
5066 pSMB->SetupCount = 1;
5067 pSMB->Reserved3 = 0;
5068 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5069 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
5070 inc_rfc1001_len(pSMB, byte_count);
5071 pSMB->ByteCount = cpu_to_le16(byte_count);
5073 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5074 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5076 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5077 } else { /* decode response */
5078 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5080 if (rc || get_bcc(&pSMBr->hdr) < 18)
5081 rc = -EIO; /* bad smb */
5083 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5084 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
5085 get_bcc(&pSMBr->hdr), data_offset);
5087 response_data = (FILE_SYSTEM_ALLOC_INFO *)
5088 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5090 le16_to_cpu(response_data->BytesPerSector) *
5091 le32_to_cpu(response_data->
5092 SectorsPerAllocationUnit);
5094 * much prefer larger but if server doesn't report
5095 * a valid size than 4K is a reasonable minimum
5097 if (FSData->f_bsize < 512)
5098 FSData->f_bsize = 4096;
5101 le32_to_cpu(response_data->TotalAllocationUnits);
5102 FSData->f_bfree = FSData->f_bavail =
5103 le32_to_cpu(response_data->FreeAllocationUnits);
5104 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5105 (unsigned long long)FSData->f_blocks,
5106 (unsigned long long)FSData->f_bfree,
5110 cifs_buf_release(pSMB);
5113 goto oldQFSInfoRetry;
5119 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
5120 struct kstatfs *FSData)
5122 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5123 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5124 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5125 FILE_SYSTEM_INFO *response_data;
5127 int bytes_returned = 0;
5128 __u16 params, byte_count;
5130 cifs_dbg(FYI, "In QFSInfo\n");
5132 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5137 params = 2; /* level */
5138 pSMB->TotalDataCount = 0;
5139 pSMB->MaxParameterCount = cpu_to_le16(2);
5140 pSMB->MaxDataCount = cpu_to_le16(1000);
5141 pSMB->MaxSetupCount = 0;
5145 pSMB->Reserved2 = 0;
5146 byte_count = params + 1 /* pad */ ;
5147 pSMB->TotalParameterCount = cpu_to_le16(params);
5148 pSMB->ParameterCount = pSMB->TotalParameterCount;
5149 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5150 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5151 pSMB->DataCount = 0;
5152 pSMB->DataOffset = 0;
5153 pSMB->SetupCount = 1;
5154 pSMB->Reserved3 = 0;
5155 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5156 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5157 inc_rfc1001_len(pSMB, byte_count);
5158 pSMB->ByteCount = cpu_to_le16(byte_count);
5160 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5161 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5163 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5164 } else { /* decode response */
5165 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5167 if (rc || get_bcc(&pSMBr->hdr) < 24)
5168 rc = -EIO; /* bad smb */
5170 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5174 *) (((char *) &pSMBr->hdr.Protocol) +
5177 le32_to_cpu(response_data->BytesPerSector) *
5178 le32_to_cpu(response_data->
5179 SectorsPerAllocationUnit);
5181 * much prefer larger but if server doesn't report
5182 * a valid size than 4K is a reasonable minimum
5184 if (FSData->f_bsize < 512)
5185 FSData->f_bsize = 4096;
5188 le64_to_cpu(response_data->TotalAllocationUnits);
5189 FSData->f_bfree = FSData->f_bavail =
5190 le64_to_cpu(response_data->FreeAllocationUnits);
5191 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5192 (unsigned long long)FSData->f_blocks,
5193 (unsigned long long)FSData->f_bfree,
5197 cifs_buf_release(pSMB);
5206 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5208 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5209 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5210 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5211 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5213 int bytes_returned = 0;
5214 __u16 params, byte_count;
5216 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5218 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5223 params = 2; /* level */
5224 pSMB->TotalDataCount = 0;
5225 pSMB->MaxParameterCount = cpu_to_le16(2);
5226 /* BB find exact max SMB PDU from sess structure BB */
5227 pSMB->MaxDataCount = cpu_to_le16(1000);
5228 pSMB->MaxSetupCount = 0;
5232 pSMB->Reserved2 = 0;
5233 byte_count = params + 1 /* pad */ ;
5234 pSMB->TotalParameterCount = cpu_to_le16(params);
5235 pSMB->ParameterCount = pSMB->TotalParameterCount;
5236 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5237 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5238 pSMB->DataCount = 0;
5239 pSMB->DataOffset = 0;
5240 pSMB->SetupCount = 1;
5241 pSMB->Reserved3 = 0;
5242 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5243 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5244 inc_rfc1001_len(pSMB, byte_count);
5245 pSMB->ByteCount = cpu_to_le16(byte_count);
5247 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5248 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5250 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5251 } else { /* decode response */
5252 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5254 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5255 /* BB also check if enough bytes returned */
5256 rc = -EIO; /* bad smb */
5258 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5260 (FILE_SYSTEM_ATTRIBUTE_INFO
5261 *) (((char *) &pSMBr->hdr.Protocol) +
5263 memcpy(&tcon->fsAttrInfo, response_data,
5264 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5267 cifs_buf_release(pSMB);
5270 goto QFSAttributeRetry;
5276 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5278 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5279 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5280 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5281 FILE_SYSTEM_DEVICE_INFO *response_data;
5283 int bytes_returned = 0;
5284 __u16 params, byte_count;
5286 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5288 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5293 params = 2; /* level */
5294 pSMB->TotalDataCount = 0;
5295 pSMB->MaxParameterCount = cpu_to_le16(2);
5296 /* BB find exact max SMB PDU from sess structure BB */
5297 pSMB->MaxDataCount = cpu_to_le16(1000);
5298 pSMB->MaxSetupCount = 0;
5302 pSMB->Reserved2 = 0;
5303 byte_count = params + 1 /* pad */ ;
5304 pSMB->TotalParameterCount = cpu_to_le16(params);
5305 pSMB->ParameterCount = pSMB->TotalParameterCount;
5306 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5307 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5309 pSMB->DataCount = 0;
5310 pSMB->DataOffset = 0;
5311 pSMB->SetupCount = 1;
5312 pSMB->Reserved3 = 0;
5313 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5314 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5315 inc_rfc1001_len(pSMB, byte_count);
5316 pSMB->ByteCount = cpu_to_le16(byte_count);
5318 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5319 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5321 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5322 } else { /* decode response */
5323 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5325 if (rc || get_bcc(&pSMBr->hdr) <
5326 sizeof(FILE_SYSTEM_DEVICE_INFO))
5327 rc = -EIO; /* bad smb */
5329 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5331 (FILE_SYSTEM_DEVICE_INFO *)
5332 (((char *) &pSMBr->hdr.Protocol) +
5334 memcpy(&tcon->fsDevInfo, response_data,
5335 sizeof(FILE_SYSTEM_DEVICE_INFO));
5338 cifs_buf_release(pSMB);
5341 goto QFSDeviceRetry;
5347 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5349 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5350 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5351 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5352 FILE_SYSTEM_UNIX_INFO *response_data;
5354 int bytes_returned = 0;
5355 __u16 params, byte_count;
5357 cifs_dbg(FYI, "In QFSUnixInfo\n");
5359 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5360 (void **) &pSMB, (void **) &pSMBr);
5364 params = 2; /* level */
5365 pSMB->TotalDataCount = 0;
5366 pSMB->DataCount = 0;
5367 pSMB->DataOffset = 0;
5368 pSMB->MaxParameterCount = cpu_to_le16(2);
5369 /* BB find exact max SMB PDU from sess structure BB */
5370 pSMB->MaxDataCount = cpu_to_le16(100);
5371 pSMB->MaxSetupCount = 0;
5375 pSMB->Reserved2 = 0;
5376 byte_count = params + 1 /* pad */ ;
5377 pSMB->ParameterCount = cpu_to_le16(params);
5378 pSMB->TotalParameterCount = pSMB->ParameterCount;
5379 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5380 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5381 pSMB->SetupCount = 1;
5382 pSMB->Reserved3 = 0;
5383 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5384 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5385 inc_rfc1001_len(pSMB, byte_count);
5386 pSMB->ByteCount = cpu_to_le16(byte_count);
5388 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5389 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5391 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5392 } else { /* decode response */
5393 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5395 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5396 rc = -EIO; /* bad smb */
5398 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5400 (FILE_SYSTEM_UNIX_INFO
5401 *) (((char *) &pSMBr->hdr.Protocol) +
5403 memcpy(&tcon->fsUnixInfo, response_data,
5404 sizeof(FILE_SYSTEM_UNIX_INFO));
5407 cifs_buf_release(pSMB);
5417 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5419 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5420 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5421 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5423 int bytes_returned = 0;
5424 __u16 params, param_offset, offset, byte_count;
5426 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5428 /* BB switch to small buf init to save memory */
5429 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5430 (void **) &pSMB, (void **) &pSMBr);
5434 params = 4; /* 2 bytes zero followed by info level. */
5435 pSMB->MaxSetupCount = 0;
5439 pSMB->Reserved2 = 0;
5440 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5442 offset = param_offset + params;
5444 pSMB->MaxParameterCount = cpu_to_le16(4);
5445 /* BB find exact max SMB PDU from sess structure BB */
5446 pSMB->MaxDataCount = cpu_to_le16(100);
5447 pSMB->SetupCount = 1;
5448 pSMB->Reserved3 = 0;
5449 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5450 byte_count = 1 /* pad */ + params + 12;
5452 pSMB->DataCount = cpu_to_le16(12);
5453 pSMB->ParameterCount = cpu_to_le16(params);
5454 pSMB->TotalDataCount = pSMB->DataCount;
5455 pSMB->TotalParameterCount = pSMB->ParameterCount;
5456 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5457 pSMB->DataOffset = cpu_to_le16(offset);
5461 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5464 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5465 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5466 pSMB->ClientUnixCap = cpu_to_le64(cap);
5468 inc_rfc1001_len(pSMB, byte_count);
5469 pSMB->ByteCount = cpu_to_le16(byte_count);
5471 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5472 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5474 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5475 } else { /* decode response */
5476 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5478 rc = -EIO; /* bad smb */
5480 cifs_buf_release(pSMB);
5483 goto SETFSUnixRetry;
5491 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5492 struct kstatfs *FSData)
5494 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5495 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5496 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5497 FILE_SYSTEM_POSIX_INFO *response_data;
5499 int bytes_returned = 0;
5500 __u16 params, byte_count;
5502 cifs_dbg(FYI, "In QFSPosixInfo\n");
5504 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5509 params = 2; /* level */
5510 pSMB->TotalDataCount = 0;
5511 pSMB->DataCount = 0;
5512 pSMB->DataOffset = 0;
5513 pSMB->MaxParameterCount = cpu_to_le16(2);
5514 /* BB find exact max SMB PDU from sess structure BB */
5515 pSMB->MaxDataCount = cpu_to_le16(100);
5516 pSMB->MaxSetupCount = 0;
5520 pSMB->Reserved2 = 0;
5521 byte_count = params + 1 /* pad */ ;
5522 pSMB->ParameterCount = cpu_to_le16(params);
5523 pSMB->TotalParameterCount = pSMB->ParameterCount;
5524 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5525 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5526 pSMB->SetupCount = 1;
5527 pSMB->Reserved3 = 0;
5528 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5529 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5530 inc_rfc1001_len(pSMB, byte_count);
5531 pSMB->ByteCount = cpu_to_le16(byte_count);
5533 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5534 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5536 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5537 } else { /* decode response */
5538 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5540 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5541 rc = -EIO; /* bad smb */
5543 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5545 (FILE_SYSTEM_POSIX_INFO
5546 *) (((char *) &pSMBr->hdr.Protocol) +
5549 le32_to_cpu(response_data->BlockSize);
5551 * much prefer larger but if server doesn't report
5552 * a valid size than 4K is a reasonable minimum
5554 if (FSData->f_bsize < 512)
5555 FSData->f_bsize = 4096;
5558 le64_to_cpu(response_data->TotalBlocks);
5560 le64_to_cpu(response_data->BlocksAvail);
5561 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5562 FSData->f_bavail = FSData->f_bfree;
5565 le64_to_cpu(response_data->UserBlocksAvail);
5567 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5569 le64_to_cpu(response_data->TotalFileNodes);
5570 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5572 le64_to_cpu(response_data->FreeFileNodes);
5575 cifs_buf_release(pSMB);
5585 * We can not use write of zero bytes trick to set file size due to need for
5586 * large file support. Also note that this SetPathInfo is preferred to
5587 * SetFileInfo based method in next routine which is only needed to work around
5588 * a sharing violation bugin Samba which this routine can run into.
5591 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5592 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5593 bool set_allocation)
5595 struct smb_com_transaction2_spi_req *pSMB = NULL;
5596 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5597 struct file_end_of_file_info *parm_data;
5600 int bytes_returned = 0;
5601 int remap = cifs_remap(cifs_sb);
5603 __u16 params, byte_count, data_count, param_offset, offset;
5605 cifs_dbg(FYI, "In SetEOF\n");
5607 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5612 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5614 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5615 PATH_MAX, cifs_sb->local_nls, remap);
5616 name_len++; /* trailing null */
5619 name_len = copy_path_name(pSMB->FileName, file_name);
5621 params = 6 + name_len;
5622 data_count = sizeof(struct file_end_of_file_info);
5623 pSMB->MaxParameterCount = cpu_to_le16(2);
5624 pSMB->MaxDataCount = cpu_to_le16(4100);
5625 pSMB->MaxSetupCount = 0;
5629 pSMB->Reserved2 = 0;
5630 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5631 InformationLevel) - 4;
5632 offset = param_offset + params;
5633 if (set_allocation) {
5634 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5635 pSMB->InformationLevel =
5636 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5638 pSMB->InformationLevel =
5639 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5640 } else /* Set File Size */ {
5641 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5642 pSMB->InformationLevel =
5643 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5645 pSMB->InformationLevel =
5646 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5650 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5652 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5653 pSMB->DataOffset = cpu_to_le16(offset);
5654 pSMB->SetupCount = 1;
5655 pSMB->Reserved3 = 0;
5656 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5657 byte_count = 3 /* pad */ + params + data_count;
5658 pSMB->DataCount = cpu_to_le16(data_count);
5659 pSMB->TotalDataCount = pSMB->DataCount;
5660 pSMB->ParameterCount = cpu_to_le16(params);
5661 pSMB->TotalParameterCount = pSMB->ParameterCount;
5662 pSMB->Reserved4 = 0;
5663 inc_rfc1001_len(pSMB, byte_count);
5664 parm_data->FileSize = cpu_to_le64(size);
5665 pSMB->ByteCount = cpu_to_le16(byte_count);
5666 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5667 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5669 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5671 cifs_buf_release(pSMB);
5680 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5681 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5683 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5684 struct file_end_of_file_info *parm_data;
5686 __u16 params, param_offset, offset, byte_count, count;
5688 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5690 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5695 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5696 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5699 pSMB->MaxSetupCount = 0;
5703 pSMB->Reserved2 = 0;
5704 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5705 offset = param_offset + params;
5707 count = sizeof(struct file_end_of_file_info);
5708 pSMB->MaxParameterCount = cpu_to_le16(2);
5709 /* BB find exact max SMB PDU from sess structure BB */
5710 pSMB->MaxDataCount = cpu_to_le16(1000);
5711 pSMB->SetupCount = 1;
5712 pSMB->Reserved3 = 0;
5713 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5714 byte_count = 3 /* pad */ + params + count;
5715 pSMB->DataCount = cpu_to_le16(count);
5716 pSMB->ParameterCount = cpu_to_le16(params);
5717 pSMB->TotalDataCount = pSMB->DataCount;
5718 pSMB->TotalParameterCount = pSMB->ParameterCount;
5719 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5721 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5723 pSMB->DataOffset = cpu_to_le16(offset);
5724 parm_data->FileSize = cpu_to_le64(size);
5725 pSMB->Fid = cfile->fid.netfid;
5726 if (set_allocation) {
5727 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5728 pSMB->InformationLevel =
5729 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5731 pSMB->InformationLevel =
5732 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5733 } else /* Set File Size */ {
5734 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5735 pSMB->InformationLevel =
5736 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5738 pSMB->InformationLevel =
5739 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5741 pSMB->Reserved4 = 0;
5742 inc_rfc1001_len(pSMB, byte_count);
5743 pSMB->ByteCount = cpu_to_le16(byte_count);
5744 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5745 cifs_small_buf_release(pSMB);
5747 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5751 /* Note: On -EAGAIN error only caller can retry on handle based calls
5752 since file handle passed in no longer valid */
5757 /* Some legacy servers such as NT4 require that the file times be set on
5758 an open handle, rather than by pathname - this is awkward due to
5759 potential access conflicts on the open, but it is unavoidable for these
5760 old servers since the only other choice is to go from 100 nanosecond DCE
5761 time and resort to the original setpathinfo level which takes the ancient
5762 DOS time format with 2 second granularity */
5764 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5765 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5767 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5770 __u16 params, param_offset, offset, byte_count, count;
5772 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5773 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5778 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5779 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5782 pSMB->MaxSetupCount = 0;
5786 pSMB->Reserved2 = 0;
5787 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5788 offset = param_offset + params;
5790 data_offset = (char *)pSMB +
5791 offsetof(struct smb_hdr, Protocol) + offset;
5793 count = sizeof(FILE_BASIC_INFO);
5794 pSMB->MaxParameterCount = cpu_to_le16(2);
5795 /* BB find max SMB PDU from sess */
5796 pSMB->MaxDataCount = cpu_to_le16(1000);
5797 pSMB->SetupCount = 1;
5798 pSMB->Reserved3 = 0;
5799 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5800 byte_count = 3 /* pad */ + params + count;
5801 pSMB->DataCount = cpu_to_le16(count);
5802 pSMB->ParameterCount = cpu_to_le16(params);
5803 pSMB->TotalDataCount = pSMB->DataCount;
5804 pSMB->TotalParameterCount = pSMB->ParameterCount;
5805 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5806 pSMB->DataOffset = cpu_to_le16(offset);
5808 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5809 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5811 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5812 pSMB->Reserved4 = 0;
5813 inc_rfc1001_len(pSMB, byte_count);
5814 pSMB->ByteCount = cpu_to_le16(byte_count);
5815 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5816 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5817 cifs_small_buf_release(pSMB);
5819 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5822 /* Note: On -EAGAIN error only caller can retry on handle based calls
5823 since file handle passed in no longer valid */
5829 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5830 bool delete_file, __u16 fid, __u32 pid_of_opener)
5832 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5835 __u16 params, param_offset, offset, byte_count, count;
5837 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5838 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5843 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5844 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5847 pSMB->MaxSetupCount = 0;
5851 pSMB->Reserved2 = 0;
5852 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5853 offset = param_offset + params;
5855 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5858 pSMB->MaxParameterCount = cpu_to_le16(2);
5859 /* BB find max SMB PDU from sess */
5860 pSMB->MaxDataCount = cpu_to_le16(1000);
5861 pSMB->SetupCount = 1;
5862 pSMB->Reserved3 = 0;
5863 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5864 byte_count = 3 /* pad */ + params + count;
5865 pSMB->DataCount = cpu_to_le16(count);
5866 pSMB->ParameterCount = cpu_to_le16(params);
5867 pSMB->TotalDataCount = pSMB->DataCount;
5868 pSMB->TotalParameterCount = pSMB->ParameterCount;
5869 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5870 pSMB->DataOffset = cpu_to_le16(offset);
5872 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5873 pSMB->Reserved4 = 0;
5874 inc_rfc1001_len(pSMB, byte_count);
5875 pSMB->ByteCount = cpu_to_le16(byte_count);
5876 *data_offset = delete_file ? 1 : 0;
5877 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5878 cifs_small_buf_release(pSMB);
5880 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5886 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5887 const char *fileName, const FILE_BASIC_INFO *data,
5888 const struct nls_table *nls_codepage, int remap)
5890 TRANSACTION2_SPI_REQ *pSMB = NULL;
5891 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5894 int bytes_returned = 0;
5896 __u16 params, param_offset, offset, byte_count, count;
5898 cifs_dbg(FYI, "In SetTimes\n");
5901 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5906 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5908 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5909 PATH_MAX, nls_codepage, remap);
5910 name_len++; /* trailing null */
5913 name_len = copy_path_name(pSMB->FileName, fileName);
5916 params = 6 + name_len;
5917 count = sizeof(FILE_BASIC_INFO);
5918 pSMB->MaxParameterCount = cpu_to_le16(2);
5919 /* BB find max SMB PDU from sess structure BB */
5920 pSMB->MaxDataCount = cpu_to_le16(1000);
5921 pSMB->MaxSetupCount = 0;
5925 pSMB->Reserved2 = 0;
5926 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5927 InformationLevel) - 4;
5928 offset = param_offset + params;
5929 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5930 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5931 pSMB->DataOffset = cpu_to_le16(offset);
5932 pSMB->SetupCount = 1;
5933 pSMB->Reserved3 = 0;
5934 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5935 byte_count = 3 /* pad */ + params + count;
5937 pSMB->DataCount = cpu_to_le16(count);
5938 pSMB->ParameterCount = cpu_to_le16(params);
5939 pSMB->TotalDataCount = pSMB->DataCount;
5940 pSMB->TotalParameterCount = pSMB->ParameterCount;
5941 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5942 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5944 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5945 pSMB->Reserved4 = 0;
5946 inc_rfc1001_len(pSMB, byte_count);
5947 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5948 pSMB->ByteCount = cpu_to_le16(byte_count);
5949 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5950 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5952 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5954 cifs_buf_release(pSMB);
5962 /* Can not be used to set time stamps yet (due to old DOS time format) */
5963 /* Can be used to set attributes */
5964 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5965 handling it anyway and NT4 was what we thought it would be needed for
5966 Do not delete it until we prove whether needed for Win9x though */
5968 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
5969 __u16 dos_attrs, const struct nls_table *nls_codepage)
5971 SETATTR_REQ *pSMB = NULL;
5972 SETATTR_RSP *pSMBr = NULL;
5977 cifs_dbg(FYI, "In SetAttrLegacy\n");
5980 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5985 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5987 ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5988 PATH_MAX, nls_codepage);
5989 name_len++; /* trailing null */
5992 name_len = copy_path_name(pSMB->fileName, fileName);
5994 pSMB->attr = cpu_to_le16(dos_attrs);
5995 pSMB->BufferFormat = 0x04;
5996 inc_rfc1001_len(pSMB, name_len + 1);
5997 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5998 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5999 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6001 cifs_dbg(FYI, "Error in LegacySetAttr = %d\n", rc);
6003 cifs_buf_release(pSMB);
6006 goto SetAttrLgcyRetry;
6010 #endif /* temporarily unneeded SetAttr legacy function */
6013 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
6014 const struct cifs_unix_set_info_args *args)
6016 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
6017 u64 mode = args->mode;
6019 if (uid_valid(args->uid))
6020 uid = from_kuid(&init_user_ns, args->uid);
6021 if (gid_valid(args->gid))
6022 gid = from_kgid(&init_user_ns, args->gid);
6025 * Samba server ignores set of file size to zero due to bugs in some
6026 * older clients, but we should be precise - we use SetFileSize to
6027 * set file size and do not want to truncate file size to zero
6028 * accidentally as happened on one Samba server beta by putting
6029 * zero instead of -1 here
6031 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
6032 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
6033 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
6034 data_offset->LastAccessTime = cpu_to_le64(args->atime);
6035 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
6036 data_offset->Uid = cpu_to_le64(uid);
6037 data_offset->Gid = cpu_to_le64(gid);
6038 /* better to leave device as zero when it is */
6039 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
6040 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
6041 data_offset->Permissions = cpu_to_le64(mode);
6044 data_offset->Type = cpu_to_le32(UNIX_FILE);
6045 else if (S_ISDIR(mode))
6046 data_offset->Type = cpu_to_le32(UNIX_DIR);
6047 else if (S_ISLNK(mode))
6048 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
6049 else if (S_ISCHR(mode))
6050 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
6051 else if (S_ISBLK(mode))
6052 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
6053 else if (S_ISFIFO(mode))
6054 data_offset->Type = cpu_to_le32(UNIX_FIFO);
6055 else if (S_ISSOCK(mode))
6056 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
6060 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
6061 const struct cifs_unix_set_info_args *args,
6062 u16 fid, u32 pid_of_opener)
6064 struct smb_com_transaction2_sfi_req *pSMB = NULL;
6067 u16 params, param_offset, offset, byte_count, count;
6069 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
6070 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
6075 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
6076 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
6079 pSMB->MaxSetupCount = 0;
6083 pSMB->Reserved2 = 0;
6084 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
6085 offset = param_offset + params;
6087 data_offset = (char *)pSMB +
6088 offsetof(struct smb_hdr, Protocol) + offset;
6090 count = sizeof(FILE_UNIX_BASIC_INFO);
6092 pSMB->MaxParameterCount = cpu_to_le16(2);
6093 /* BB find max SMB PDU from sess */
6094 pSMB->MaxDataCount = cpu_to_le16(1000);
6095 pSMB->SetupCount = 1;
6096 pSMB->Reserved3 = 0;
6097 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
6098 byte_count = 3 /* pad */ + params + count;
6099 pSMB->DataCount = cpu_to_le16(count);
6100 pSMB->ParameterCount = cpu_to_le16(params);
6101 pSMB->TotalDataCount = pSMB->DataCount;
6102 pSMB->TotalParameterCount = pSMB->ParameterCount;
6103 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6104 pSMB->DataOffset = cpu_to_le16(offset);
6106 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6107 pSMB->Reserved4 = 0;
6108 inc_rfc1001_len(pSMB, byte_count);
6109 pSMB->ByteCount = cpu_to_le16(byte_count);
6111 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
6113 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
6114 cifs_small_buf_release(pSMB);
6116 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
6119 /* Note: On -EAGAIN error only caller can retry on handle based calls
6120 since file handle passed in no longer valid */
6126 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
6127 const char *file_name,
6128 const struct cifs_unix_set_info_args *args,
6129 const struct nls_table *nls_codepage, int remap)
6131 TRANSACTION2_SPI_REQ *pSMB = NULL;
6132 TRANSACTION2_SPI_RSP *pSMBr = NULL;
6135 int bytes_returned = 0;
6136 FILE_UNIX_BASIC_INFO *data_offset;
6137 __u16 params, param_offset, offset, count, byte_count;
6139 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
6141 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6146 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6148 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6149 PATH_MAX, nls_codepage, remap);
6150 name_len++; /* trailing null */
6153 name_len = copy_path_name(pSMB->FileName, file_name);
6156 params = 6 + name_len;
6157 count = sizeof(FILE_UNIX_BASIC_INFO);
6158 pSMB->MaxParameterCount = cpu_to_le16(2);
6159 /* BB find max SMB PDU from sess structure BB */
6160 pSMB->MaxDataCount = cpu_to_le16(1000);
6161 pSMB->MaxSetupCount = 0;
6165 pSMB->Reserved2 = 0;
6166 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6167 InformationLevel) - 4;
6168 offset = param_offset + params;
6170 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6172 memset(data_offset, 0, count);
6173 pSMB->DataOffset = cpu_to_le16(offset);
6174 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6175 pSMB->SetupCount = 1;
6176 pSMB->Reserved3 = 0;
6177 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6178 byte_count = 3 /* pad */ + params + count;
6179 pSMB->ParameterCount = cpu_to_le16(params);
6180 pSMB->DataCount = cpu_to_le16(count);
6181 pSMB->TotalParameterCount = pSMB->ParameterCount;
6182 pSMB->TotalDataCount = pSMB->DataCount;
6183 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6184 pSMB->Reserved4 = 0;
6185 inc_rfc1001_len(pSMB, byte_count);
6187 cifs_fill_unix_set_info(data_offset, args);
6189 pSMB->ByteCount = cpu_to_le16(byte_count);
6190 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6191 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6193 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6195 cifs_buf_release(pSMB);
6201 #ifdef CONFIG_CIFS_XATTR
6203 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6204 * function used by listxattr and getxattr type calls. When ea_name is set,
6205 * it looks for that attribute name and stuffs that value into the EAData
6206 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6207 * buffer. In both cases, the return value is either the length of the
6208 * resulting data or a negative error code. If EAData is a NULL pointer then
6209 * the data isn't copied to it, but the length is returned.
6212 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6213 const unsigned char *searchName, const unsigned char *ea_name,
6214 char *EAData, size_t buf_size,
6215 struct cifs_sb_info *cifs_sb)
6217 /* BB assumes one setup word */
6218 TRANSACTION2_QPI_REQ *pSMB = NULL;
6219 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6220 int remap = cifs_remap(cifs_sb);
6221 struct nls_table *nls_codepage = cifs_sb->local_nls;
6225 struct fealist *ea_response_data;
6226 struct fea *temp_fea;
6229 __u16 params, byte_count, data_offset;
6230 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6232 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6234 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6239 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6241 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6242 PATH_MAX, nls_codepage, remap);
6243 list_len++; /* trailing null */
6246 list_len = copy_path_name(pSMB->FileName, searchName);
6249 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6250 pSMB->TotalDataCount = 0;
6251 pSMB->MaxParameterCount = cpu_to_le16(2);
6252 /* BB find exact max SMB PDU from sess structure BB */
6253 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6254 pSMB->MaxSetupCount = 0;
6258 pSMB->Reserved2 = 0;
6259 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6260 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6261 pSMB->DataCount = 0;
6262 pSMB->DataOffset = 0;
6263 pSMB->SetupCount = 1;
6264 pSMB->Reserved3 = 0;
6265 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6266 byte_count = params + 1 /* pad */ ;
6267 pSMB->TotalParameterCount = cpu_to_le16(params);
6268 pSMB->ParameterCount = pSMB->TotalParameterCount;
6269 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6270 pSMB->Reserved4 = 0;
6271 inc_rfc1001_len(pSMB, byte_count);
6272 pSMB->ByteCount = cpu_to_le16(byte_count);
6274 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6275 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6277 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6282 /* BB also check enough total bytes returned */
6283 /* BB we need to improve the validity checking
6284 of these trans2 responses */
6286 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6287 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6288 rc = -EIO; /* bad smb */
6292 /* check that length of list is not more than bcc */
6293 /* check that each entry does not go beyond length
6295 /* check that each element of each entry does not
6296 go beyond end of list */
6297 /* validate_trans2_offsets() */
6298 /* BB check if start of smb + data_offset > &bcc+ bcc */
6300 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6301 ea_response_data = (struct fealist *)
6302 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6304 list_len = le32_to_cpu(ea_response_data->list_len);
6305 cifs_dbg(FYI, "ea length %d\n", list_len);
6306 if (list_len <= 8) {
6307 cifs_dbg(FYI, "empty EA list returned from server\n");
6308 /* didn't find the named attribute */
6314 /* make sure list_len doesn't go past end of SMB */
6315 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6316 if ((char *)ea_response_data + list_len > end_of_smb) {
6317 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6322 /* account for ea list len */
6324 temp_fea = ea_response_data->list;
6325 temp_ptr = (char *)temp_fea;
6326 while (list_len > 0) {
6327 unsigned int name_len;
6332 /* make sure we can read name_len and value_len */
6334 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6339 name_len = temp_fea->name_len;
6340 value_len = le16_to_cpu(temp_fea->value_len);
6341 list_len -= name_len + 1 + value_len;
6343 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6349 if (ea_name_len == name_len &&
6350 memcmp(ea_name, temp_ptr, name_len) == 0) {
6351 temp_ptr += name_len + 1;
6355 if ((size_t)value_len > buf_size) {
6359 memcpy(EAData, temp_ptr, value_len);
6363 /* account for prefix user. and trailing null */
6364 rc += (5 + 1 + name_len);
6365 if (rc < (int) buf_size) {
6366 memcpy(EAData, "user.", 5);
6368 memcpy(EAData, temp_ptr, name_len);
6370 /* null terminate name */
6373 } else if (buf_size == 0) {
6374 /* skip copy - calc size only */
6376 /* stop before overrun buffer */
6381 temp_ptr += name_len + 1 + value_len;
6382 temp_fea = (struct fea *)temp_ptr;
6385 /* didn't find the named attribute */
6390 cifs_buf_release(pSMB);
6398 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6399 const char *fileName, const char *ea_name, const void *ea_value,
6400 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6401 struct cifs_sb_info *cifs_sb)
6403 struct smb_com_transaction2_spi_req *pSMB = NULL;
6404 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6405 struct fealist *parm_data;
6408 int bytes_returned = 0;
6409 __u16 params, param_offset, byte_count, offset, count;
6410 int remap = cifs_remap(cifs_sb);
6412 cifs_dbg(FYI, "In SetEA\n");
6414 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6419 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6421 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6422 PATH_MAX, nls_codepage, remap);
6423 name_len++; /* trailing null */
6426 name_len = copy_path_name(pSMB->FileName, fileName);
6429 params = 6 + name_len;
6431 /* done calculating parms using name_len of file name,
6432 now use name_len to calculate length of ea name
6433 we are going to create in the inode xattrs */
6434 if (ea_name == NULL)
6437 name_len = strnlen(ea_name, 255);
6439 count = sizeof(*parm_data) + ea_value_len + name_len;
6440 pSMB->MaxParameterCount = cpu_to_le16(2);
6441 /* BB find max SMB PDU from sess */
6442 pSMB->MaxDataCount = cpu_to_le16(1000);
6443 pSMB->MaxSetupCount = 0;
6447 pSMB->Reserved2 = 0;
6448 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6449 InformationLevel) - 4;
6450 offset = param_offset + params;
6451 pSMB->InformationLevel =
6452 cpu_to_le16(SMB_SET_FILE_EA);
6454 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6455 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6456 pSMB->DataOffset = cpu_to_le16(offset);
6457 pSMB->SetupCount = 1;
6458 pSMB->Reserved3 = 0;
6459 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6460 byte_count = 3 /* pad */ + params + count;
6461 pSMB->DataCount = cpu_to_le16(count);
6462 parm_data->list_len = cpu_to_le32(count);
6463 parm_data->list[0].EA_flags = 0;
6464 /* we checked above that name len is less than 255 */
6465 parm_data->list[0].name_len = (__u8)name_len;
6466 /* EA names are always ASCII */
6468 strncpy(parm_data->list[0].name, ea_name, name_len);
6469 parm_data->list[0].name[name_len] = 0;
6470 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6471 /* caller ensures that ea_value_len is less than 64K but
6472 we need to ensure that it fits within the smb */
6474 /*BB add length check to see if it would fit in
6475 negotiated SMB buffer size BB */
6476 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6478 memcpy(parm_data->list[0].name+name_len+1,
6479 ea_value, ea_value_len);
6481 pSMB->TotalDataCount = pSMB->DataCount;
6482 pSMB->ParameterCount = cpu_to_le16(params);
6483 pSMB->TotalParameterCount = pSMB->ParameterCount;
6484 pSMB->Reserved4 = 0;
6485 inc_rfc1001_len(pSMB, byte_count);
6486 pSMB->ByteCount = cpu_to_le16(byte_count);
6487 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6488 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6490 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6492 cifs_buf_release(pSMB);