4 * Copyright (C) International Business Machines Corp., 2002,2010
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"
45 #include "smb2proto.h"
47 #include "smbdirect.h"
48 #ifdef CONFIG_CIFS_DFS_UPCALL
49 #include "dfs_cache.h"
52 #ifdef CONFIG_CIFS_POSIX
57 #ifdef CONFIG_CIFS_WEAK_PW_HASH
58 {LANMAN_PROT, "\2LM1.2X002"},
59 {LANMAN2_PROT, "\2LANMAN2.1"},
60 #endif /* weak password hashing for legacy clients */
61 {CIFS_PROT, "\2NT LM 0.12"},
62 {POSIX_PROT, "\2POSIX 2"},
70 #ifdef CONFIG_CIFS_WEAK_PW_HASH
71 {LANMAN_PROT, "\2LM1.2X002"},
72 {LANMAN2_PROT, "\2LANMAN2.1"},
73 #endif /* weak password hashing for legacy clients */
74 {CIFS_PROT, "\2NT LM 0.12"},
79 /* define the number of elements in the cifs dialect array */
80 #ifdef CONFIG_CIFS_POSIX
81 #ifdef CONFIG_CIFS_WEAK_PW_HASH
82 #define CIFS_NUM_PROT 4
84 #define CIFS_NUM_PROT 2
85 #endif /* CIFS_WEAK_PW_HASH */
87 #ifdef CONFIG_CIFS_WEAK_PW_HASH
88 #define CIFS_NUM_PROT 3
90 #define CIFS_NUM_PROT 1
91 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
92 #endif /* CIFS_POSIX */
95 * Mark as invalid, all open files on tree connections since they
96 * were closed when session to server was lost.
99 cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
101 struct cifsFileInfo *open_file = NULL;
102 struct list_head *tmp;
103 struct list_head *tmp1;
105 /* list all files open on tree connection and mark them invalid */
106 spin_lock(&tcon->open_file_lock);
107 list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
108 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
109 open_file->invalidHandle = true;
110 open_file->oplock_break_cancelled = true;
112 spin_unlock(&tcon->open_file_lock);
114 mutex_lock(&tcon->crfid.fid_mutex);
115 tcon->crfid.is_valid = false;
116 /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
117 close_shroot_lease_locked(&tcon->crfid);
118 memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
119 mutex_unlock(&tcon->crfid.fid_mutex);
122 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
127 #ifdef CONFIG_CIFS_DFS_UPCALL
128 static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
129 struct cifs_tcon *tcon)
132 struct dfs_cache_tgt_list tl;
133 struct dfs_cache_tgt_iterator *it = NULL;
135 const char *tcp_host;
137 const char *dfs_host;
140 tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
145 scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
146 tcon->ses->server->hostname);
147 rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
151 if (!tcon->dfs_path) {
152 rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
156 rc = dfs_cache_noreq_find(tcon->dfs_path + 1, NULL, &tl);
160 extract_unc_hostname(tcon->ses->server->hostname, &tcp_host,
163 for (it = dfs_cache_get_tgt_iterator(&tl); it;
164 it = dfs_cache_get_next_tgt(&tl, it)) {
165 const char *tgt = dfs_cache_get_tgt_name(it);
167 extract_unc_hostname(tgt, &dfs_host, &dfs_host_len);
169 if (dfs_host_len != tcp_host_len
170 || strncasecmp(dfs_host, tcp_host, dfs_host_len) != 0) {
171 cifs_dbg(FYI, "%s: skipping %.*s, doesn't match %.*s",
173 (int)dfs_host_len, dfs_host,
174 (int)tcp_host_len, tcp_host);
178 scnprintf(tree, MAX_TREE_SIZE, "\\%s", tgt);
180 rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
189 rc = dfs_cache_noreq_update_tgthint(tcon->dfs_path + 1,
194 dfs_cache_free_tgts(&tl);
200 static inline int __cifs_reconnect_tcon(const struct nls_table *nlsc,
201 struct cifs_tcon *tcon)
203 return CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
207 /* reconnect the socket, tcon, and smb session if needed */
209 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
212 struct cifs_ses *ses;
213 struct TCP_Server_Info *server;
214 struct nls_table *nls_codepage;
218 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
219 * tcp and smb session status done differently for those three - in the
226 server = ses->server;
229 * only tree disconnect, open, and write, (and ulogoff which does not
230 * have tcon) are allowed as we start force umount
232 if (tcon->tidStatus == CifsExiting) {
233 if (smb_command != SMB_COM_WRITE_ANDX &&
234 smb_command != SMB_COM_OPEN_ANDX &&
235 smb_command != SMB_COM_TREE_DISCONNECT) {
236 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
242 retries = server->nr_targets;
245 * Give demultiplex thread up to 10 seconds to each target available for
246 * reconnect -- should be greater than cifs socket timeout which is 7
249 while (server->tcpStatus == CifsNeedReconnect) {
250 rc = wait_event_interruptible_timeout(server->response_q,
251 (server->tcpStatus != CifsNeedReconnect),
254 cifs_dbg(FYI, "%s: aborting reconnect due to a received"
255 " signal by the process\n", __func__);
259 /* are we still trying to reconnect? */
260 if (server->tcpStatus != CifsNeedReconnect)
267 * on "soft" mounts we wait once. Hard mounts keep
268 * retrying until process is killed or server comes
272 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
275 retries = server->nr_targets;
278 if (!ses->need_reconnect && !tcon->need_reconnect)
281 nls_codepage = load_nls_default();
284 * need to prevent multiple threads trying to simultaneously
285 * reconnect the same SMB session
287 mutex_lock(&ses->session_mutex);
290 * Recheck after acquire mutex. If another thread is negotiating
291 * and the server never sends an answer the socket will be closed
292 * and tcpStatus set to reconnect.
294 if (server->tcpStatus == CifsNeedReconnect) {
296 mutex_unlock(&ses->session_mutex);
300 rc = cifs_negotiate_protocol(0, ses);
301 if (rc == 0 && ses->need_reconnect)
302 rc = cifs_setup_session(0, ses, nls_codepage);
304 /* do we need to reconnect tcon? */
305 if (rc || !tcon->need_reconnect) {
306 mutex_unlock(&ses->session_mutex);
310 cifs_mark_open_files_invalid(tcon);
311 rc = __cifs_reconnect_tcon(nls_codepage, tcon);
312 mutex_unlock(&ses->session_mutex);
313 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
316 printk_once(KERN_WARNING "reconnect tcon failed rc = %d\n", rc);
320 atomic_inc(&tconInfoReconnectCount);
322 /* tell server Unix caps we support */
323 if (ses->capabilities & CAP_UNIX)
324 reset_cifs_unix_caps(0, tcon, NULL, NULL);
327 * Removed call to reopen open files here. It is safer (and faster) to
328 * reopen files one at a time as needed in read and write.
330 * FIXME: what about file locks? don't we need to reclaim them ASAP?
335 * Check if handle based operation so we know whether we can continue
336 * or not without returning to caller to reset file handle
338 switch (smb_command) {
339 case SMB_COM_READ_ANDX:
340 case SMB_COM_WRITE_ANDX:
342 case SMB_COM_FIND_CLOSE2:
343 case SMB_COM_LOCKING_ANDX:
347 unload_nls(nls_codepage);
351 /* Allocate and return pointer to an SMB request buffer, and set basic
352 SMB information in the SMB header. If the return code is zero, this
353 function must have filled in request_buf pointer */
355 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
360 rc = cifs_reconnect_tcon(tcon, smb_command);
364 *request_buf = cifs_small_buf_get();
365 if (*request_buf == NULL) {
366 /* BB should we add a retry in here if not a writepage? */
370 header_assemble((struct smb_hdr *) *request_buf, smb_command,
374 cifs_stats_inc(&tcon->num_smbs_sent);
380 small_smb_init_no_tc(const int smb_command, const int wct,
381 struct cifs_ses *ses, void **request_buf)
384 struct smb_hdr *buffer;
386 rc = small_smb_init(smb_command, wct, NULL, request_buf);
390 buffer = (struct smb_hdr *)*request_buf;
391 buffer->Mid = get_next_mid(ses->server);
392 if (ses->capabilities & CAP_UNICODE)
393 buffer->Flags2 |= SMBFLG2_UNICODE;
394 if (ses->capabilities & CAP_STATUS32)
395 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
397 /* uid, tid can stay at zero as set in header assemble */
399 /* BB add support for turning on the signing when
400 this function is used after 1st of session setup requests */
405 /* If the return code is zero, this function must fill in request_buf pointer */
407 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
408 void **request_buf, void **response_buf)
410 *request_buf = cifs_buf_get();
411 if (*request_buf == NULL) {
412 /* BB should we add a retry in here if not a writepage? */
415 /* Although the original thought was we needed the response buf for */
416 /* potential retries of smb operations it turns out we can determine */
417 /* from the mid flags when the request buffer can be resent without */
418 /* having to use a second distinct buffer for the response */
420 *response_buf = *request_buf;
422 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
426 cifs_stats_inc(&tcon->num_smbs_sent);
431 /* If the return code is zero, this function must fill in request_buf pointer */
433 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
434 void **request_buf, void **response_buf)
438 rc = cifs_reconnect_tcon(tcon, smb_command);
442 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
446 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
447 void **request_buf, void **response_buf)
449 if (tcon->ses->need_reconnect || tcon->need_reconnect)
452 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
455 static int validate_t2(struct smb_t2_rsp *pSMB)
457 unsigned int total_size;
459 /* check for plausible wct */
460 if (pSMB->hdr.WordCount < 10)
463 /* check for parm and data offset going beyond end of smb */
464 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
465 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
468 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
469 if (total_size >= 512)
472 /* check that bcc is at least as big as parms + data, and that it is
473 * less than negotiated smb buffer
475 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
476 if (total_size > get_bcc(&pSMB->hdr) ||
477 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
482 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
483 sizeof(struct smb_t2_rsp) + 16);
488 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
492 char *guid = pSMBr->u.extended_response.GUID;
493 struct TCP_Server_Info *server = ses->server;
495 count = get_bcc(&pSMBr->hdr);
496 if (count < SMB1_CLIENT_GUID_SIZE)
499 spin_lock(&cifs_tcp_ses_lock);
500 if (server->srv_count > 1) {
501 spin_unlock(&cifs_tcp_ses_lock);
502 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
503 cifs_dbg(FYI, "server UID changed\n");
504 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
507 spin_unlock(&cifs_tcp_ses_lock);
508 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
511 if (count == SMB1_CLIENT_GUID_SIZE) {
512 server->sec_ntlmssp = true;
514 count -= SMB1_CLIENT_GUID_SIZE;
515 rc = decode_negTokenInit(
516 pSMBr->u.extended_response.SecurityBlob, count, server);
525 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
527 bool srv_sign_required = server->sec_mode & server->vals->signing_required;
528 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
529 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
532 * Is signing required by mnt options? If not then check
533 * global_secflags to see if it is there.
535 if (!mnt_sign_required)
536 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
540 * If signing is required then it's automatically enabled too,
541 * otherwise, check to see if the secflags allow it.
543 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
544 (global_secflags & CIFSSEC_MAY_SIGN);
546 /* If server requires signing, does client allow it? */
547 if (srv_sign_required) {
548 if (!mnt_sign_enabled) {
549 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!");
555 /* If client requires signing, does server allow it? */
556 if (mnt_sign_required) {
557 if (!srv_sign_enabled) {
558 cifs_dbg(VFS, "Server does not support signing!");
564 if (cifs_rdma_enabled(server) && server->sign)
565 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled");
570 #ifdef CONFIG_CIFS_WEAK_PW_HASH
572 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
575 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
577 if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
580 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
581 server->maxReq = min_t(unsigned int,
582 le16_to_cpu(rsp->MaxMpxCount),
584 set_credits(server, server->maxReq);
585 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
586 /* even though we do not use raw we might as well set this
587 accurately, in case we ever find a need for it */
588 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
589 server->max_rw = 0xFF00;
590 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
592 server->max_rw = 0;/* do not need to use raw anyway */
593 server->capabilities = CAP_MPX_MODE;
595 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
597 /* OS/2 often does not set timezone therefore
598 * we must use server time to calc time zone.
599 * Could deviate slightly from the right zone.
600 * Smallest defined timezone difference is 15 minutes
601 * (i.e. Nepal). Rounding up/down is done to match
604 int val, seconds, remain, result;
605 struct timespec64 ts;
606 time64_t utc = ktime_get_real_seconds();
607 ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
608 rsp->SrvTime.Time, 0);
609 cifs_dbg(FYI, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
612 val = (int)(utc - ts.tv_sec);
614 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
615 remain = seconds % MIN_TZ_ADJ;
616 if (remain >= (MIN_TZ_ADJ / 2))
617 result += MIN_TZ_ADJ;
620 server->timeAdj = result;
622 server->timeAdj = (int)tmp;
623 server->timeAdj *= 60; /* also in seconds */
625 cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
628 /* BB get server time for time conversions and add
629 code to use it and timezone since this is not UTC */
631 if (rsp->EncryptionKeyLength ==
632 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
633 memcpy(server->cryptkey, rsp->EncryptionKey,
634 CIFS_CRYPTO_KEY_SIZE);
635 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
636 return -EIO; /* need cryptkey unless plain text */
639 cifs_dbg(FYI, "LANMAN negotiated\n");
644 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
646 cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
652 should_set_ext_sec_flag(enum securityEnum sectype)
659 if (global_secflags &
660 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
669 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
672 NEGOTIATE_RSP *pSMBr;
676 struct TCP_Server_Info *server = ses->server;
680 WARN(1, "%s: server is NULL!\n", __func__);
684 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
685 (void **) &pSMB, (void **) &pSMBr);
689 pSMB->hdr.Mid = get_next_mid(server);
690 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
692 if (should_set_ext_sec_flag(ses->sectype)) {
693 cifs_dbg(FYI, "Requesting extended security.");
694 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
699 * We know that all the name entries in the protocols array
700 * are short (< 16 bytes anyway) and are NUL terminated.
702 for (i = 0; i < CIFS_NUM_PROT; i++) {
703 size_t len = strlen(protocols[i].name) + 1;
705 memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
708 inc_rfc1001_len(pSMB, count);
709 pSMB->ByteCount = cpu_to_le16(count);
711 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
712 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
716 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
717 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
718 /* Check wct = 1 error case */
719 if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
720 /* core returns wct = 1, but we do not ask for core - otherwise
721 small wct just comes when dialect index is -1 indicating we
722 could not negotiate a common dialect */
725 } else if (pSMBr->hdr.WordCount == 13) {
726 server->negflavor = CIFS_NEGFLAVOR_LANMAN;
727 rc = decode_lanman_negprot_rsp(server, pSMBr);
729 } else if (pSMBr->hdr.WordCount != 17) {
734 /* else wct == 17, NTLM or better */
736 server->sec_mode = pSMBr->SecurityMode;
737 if ((server->sec_mode & SECMODE_USER) == 0)
738 cifs_dbg(FYI, "share mode security\n");
740 /* one byte, so no need to convert this or EncryptionKeyLen from
742 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
744 set_credits(server, server->maxReq);
745 /* probably no need to store and check maxvcs */
746 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
747 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
748 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
749 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
750 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
751 server->timeAdj *= 60;
753 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
754 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
755 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
756 CIFS_CRYPTO_KEY_SIZE);
757 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
758 server->capabilities & CAP_EXTENDED_SECURITY) {
759 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
760 rc = decode_ext_sec_blob(ses, pSMBr);
761 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
762 rc = -EIO; /* no crypt key only if plain text pwd */
764 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
765 server->capabilities &= ~CAP_EXTENDED_SECURITY;
770 rc = cifs_enable_signing(server, ses->sign);
772 cifs_buf_release(pSMB);
774 cifs_dbg(FYI, "negprot rc %d\n", rc);
779 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
781 struct smb_hdr *smb_buffer;
784 cifs_dbg(FYI, "In tree disconnect\n");
786 /* BB: do we need to check this? These should never be NULL. */
787 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
791 * No need to return error on this operation if tid invalidated and
792 * closed on server already e.g. due to tcp session crashing. Also,
793 * the tcon is no longer on the list, so no need to take lock before
796 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
799 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
800 (void **)&smb_buffer);
804 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
805 cifs_small_buf_release(smb_buffer);
807 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
809 /* No need to return error on this operation if tid invalidated and
810 closed on server already e.g. due to tcp session crashing */
818 * This is a no-op for now. We're not really interested in the reply, but
819 * rather in the fact that the server sent one and that server->lstrp
822 * FIXME: maybe we should consider checking that the reply matches request?
825 cifs_echo_callback(struct mid_q_entry *mid)
827 struct TCP_Server_Info *server = mid->callback_data;
828 struct cifs_credits credits = { .value = 1, .instance = 0 };
830 DeleteMidQEntry(mid);
831 add_credits(server, &credits, CIFS_ECHO_OP);
835 CIFSSMBEcho(struct TCP_Server_Info *server)
840 struct smb_rqst rqst = { .rq_iov = iov,
843 cifs_dbg(FYI, "In echo request\n");
845 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
849 if (server->capabilities & CAP_UNICODE)
850 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
852 /* set up echo request */
853 smb->hdr.Tid = 0xffff;
854 smb->hdr.WordCount = 1;
855 put_unaligned_le16(1, &smb->EchoCount);
856 put_bcc(1, &smb->hdr);
858 inc_rfc1001_len(smb, 3);
861 iov[0].iov_base = smb;
862 iov[1].iov_len = get_rfc1002_length(smb);
863 iov[1].iov_base = (char *)smb + 4;
865 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
866 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
868 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
870 cifs_small_buf_release(smb);
876 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
878 LOGOFF_ANDX_REQ *pSMB;
881 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
884 * BB: do we need to check validity of ses and server? They should
885 * always be valid since we have an active reference. If not, that
886 * should probably be a BUG()
888 if (!ses || !ses->server)
891 mutex_lock(&ses->session_mutex);
892 if (ses->need_reconnect)
893 goto session_already_dead; /* no need to send SMBlogoff if uid
894 already closed due to reconnect */
895 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
897 mutex_unlock(&ses->session_mutex);
901 pSMB->hdr.Mid = get_next_mid(ses->server);
903 if (ses->server->sign)
904 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
906 pSMB->hdr.Uid = ses->Suid;
908 pSMB->AndXCommand = 0xFF;
909 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
910 cifs_small_buf_release(pSMB);
911 session_already_dead:
912 mutex_unlock(&ses->session_mutex);
914 /* if session dead then we do not need to do ulogoff,
915 since server closed smb session, no sense reporting
923 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
924 const char *fileName, __u16 type,
925 const struct nls_table *nls_codepage, int remap)
927 TRANSACTION2_SPI_REQ *pSMB = NULL;
928 TRANSACTION2_SPI_RSP *pSMBr = NULL;
929 struct unlink_psx_rq *pRqD;
932 int bytes_returned = 0;
933 __u16 params, param_offset, offset, byte_count;
935 cifs_dbg(FYI, "In POSIX delete\n");
937 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
942 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
944 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
945 PATH_MAX, nls_codepage, remap);
946 name_len++; /* trailing null */
949 name_len = copy_path_name(pSMB->FileName, fileName);
952 params = 6 + name_len;
953 pSMB->MaxParameterCount = cpu_to_le16(2);
954 pSMB->MaxDataCount = 0; /* BB double check this with jra */
955 pSMB->MaxSetupCount = 0;
960 param_offset = offsetof(struct smb_com_transaction2_spi_req,
961 InformationLevel) - 4;
962 offset = param_offset + params;
964 /* Setup pointer to Request Data (inode type) */
965 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
966 pRqD->type = cpu_to_le16(type);
967 pSMB->ParameterOffset = cpu_to_le16(param_offset);
968 pSMB->DataOffset = cpu_to_le16(offset);
969 pSMB->SetupCount = 1;
971 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
972 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
974 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
975 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
976 pSMB->ParameterCount = cpu_to_le16(params);
977 pSMB->TotalParameterCount = pSMB->ParameterCount;
978 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
980 inc_rfc1001_len(pSMB, byte_count);
981 pSMB->ByteCount = cpu_to_le16(byte_count);
982 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
983 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
985 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
986 cifs_buf_release(pSMB);
988 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
997 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
998 struct cifs_sb_info *cifs_sb)
1000 DELETE_FILE_REQ *pSMB = NULL;
1001 DELETE_FILE_RSP *pSMBr = NULL;
1005 int remap = cifs_remap(cifs_sb);
1008 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
1013 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1014 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
1015 PATH_MAX, cifs_sb->local_nls,
1017 name_len++; /* trailing null */
1020 name_len = copy_path_name(pSMB->fileName, name);
1022 pSMB->SearchAttributes =
1023 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
1024 pSMB->BufferFormat = 0x04;
1025 inc_rfc1001_len(pSMB, name_len + 1);
1026 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1027 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1028 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1029 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
1031 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
1033 cifs_buf_release(pSMB);
1041 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
1042 struct cifs_sb_info *cifs_sb)
1044 DELETE_DIRECTORY_REQ *pSMB = NULL;
1045 DELETE_DIRECTORY_RSP *pSMBr = NULL;
1049 int remap = cifs_remap(cifs_sb);
1051 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
1053 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
1058 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1059 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1060 PATH_MAX, cifs_sb->local_nls,
1062 name_len++; /* trailing null */
1065 name_len = copy_path_name(pSMB->DirName, name);
1068 pSMB->BufferFormat = 0x04;
1069 inc_rfc1001_len(pSMB, name_len + 1);
1070 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1071 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1072 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1073 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
1075 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
1077 cifs_buf_release(pSMB);
1084 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
1085 struct cifs_tcon *tcon, const char *name,
1086 struct cifs_sb_info *cifs_sb)
1089 CREATE_DIRECTORY_REQ *pSMB = NULL;
1090 CREATE_DIRECTORY_RSP *pSMBr = NULL;
1093 int remap = cifs_remap(cifs_sb);
1095 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
1097 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
1102 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1103 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1104 PATH_MAX, cifs_sb->local_nls,
1106 name_len++; /* trailing null */
1109 name_len = copy_path_name(pSMB->DirName, name);
1112 pSMB->BufferFormat = 0x04;
1113 inc_rfc1001_len(pSMB, name_len + 1);
1114 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1115 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1116 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1117 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1119 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
1121 cifs_buf_release(pSMB);
1128 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1129 __u32 posix_flags, __u64 mode, __u16 *netfid,
1130 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1131 const char *name, const struct nls_table *nls_codepage,
1134 TRANSACTION2_SPI_REQ *pSMB = NULL;
1135 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1138 int bytes_returned = 0;
1139 __u16 params, param_offset, offset, byte_count, count;
1140 OPEN_PSX_REQ *pdata;
1141 OPEN_PSX_RSP *psx_rsp;
1143 cifs_dbg(FYI, "In POSIX Create\n");
1145 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1150 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1152 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1153 PATH_MAX, nls_codepage, remap);
1154 name_len++; /* trailing null */
1157 name_len = copy_path_name(pSMB->FileName, name);
1160 params = 6 + name_len;
1161 count = sizeof(OPEN_PSX_REQ);
1162 pSMB->MaxParameterCount = cpu_to_le16(2);
1163 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1164 pSMB->MaxSetupCount = 0;
1168 pSMB->Reserved2 = 0;
1169 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1170 InformationLevel) - 4;
1171 offset = param_offset + params;
1172 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1173 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1174 pdata->Permissions = cpu_to_le64(mode);
1175 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1176 pdata->OpenFlags = cpu_to_le32(*pOplock);
1177 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1178 pSMB->DataOffset = cpu_to_le16(offset);
1179 pSMB->SetupCount = 1;
1180 pSMB->Reserved3 = 0;
1181 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1182 byte_count = 3 /* pad */ + params + count;
1184 pSMB->DataCount = cpu_to_le16(count);
1185 pSMB->ParameterCount = cpu_to_le16(params);
1186 pSMB->TotalDataCount = pSMB->DataCount;
1187 pSMB->TotalParameterCount = pSMB->ParameterCount;
1188 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1189 pSMB->Reserved4 = 0;
1190 inc_rfc1001_len(pSMB, byte_count);
1191 pSMB->ByteCount = cpu_to_le16(byte_count);
1192 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1193 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1195 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1196 goto psx_create_err;
1199 cifs_dbg(FYI, "copying inode info\n");
1200 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1202 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1203 rc = -EIO; /* bad smb */
1204 goto psx_create_err;
1207 /* copy return information to pRetData */
1208 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1209 + le16_to_cpu(pSMBr->t2.DataOffset));
1211 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1213 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1214 /* Let caller know file was created so we can set the mode. */
1215 /* Do we care about the CreateAction in any other cases? */
1216 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1217 *pOplock |= CIFS_CREATE_ACTION;
1218 /* check to make sure response data is there */
1219 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1220 pRetData->Type = cpu_to_le32(-1); /* unknown */
1221 cifs_dbg(NOISY, "unknown type\n");
1223 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1224 + sizeof(FILE_UNIX_BASIC_INFO)) {
1225 cifs_dbg(VFS, "Open response data too small\n");
1226 pRetData->Type = cpu_to_le32(-1);
1227 goto psx_create_err;
1229 memcpy((char *) pRetData,
1230 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1231 sizeof(FILE_UNIX_BASIC_INFO));
1235 cifs_buf_release(pSMB);
1237 if (posix_flags & SMB_O_DIRECTORY)
1238 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1240 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1248 static __u16 convert_disposition(int disposition)
1252 switch (disposition) {
1253 case FILE_SUPERSEDE:
1254 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1257 ofun = SMBOPEN_OAPPEND;
1260 ofun = SMBOPEN_OCREATE;
1263 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1265 case FILE_OVERWRITE:
1266 ofun = SMBOPEN_OTRUNC;
1268 case FILE_OVERWRITE_IF:
1269 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1272 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1273 ofun = SMBOPEN_OAPPEND; /* regular open */
1279 access_flags_to_smbopen_mode(const int access_flags)
1281 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1283 if (masked_flags == GENERIC_READ)
1284 return SMBOPEN_READ;
1285 else if (masked_flags == GENERIC_WRITE)
1286 return SMBOPEN_WRITE;
1288 /* just go for read/write */
1289 return SMBOPEN_READWRITE;
1293 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1294 const char *fileName, const int openDisposition,
1295 const int access_flags, const int create_options, __u16 *netfid,
1296 int *pOplock, FILE_ALL_INFO *pfile_info,
1297 const struct nls_table *nls_codepage, int remap)
1300 OPENX_REQ *pSMB = NULL;
1301 OPENX_RSP *pSMBr = NULL;
1307 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1312 pSMB->AndXCommand = 0xFF; /* none */
1314 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1315 count = 1; /* account for one byte pad to word boundary */
1317 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1318 fileName, PATH_MAX, nls_codepage, remap);
1319 name_len++; /* trailing null */
1322 count = 0; /* no pad */
1323 name_len = copy_path_name(pSMB->fileName, fileName);
1325 if (*pOplock & REQ_OPLOCK)
1326 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1327 else if (*pOplock & REQ_BATCHOPLOCK)
1328 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1330 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1331 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1332 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1333 /* set file as system file if special file such
1334 as fifo and server expecting SFU style and
1335 no Unix extensions */
1337 if (create_options & CREATE_OPTION_SPECIAL)
1338 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1339 else /* BB FIXME BB */
1340 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1342 if (create_options & CREATE_OPTION_READONLY)
1343 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1346 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1347 CREATE_OPTIONS_MASK); */
1348 /* BB FIXME END BB */
1350 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1351 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1353 inc_rfc1001_len(pSMB, count);
1355 pSMB->ByteCount = cpu_to_le16(count);
1356 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1357 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1358 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1360 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1362 /* BB verify if wct == 15 */
1364 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1366 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1367 /* Let caller know file was created so we can set the mode. */
1368 /* Do we care about the CreateAction in any other cases? */
1370 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1371 *pOplock |= CIFS_CREATE_ACTION; */
1375 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1376 pfile_info->LastAccessTime = 0; /* BB fixme */
1377 pfile_info->LastWriteTime = 0; /* BB fixme */
1378 pfile_info->ChangeTime = 0; /* BB fixme */
1379 pfile_info->Attributes =
1380 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1381 /* the file_info buf is endian converted by caller */
1382 pfile_info->AllocationSize =
1383 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1384 pfile_info->EndOfFile = pfile_info->AllocationSize;
1385 pfile_info->NumberOfLinks = cpu_to_le32(1);
1386 pfile_info->DeletePending = 0;
1390 cifs_buf_release(pSMB);
1397 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1401 OPEN_REQ *req = NULL;
1402 OPEN_RSP *rsp = NULL;
1406 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1407 struct cifs_tcon *tcon = oparms->tcon;
1408 int remap = cifs_remap(cifs_sb);
1409 const struct nls_table *nls = cifs_sb->local_nls;
1410 int create_options = oparms->create_options;
1411 int desired_access = oparms->desired_access;
1412 int disposition = oparms->disposition;
1413 const char *path = oparms->path;
1416 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1421 /* no commands go after this */
1422 req->AndXCommand = 0xFF;
1424 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1425 /* account for one byte pad to word boundary */
1427 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1428 path, PATH_MAX, nls, remap);
1432 req->NameLength = cpu_to_le16(name_len);
1434 /* BB improve check for buffer overruns BB */
1437 name_len = copy_path_name(req->fileName, path);
1438 req->NameLength = cpu_to_le16(name_len);
1441 if (*oplock & REQ_OPLOCK)
1442 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1443 else if (*oplock & REQ_BATCHOPLOCK)
1444 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1446 req->DesiredAccess = cpu_to_le32(desired_access);
1447 req->AllocationSize = 0;
1450 * Set file as system file if special file such as fifo and server
1451 * expecting SFU style and no Unix extensions.
1453 if (create_options & CREATE_OPTION_SPECIAL)
1454 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1456 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1459 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1460 * sensitive checks for other servers such as Samba.
1462 if (tcon->ses->capabilities & CAP_UNIX)
1463 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1465 if (create_options & CREATE_OPTION_READONLY)
1466 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1468 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1469 req->CreateDisposition = cpu_to_le32(disposition);
1470 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1472 /* BB Expirement with various impersonation levels and verify */
1473 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1474 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1477 inc_rfc1001_len(req, count);
1479 req->ByteCount = cpu_to_le16(count);
1480 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1481 (struct smb_hdr *)rsp, &bytes_returned, 0);
1482 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1484 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1485 cifs_buf_release(req);
1491 /* 1 byte no need to le_to_cpu */
1492 *oplock = rsp->OplockLevel;
1493 /* cifs fid stays in le */
1494 oparms->fid->netfid = rsp->Fid;
1496 /* Let caller know file was created so we can set the mode. */
1497 /* Do we care about the CreateAction in any other cases? */
1498 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1499 *oplock |= CIFS_CREATE_ACTION;
1502 /* copy from CreationTime to Attributes */
1503 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1504 /* the file_info buf is endian converted by caller */
1505 buf->AllocationSize = rsp->AllocationSize;
1506 buf->EndOfFile = rsp->EndOfFile;
1507 buf->NumberOfLinks = cpu_to_le32(1);
1508 buf->DeletePending = 0;
1511 cifs_buf_release(req);
1516 * Discard any remaining data in the current SMB. To do this, we borrow the
1520 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1522 unsigned int rfclen = server->pdu_size;
1523 int remaining = rfclen + server->vals->header_preamble_size -
1526 while (remaining > 0) {
1529 length = cifs_read_from_socket(server, server->bigbuf,
1530 min_t(unsigned int, remaining,
1531 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1534 server->total_read += length;
1535 remaining -= length;
1542 __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
1547 length = cifs_discard_remaining_data(server);
1548 dequeue_mid(mid, malformed);
1549 mid->resp_buf = server->smallbuf;
1550 server->smallbuf = NULL;
1555 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1557 struct cifs_readdata *rdata = mid->callback_data;
1559 return __cifs_readv_discard(server, mid, rdata->result);
1563 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1566 unsigned int data_offset, data_len;
1567 struct cifs_readdata *rdata = mid->callback_data;
1568 char *buf = server->smallbuf;
1569 unsigned int buflen = server->pdu_size +
1570 server->vals->header_preamble_size;
1571 bool use_rdma_mr = false;
1573 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1574 __func__, mid->mid, rdata->offset, rdata->bytes);
1577 * read the rest of READ_RSP header (sans Data array), or whatever we
1578 * can if there's not enough data. At this point, we've read down to
1581 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1582 HEADER_SIZE(server) + 1;
1584 length = cifs_read_from_socket(server,
1585 buf + HEADER_SIZE(server) - 1, len);
1588 server->total_read += length;
1590 if (server->ops->is_session_expired &&
1591 server->ops->is_session_expired(buf)) {
1592 cifs_reconnect(server);
1593 wake_up(&server->response_q);
1597 if (server->ops->is_status_pending &&
1598 server->ops->is_status_pending(buf, server)) {
1599 cifs_discard_remaining_data(server);
1603 /* set up first two iov for signature check and to get credits */
1604 rdata->iov[0].iov_base = buf;
1605 rdata->iov[0].iov_len = server->vals->header_preamble_size;
1606 rdata->iov[1].iov_base = buf + server->vals->header_preamble_size;
1607 rdata->iov[1].iov_len =
1608 server->total_read - server->vals->header_preamble_size;
1609 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1610 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1611 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
1612 rdata->iov[1].iov_base, rdata->iov[1].iov_len);
1614 /* Was the SMB read successful? */
1615 rdata->result = server->ops->map_error(buf, false);
1616 if (rdata->result != 0) {
1617 cifs_dbg(FYI, "%s: server returned error %d\n",
1618 __func__, rdata->result);
1619 /* normal error on read response */
1620 return __cifs_readv_discard(server, mid, false);
1623 /* Is there enough to get to the rest of the READ_RSP header? */
1624 if (server->total_read < server->vals->read_rsp_size) {
1625 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1626 __func__, server->total_read,
1627 server->vals->read_rsp_size);
1628 rdata->result = -EIO;
1629 return cifs_readv_discard(server, mid);
1632 data_offset = server->ops->read_data_offset(buf) +
1633 server->vals->header_preamble_size;
1634 if (data_offset < server->total_read) {
1636 * win2k8 sometimes sends an offset of 0 when the read
1637 * is beyond the EOF. Treat it as if the data starts just after
1640 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1641 __func__, data_offset);
1642 data_offset = server->total_read;
1643 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1644 /* data_offset is beyond the end of smallbuf */
1645 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1646 __func__, data_offset);
1647 rdata->result = -EIO;
1648 return cifs_readv_discard(server, mid);
1651 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1652 __func__, server->total_read, data_offset);
1654 len = data_offset - server->total_read;
1656 /* read any junk before data into the rest of smallbuf */
1657 length = cifs_read_from_socket(server,
1658 buf + server->total_read, len);
1661 server->total_read += length;
1664 /* how much data is in the response? */
1665 #ifdef CONFIG_CIFS_SMB_DIRECT
1666 use_rdma_mr = rdata->mr;
1668 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1669 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1670 /* data_len is corrupt -- discard frame */
1671 rdata->result = -EIO;
1672 return cifs_readv_discard(server, mid);
1675 length = rdata->read_into_pages(server, rdata, data_len);
1679 server->total_read += length;
1681 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1682 server->total_read, buflen, data_len);
1684 /* discard anything left over */
1685 if (server->total_read < buflen)
1686 return cifs_readv_discard(server, mid);
1688 dequeue_mid(mid, false);
1689 mid->resp_buf = server->smallbuf;
1690 server->smallbuf = NULL;
1695 cifs_readv_callback(struct mid_q_entry *mid)
1697 struct cifs_readdata *rdata = mid->callback_data;
1698 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1699 struct TCP_Server_Info *server = tcon->ses->server;
1700 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1702 .rq_pages = rdata->pages,
1703 .rq_offset = rdata->page_offset,
1704 .rq_npages = rdata->nr_pages,
1705 .rq_pagesz = rdata->pagesz,
1706 .rq_tailsz = rdata->tailsz };
1707 struct cifs_credits credits = { .value = 1, .instance = 0 };
1709 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1710 __func__, mid->mid, mid->mid_state, rdata->result,
1713 switch (mid->mid_state) {
1714 case MID_RESPONSE_RECEIVED:
1715 /* result already set, check signature */
1719 rc = cifs_verify_signature(&rqst, server,
1720 mid->sequence_number);
1722 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1725 /* FIXME: should this be counted toward the initiating task? */
1726 task_io_account_read(rdata->got_bytes);
1727 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1729 case MID_REQUEST_SUBMITTED:
1730 case MID_RETRY_NEEDED:
1731 rdata->result = -EAGAIN;
1732 if (server->sign && rdata->got_bytes)
1733 /* reset bytes number since we can not check a sign */
1734 rdata->got_bytes = 0;
1735 /* FIXME: should this be counted toward the initiating task? */
1736 task_io_account_read(rdata->got_bytes);
1737 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1740 rdata->result = -EIO;
1743 queue_work(cifsiod_wq, &rdata->work);
1744 DeleteMidQEntry(mid);
1745 add_credits(server, &credits, 0);
1748 /* cifs_async_readv - send an async write, and set up mid to handle result */
1750 cifs_async_readv(struct cifs_readdata *rdata)
1753 READ_REQ *smb = NULL;
1755 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1756 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1759 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1760 __func__, rdata->offset, rdata->bytes);
1762 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1765 wct = 10; /* old style read */
1766 if ((rdata->offset >> 32) > 0) {
1767 /* can not handle this big offset for old */
1772 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1776 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1777 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1779 smb->AndXCommand = 0xFF; /* none */
1780 smb->Fid = rdata->cfile->fid.netfid;
1781 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1783 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1785 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1786 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1790 /* old style read */
1791 struct smb_com_readx_req *smbr =
1792 (struct smb_com_readx_req *)smb;
1793 smbr->ByteCount = 0;
1796 /* 4 for RFC1001 length + 1 for BCC */
1797 rdata->iov[0].iov_base = smb;
1798 rdata->iov[0].iov_len = 4;
1799 rdata->iov[1].iov_base = (char *)smb + 4;
1800 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1802 kref_get(&rdata->refcount);
1803 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1804 cifs_readv_callback, NULL, rdata, 0, NULL);
1807 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1809 kref_put(&rdata->refcount, cifs_readdata_release);
1811 cifs_small_buf_release(smb);
1816 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1817 unsigned int *nbytes, char **buf, int *pbuf_type)
1820 READ_REQ *pSMB = NULL;
1821 READ_RSP *pSMBr = NULL;
1822 char *pReadData = NULL;
1824 int resp_buf_type = 0;
1826 struct kvec rsp_iov;
1827 __u32 pid = io_parms->pid;
1828 __u16 netfid = io_parms->netfid;
1829 __u64 offset = io_parms->offset;
1830 struct cifs_tcon *tcon = io_parms->tcon;
1831 unsigned int count = io_parms->length;
1833 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1834 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1837 wct = 10; /* old style read */
1838 if ((offset >> 32) > 0) {
1839 /* can not handle this big offset for old */
1845 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1849 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1850 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1852 /* tcon and ses pointer are checked in smb_init */
1853 if (tcon->ses->server == NULL)
1854 return -ECONNABORTED;
1856 pSMB->AndXCommand = 0xFF; /* none */
1858 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1860 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1862 pSMB->Remaining = 0;
1863 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1864 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1866 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1868 /* old style read */
1869 struct smb_com_readx_req *pSMBW =
1870 (struct smb_com_readx_req *)pSMB;
1871 pSMBW->ByteCount = 0;
1874 iov[0].iov_base = (char *)pSMB;
1875 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1876 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1877 CIFS_LOG_ERROR, &rsp_iov);
1878 cifs_small_buf_release(pSMB);
1879 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1880 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1882 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1884 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1885 data_length = data_length << 16;
1886 data_length += le16_to_cpu(pSMBr->DataLength);
1887 *nbytes = data_length;
1889 /*check that DataLength would not go beyond end of SMB */
1890 if ((data_length > CIFSMaxBufSize)
1891 || (data_length > count)) {
1892 cifs_dbg(FYI, "bad length %d for count %d\n",
1893 data_length, count);
1897 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1898 le16_to_cpu(pSMBr->DataOffset);
1899 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1900 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1902 }*/ /* can not use copy_to_user when using page cache*/
1904 memcpy(*buf, pReadData, data_length);
1909 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1910 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1911 /* return buffer to caller to free */
1912 *buf = rsp_iov.iov_base;
1913 if (resp_buf_type == CIFS_SMALL_BUFFER)
1914 *pbuf_type = CIFS_SMALL_BUFFER;
1915 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1916 *pbuf_type = CIFS_LARGE_BUFFER;
1917 } /* else no valid buffer on return - leave as null */
1919 /* Note: On -EAGAIN error only caller can retry on handle based calls
1920 since file handle passed in no longer valid */
1926 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1927 unsigned int *nbytes, const char *buf)
1930 WRITE_REQ *pSMB = NULL;
1931 WRITE_RSP *pSMBr = NULL;
1932 int bytes_returned, wct;
1935 __u32 pid = io_parms->pid;
1936 __u16 netfid = io_parms->netfid;
1937 __u64 offset = io_parms->offset;
1938 struct cifs_tcon *tcon = io_parms->tcon;
1939 unsigned int count = io_parms->length;
1943 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1944 if (tcon->ses == NULL)
1945 return -ECONNABORTED;
1947 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1951 if ((offset >> 32) > 0) {
1952 /* can not handle big offset for old srv */
1957 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1962 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1963 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1965 /* tcon and ses pointer are checked in smb_init */
1966 if (tcon->ses->server == NULL)
1967 return -ECONNABORTED;
1969 pSMB->AndXCommand = 0xFF; /* none */
1971 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1973 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1975 pSMB->Reserved = 0xFFFFFFFF;
1976 pSMB->WriteMode = 0;
1977 pSMB->Remaining = 0;
1979 /* Can increase buffer size if buffer is big enough in some cases ie we
1980 can send more if LARGE_WRITE_X capability returned by the server and if
1981 our buffer is big enough or if we convert to iovecs on socket writes
1982 and eliminate the copy to the CIFS buffer */
1983 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1984 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1986 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1990 if (bytes_sent > count)
1993 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1995 memcpy(pSMB->Data, buf, bytes_sent);
1996 else if (count != 0) {
1998 cifs_buf_release(pSMB);
2000 } /* else setting file size with write of zero bytes */
2002 byte_count = bytes_sent + 1; /* pad */
2003 else /* wct == 12 */
2004 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
2006 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
2007 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
2008 inc_rfc1001_len(pSMB, byte_count);
2011 pSMB->ByteCount = cpu_to_le16(byte_count);
2012 else { /* old style write has byte count 4 bytes earlier
2014 struct smb_com_writex_req *pSMBW =
2015 (struct smb_com_writex_req *)pSMB;
2016 pSMBW->ByteCount = cpu_to_le16(byte_count);
2019 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2020 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2021 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2023 cifs_dbg(FYI, "Send error in write = %d\n", rc);
2025 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2026 *nbytes = (*nbytes) << 16;
2027 *nbytes += le16_to_cpu(pSMBr->Count);
2030 * Mask off high 16 bits when bytes written as returned by the
2031 * server is greater than bytes requested by the client. Some
2032 * OS/2 servers are known to set incorrect CountHigh values.
2034 if (*nbytes > count)
2038 cifs_buf_release(pSMB);
2040 /* Note: On -EAGAIN error only caller can retry on handle based calls
2041 since file handle passed in no longer valid */
2047 cifs_writedata_release(struct kref *refcount)
2049 struct cifs_writedata *wdata = container_of(refcount,
2050 struct cifs_writedata, refcount);
2051 #ifdef CONFIG_CIFS_SMB_DIRECT
2053 smbd_deregister_mr(wdata->mr);
2059 cifsFileInfo_put(wdata->cfile);
2061 kvfree(wdata->pages);
2066 * Write failed with a retryable error. Resend the write request. It's also
2067 * possible that the page was redirtied so re-clean the page.
2070 cifs_writev_requeue(struct cifs_writedata *wdata)
2073 struct inode *inode = d_inode(wdata->cfile->dentry);
2074 struct TCP_Server_Info *server;
2075 unsigned int rest_len;
2077 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
2079 rest_len = wdata->bytes;
2081 struct cifs_writedata *wdata2;
2082 unsigned int j, nr_pages, wsize, tailsz, cur_len;
2084 wsize = server->ops->wp_retry_size(inode);
2085 if (wsize < rest_len) {
2086 nr_pages = wsize / PAGE_SIZE;
2091 cur_len = nr_pages * PAGE_SIZE;
2094 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
2096 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
2099 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
2105 for (j = 0; j < nr_pages; j++) {
2106 wdata2->pages[j] = wdata->pages[i + j];
2107 lock_page(wdata2->pages[j]);
2108 clear_page_dirty_for_io(wdata2->pages[j]);
2111 wdata2->sync_mode = wdata->sync_mode;
2112 wdata2->nr_pages = nr_pages;
2113 wdata2->offset = page_offset(wdata2->pages[0]);
2114 wdata2->pagesz = PAGE_SIZE;
2115 wdata2->tailsz = tailsz;
2116 wdata2->bytes = cur_len;
2118 rc = cifs_get_writable_file(CIFS_I(inode), false,
2120 if (!wdata2->cfile) {
2121 cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
2123 if (!is_retryable_error(rc))
2126 wdata2->pid = wdata2->cfile->pid;
2127 rc = server->ops->async_writev(wdata2,
2128 cifs_writedata_release);
2131 for (j = 0; j < nr_pages; j++) {
2132 unlock_page(wdata2->pages[j]);
2133 if (rc != 0 && !is_retryable_error(rc)) {
2134 SetPageError(wdata2->pages[j]);
2135 end_page_writeback(wdata2->pages[j]);
2136 put_page(wdata2->pages[j]);
2141 kref_put(&wdata2->refcount, cifs_writedata_release);
2142 if (is_retryable_error(rc))
2148 rest_len -= cur_len;
2150 } while (i < wdata->nr_pages);
2152 /* cleanup remaining pages from the original wdata */
2153 for (; i < wdata->nr_pages; i++) {
2154 SetPageError(wdata->pages[i]);
2155 end_page_writeback(wdata->pages[i]);
2156 put_page(wdata->pages[i]);
2159 if (rc != 0 && !is_retryable_error(rc))
2160 mapping_set_error(inode->i_mapping, rc);
2161 kref_put(&wdata->refcount, cifs_writedata_release);
2165 cifs_writev_complete(struct work_struct *work)
2167 struct cifs_writedata *wdata = container_of(work,
2168 struct cifs_writedata, work);
2169 struct inode *inode = d_inode(wdata->cfile->dentry);
2172 if (wdata->result == 0) {
2173 spin_lock(&inode->i_lock);
2174 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2175 spin_unlock(&inode->i_lock);
2176 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2178 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2179 return cifs_writev_requeue(wdata);
2181 for (i = 0; i < wdata->nr_pages; i++) {
2182 struct page *page = wdata->pages[i];
2183 if (wdata->result == -EAGAIN)
2184 __set_page_dirty_nobuffers(page);
2185 else if (wdata->result < 0)
2187 end_page_writeback(page);
2190 if (wdata->result != -EAGAIN)
2191 mapping_set_error(inode->i_mapping, wdata->result);
2192 kref_put(&wdata->refcount, cifs_writedata_release);
2195 struct cifs_writedata *
2196 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2198 struct page **pages =
2199 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2201 return cifs_writedata_direct_alloc(pages, complete);
2206 struct cifs_writedata *
2207 cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2209 struct cifs_writedata *wdata;
2211 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2212 if (wdata != NULL) {
2213 wdata->pages = pages;
2214 kref_init(&wdata->refcount);
2215 INIT_LIST_HEAD(&wdata->list);
2216 init_completion(&wdata->done);
2217 INIT_WORK(&wdata->work, complete);
2223 * Check the mid_state and signature on received buffer (if any), and queue the
2224 * workqueue completion task.
2227 cifs_writev_callback(struct mid_q_entry *mid)
2229 struct cifs_writedata *wdata = mid->callback_data;
2230 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2231 unsigned int written;
2232 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2233 struct cifs_credits credits = { .value = 1, .instance = 0 };
2235 switch (mid->mid_state) {
2236 case MID_RESPONSE_RECEIVED:
2237 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2238 if (wdata->result != 0)
2241 written = le16_to_cpu(smb->CountHigh);
2243 written += le16_to_cpu(smb->Count);
2245 * Mask off high 16 bits when bytes written as returned
2246 * by the server is greater than bytes requested by the
2247 * client. OS/2 servers are known to set incorrect
2250 if (written > wdata->bytes)
2253 if (written < wdata->bytes)
2254 wdata->result = -ENOSPC;
2256 wdata->bytes = written;
2258 case MID_REQUEST_SUBMITTED:
2259 case MID_RETRY_NEEDED:
2260 wdata->result = -EAGAIN;
2263 wdata->result = -EIO;
2267 queue_work(cifsiod_wq, &wdata->work);
2268 DeleteMidQEntry(mid);
2269 add_credits(tcon->ses->server, &credits, 0);
2272 /* cifs_async_writev - send an async write, and set up mid to handle result */
2274 cifs_async_writev(struct cifs_writedata *wdata,
2275 void (*release)(struct kref *kref))
2278 WRITE_REQ *smb = NULL;
2280 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2282 struct smb_rqst rqst = { };
2284 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2288 if (wdata->offset >> 32 > 0) {
2289 /* can not handle big offset for old srv */
2294 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2296 goto async_writev_out;
2298 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2299 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2301 smb->AndXCommand = 0xFF; /* none */
2302 smb->Fid = wdata->cfile->fid.netfid;
2303 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2305 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2306 smb->Reserved = 0xFFFFFFFF;
2311 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2313 /* 4 for RFC1001 length + 1 for BCC */
2315 iov[0].iov_base = smb;
2316 iov[1].iov_len = get_rfc1002_length(smb) + 1;
2317 iov[1].iov_base = (char *)smb + 4;
2321 rqst.rq_pages = wdata->pages;
2322 rqst.rq_offset = wdata->page_offset;
2323 rqst.rq_npages = wdata->nr_pages;
2324 rqst.rq_pagesz = wdata->pagesz;
2325 rqst.rq_tailsz = wdata->tailsz;
2327 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2328 wdata->offset, wdata->bytes);
2330 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2331 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2334 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2335 put_bcc(wdata->bytes + 1, &smb->hdr);
2338 struct smb_com_writex_req *smbw =
2339 (struct smb_com_writex_req *)smb;
2340 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2341 put_bcc(wdata->bytes + 5, &smbw->hdr);
2342 iov[1].iov_len += 4; /* pad bigger by four bytes */
2345 kref_get(&wdata->refcount);
2346 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2347 cifs_writev_callback, NULL, wdata, 0, NULL);
2350 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2352 kref_put(&wdata->refcount, release);
2355 cifs_small_buf_release(smb);
2360 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2361 unsigned int *nbytes, struct kvec *iov, int n_vec)
2364 WRITE_REQ *pSMB = NULL;
2367 int resp_buf_type = 0;
2368 __u32 pid = io_parms->pid;
2369 __u16 netfid = io_parms->netfid;
2370 __u64 offset = io_parms->offset;
2371 struct cifs_tcon *tcon = io_parms->tcon;
2372 unsigned int count = io_parms->length;
2373 struct kvec rsp_iov;
2377 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2379 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2383 if ((offset >> 32) > 0) {
2384 /* can not handle big offset for old srv */
2388 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2392 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2393 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2395 /* tcon and ses pointer are checked in smb_init */
2396 if (tcon->ses->server == NULL)
2397 return -ECONNABORTED;
2399 pSMB->AndXCommand = 0xFF; /* none */
2401 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2403 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2404 pSMB->Reserved = 0xFFFFFFFF;
2405 pSMB->WriteMode = 0;
2406 pSMB->Remaining = 0;
2409 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2411 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2412 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2413 /* header + 1 byte pad */
2414 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2416 inc_rfc1001_len(pSMB, count + 1);
2417 else /* wct == 12 */
2418 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2420 pSMB->ByteCount = cpu_to_le16(count + 1);
2421 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2422 struct smb_com_writex_req *pSMBW =
2423 (struct smb_com_writex_req *)pSMB;
2424 pSMBW->ByteCount = cpu_to_le16(count + 5);
2426 iov[0].iov_base = pSMB;
2428 iov[0].iov_len = smb_hdr_len + 4;
2429 else /* wct == 12 pad bigger by four bytes */
2430 iov[0].iov_len = smb_hdr_len + 8;
2432 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2434 cifs_small_buf_release(pSMB);
2435 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2437 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2438 } else if (resp_buf_type == 0) {
2439 /* presumably this can not happen, but best to be safe */
2442 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2443 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2444 *nbytes = (*nbytes) << 16;
2445 *nbytes += le16_to_cpu(pSMBr->Count);
2448 * Mask off high 16 bits when bytes written as returned by the
2449 * server is greater than bytes requested by the client. OS/2
2450 * servers are known to set incorrect CountHigh values.
2452 if (*nbytes > count)
2456 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2458 /* Note: On -EAGAIN error only caller can retry on handle based calls
2459 since file handle passed in no longer valid */
2464 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2465 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2466 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2469 LOCK_REQ *pSMB = NULL;
2471 struct kvec rsp_iov;
2475 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2476 num_lock, num_unlock);
2478 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2483 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2484 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2485 pSMB->LockType = lock_type;
2486 pSMB->AndXCommand = 0xFF; /* none */
2487 pSMB->Fid = netfid; /* netfid stays le */
2489 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2490 inc_rfc1001_len(pSMB, count);
2491 pSMB->ByteCount = cpu_to_le16(count);
2493 iov[0].iov_base = (char *)pSMB;
2494 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2495 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2496 iov[1].iov_base = (char *)buf;
2497 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2499 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2500 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
2501 CIFS_NO_RSP_BUF, &rsp_iov);
2502 cifs_small_buf_release(pSMB);
2504 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2510 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2511 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2512 const __u64 offset, const __u32 numUnlock,
2513 const __u32 numLock, const __u8 lockType,
2514 const bool waitFlag, const __u8 oplock_level)
2517 LOCK_REQ *pSMB = NULL;
2518 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2523 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2524 (int)waitFlag, numLock);
2525 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2530 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2531 /* no response expected */
2532 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
2534 } else if (waitFlag) {
2535 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2536 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2541 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2542 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2543 pSMB->LockType = lockType;
2544 pSMB->OplockLevel = oplock_level;
2545 pSMB->AndXCommand = 0xFF; /* none */
2546 pSMB->Fid = smb_file_id; /* netfid stays le */
2548 if ((numLock != 0) || (numUnlock != 0)) {
2549 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2550 /* BB where to store pid high? */
2551 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2552 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2553 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2554 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2555 count = sizeof(LOCKING_ANDX_RANGE);
2560 inc_rfc1001_len(pSMB, count);
2561 pSMB->ByteCount = cpu_to_le16(count);
2564 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2565 (struct smb_hdr *) pSMB, &bytes_returned);
2567 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2568 cifs_small_buf_release(pSMB);
2569 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2571 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2573 /* Note: On -EAGAIN error only caller can retry on handle based calls
2574 since file handle passed in no longer valid */
2579 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2580 const __u16 smb_file_id, const __u32 netpid,
2581 const loff_t start_offset, const __u64 len,
2582 struct file_lock *pLockData, const __u16 lock_type,
2583 const bool waitFlag)
2585 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2586 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2587 struct cifs_posix_lock *parm_data;
2590 int bytes_returned = 0;
2591 int resp_buf_type = 0;
2592 __u16 params, param_offset, offset, byte_count, count;
2594 struct kvec rsp_iov;
2596 cifs_dbg(FYI, "Posix Lock\n");
2598 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2603 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2606 pSMB->MaxSetupCount = 0;
2609 pSMB->Reserved2 = 0;
2610 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2611 offset = param_offset + params;
2613 count = sizeof(struct cifs_posix_lock);
2614 pSMB->MaxParameterCount = cpu_to_le16(2);
2615 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2616 pSMB->SetupCount = 1;
2617 pSMB->Reserved3 = 0;
2619 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2621 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2622 byte_count = 3 /* pad */ + params + count;
2623 pSMB->DataCount = cpu_to_le16(count);
2624 pSMB->ParameterCount = cpu_to_le16(params);
2625 pSMB->TotalDataCount = pSMB->DataCount;
2626 pSMB->TotalParameterCount = pSMB->ParameterCount;
2627 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2628 parm_data = (struct cifs_posix_lock *)
2629 (((char *) &pSMB->hdr.Protocol) + offset);
2631 parm_data->lock_type = cpu_to_le16(lock_type);
2633 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2634 parm_data->lock_flags = cpu_to_le16(1);
2635 pSMB->Timeout = cpu_to_le32(-1);
2639 parm_data->pid = cpu_to_le32(netpid);
2640 parm_data->start = cpu_to_le64(start_offset);
2641 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2643 pSMB->DataOffset = cpu_to_le16(offset);
2644 pSMB->Fid = smb_file_id;
2645 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2646 pSMB->Reserved4 = 0;
2647 inc_rfc1001_len(pSMB, byte_count);
2648 pSMB->ByteCount = cpu_to_le16(byte_count);
2650 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2651 (struct smb_hdr *) pSMBr, &bytes_returned);
2653 iov[0].iov_base = (char *)pSMB;
2654 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2655 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2656 &resp_buf_type, timeout, &rsp_iov);
2657 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2659 cifs_small_buf_release(pSMB);
2662 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2663 } else if (pLockData) {
2664 /* lock structure can be returned on get */
2667 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2669 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2670 rc = -EIO; /* bad smb */
2673 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2674 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2675 if (data_count < sizeof(struct cifs_posix_lock)) {
2679 parm_data = (struct cifs_posix_lock *)
2680 ((char *)&pSMBr->hdr.Protocol + data_offset);
2681 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2682 pLockData->fl_type = F_UNLCK;
2684 if (parm_data->lock_type ==
2685 cpu_to_le16(CIFS_RDLCK))
2686 pLockData->fl_type = F_RDLCK;
2687 else if (parm_data->lock_type ==
2688 cpu_to_le16(CIFS_WRLCK))
2689 pLockData->fl_type = F_WRLCK;
2691 pLockData->fl_start = le64_to_cpu(parm_data->start);
2692 pLockData->fl_end = pLockData->fl_start +
2693 le64_to_cpu(parm_data->length) - 1;
2694 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2699 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2701 /* Note: On -EAGAIN error only caller can retry on handle based calls
2702 since file handle passed in no longer valid */
2709 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2712 CLOSE_REQ *pSMB = NULL;
2713 cifs_dbg(FYI, "In CIFSSMBClose\n");
2715 /* do not retry on dead session on close */
2716 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2722 pSMB->FileID = (__u16) smb_file_id;
2723 pSMB->LastWriteTime = 0xFFFFFFFF;
2724 pSMB->ByteCount = 0;
2725 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2726 cifs_small_buf_release(pSMB);
2727 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2730 /* EINTR is expected when user ctl-c to kill app */
2731 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2735 /* Since session is dead, file will be closed on server already */
2743 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2746 FLUSH_REQ *pSMB = NULL;
2747 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2749 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2753 pSMB->FileID = (__u16) smb_file_id;
2754 pSMB->ByteCount = 0;
2755 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2756 cifs_small_buf_release(pSMB);
2757 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2759 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2765 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2766 const char *from_name, const char *to_name,
2767 struct cifs_sb_info *cifs_sb)
2770 RENAME_REQ *pSMB = NULL;
2771 RENAME_RSP *pSMBr = NULL;
2773 int name_len, name_len2;
2775 int remap = cifs_remap(cifs_sb);
2777 cifs_dbg(FYI, "In CIFSSMBRename\n");
2779 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2784 pSMB->BufferFormat = 0x04;
2785 pSMB->SearchAttributes =
2786 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2789 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2790 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2791 from_name, PATH_MAX,
2792 cifs_sb->local_nls, remap);
2793 name_len++; /* trailing null */
2795 pSMB->OldFileName[name_len] = 0x04; /* pad */
2796 /* protocol requires ASCII signature byte on Unicode string */
2797 pSMB->OldFileName[name_len + 1] = 0x00;
2799 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2800 to_name, PATH_MAX, cifs_sb->local_nls,
2802 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2803 name_len2 *= 2; /* convert to bytes */
2805 name_len = copy_path_name(pSMB->OldFileName, from_name);
2806 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2807 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2808 name_len2++; /* signature byte */
2811 count = 1 /* 1st signature byte */ + name_len + name_len2;
2812 inc_rfc1001_len(pSMB, count);
2813 pSMB->ByteCount = cpu_to_le16(count);
2815 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2816 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2817 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2819 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2821 cifs_buf_release(pSMB);
2829 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2830 int netfid, const char *target_name,
2831 const struct nls_table *nls_codepage, int remap)
2833 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2834 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2835 struct set_file_rename *rename_info;
2837 char dummy_string[30];
2839 int bytes_returned = 0;
2841 __u16 params, param_offset, offset, count, byte_count;
2843 cifs_dbg(FYI, "Rename to File by handle\n");
2844 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2850 pSMB->MaxSetupCount = 0;
2854 pSMB->Reserved2 = 0;
2855 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2856 offset = param_offset + params;
2858 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2859 rename_info = (struct set_file_rename *) data_offset;
2860 pSMB->MaxParameterCount = cpu_to_le16(2);
2861 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2862 pSMB->SetupCount = 1;
2863 pSMB->Reserved3 = 0;
2864 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2865 byte_count = 3 /* pad */ + params;
2866 pSMB->ParameterCount = cpu_to_le16(params);
2867 pSMB->TotalParameterCount = pSMB->ParameterCount;
2868 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2869 pSMB->DataOffset = cpu_to_le16(offset);
2870 /* construct random name ".cifs_tmp<inodenum><mid>" */
2871 rename_info->overwrite = cpu_to_le32(1);
2872 rename_info->root_fid = 0;
2873 /* unicode only call */
2874 if (target_name == NULL) {
2875 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2877 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2878 dummy_string, 24, nls_codepage, remap);
2881 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2882 target_name, PATH_MAX, nls_codepage,
2885 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2886 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2887 byte_count += count;
2888 pSMB->DataCount = cpu_to_le16(count);
2889 pSMB->TotalDataCount = pSMB->DataCount;
2891 pSMB->InformationLevel =
2892 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2893 pSMB->Reserved4 = 0;
2894 inc_rfc1001_len(pSMB, byte_count);
2895 pSMB->ByteCount = cpu_to_le16(byte_count);
2896 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2897 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2898 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2900 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2903 cifs_buf_release(pSMB);
2905 /* Note: On -EAGAIN error only caller can retry on handle based calls
2906 since file handle passed in no longer valid */
2912 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2913 const char *fromName, const __u16 target_tid, const char *toName,
2914 const int flags, const struct nls_table *nls_codepage, int remap)
2917 COPY_REQ *pSMB = NULL;
2918 COPY_RSP *pSMBr = NULL;
2920 int name_len, name_len2;
2923 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2925 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2930 pSMB->BufferFormat = 0x04;
2931 pSMB->Tid2 = target_tid;
2933 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2935 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2936 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2937 fromName, PATH_MAX, nls_codepage,
2939 name_len++; /* trailing null */
2941 pSMB->OldFileName[name_len] = 0x04; /* pad */
2942 /* protocol requires ASCII signature byte on Unicode string */
2943 pSMB->OldFileName[name_len + 1] = 0x00;
2945 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2946 toName, PATH_MAX, nls_codepage, remap);
2947 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2948 name_len2 *= 2; /* convert to bytes */
2950 name_len = copy_path_name(pSMB->OldFileName, fromName);
2951 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2952 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2953 name_len2++; /* signature byte */
2956 count = 1 /* 1st signature byte */ + name_len + name_len2;
2957 inc_rfc1001_len(pSMB, count);
2958 pSMB->ByteCount = cpu_to_le16(count);
2960 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2961 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2963 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2964 rc, le16_to_cpu(pSMBr->CopyCount));
2966 cifs_buf_release(pSMB);
2975 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2976 const char *fromName, const char *toName,
2977 const struct nls_table *nls_codepage, int remap)
2979 TRANSACTION2_SPI_REQ *pSMB = NULL;
2980 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2983 int name_len_target;
2985 int bytes_returned = 0;
2986 __u16 params, param_offset, offset, byte_count;
2988 cifs_dbg(FYI, "In Symlink Unix style\n");
2990 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2995 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2997 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2998 /* find define for this maxpathcomponent */
2999 PATH_MAX, nls_codepage, remap);
3000 name_len++; /* trailing null */
3004 name_len = copy_path_name(pSMB->FileName, fromName);
3006 params = 6 + name_len;
3007 pSMB->MaxSetupCount = 0;
3011 pSMB->Reserved2 = 0;
3012 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3013 InformationLevel) - 4;
3014 offset = param_offset + params;
3016 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
3017 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3019 cifsConvertToUTF16((__le16 *) data_offset, toName,
3020 /* find define for this maxpathcomponent */
3021 PATH_MAX, nls_codepage, remap);
3022 name_len_target++; /* trailing null */
3023 name_len_target *= 2;
3025 name_len_target = copy_path_name(data_offset, toName);
3028 pSMB->MaxParameterCount = cpu_to_le16(2);
3029 /* BB find exact max on data count below from sess */
3030 pSMB->MaxDataCount = cpu_to_le16(1000);
3031 pSMB->SetupCount = 1;
3032 pSMB->Reserved3 = 0;
3033 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3034 byte_count = 3 /* pad */ + params + name_len_target;
3035 pSMB->DataCount = cpu_to_le16(name_len_target);
3036 pSMB->ParameterCount = cpu_to_le16(params);
3037 pSMB->TotalDataCount = pSMB->DataCount;
3038 pSMB->TotalParameterCount = pSMB->ParameterCount;
3039 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3040 pSMB->DataOffset = cpu_to_le16(offset);
3041 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
3042 pSMB->Reserved4 = 0;
3043 inc_rfc1001_len(pSMB, byte_count);
3044 pSMB->ByteCount = cpu_to_le16(byte_count);
3045 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3046 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3047 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
3049 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
3052 cifs_buf_release(pSMB);
3055 goto createSymLinkRetry;
3061 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3062 const char *fromName, const char *toName,
3063 const struct nls_table *nls_codepage, int remap)
3065 TRANSACTION2_SPI_REQ *pSMB = NULL;
3066 TRANSACTION2_SPI_RSP *pSMBr = NULL;
3069 int name_len_target;
3071 int bytes_returned = 0;
3072 __u16 params, param_offset, offset, byte_count;
3074 cifs_dbg(FYI, "In Create Hard link Unix style\n");
3075 createHardLinkRetry:
3076 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3081 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3082 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
3083 PATH_MAX, nls_codepage, remap);
3084 name_len++; /* trailing null */
3088 name_len = copy_path_name(pSMB->FileName, toName);
3090 params = 6 + name_len;
3091 pSMB->MaxSetupCount = 0;
3095 pSMB->Reserved2 = 0;
3096 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3097 InformationLevel) - 4;
3098 offset = param_offset + params;
3100 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
3101 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3103 cifsConvertToUTF16((__le16 *) data_offset, fromName,
3104 PATH_MAX, nls_codepage, remap);
3105 name_len_target++; /* trailing null */
3106 name_len_target *= 2;
3108 name_len_target = copy_path_name(data_offset, fromName);
3111 pSMB->MaxParameterCount = cpu_to_le16(2);
3112 /* BB find exact max on data count below from sess*/
3113 pSMB->MaxDataCount = cpu_to_le16(1000);
3114 pSMB->SetupCount = 1;
3115 pSMB->Reserved3 = 0;
3116 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3117 byte_count = 3 /* pad */ + params + name_len_target;
3118 pSMB->ParameterCount = cpu_to_le16(params);
3119 pSMB->TotalParameterCount = pSMB->ParameterCount;
3120 pSMB->DataCount = cpu_to_le16(name_len_target);
3121 pSMB->TotalDataCount = pSMB->DataCount;
3122 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3123 pSMB->DataOffset = cpu_to_le16(offset);
3124 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3125 pSMB->Reserved4 = 0;
3126 inc_rfc1001_len(pSMB, byte_count);
3127 pSMB->ByteCount = cpu_to_le16(byte_count);
3128 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3129 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3130 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3132 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3135 cifs_buf_release(pSMB);
3137 goto createHardLinkRetry;
3143 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3144 const char *from_name, const char *to_name,
3145 struct cifs_sb_info *cifs_sb)
3148 NT_RENAME_REQ *pSMB = NULL;
3149 RENAME_RSP *pSMBr = NULL;
3151 int name_len, name_len2;
3153 int remap = cifs_remap(cifs_sb);
3155 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3156 winCreateHardLinkRetry:
3158 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3163 pSMB->SearchAttributes =
3164 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3166 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3167 pSMB->ClusterCount = 0;
3169 pSMB->BufferFormat = 0x04;
3171 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3173 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3174 PATH_MAX, cifs_sb->local_nls, remap);
3175 name_len++; /* trailing null */
3178 /* protocol specifies ASCII buffer format (0x04) for unicode */
3179 pSMB->OldFileName[name_len] = 0x04;
3180 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3182 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3183 to_name, PATH_MAX, cifs_sb->local_nls,
3185 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3186 name_len2 *= 2; /* convert to bytes */
3188 name_len = copy_path_name(pSMB->OldFileName, from_name);
3189 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3190 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
3191 name_len2++; /* signature byte */
3194 count = 1 /* string type byte */ + name_len + name_len2;
3195 inc_rfc1001_len(pSMB, count);
3196 pSMB->ByteCount = cpu_to_le16(count);
3198 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3199 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3200 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3202 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3204 cifs_buf_release(pSMB);
3206 goto winCreateHardLinkRetry;
3212 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3213 const unsigned char *searchName, char **symlinkinfo,
3214 const struct nls_table *nls_codepage, int remap)
3216 /* SMB_QUERY_FILE_UNIX_LINK */
3217 TRANSACTION2_QPI_REQ *pSMB = NULL;
3218 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3222 __u16 params, byte_count;
3225 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3228 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3233 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3235 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3236 searchName, PATH_MAX, nls_codepage,
3238 name_len++; /* trailing null */
3241 name_len = copy_path_name(pSMB->FileName, searchName);
3244 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3245 pSMB->TotalDataCount = 0;
3246 pSMB->MaxParameterCount = cpu_to_le16(2);
3247 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3248 pSMB->MaxSetupCount = 0;
3252 pSMB->Reserved2 = 0;
3253 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3254 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3255 pSMB->DataCount = 0;
3256 pSMB->DataOffset = 0;
3257 pSMB->SetupCount = 1;
3258 pSMB->Reserved3 = 0;
3259 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3260 byte_count = params + 1 /* pad */ ;
3261 pSMB->TotalParameterCount = cpu_to_le16(params);
3262 pSMB->ParameterCount = pSMB->TotalParameterCount;
3263 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3264 pSMB->Reserved4 = 0;
3265 inc_rfc1001_len(pSMB, byte_count);
3266 pSMB->ByteCount = cpu_to_le16(byte_count);
3268 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3269 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3271 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3273 /* decode response */
3275 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3276 /* BB also check enough total bytes returned */
3277 if (rc || get_bcc(&pSMBr->hdr) < 2)
3281 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3283 data_start = ((char *) &pSMBr->hdr.Protocol) +
3284 le16_to_cpu(pSMBr->t2.DataOffset);
3286 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3291 /* BB FIXME investigate remapping reserved chars here */
3292 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3293 count, is_unicode, nls_codepage);
3298 cifs_buf_release(pSMB);
3300 goto querySymLinkRetry;
3305 * Recent Windows versions now create symlinks more frequently
3306 * and they use the "reparse point" mechanism below. We can of course
3307 * do symlinks nicely to Samba and other servers which support the
3308 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3309 * "MF" symlinks optionally, but for recent Windows we really need to
3310 * reenable the code below and fix the cifs_symlink callers to handle this.
3311 * In the interim this code has been moved to its own config option so
3312 * it is not compiled in by default until callers fixed up and more tested.
3315 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3316 __u16 fid, char **symlinkinfo,
3317 const struct nls_table *nls_codepage)
3321 struct smb_com_transaction_ioctl_req *pSMB;
3322 struct smb_com_transaction_ioctl_rsp *pSMBr;
3324 unsigned int sub_len;
3326 struct reparse_symlink_data *reparse_buf;
3327 struct reparse_posix_data *posix_buf;
3328 __u32 data_offset, data_count;
3331 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3332 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3337 pSMB->TotalParameterCount = 0 ;
3338 pSMB->TotalDataCount = 0;
3339 pSMB->MaxParameterCount = cpu_to_le32(2);
3340 /* BB find exact data count max from sess structure BB */
3341 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3342 pSMB->MaxSetupCount = 4;
3344 pSMB->ParameterOffset = 0;
3345 pSMB->DataCount = 0;
3346 pSMB->DataOffset = 0;
3347 pSMB->SetupCount = 4;
3348 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3349 pSMB->ParameterCount = pSMB->TotalParameterCount;
3350 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3351 pSMB->IsFsctl = 1; /* FSCTL */
3352 pSMB->IsRootFlag = 0;
3353 pSMB->Fid = fid; /* file handle always le */
3354 pSMB->ByteCount = 0;
3356 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3357 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3359 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3363 data_offset = le32_to_cpu(pSMBr->DataOffset);
3364 data_count = le32_to_cpu(pSMBr->DataCount);
3365 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3366 /* BB also check enough total bytes returned */
3367 rc = -EIO; /* bad smb */
3370 if (!data_count || (data_count > 2048)) {
3372 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3375 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3376 reparse_buf = (struct reparse_symlink_data *)
3377 ((char *)&pSMBr->hdr.Protocol + data_offset);
3378 if ((char *)reparse_buf >= end_of_smb) {
3382 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3383 cifs_dbg(FYI, "NFS style reparse tag\n");
3384 posix_buf = (struct reparse_posix_data *)reparse_buf;
3386 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3387 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3388 le64_to_cpu(posix_buf->InodeType));
3393 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3394 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3395 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3399 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3400 sub_len, is_unicode, nls_codepage);
3402 } else if (reparse_buf->ReparseTag !=
3403 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3408 /* Reparse tag is NTFS symlink */
3409 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3410 reparse_buf->PathBuffer;
3411 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3412 if (sub_start + sub_len > end_of_smb) {
3413 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3417 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3422 /* BB FIXME investigate remapping reserved chars here */
3423 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3428 cifs_buf_release(pSMB);
3431 * Note: On -EAGAIN error only caller can retry on handle based calls
3432 * since file handle passed in no longer valid.
3438 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3443 struct smb_com_transaction_compr_ioctl_req *pSMB;
3444 struct smb_com_transaction_ioctl_rsp *pSMBr;
3446 cifs_dbg(FYI, "Set compression for %u\n", fid);
3447 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3452 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3454 pSMB->TotalParameterCount = 0;
3455 pSMB->TotalDataCount = cpu_to_le32(2);
3456 pSMB->MaxParameterCount = 0;
3457 pSMB->MaxDataCount = 0;
3458 pSMB->MaxSetupCount = 4;
3460 pSMB->ParameterOffset = 0;
3461 pSMB->DataCount = cpu_to_le32(2);
3463 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3464 compression_state) - 4); /* 84 */
3465 pSMB->SetupCount = 4;
3466 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3467 pSMB->ParameterCount = 0;
3468 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3469 pSMB->IsFsctl = 1; /* FSCTL */
3470 pSMB->IsRootFlag = 0;
3471 pSMB->Fid = fid; /* file handle always le */
3472 /* 3 byte pad, followed by 2 byte compress state */
3473 pSMB->ByteCount = cpu_to_le16(5);
3474 inc_rfc1001_len(pSMB, 5);
3476 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3477 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3479 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3481 cifs_buf_release(pSMB);
3484 * Note: On -EAGAIN error only caller can retry on handle based calls
3485 * since file handle passed in no longer valid.
3491 #ifdef CONFIG_CIFS_POSIX
3493 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3494 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3495 struct cifs_posix_ace *cifs_ace)
3497 /* u8 cifs fields do not need le conversion */
3498 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3499 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3500 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3502 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3503 ace->e_perm, ace->e_tag, ace->e_id);
3509 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3510 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3511 const int acl_type, const int size_of_data_area)
3516 struct cifs_posix_ace *pACE;
3517 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3518 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3520 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3523 if (acl_type == ACL_TYPE_ACCESS) {
3524 count = le16_to_cpu(cifs_acl->access_entry_count);
3525 pACE = &cifs_acl->ace_array[0];
3526 size = sizeof(struct cifs_posix_acl);
3527 size += sizeof(struct cifs_posix_ace) * count;
3528 /* check if we would go beyond end of SMB */
3529 if (size_of_data_area < size) {
3530 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3531 size_of_data_area, size);
3534 } else if (acl_type == ACL_TYPE_DEFAULT) {
3535 count = le16_to_cpu(cifs_acl->access_entry_count);
3536 size = sizeof(struct cifs_posix_acl);
3537 size += sizeof(struct cifs_posix_ace) * count;
3538 /* skip past access ACEs to get to default ACEs */
3539 pACE = &cifs_acl->ace_array[count];
3540 count = le16_to_cpu(cifs_acl->default_entry_count);
3541 size += sizeof(struct cifs_posix_ace) * count;
3542 /* check if we would go beyond end of SMB */
3543 if (size_of_data_area < size)
3550 size = posix_acl_xattr_size(count);
3551 if ((buflen == 0) || (local_acl == NULL)) {
3552 /* used to query ACL EA size */
3553 } else if (size > buflen) {
3555 } else /* buffer big enough */ {
3556 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3558 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3559 for (i = 0; i < count ; i++) {
3560 cifs_convert_ace(&ace[i], pACE);
3567 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3568 const struct posix_acl_xattr_entry *local_ace)
3570 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3571 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3572 /* BB is there a better way to handle the large uid? */
3573 if (local_ace->e_id == cpu_to_le32(-1)) {
3574 /* Probably no need to le convert -1 on any arch but can not hurt */
3575 cifs_ace->cifs_uid = cpu_to_le64(-1);
3577 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3579 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3580 ace->e_perm, ace->e_tag, ace->e_id);
3584 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3585 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3586 const int buflen, const int acl_type)
3589 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3590 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3591 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3595 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3598 count = posix_acl_xattr_count((size_t)buflen);
3599 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3600 count, buflen, le32_to_cpu(local_acl->a_version));
3601 if (le32_to_cpu(local_acl->a_version) != 2) {
3602 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3603 le32_to_cpu(local_acl->a_version));
3606 cifs_acl->version = cpu_to_le16(1);
3607 if (acl_type == ACL_TYPE_ACCESS) {
3608 cifs_acl->access_entry_count = cpu_to_le16(count);
3609 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3610 } else if (acl_type == ACL_TYPE_DEFAULT) {
3611 cifs_acl->default_entry_count = cpu_to_le16(count);
3612 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3614 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3617 for (i = 0; i < count; i++)
3618 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3620 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3621 rc += sizeof(struct cifs_posix_acl);
3622 /* BB add check to make sure ACL does not overflow SMB */
3628 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3629 const unsigned char *searchName,
3630 char *acl_inf, const int buflen, const int acl_type,
3631 const struct nls_table *nls_codepage, int remap)
3633 /* SMB_QUERY_POSIX_ACL */
3634 TRANSACTION2_QPI_REQ *pSMB = NULL;
3635 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3639 __u16 params, byte_count;
3641 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3644 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3649 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3651 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3652 searchName, PATH_MAX, nls_codepage,
3654 name_len++; /* trailing null */
3656 pSMB->FileName[name_len] = 0;
3657 pSMB->FileName[name_len+1] = 0;
3659 name_len = copy_path_name(pSMB->FileName, searchName);
3662 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3663 pSMB->TotalDataCount = 0;
3664 pSMB->MaxParameterCount = cpu_to_le16(2);
3665 /* BB find exact max data count below from sess structure BB */
3666 pSMB->MaxDataCount = cpu_to_le16(4000);
3667 pSMB->MaxSetupCount = 0;
3671 pSMB->Reserved2 = 0;
3672 pSMB->ParameterOffset = cpu_to_le16(
3673 offsetof(struct smb_com_transaction2_qpi_req,
3674 InformationLevel) - 4);
3675 pSMB->DataCount = 0;
3676 pSMB->DataOffset = 0;
3677 pSMB->SetupCount = 1;
3678 pSMB->Reserved3 = 0;
3679 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3680 byte_count = params + 1 /* pad */ ;
3681 pSMB->TotalParameterCount = cpu_to_le16(params);
3682 pSMB->ParameterCount = pSMB->TotalParameterCount;
3683 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3684 pSMB->Reserved4 = 0;
3685 inc_rfc1001_len(pSMB, byte_count);
3686 pSMB->ByteCount = cpu_to_le16(byte_count);
3688 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3689 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3690 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3692 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3694 /* decode response */
3696 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3697 /* BB also check enough total bytes returned */
3698 if (rc || get_bcc(&pSMBr->hdr) < 2)
3699 rc = -EIO; /* bad smb */
3701 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3702 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3703 rc = cifs_copy_posix_acl(acl_inf,
3704 (char *)&pSMBr->hdr.Protocol+data_offset,
3705 buflen, acl_type, count);
3708 cifs_buf_release(pSMB);
3715 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3716 const unsigned char *fileName,
3717 const char *local_acl, const int buflen,
3719 const struct nls_table *nls_codepage, int remap)
3721 struct smb_com_transaction2_spi_req *pSMB = NULL;
3722 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3726 int bytes_returned = 0;
3727 __u16 params, byte_count, data_count, param_offset, offset;
3729 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3731 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3735 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3737 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3738 PATH_MAX, nls_codepage, remap);
3739 name_len++; /* trailing null */
3742 name_len = copy_path_name(pSMB->FileName, fileName);
3744 params = 6 + name_len;
3745 pSMB->MaxParameterCount = cpu_to_le16(2);
3746 /* BB find max SMB size from sess */
3747 pSMB->MaxDataCount = cpu_to_le16(1000);
3748 pSMB->MaxSetupCount = 0;
3752 pSMB->Reserved2 = 0;
3753 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3754 InformationLevel) - 4;
3755 offset = param_offset + params;
3756 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3757 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3759 /* convert to on the wire format for POSIX ACL */
3760 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3762 if (data_count == 0) {
3764 goto setACLerrorExit;
3766 pSMB->DataOffset = cpu_to_le16(offset);
3767 pSMB->SetupCount = 1;
3768 pSMB->Reserved3 = 0;
3769 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3770 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3771 byte_count = 3 /* pad */ + params + data_count;
3772 pSMB->DataCount = cpu_to_le16(data_count);
3773 pSMB->TotalDataCount = pSMB->DataCount;
3774 pSMB->ParameterCount = cpu_to_le16(params);
3775 pSMB->TotalParameterCount = pSMB->ParameterCount;
3776 pSMB->Reserved4 = 0;
3777 inc_rfc1001_len(pSMB, byte_count);
3778 pSMB->ByteCount = cpu_to_le16(byte_count);
3779 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3780 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3782 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3785 cifs_buf_release(pSMB);
3791 /* BB fix tabs in this function FIXME BB */
3793 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3794 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3797 struct smb_t2_qfi_req *pSMB = NULL;
3798 struct smb_t2_qfi_rsp *pSMBr = NULL;
3800 __u16 params, byte_count;
3802 cifs_dbg(FYI, "In GetExtAttr\n");
3807 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3812 params = 2 /* level */ + 2 /* fid */;
3813 pSMB->t2.TotalDataCount = 0;
3814 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3815 /* BB find exact max data count below from sess structure BB */
3816 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3817 pSMB->t2.MaxSetupCount = 0;
3818 pSMB->t2.Reserved = 0;
3820 pSMB->t2.Timeout = 0;
3821 pSMB->t2.Reserved2 = 0;
3822 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3824 pSMB->t2.DataCount = 0;
3825 pSMB->t2.DataOffset = 0;
3826 pSMB->t2.SetupCount = 1;
3827 pSMB->t2.Reserved3 = 0;
3828 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3829 byte_count = params + 1 /* pad */ ;
3830 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3831 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3832 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3835 inc_rfc1001_len(pSMB, byte_count);
3836 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3838 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3839 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3841 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3843 /* decode response */
3844 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3845 /* BB also check enough total bytes returned */
3846 if (rc || get_bcc(&pSMBr->hdr) < 2)
3847 /* If rc should we check for EOPNOSUPP and
3848 disable the srvino flag? or in caller? */
3849 rc = -EIO; /* bad smb */
3851 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3852 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3853 struct file_chattr_info *pfinfo;
3854 /* BB Do we need a cast or hash here ? */
3856 cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n");
3860 pfinfo = (struct file_chattr_info *)
3861 (data_offset + (char *) &pSMBr->hdr.Protocol);
3862 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3863 *pMask = le64_to_cpu(pfinfo->mask);
3867 cifs_buf_release(pSMB);
3869 goto GetExtAttrRetry;
3873 #endif /* CONFIG_POSIX */
3876 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3877 * all NT TRANSACTS that we init here have total parm and data under about 400
3878 * bytes (to fit in small cifs buffer size), which is the case so far, it
3879 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3880 * returned setup area) and MaxParameterCount (returned parms size) must be set
3884 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3885 const int parm_len, struct cifs_tcon *tcon,
3890 struct smb_com_ntransact_req *pSMB;
3892 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3896 *ret_buf = (void *)pSMB;
3898 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3899 pSMB->TotalDataCount = 0;
3900 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3901 pSMB->ParameterCount = pSMB->TotalParameterCount;
3902 pSMB->DataCount = pSMB->TotalDataCount;
3903 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3904 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3905 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3906 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3907 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3908 pSMB->SubCommand = cpu_to_le16(sub_command);
3913 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3914 __u32 *pparmlen, __u32 *pdatalen)
3917 __u32 data_count, data_offset, parm_count, parm_offset;
3918 struct smb_com_ntransact_rsp *pSMBr;
3927 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3929 bcc = get_bcc(&pSMBr->hdr);
3930 end_of_smb = 2 /* sizeof byte count */ + bcc +
3931 (char *)&pSMBr->ByteCount;
3933 data_offset = le32_to_cpu(pSMBr->DataOffset);
3934 data_count = le32_to_cpu(pSMBr->DataCount);
3935 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3936 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3938 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3939 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3941 /* should we also check that parm and data areas do not overlap? */
3942 if (*ppparm > end_of_smb) {
3943 cifs_dbg(FYI, "parms start after end of smb\n");
3945 } else if (parm_count + *ppparm > end_of_smb) {
3946 cifs_dbg(FYI, "parm end after end of smb\n");
3948 } else if (*ppdata > end_of_smb) {
3949 cifs_dbg(FYI, "data starts after end of smb\n");
3951 } else if (data_count + *ppdata > end_of_smb) {
3952 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3953 *ppdata, data_count, (data_count + *ppdata),
3956 } else if (parm_count + data_count > bcc) {
3957 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3960 *pdatalen = data_count;
3961 *pparmlen = parm_count;
3965 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3967 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3968 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3972 QUERY_SEC_DESC_REQ *pSMB;
3974 struct kvec rsp_iov;
3976 cifs_dbg(FYI, "GetCifsACL\n");
3981 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3982 8 /* parm len */, tcon, (void **) &pSMB);
3986 pSMB->MaxParameterCount = cpu_to_le32(4);
3987 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3988 pSMB->MaxSetupCount = 0;
3989 pSMB->Fid = fid; /* file handle always le */
3990 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3992 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3993 inc_rfc1001_len(pSMB, 11);
3994 iov[0].iov_base = (char *)pSMB;
3995 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3997 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3999 cifs_small_buf_release(pSMB);
4000 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
4002 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
4003 } else { /* decode response */
4007 struct smb_com_ntransact_rsp *pSMBr;
4010 /* validate_nttransact */
4011 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
4012 &pdata, &parm_len, pbuflen);
4015 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
4017 cifs_dbg(FYI, "smb %p parm %p data %p\n",
4018 pSMBr, parm, *acl_inf);
4020 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
4021 rc = -EIO; /* bad smb */
4026 /* BB check that data area is minimum length and as big as acl_len */
4028 acl_len = le32_to_cpu(*parm);
4029 if (acl_len != *pbuflen) {
4030 cifs_dbg(VFS, "acl length %d does not match %d\n",
4032 if (*pbuflen > acl_len)
4036 /* check if buffer is big enough for the acl
4037 header followed by the smallest SID */
4038 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
4039 (*pbuflen >= 64 * 1024)) {
4040 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
4044 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
4045 if (*acl_inf == NULL) {
4052 free_rsp_buf(buf_type, rsp_iov.iov_base);
4057 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
4058 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
4060 __u16 byte_count, param_count, data_count, param_offset, data_offset;
4062 int bytes_returned = 0;
4063 SET_SEC_DESC_REQ *pSMB = NULL;
4067 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
4071 pSMB->MaxSetupCount = 0;
4075 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
4076 data_count = acllen;
4077 data_offset = param_offset + param_count;
4078 byte_count = 3 /* pad */ + param_count;
4080 pSMB->DataCount = cpu_to_le32(data_count);
4081 pSMB->TotalDataCount = pSMB->DataCount;
4082 pSMB->MaxParameterCount = cpu_to_le32(4);
4083 pSMB->MaxDataCount = cpu_to_le32(16384);
4084 pSMB->ParameterCount = cpu_to_le32(param_count);
4085 pSMB->ParameterOffset = cpu_to_le32(param_offset);
4086 pSMB->TotalParameterCount = pSMB->ParameterCount;
4087 pSMB->DataOffset = cpu_to_le32(data_offset);
4088 pSMB->SetupCount = 0;
4089 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
4090 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
4092 pSMB->Fid = fid; /* file handle always le */
4093 pSMB->Reserved2 = 0;
4094 pSMB->AclFlags = cpu_to_le32(aclflag);
4096 if (pntsd && acllen) {
4097 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
4098 data_offset, pntsd, acllen);
4099 inc_rfc1001_len(pSMB, byte_count + data_count);
4101 inc_rfc1001_len(pSMB, byte_count);
4103 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4104 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4106 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4107 bytes_returned, rc);
4109 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
4110 cifs_buf_release(pSMB);
4113 goto setCifsAclRetry;
4119 /* Legacy Query Path Information call for lookup to old servers such
4122 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
4123 const char *search_name, FILE_ALL_INFO *data,
4124 const struct nls_table *nls_codepage, int remap)
4126 QUERY_INFORMATION_REQ *pSMB;
4127 QUERY_INFORMATION_RSP *pSMBr;
4132 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4134 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4139 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4141 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4142 search_name, PATH_MAX, nls_codepage,
4144 name_len++; /* trailing null */
4147 name_len = copy_path_name(pSMB->FileName, search_name);
4149 pSMB->BufferFormat = 0x04;
4150 name_len++; /* account for buffer type byte */
4151 inc_rfc1001_len(pSMB, (__u16)name_len);
4152 pSMB->ByteCount = cpu_to_le16(name_len);
4154 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4155 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4157 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4159 struct timespec64 ts;
4160 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4162 /* decode response */
4163 /* BB FIXME - add time zone adjustment BB */
4164 memset(data, 0, sizeof(FILE_ALL_INFO));
4167 /* decode time fields */
4168 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4169 data->LastWriteTime = data->ChangeTime;
4170 data->LastAccessTime = 0;
4171 data->AllocationSize =
4172 cpu_to_le64(le32_to_cpu(pSMBr->size));
4173 data->EndOfFile = data->AllocationSize;
4175 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4177 rc = -EIO; /* bad buffer passed in */
4179 cifs_buf_release(pSMB);
4188 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4189 u16 netfid, FILE_ALL_INFO *pFindData)
4191 struct smb_t2_qfi_req *pSMB = NULL;
4192 struct smb_t2_qfi_rsp *pSMBr = NULL;
4195 __u16 params, byte_count;
4198 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4203 params = 2 /* level */ + 2 /* fid */;
4204 pSMB->t2.TotalDataCount = 0;
4205 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4206 /* BB find exact max data count below from sess structure BB */
4207 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4208 pSMB->t2.MaxSetupCount = 0;
4209 pSMB->t2.Reserved = 0;
4211 pSMB->t2.Timeout = 0;
4212 pSMB->t2.Reserved2 = 0;
4213 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4215 pSMB->t2.DataCount = 0;
4216 pSMB->t2.DataOffset = 0;
4217 pSMB->t2.SetupCount = 1;
4218 pSMB->t2.Reserved3 = 0;
4219 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4220 byte_count = params + 1 /* pad */ ;
4221 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4222 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4223 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4226 inc_rfc1001_len(pSMB, byte_count);
4227 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4229 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4230 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4232 cifs_dbg(FYI, "Send error in QFileInfo = %d", rc);
4233 } else { /* decode response */
4234 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4236 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4238 else if (get_bcc(&pSMBr->hdr) < 40)
4239 rc = -EIO; /* bad smb */
4240 else if (pFindData) {
4241 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4242 memcpy((char *) pFindData,
4243 (char *) &pSMBr->hdr.Protocol +
4244 data_offset, sizeof(FILE_ALL_INFO));
4248 cifs_buf_release(pSMB);
4250 goto QFileInfoRetry;
4256 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4257 const char *search_name, FILE_ALL_INFO *data,
4258 int legacy /* old style infolevel */,
4259 const struct nls_table *nls_codepage, int remap)
4261 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4262 TRANSACTION2_QPI_REQ *pSMB = NULL;
4263 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4267 __u16 params, byte_count;
4269 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4271 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4276 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4278 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4279 PATH_MAX, nls_codepage, remap);
4280 name_len++; /* trailing null */
4283 name_len = copy_path_name(pSMB->FileName, search_name);
4286 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4287 pSMB->TotalDataCount = 0;
4288 pSMB->MaxParameterCount = cpu_to_le16(2);
4289 /* BB find exact max SMB PDU from sess structure BB */
4290 pSMB->MaxDataCount = cpu_to_le16(4000);
4291 pSMB->MaxSetupCount = 0;
4295 pSMB->Reserved2 = 0;
4296 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4297 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4298 pSMB->DataCount = 0;
4299 pSMB->DataOffset = 0;
4300 pSMB->SetupCount = 1;
4301 pSMB->Reserved3 = 0;
4302 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4303 byte_count = params + 1 /* pad */ ;
4304 pSMB->TotalParameterCount = cpu_to_le16(params);
4305 pSMB->ParameterCount = pSMB->TotalParameterCount;
4307 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4309 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4310 pSMB->Reserved4 = 0;
4311 inc_rfc1001_len(pSMB, byte_count);
4312 pSMB->ByteCount = cpu_to_le16(byte_count);
4314 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4315 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4317 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4318 } else { /* decode response */
4319 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4321 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4323 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4324 rc = -EIO; /* bad smb */
4325 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4326 rc = -EIO; /* 24 or 26 expected but we do not read
4330 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4333 * On legacy responses we do not read the last field,
4334 * EAsize, fortunately since it varies by subdialect and
4335 * also note it differs on Set vs Get, ie two bytes or 4
4336 * bytes depending but we don't care here.
4339 size = sizeof(FILE_INFO_STANDARD);
4341 size = sizeof(FILE_ALL_INFO);
4342 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4347 cifs_buf_release(pSMB);
4349 goto QPathInfoRetry;
4355 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4356 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4358 struct smb_t2_qfi_req *pSMB = NULL;
4359 struct smb_t2_qfi_rsp *pSMBr = NULL;
4362 __u16 params, byte_count;
4365 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4370 params = 2 /* level */ + 2 /* fid */;
4371 pSMB->t2.TotalDataCount = 0;
4372 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4373 /* BB find exact max data count below from sess structure BB */
4374 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4375 pSMB->t2.MaxSetupCount = 0;
4376 pSMB->t2.Reserved = 0;
4378 pSMB->t2.Timeout = 0;
4379 pSMB->t2.Reserved2 = 0;
4380 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4382 pSMB->t2.DataCount = 0;
4383 pSMB->t2.DataOffset = 0;
4384 pSMB->t2.SetupCount = 1;
4385 pSMB->t2.Reserved3 = 0;
4386 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4387 byte_count = params + 1 /* pad */ ;
4388 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4389 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4390 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4393 inc_rfc1001_len(pSMB, byte_count);
4394 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4396 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4397 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4399 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d", rc);
4400 } else { /* decode response */
4401 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4403 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4404 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4405 rc = -EIO; /* bad smb */
4407 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4408 memcpy((char *) pFindData,
4409 (char *) &pSMBr->hdr.Protocol +
4411 sizeof(FILE_UNIX_BASIC_INFO));
4415 cifs_buf_release(pSMB);
4417 goto UnixQFileInfoRetry;
4423 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4424 const unsigned char *searchName,
4425 FILE_UNIX_BASIC_INFO *pFindData,
4426 const struct nls_table *nls_codepage, int remap)
4428 /* SMB_QUERY_FILE_UNIX_BASIC */
4429 TRANSACTION2_QPI_REQ *pSMB = NULL;
4430 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4432 int bytes_returned = 0;
4434 __u16 params, byte_count;
4436 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4438 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4443 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4445 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4446 PATH_MAX, nls_codepage, remap);
4447 name_len++; /* trailing null */
4450 name_len = copy_path_name(pSMB->FileName, searchName);
4453 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4454 pSMB->TotalDataCount = 0;
4455 pSMB->MaxParameterCount = cpu_to_le16(2);
4456 /* BB find exact max SMB PDU from sess structure BB */
4457 pSMB->MaxDataCount = cpu_to_le16(4000);
4458 pSMB->MaxSetupCount = 0;
4462 pSMB->Reserved2 = 0;
4463 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4464 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4465 pSMB->DataCount = 0;
4466 pSMB->DataOffset = 0;
4467 pSMB->SetupCount = 1;
4468 pSMB->Reserved3 = 0;
4469 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4470 byte_count = params + 1 /* pad */ ;
4471 pSMB->TotalParameterCount = cpu_to_le16(params);
4472 pSMB->ParameterCount = pSMB->TotalParameterCount;
4473 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4474 pSMB->Reserved4 = 0;
4475 inc_rfc1001_len(pSMB, byte_count);
4476 pSMB->ByteCount = cpu_to_le16(byte_count);
4478 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4479 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4481 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d", rc);
4482 } else { /* decode response */
4483 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4485 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4486 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4487 rc = -EIO; /* bad smb */
4489 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4490 memcpy((char *) pFindData,
4491 (char *) &pSMBr->hdr.Protocol +
4493 sizeof(FILE_UNIX_BASIC_INFO));
4496 cifs_buf_release(pSMB);
4498 goto UnixQPathInfoRetry;
4503 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4505 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4506 const char *searchName, struct cifs_sb_info *cifs_sb,
4507 __u16 *pnetfid, __u16 search_flags,
4508 struct cifs_search_info *psrch_inf, bool msearch)
4510 /* level 257 SMB_ */
4511 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4512 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4513 T2_FFIRST_RSP_PARMS *parms;
4515 int bytes_returned = 0;
4516 int name_len, remap;
4517 __u16 params, byte_count;
4518 struct nls_table *nls_codepage;
4520 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4523 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4528 nls_codepage = cifs_sb->local_nls;
4529 remap = cifs_remap(cifs_sb);
4531 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4533 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4534 PATH_MAX, nls_codepage, remap);
4535 /* We can not add the asterik earlier in case
4536 it got remapped to 0xF03A as if it were part of the
4537 directory name instead of a wildcard */
4540 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4541 pSMB->FileName[name_len+1] = 0;
4542 pSMB->FileName[name_len+2] = '*';
4543 pSMB->FileName[name_len+3] = 0;
4544 name_len += 4; /* now the trailing null */
4545 /* null terminate just in case */
4546 pSMB->FileName[name_len] = 0;
4547 pSMB->FileName[name_len+1] = 0;
4551 name_len = copy_path_name(pSMB->FileName, searchName);
4553 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4554 name_len = PATH_MAX-2;
4555 /* overwrite nul byte */
4556 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4557 pSMB->FileName[name_len] = '*';
4558 pSMB->FileName[name_len+1] = 0;
4563 params = 12 + name_len /* includes null */ ;
4564 pSMB->TotalDataCount = 0; /* no EAs */
4565 pSMB->MaxParameterCount = cpu_to_le16(10);
4566 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4567 pSMB->MaxSetupCount = 0;
4571 pSMB->Reserved2 = 0;
4572 byte_count = params + 1 /* pad */ ;
4573 pSMB->TotalParameterCount = cpu_to_le16(params);
4574 pSMB->ParameterCount = pSMB->TotalParameterCount;
4575 pSMB->ParameterOffset = cpu_to_le16(
4576 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4578 pSMB->DataCount = 0;
4579 pSMB->DataOffset = 0;
4580 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4581 pSMB->Reserved3 = 0;
4582 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4583 pSMB->SearchAttributes =
4584 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4586 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4587 pSMB->SearchFlags = cpu_to_le16(search_flags);
4588 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4590 /* BB what should we set StorageType to? Does it matter? BB */
4591 pSMB->SearchStorageType = 0;
4592 inc_rfc1001_len(pSMB, byte_count);
4593 pSMB->ByteCount = cpu_to_le16(byte_count);
4595 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4596 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4597 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4599 if (rc) {/* BB add logic to retry regular search if Unix search
4600 rejected unexpectedly by server */
4601 /* BB Add code to handle unsupported level rc */
4602 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4604 cifs_buf_release(pSMB);
4606 /* BB eventually could optimize out free and realloc of buf */
4609 goto findFirstRetry;
4610 } else { /* decode response */
4611 /* BB remember to free buffer if error BB */
4612 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4616 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4617 psrch_inf->unicode = true;
4619 psrch_inf->unicode = false;
4621 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4622 psrch_inf->smallBuf = 0;
4623 psrch_inf->srch_entries_start =
4624 (char *) &pSMBr->hdr.Protocol +
4625 le16_to_cpu(pSMBr->t2.DataOffset);
4626 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4627 le16_to_cpu(pSMBr->t2.ParameterOffset));
4629 if (parms->EndofSearch)
4630 psrch_inf->endOfSearch = true;
4632 psrch_inf->endOfSearch = false;
4634 psrch_inf->entries_in_buffer =
4635 le16_to_cpu(parms->SearchCount);
4636 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4637 psrch_inf->entries_in_buffer;
4638 lnoff = le16_to_cpu(parms->LastNameOffset);
4639 if (CIFSMaxBufSize < lnoff) {
4640 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4641 psrch_inf->last_entry = NULL;
4645 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4649 *pnetfid = parms->SearchHandle;
4651 cifs_buf_release(pSMB);
4658 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4659 __u16 searchHandle, __u16 search_flags,
4660 struct cifs_search_info *psrch_inf)
4662 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4663 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4664 T2_FNEXT_RSP_PARMS *parms;
4665 char *response_data;
4668 unsigned int name_len;
4669 __u16 params, byte_count;
4671 cifs_dbg(FYI, "In FindNext\n");
4673 if (psrch_inf->endOfSearch)
4676 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4681 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4683 pSMB->TotalDataCount = 0; /* no EAs */
4684 pSMB->MaxParameterCount = cpu_to_le16(8);
4685 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4686 pSMB->MaxSetupCount = 0;
4690 pSMB->Reserved2 = 0;
4691 pSMB->ParameterOffset = cpu_to_le16(
4692 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4693 pSMB->DataCount = 0;
4694 pSMB->DataOffset = 0;
4695 pSMB->SetupCount = 1;
4696 pSMB->Reserved3 = 0;
4697 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4698 pSMB->SearchHandle = searchHandle; /* always kept as le */
4700 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4701 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4702 pSMB->ResumeKey = psrch_inf->resume_key;
4703 pSMB->SearchFlags = cpu_to_le16(search_flags);
4705 name_len = psrch_inf->resume_name_len;
4707 if (name_len < PATH_MAX) {
4708 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4709 byte_count += name_len;
4710 /* 14 byte parm len above enough for 2 byte null terminator */
4711 pSMB->ResumeFileName[name_len] = 0;
4712 pSMB->ResumeFileName[name_len+1] = 0;
4715 goto FNext2_err_exit;
4717 byte_count = params + 1 /* pad */ ;
4718 pSMB->TotalParameterCount = cpu_to_le16(params);
4719 pSMB->ParameterCount = pSMB->TotalParameterCount;
4720 inc_rfc1001_len(pSMB, byte_count);
4721 pSMB->ByteCount = cpu_to_le16(byte_count);
4723 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4724 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4725 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4728 psrch_inf->endOfSearch = true;
4729 cifs_buf_release(pSMB);
4730 rc = 0; /* search probably was closed at end of search*/
4732 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4733 } else { /* decode response */
4734 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4739 /* BB fixme add lock for file (srch_info) struct here */
4740 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4741 psrch_inf->unicode = true;
4743 psrch_inf->unicode = false;
4744 response_data = (char *) &pSMBr->hdr.Protocol +
4745 le16_to_cpu(pSMBr->t2.ParameterOffset);
4746 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4747 response_data = (char *)&pSMBr->hdr.Protocol +
4748 le16_to_cpu(pSMBr->t2.DataOffset);
4749 if (psrch_inf->smallBuf)
4750 cifs_small_buf_release(
4751 psrch_inf->ntwrk_buf_start);
4753 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4754 psrch_inf->srch_entries_start = response_data;
4755 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4756 psrch_inf->smallBuf = 0;
4757 if (parms->EndofSearch)
4758 psrch_inf->endOfSearch = true;
4760 psrch_inf->endOfSearch = false;
4761 psrch_inf->entries_in_buffer =
4762 le16_to_cpu(parms->SearchCount);
4763 psrch_inf->index_of_last_entry +=
4764 psrch_inf->entries_in_buffer;
4765 lnoff = le16_to_cpu(parms->LastNameOffset);
4766 if (CIFSMaxBufSize < lnoff) {
4767 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4768 psrch_inf->last_entry = NULL;
4771 psrch_inf->last_entry =
4772 psrch_inf->srch_entries_start + lnoff;
4774 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4775 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4777 /* BB fixme add unlock here */
4782 /* BB On error, should we leave previous search buf (and count and
4783 last entry fields) intact or free the previous one? */
4785 /* Note: On -EAGAIN error only caller can retry on handle based calls
4786 since file handle passed in no longer valid */
4789 cifs_buf_release(pSMB);
4794 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4795 const __u16 searchHandle)
4798 FINDCLOSE_REQ *pSMB = NULL;
4800 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4801 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4803 /* no sense returning error if session restarted
4804 as file handle has been closed */
4810 pSMB->FileID = searchHandle;
4811 pSMB->ByteCount = 0;
4812 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4813 cifs_small_buf_release(pSMB);
4815 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4817 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4819 /* Since session is dead, search handle closed on server already */
4827 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4828 const char *search_name, __u64 *inode_number,
4829 const struct nls_table *nls_codepage, int remap)
4832 TRANSACTION2_QPI_REQ *pSMB = NULL;
4833 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4834 int name_len, bytes_returned;
4835 __u16 params, byte_count;
4837 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4841 GetInodeNumberRetry:
4842 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4847 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4849 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4850 search_name, PATH_MAX, nls_codepage,
4852 name_len++; /* trailing null */
4855 name_len = copy_path_name(pSMB->FileName, search_name);
4858 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4859 pSMB->TotalDataCount = 0;
4860 pSMB->MaxParameterCount = cpu_to_le16(2);
4861 /* BB find exact max data count below from sess structure BB */
4862 pSMB->MaxDataCount = cpu_to_le16(4000);
4863 pSMB->MaxSetupCount = 0;
4867 pSMB->Reserved2 = 0;
4868 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4869 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4870 pSMB->DataCount = 0;
4871 pSMB->DataOffset = 0;
4872 pSMB->SetupCount = 1;
4873 pSMB->Reserved3 = 0;
4874 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4875 byte_count = params + 1 /* pad */ ;
4876 pSMB->TotalParameterCount = cpu_to_le16(params);
4877 pSMB->ParameterCount = pSMB->TotalParameterCount;
4878 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4879 pSMB->Reserved4 = 0;
4880 inc_rfc1001_len(pSMB, byte_count);
4881 pSMB->ByteCount = cpu_to_le16(byte_count);
4883 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4884 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4886 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4888 /* decode response */
4889 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4890 /* BB also check enough total bytes returned */
4891 if (rc || get_bcc(&pSMBr->hdr) < 2)
4892 /* If rc should we check for EOPNOSUPP and
4893 disable the srvino flag? or in caller? */
4894 rc = -EIO; /* bad smb */
4896 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4897 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4898 struct file_internal_info *pfinfo;
4899 /* BB Do we need a cast or hash here ? */
4901 cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n");
4903 goto GetInodeNumOut;
4905 pfinfo = (struct file_internal_info *)
4906 (data_offset + (char *) &pSMBr->hdr.Protocol);
4907 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4911 cifs_buf_release(pSMB);
4913 goto GetInodeNumberRetry;
4918 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4919 const char *search_name, struct dfs_info3_param **target_nodes,
4920 unsigned int *num_of_nodes,
4921 const struct nls_table *nls_codepage, int remap)
4923 /* TRANS2_GET_DFS_REFERRAL */
4924 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4925 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4929 __u16 params, byte_count;
4931 *target_nodes = NULL;
4933 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4934 if (ses == NULL || ses->tcon_ipc == NULL)
4938 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4943 /* server pointer checked in called function,
4944 but should never be null here anyway */
4945 pSMB->hdr.Mid = get_next_mid(ses->server);
4946 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4947 pSMB->hdr.Uid = ses->Suid;
4948 if (ses->capabilities & CAP_STATUS32)
4949 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4950 if (ses->capabilities & CAP_DFS)
4951 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4953 if (ses->capabilities & CAP_UNICODE) {
4954 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4956 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4957 search_name, PATH_MAX, nls_codepage,
4959 name_len++; /* trailing null */
4961 } else { /* BB improve the check for buffer overruns BB */
4962 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4965 if (ses->server->sign)
4966 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4968 pSMB->hdr.Uid = ses->Suid;
4970 params = 2 /* level */ + name_len /*includes null */ ;
4971 pSMB->TotalDataCount = 0;
4972 pSMB->DataCount = 0;
4973 pSMB->DataOffset = 0;
4974 pSMB->MaxParameterCount = 0;
4975 /* BB find exact max SMB PDU from sess structure BB */
4976 pSMB->MaxDataCount = cpu_to_le16(4000);
4977 pSMB->MaxSetupCount = 0;
4981 pSMB->Reserved2 = 0;
4982 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4983 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4984 pSMB->SetupCount = 1;
4985 pSMB->Reserved3 = 0;
4986 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4987 byte_count = params + 3 /* pad */ ;
4988 pSMB->ParameterCount = cpu_to_le16(params);
4989 pSMB->TotalParameterCount = pSMB->ParameterCount;
4990 pSMB->MaxReferralLevel = cpu_to_le16(3);
4991 inc_rfc1001_len(pSMB, byte_count);
4992 pSMB->ByteCount = cpu_to_le16(byte_count);
4994 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4995 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4997 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
5000 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5002 /* BB Also check if enough total bytes returned? */
5003 if (rc || get_bcc(&pSMBr->hdr) < 17) {
5004 rc = -EIO; /* bad smb */
5008 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
5009 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
5011 /* parse returned result into more usable form */
5012 rc = parse_dfs_referrals(&pSMBr->dfs_data,
5013 le16_to_cpu(pSMBr->t2.DataCount),
5014 num_of_nodes, target_nodes, nls_codepage,
5016 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
5019 cifs_buf_release(pSMB);
5027 /* Query File System Info such as free space to old servers such as Win 9x */
5029 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
5030 struct kstatfs *FSData)
5032 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
5033 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5034 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5035 FILE_SYSTEM_ALLOC_INFO *response_data;
5037 int bytes_returned = 0;
5038 __u16 params, byte_count;
5040 cifs_dbg(FYI, "OldQFSInfo\n");
5042 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5047 params = 2; /* level */
5048 pSMB->TotalDataCount = 0;
5049 pSMB->MaxParameterCount = cpu_to_le16(2);
5050 pSMB->MaxDataCount = cpu_to_le16(1000);
5051 pSMB->MaxSetupCount = 0;
5055 pSMB->Reserved2 = 0;
5056 byte_count = params + 1 /* pad */ ;
5057 pSMB->TotalParameterCount = cpu_to_le16(params);
5058 pSMB->ParameterCount = pSMB->TotalParameterCount;
5059 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5060 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5061 pSMB->DataCount = 0;
5062 pSMB->DataOffset = 0;
5063 pSMB->SetupCount = 1;
5064 pSMB->Reserved3 = 0;
5065 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5066 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
5067 inc_rfc1001_len(pSMB, byte_count);
5068 pSMB->ByteCount = cpu_to_le16(byte_count);
5070 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5071 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5073 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5074 } else { /* decode response */
5075 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5077 if (rc || get_bcc(&pSMBr->hdr) < 18)
5078 rc = -EIO; /* bad smb */
5080 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5081 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
5082 get_bcc(&pSMBr->hdr), data_offset);
5084 response_data = (FILE_SYSTEM_ALLOC_INFO *)
5085 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5087 le16_to_cpu(response_data->BytesPerSector) *
5088 le32_to_cpu(response_data->
5089 SectorsPerAllocationUnit);
5091 * much prefer larger but if server doesn't report
5092 * a valid size than 4K is a reasonable minimum
5094 if (FSData->f_bsize < 512)
5095 FSData->f_bsize = 4096;
5098 le32_to_cpu(response_data->TotalAllocationUnits);
5099 FSData->f_bfree = FSData->f_bavail =
5100 le32_to_cpu(response_data->FreeAllocationUnits);
5101 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5102 (unsigned long long)FSData->f_blocks,
5103 (unsigned long long)FSData->f_bfree,
5107 cifs_buf_release(pSMB);
5110 goto oldQFSInfoRetry;
5116 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
5117 struct kstatfs *FSData)
5119 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5120 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5121 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5122 FILE_SYSTEM_INFO *response_data;
5124 int bytes_returned = 0;
5125 __u16 params, byte_count;
5127 cifs_dbg(FYI, "In QFSInfo\n");
5129 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5134 params = 2; /* level */
5135 pSMB->TotalDataCount = 0;
5136 pSMB->MaxParameterCount = cpu_to_le16(2);
5137 pSMB->MaxDataCount = cpu_to_le16(1000);
5138 pSMB->MaxSetupCount = 0;
5142 pSMB->Reserved2 = 0;
5143 byte_count = params + 1 /* pad */ ;
5144 pSMB->TotalParameterCount = cpu_to_le16(params);
5145 pSMB->ParameterCount = pSMB->TotalParameterCount;
5146 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5147 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5148 pSMB->DataCount = 0;
5149 pSMB->DataOffset = 0;
5150 pSMB->SetupCount = 1;
5151 pSMB->Reserved3 = 0;
5152 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5153 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5154 inc_rfc1001_len(pSMB, byte_count);
5155 pSMB->ByteCount = cpu_to_le16(byte_count);
5157 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5158 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5160 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5161 } else { /* decode response */
5162 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5164 if (rc || get_bcc(&pSMBr->hdr) < 24)
5165 rc = -EIO; /* bad smb */
5167 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5171 *) (((char *) &pSMBr->hdr.Protocol) +
5174 le32_to_cpu(response_data->BytesPerSector) *
5175 le32_to_cpu(response_data->
5176 SectorsPerAllocationUnit);
5178 * much prefer larger but if server doesn't report
5179 * a valid size than 4K is a reasonable minimum
5181 if (FSData->f_bsize < 512)
5182 FSData->f_bsize = 4096;
5185 le64_to_cpu(response_data->TotalAllocationUnits);
5186 FSData->f_bfree = FSData->f_bavail =
5187 le64_to_cpu(response_data->FreeAllocationUnits);
5188 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5189 (unsigned long long)FSData->f_blocks,
5190 (unsigned long long)FSData->f_bfree,
5194 cifs_buf_release(pSMB);
5203 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5205 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5206 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5207 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5208 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5210 int bytes_returned = 0;
5211 __u16 params, byte_count;
5213 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5215 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5220 params = 2; /* level */
5221 pSMB->TotalDataCount = 0;
5222 pSMB->MaxParameterCount = cpu_to_le16(2);
5223 /* BB find exact max SMB PDU from sess structure BB */
5224 pSMB->MaxDataCount = cpu_to_le16(1000);
5225 pSMB->MaxSetupCount = 0;
5229 pSMB->Reserved2 = 0;
5230 byte_count = params + 1 /* pad */ ;
5231 pSMB->TotalParameterCount = cpu_to_le16(params);
5232 pSMB->ParameterCount = pSMB->TotalParameterCount;
5233 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5234 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5235 pSMB->DataCount = 0;
5236 pSMB->DataOffset = 0;
5237 pSMB->SetupCount = 1;
5238 pSMB->Reserved3 = 0;
5239 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5240 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5241 inc_rfc1001_len(pSMB, byte_count);
5242 pSMB->ByteCount = cpu_to_le16(byte_count);
5244 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5245 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5247 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5248 } else { /* decode response */
5249 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5251 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5252 /* BB also check if enough bytes returned */
5253 rc = -EIO; /* bad smb */
5255 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5257 (FILE_SYSTEM_ATTRIBUTE_INFO
5258 *) (((char *) &pSMBr->hdr.Protocol) +
5260 memcpy(&tcon->fsAttrInfo, response_data,
5261 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5264 cifs_buf_release(pSMB);
5267 goto QFSAttributeRetry;
5273 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5275 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5276 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5277 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5278 FILE_SYSTEM_DEVICE_INFO *response_data;
5280 int bytes_returned = 0;
5281 __u16 params, byte_count;
5283 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5285 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5290 params = 2; /* level */
5291 pSMB->TotalDataCount = 0;
5292 pSMB->MaxParameterCount = cpu_to_le16(2);
5293 /* BB find exact max SMB PDU from sess structure BB */
5294 pSMB->MaxDataCount = cpu_to_le16(1000);
5295 pSMB->MaxSetupCount = 0;
5299 pSMB->Reserved2 = 0;
5300 byte_count = params + 1 /* pad */ ;
5301 pSMB->TotalParameterCount = cpu_to_le16(params);
5302 pSMB->ParameterCount = pSMB->TotalParameterCount;
5303 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5304 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5306 pSMB->DataCount = 0;
5307 pSMB->DataOffset = 0;
5308 pSMB->SetupCount = 1;
5309 pSMB->Reserved3 = 0;
5310 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5311 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5312 inc_rfc1001_len(pSMB, byte_count);
5313 pSMB->ByteCount = cpu_to_le16(byte_count);
5315 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5316 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5318 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5319 } else { /* decode response */
5320 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5322 if (rc || get_bcc(&pSMBr->hdr) <
5323 sizeof(FILE_SYSTEM_DEVICE_INFO))
5324 rc = -EIO; /* bad smb */
5326 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5328 (FILE_SYSTEM_DEVICE_INFO *)
5329 (((char *) &pSMBr->hdr.Protocol) +
5331 memcpy(&tcon->fsDevInfo, response_data,
5332 sizeof(FILE_SYSTEM_DEVICE_INFO));
5335 cifs_buf_release(pSMB);
5338 goto QFSDeviceRetry;
5344 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5346 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5347 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5348 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5349 FILE_SYSTEM_UNIX_INFO *response_data;
5351 int bytes_returned = 0;
5352 __u16 params, byte_count;
5354 cifs_dbg(FYI, "In QFSUnixInfo\n");
5356 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5357 (void **) &pSMB, (void **) &pSMBr);
5361 params = 2; /* level */
5362 pSMB->TotalDataCount = 0;
5363 pSMB->DataCount = 0;
5364 pSMB->DataOffset = 0;
5365 pSMB->MaxParameterCount = cpu_to_le16(2);
5366 /* BB find exact max SMB PDU from sess structure BB */
5367 pSMB->MaxDataCount = cpu_to_le16(100);
5368 pSMB->MaxSetupCount = 0;
5372 pSMB->Reserved2 = 0;
5373 byte_count = params + 1 /* pad */ ;
5374 pSMB->ParameterCount = cpu_to_le16(params);
5375 pSMB->TotalParameterCount = pSMB->ParameterCount;
5376 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5377 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5378 pSMB->SetupCount = 1;
5379 pSMB->Reserved3 = 0;
5380 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5381 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5382 inc_rfc1001_len(pSMB, byte_count);
5383 pSMB->ByteCount = cpu_to_le16(byte_count);
5385 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5386 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5388 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5389 } else { /* decode response */
5390 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5392 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5393 rc = -EIO; /* bad smb */
5395 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5397 (FILE_SYSTEM_UNIX_INFO
5398 *) (((char *) &pSMBr->hdr.Protocol) +
5400 memcpy(&tcon->fsUnixInfo, response_data,
5401 sizeof(FILE_SYSTEM_UNIX_INFO));
5404 cifs_buf_release(pSMB);
5414 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5416 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5417 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5418 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5420 int bytes_returned = 0;
5421 __u16 params, param_offset, offset, byte_count;
5423 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5425 /* BB switch to small buf init to save memory */
5426 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5427 (void **) &pSMB, (void **) &pSMBr);
5431 params = 4; /* 2 bytes zero followed by info level. */
5432 pSMB->MaxSetupCount = 0;
5436 pSMB->Reserved2 = 0;
5437 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5439 offset = param_offset + params;
5441 pSMB->MaxParameterCount = cpu_to_le16(4);
5442 /* BB find exact max SMB PDU from sess structure BB */
5443 pSMB->MaxDataCount = cpu_to_le16(100);
5444 pSMB->SetupCount = 1;
5445 pSMB->Reserved3 = 0;
5446 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5447 byte_count = 1 /* pad */ + params + 12;
5449 pSMB->DataCount = cpu_to_le16(12);
5450 pSMB->ParameterCount = cpu_to_le16(params);
5451 pSMB->TotalDataCount = pSMB->DataCount;
5452 pSMB->TotalParameterCount = pSMB->ParameterCount;
5453 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5454 pSMB->DataOffset = cpu_to_le16(offset);
5458 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5461 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5462 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5463 pSMB->ClientUnixCap = cpu_to_le64(cap);
5465 inc_rfc1001_len(pSMB, byte_count);
5466 pSMB->ByteCount = cpu_to_le16(byte_count);
5468 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5469 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5471 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5472 } else { /* decode response */
5473 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5475 rc = -EIO; /* bad smb */
5477 cifs_buf_release(pSMB);
5480 goto SETFSUnixRetry;
5488 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5489 struct kstatfs *FSData)
5491 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5492 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5493 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5494 FILE_SYSTEM_POSIX_INFO *response_data;
5496 int bytes_returned = 0;
5497 __u16 params, byte_count;
5499 cifs_dbg(FYI, "In QFSPosixInfo\n");
5501 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5506 params = 2; /* level */
5507 pSMB->TotalDataCount = 0;
5508 pSMB->DataCount = 0;
5509 pSMB->DataOffset = 0;
5510 pSMB->MaxParameterCount = cpu_to_le16(2);
5511 /* BB find exact max SMB PDU from sess structure BB */
5512 pSMB->MaxDataCount = cpu_to_le16(100);
5513 pSMB->MaxSetupCount = 0;
5517 pSMB->Reserved2 = 0;
5518 byte_count = params + 1 /* pad */ ;
5519 pSMB->ParameterCount = cpu_to_le16(params);
5520 pSMB->TotalParameterCount = pSMB->ParameterCount;
5521 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5522 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5523 pSMB->SetupCount = 1;
5524 pSMB->Reserved3 = 0;
5525 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5526 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5527 inc_rfc1001_len(pSMB, byte_count);
5528 pSMB->ByteCount = cpu_to_le16(byte_count);
5530 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5531 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5533 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5534 } else { /* decode response */
5535 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5537 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5538 rc = -EIO; /* bad smb */
5540 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5542 (FILE_SYSTEM_POSIX_INFO
5543 *) (((char *) &pSMBr->hdr.Protocol) +
5546 le32_to_cpu(response_data->BlockSize);
5548 * much prefer larger but if server doesn't report
5549 * a valid size than 4K is a reasonable minimum
5551 if (FSData->f_bsize < 512)
5552 FSData->f_bsize = 4096;
5555 le64_to_cpu(response_data->TotalBlocks);
5557 le64_to_cpu(response_data->BlocksAvail);
5558 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5559 FSData->f_bavail = FSData->f_bfree;
5562 le64_to_cpu(response_data->UserBlocksAvail);
5564 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5566 le64_to_cpu(response_data->TotalFileNodes);
5567 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5569 le64_to_cpu(response_data->FreeFileNodes);
5572 cifs_buf_release(pSMB);
5582 * We can not use write of zero bytes trick to set file size due to need for
5583 * large file support. Also note that this SetPathInfo is preferred to
5584 * SetFileInfo based method in next routine which is only needed to work around
5585 * a sharing violation bugin Samba which this routine can run into.
5588 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5589 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5590 bool set_allocation)
5592 struct smb_com_transaction2_spi_req *pSMB = NULL;
5593 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5594 struct file_end_of_file_info *parm_data;
5597 int bytes_returned = 0;
5598 int remap = cifs_remap(cifs_sb);
5600 __u16 params, byte_count, data_count, param_offset, offset;
5602 cifs_dbg(FYI, "In SetEOF\n");
5604 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5609 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5611 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5612 PATH_MAX, cifs_sb->local_nls, remap);
5613 name_len++; /* trailing null */
5616 name_len = copy_path_name(pSMB->FileName, file_name);
5618 params = 6 + name_len;
5619 data_count = sizeof(struct file_end_of_file_info);
5620 pSMB->MaxParameterCount = cpu_to_le16(2);
5621 pSMB->MaxDataCount = cpu_to_le16(4100);
5622 pSMB->MaxSetupCount = 0;
5626 pSMB->Reserved2 = 0;
5627 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5628 InformationLevel) - 4;
5629 offset = param_offset + params;
5630 if (set_allocation) {
5631 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5632 pSMB->InformationLevel =
5633 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5635 pSMB->InformationLevel =
5636 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5637 } else /* Set File Size */ {
5638 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5639 pSMB->InformationLevel =
5640 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5642 pSMB->InformationLevel =
5643 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5647 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5649 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5650 pSMB->DataOffset = cpu_to_le16(offset);
5651 pSMB->SetupCount = 1;
5652 pSMB->Reserved3 = 0;
5653 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5654 byte_count = 3 /* pad */ + params + data_count;
5655 pSMB->DataCount = cpu_to_le16(data_count);
5656 pSMB->TotalDataCount = pSMB->DataCount;
5657 pSMB->ParameterCount = cpu_to_le16(params);
5658 pSMB->TotalParameterCount = pSMB->ParameterCount;
5659 pSMB->Reserved4 = 0;
5660 inc_rfc1001_len(pSMB, byte_count);
5661 parm_data->FileSize = cpu_to_le64(size);
5662 pSMB->ByteCount = cpu_to_le16(byte_count);
5663 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5664 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5666 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5668 cifs_buf_release(pSMB);
5677 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5678 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5680 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5681 struct file_end_of_file_info *parm_data;
5683 __u16 params, param_offset, offset, byte_count, count;
5685 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5687 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5692 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5693 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5696 pSMB->MaxSetupCount = 0;
5700 pSMB->Reserved2 = 0;
5701 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5702 offset = param_offset + params;
5704 count = sizeof(struct file_end_of_file_info);
5705 pSMB->MaxParameterCount = cpu_to_le16(2);
5706 /* BB find exact max SMB PDU from sess structure BB */
5707 pSMB->MaxDataCount = cpu_to_le16(1000);
5708 pSMB->SetupCount = 1;
5709 pSMB->Reserved3 = 0;
5710 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5711 byte_count = 3 /* pad */ + params + count;
5712 pSMB->DataCount = cpu_to_le16(count);
5713 pSMB->ParameterCount = cpu_to_le16(params);
5714 pSMB->TotalDataCount = pSMB->DataCount;
5715 pSMB->TotalParameterCount = pSMB->ParameterCount;
5716 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5718 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5720 pSMB->DataOffset = cpu_to_le16(offset);
5721 parm_data->FileSize = cpu_to_le64(size);
5722 pSMB->Fid = cfile->fid.netfid;
5723 if (set_allocation) {
5724 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5725 pSMB->InformationLevel =
5726 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5728 pSMB->InformationLevel =
5729 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5730 } else /* Set File Size */ {
5731 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5732 pSMB->InformationLevel =
5733 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5735 pSMB->InformationLevel =
5736 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5738 pSMB->Reserved4 = 0;
5739 inc_rfc1001_len(pSMB, byte_count);
5740 pSMB->ByteCount = cpu_to_le16(byte_count);
5741 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5742 cifs_small_buf_release(pSMB);
5744 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5748 /* Note: On -EAGAIN error only caller can retry on handle based calls
5749 since file handle passed in no longer valid */
5754 /* Some legacy servers such as NT4 require that the file times be set on
5755 an open handle, rather than by pathname - this is awkward due to
5756 potential access conflicts on the open, but it is unavoidable for these
5757 old servers since the only other choice is to go from 100 nanosecond DCE
5758 time and resort to the original setpathinfo level which takes the ancient
5759 DOS time format with 2 second granularity */
5761 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5762 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5764 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5767 __u16 params, param_offset, offset, byte_count, count;
5769 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5770 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5775 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5776 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5779 pSMB->MaxSetupCount = 0;
5783 pSMB->Reserved2 = 0;
5784 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5785 offset = param_offset + params;
5787 data_offset = (char *)pSMB +
5788 offsetof(struct smb_hdr, Protocol) + offset;
5790 count = sizeof(FILE_BASIC_INFO);
5791 pSMB->MaxParameterCount = cpu_to_le16(2);
5792 /* BB find max SMB PDU from sess */
5793 pSMB->MaxDataCount = cpu_to_le16(1000);
5794 pSMB->SetupCount = 1;
5795 pSMB->Reserved3 = 0;
5796 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5797 byte_count = 3 /* pad */ + params + count;
5798 pSMB->DataCount = cpu_to_le16(count);
5799 pSMB->ParameterCount = cpu_to_le16(params);
5800 pSMB->TotalDataCount = pSMB->DataCount;
5801 pSMB->TotalParameterCount = pSMB->ParameterCount;
5802 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5803 pSMB->DataOffset = cpu_to_le16(offset);
5805 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5806 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5808 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5809 pSMB->Reserved4 = 0;
5810 inc_rfc1001_len(pSMB, byte_count);
5811 pSMB->ByteCount = cpu_to_le16(byte_count);
5812 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5813 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5814 cifs_small_buf_release(pSMB);
5816 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5819 /* Note: On -EAGAIN error only caller can retry on handle based calls
5820 since file handle passed in no longer valid */
5826 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5827 bool delete_file, __u16 fid, __u32 pid_of_opener)
5829 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5832 __u16 params, param_offset, offset, byte_count, count;
5834 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5835 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5840 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5841 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5844 pSMB->MaxSetupCount = 0;
5848 pSMB->Reserved2 = 0;
5849 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5850 offset = param_offset + params;
5852 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5855 pSMB->MaxParameterCount = cpu_to_le16(2);
5856 /* BB find max SMB PDU from sess */
5857 pSMB->MaxDataCount = cpu_to_le16(1000);
5858 pSMB->SetupCount = 1;
5859 pSMB->Reserved3 = 0;
5860 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5861 byte_count = 3 /* pad */ + params + count;
5862 pSMB->DataCount = cpu_to_le16(count);
5863 pSMB->ParameterCount = cpu_to_le16(params);
5864 pSMB->TotalDataCount = pSMB->DataCount;
5865 pSMB->TotalParameterCount = pSMB->ParameterCount;
5866 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5867 pSMB->DataOffset = cpu_to_le16(offset);
5869 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5870 pSMB->Reserved4 = 0;
5871 inc_rfc1001_len(pSMB, byte_count);
5872 pSMB->ByteCount = cpu_to_le16(byte_count);
5873 *data_offset = delete_file ? 1 : 0;
5874 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5875 cifs_small_buf_release(pSMB);
5877 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5883 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5884 const char *fileName, const FILE_BASIC_INFO *data,
5885 const struct nls_table *nls_codepage, int remap)
5887 TRANSACTION2_SPI_REQ *pSMB = NULL;
5888 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5891 int bytes_returned = 0;
5893 __u16 params, param_offset, offset, byte_count, count;
5895 cifs_dbg(FYI, "In SetTimes\n");
5898 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5903 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5905 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5906 PATH_MAX, nls_codepage, remap);
5907 name_len++; /* trailing null */
5910 name_len = copy_path_name(pSMB->FileName, fileName);
5913 params = 6 + name_len;
5914 count = sizeof(FILE_BASIC_INFO);
5915 pSMB->MaxParameterCount = cpu_to_le16(2);
5916 /* BB find max SMB PDU from sess structure BB */
5917 pSMB->MaxDataCount = cpu_to_le16(1000);
5918 pSMB->MaxSetupCount = 0;
5922 pSMB->Reserved2 = 0;
5923 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5924 InformationLevel) - 4;
5925 offset = param_offset + params;
5926 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5927 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5928 pSMB->DataOffset = cpu_to_le16(offset);
5929 pSMB->SetupCount = 1;
5930 pSMB->Reserved3 = 0;
5931 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5932 byte_count = 3 /* pad */ + params + count;
5934 pSMB->DataCount = cpu_to_le16(count);
5935 pSMB->ParameterCount = cpu_to_le16(params);
5936 pSMB->TotalDataCount = pSMB->DataCount;
5937 pSMB->TotalParameterCount = pSMB->ParameterCount;
5938 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5939 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5941 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5942 pSMB->Reserved4 = 0;
5943 inc_rfc1001_len(pSMB, byte_count);
5944 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5945 pSMB->ByteCount = cpu_to_le16(byte_count);
5946 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5947 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5949 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5951 cifs_buf_release(pSMB);
5959 /* Can not be used to set time stamps yet (due to old DOS time format) */
5960 /* Can be used to set attributes */
5961 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5962 handling it anyway and NT4 was what we thought it would be needed for
5963 Do not delete it until we prove whether needed for Win9x though */
5965 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
5966 __u16 dos_attrs, const struct nls_table *nls_codepage)
5968 SETATTR_REQ *pSMB = NULL;
5969 SETATTR_RSP *pSMBr = NULL;
5974 cifs_dbg(FYI, "In SetAttrLegacy\n");
5977 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5982 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5984 ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5985 PATH_MAX, nls_codepage);
5986 name_len++; /* trailing null */
5989 name_len = copy_path_name(pSMB->fileName, fileName);
5991 pSMB->attr = cpu_to_le16(dos_attrs);
5992 pSMB->BufferFormat = 0x04;
5993 inc_rfc1001_len(pSMB, name_len + 1);
5994 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5995 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5996 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5998 cifs_dbg(FYI, "Error in LegacySetAttr = %d\n", rc);
6000 cifs_buf_release(pSMB);
6003 goto SetAttrLgcyRetry;
6007 #endif /* temporarily unneeded SetAttr legacy function */
6010 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
6011 const struct cifs_unix_set_info_args *args)
6013 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
6014 u64 mode = args->mode;
6016 if (uid_valid(args->uid))
6017 uid = from_kuid(&init_user_ns, args->uid);
6018 if (gid_valid(args->gid))
6019 gid = from_kgid(&init_user_ns, args->gid);
6022 * Samba server ignores set of file size to zero due to bugs in some
6023 * older clients, but we should be precise - we use SetFileSize to
6024 * set file size and do not want to truncate file size to zero
6025 * accidentally as happened on one Samba server beta by putting
6026 * zero instead of -1 here
6028 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
6029 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
6030 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
6031 data_offset->LastAccessTime = cpu_to_le64(args->atime);
6032 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
6033 data_offset->Uid = cpu_to_le64(uid);
6034 data_offset->Gid = cpu_to_le64(gid);
6035 /* better to leave device as zero when it is */
6036 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
6037 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
6038 data_offset->Permissions = cpu_to_le64(mode);
6041 data_offset->Type = cpu_to_le32(UNIX_FILE);
6042 else if (S_ISDIR(mode))
6043 data_offset->Type = cpu_to_le32(UNIX_DIR);
6044 else if (S_ISLNK(mode))
6045 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
6046 else if (S_ISCHR(mode))
6047 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
6048 else if (S_ISBLK(mode))
6049 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
6050 else if (S_ISFIFO(mode))
6051 data_offset->Type = cpu_to_le32(UNIX_FIFO);
6052 else if (S_ISSOCK(mode))
6053 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
6057 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
6058 const struct cifs_unix_set_info_args *args,
6059 u16 fid, u32 pid_of_opener)
6061 struct smb_com_transaction2_sfi_req *pSMB = NULL;
6064 u16 params, param_offset, offset, byte_count, count;
6066 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
6067 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
6072 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
6073 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
6076 pSMB->MaxSetupCount = 0;
6080 pSMB->Reserved2 = 0;
6081 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
6082 offset = param_offset + params;
6084 data_offset = (char *)pSMB +
6085 offsetof(struct smb_hdr, Protocol) + offset;
6087 count = sizeof(FILE_UNIX_BASIC_INFO);
6089 pSMB->MaxParameterCount = cpu_to_le16(2);
6090 /* BB find max SMB PDU from sess */
6091 pSMB->MaxDataCount = cpu_to_le16(1000);
6092 pSMB->SetupCount = 1;
6093 pSMB->Reserved3 = 0;
6094 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
6095 byte_count = 3 /* pad */ + params + count;
6096 pSMB->DataCount = cpu_to_le16(count);
6097 pSMB->ParameterCount = cpu_to_le16(params);
6098 pSMB->TotalDataCount = pSMB->DataCount;
6099 pSMB->TotalParameterCount = pSMB->ParameterCount;
6100 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6101 pSMB->DataOffset = cpu_to_le16(offset);
6103 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6104 pSMB->Reserved4 = 0;
6105 inc_rfc1001_len(pSMB, byte_count);
6106 pSMB->ByteCount = cpu_to_le16(byte_count);
6108 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
6110 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
6111 cifs_small_buf_release(pSMB);
6113 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
6116 /* Note: On -EAGAIN error only caller can retry on handle based calls
6117 since file handle passed in no longer valid */
6123 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
6124 const char *file_name,
6125 const struct cifs_unix_set_info_args *args,
6126 const struct nls_table *nls_codepage, int remap)
6128 TRANSACTION2_SPI_REQ *pSMB = NULL;
6129 TRANSACTION2_SPI_RSP *pSMBr = NULL;
6132 int bytes_returned = 0;
6133 FILE_UNIX_BASIC_INFO *data_offset;
6134 __u16 params, param_offset, offset, count, byte_count;
6136 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
6138 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6143 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6145 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6146 PATH_MAX, nls_codepage, remap);
6147 name_len++; /* trailing null */
6150 name_len = copy_path_name(pSMB->FileName, file_name);
6153 params = 6 + name_len;
6154 count = sizeof(FILE_UNIX_BASIC_INFO);
6155 pSMB->MaxParameterCount = cpu_to_le16(2);
6156 /* BB find max SMB PDU from sess structure BB */
6157 pSMB->MaxDataCount = cpu_to_le16(1000);
6158 pSMB->MaxSetupCount = 0;
6162 pSMB->Reserved2 = 0;
6163 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6164 InformationLevel) - 4;
6165 offset = param_offset + params;
6167 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6169 memset(data_offset, 0, count);
6170 pSMB->DataOffset = cpu_to_le16(offset);
6171 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6172 pSMB->SetupCount = 1;
6173 pSMB->Reserved3 = 0;
6174 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6175 byte_count = 3 /* pad */ + params + count;
6176 pSMB->ParameterCount = cpu_to_le16(params);
6177 pSMB->DataCount = cpu_to_le16(count);
6178 pSMB->TotalParameterCount = pSMB->ParameterCount;
6179 pSMB->TotalDataCount = pSMB->DataCount;
6180 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6181 pSMB->Reserved4 = 0;
6182 inc_rfc1001_len(pSMB, byte_count);
6184 cifs_fill_unix_set_info(data_offset, args);
6186 pSMB->ByteCount = cpu_to_le16(byte_count);
6187 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6188 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6190 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6192 cifs_buf_release(pSMB);
6198 #ifdef CONFIG_CIFS_XATTR
6200 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6201 * function used by listxattr and getxattr type calls. When ea_name is set,
6202 * it looks for that attribute name and stuffs that value into the EAData
6203 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6204 * buffer. In both cases, the return value is either the length of the
6205 * resulting data or a negative error code. If EAData is a NULL pointer then
6206 * the data isn't copied to it, but the length is returned.
6209 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6210 const unsigned char *searchName, const unsigned char *ea_name,
6211 char *EAData, size_t buf_size,
6212 struct cifs_sb_info *cifs_sb)
6214 /* BB assumes one setup word */
6215 TRANSACTION2_QPI_REQ *pSMB = NULL;
6216 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6217 int remap = cifs_remap(cifs_sb);
6218 struct nls_table *nls_codepage = cifs_sb->local_nls;
6222 struct fealist *ea_response_data;
6223 struct fea *temp_fea;
6226 __u16 params, byte_count, data_offset;
6227 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6229 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6231 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6236 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6238 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6239 PATH_MAX, nls_codepage, remap);
6240 list_len++; /* trailing null */
6243 list_len = copy_path_name(pSMB->FileName, searchName);
6246 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6247 pSMB->TotalDataCount = 0;
6248 pSMB->MaxParameterCount = cpu_to_le16(2);
6249 /* BB find exact max SMB PDU from sess structure BB */
6250 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6251 pSMB->MaxSetupCount = 0;
6255 pSMB->Reserved2 = 0;
6256 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6257 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6258 pSMB->DataCount = 0;
6259 pSMB->DataOffset = 0;
6260 pSMB->SetupCount = 1;
6261 pSMB->Reserved3 = 0;
6262 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6263 byte_count = params + 1 /* pad */ ;
6264 pSMB->TotalParameterCount = cpu_to_le16(params);
6265 pSMB->ParameterCount = pSMB->TotalParameterCount;
6266 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6267 pSMB->Reserved4 = 0;
6268 inc_rfc1001_len(pSMB, byte_count);
6269 pSMB->ByteCount = cpu_to_le16(byte_count);
6271 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6272 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6274 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6279 /* BB also check enough total bytes returned */
6280 /* BB we need to improve the validity checking
6281 of these trans2 responses */
6283 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6284 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6285 rc = -EIO; /* bad smb */
6289 /* check that length of list is not more than bcc */
6290 /* check that each entry does not go beyond length
6292 /* check that each element of each entry does not
6293 go beyond end of list */
6294 /* validate_trans2_offsets() */
6295 /* BB check if start of smb + data_offset > &bcc+ bcc */
6297 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6298 ea_response_data = (struct fealist *)
6299 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6301 list_len = le32_to_cpu(ea_response_data->list_len);
6302 cifs_dbg(FYI, "ea length %d\n", list_len);
6303 if (list_len <= 8) {
6304 cifs_dbg(FYI, "empty EA list returned from server\n");
6305 /* didn't find the named attribute */
6311 /* make sure list_len doesn't go past end of SMB */
6312 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6313 if ((char *)ea_response_data + list_len > end_of_smb) {
6314 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6319 /* account for ea list len */
6321 temp_fea = ea_response_data->list;
6322 temp_ptr = (char *)temp_fea;
6323 while (list_len > 0) {
6324 unsigned int name_len;
6329 /* make sure we can read name_len and value_len */
6331 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6336 name_len = temp_fea->name_len;
6337 value_len = le16_to_cpu(temp_fea->value_len);
6338 list_len -= name_len + 1 + value_len;
6340 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6346 if (ea_name_len == name_len &&
6347 memcmp(ea_name, temp_ptr, name_len) == 0) {
6348 temp_ptr += name_len + 1;
6352 if ((size_t)value_len > buf_size) {
6356 memcpy(EAData, temp_ptr, value_len);
6360 /* account for prefix user. and trailing null */
6361 rc += (5 + 1 + name_len);
6362 if (rc < (int) buf_size) {
6363 memcpy(EAData, "user.", 5);
6365 memcpy(EAData, temp_ptr, name_len);
6367 /* null terminate name */
6370 } else if (buf_size == 0) {
6371 /* skip copy - calc size only */
6373 /* stop before overrun buffer */
6378 temp_ptr += name_len + 1 + value_len;
6379 temp_fea = (struct fea *)temp_ptr;
6382 /* didn't find the named attribute */
6387 cifs_buf_release(pSMB);
6395 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6396 const char *fileName, const char *ea_name, const void *ea_value,
6397 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6398 struct cifs_sb_info *cifs_sb)
6400 struct smb_com_transaction2_spi_req *pSMB = NULL;
6401 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6402 struct fealist *parm_data;
6405 int bytes_returned = 0;
6406 __u16 params, param_offset, byte_count, offset, count;
6407 int remap = cifs_remap(cifs_sb);
6409 cifs_dbg(FYI, "In SetEA\n");
6411 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6416 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6418 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6419 PATH_MAX, nls_codepage, remap);
6420 name_len++; /* trailing null */
6423 name_len = copy_path_name(pSMB->FileName, fileName);
6426 params = 6 + name_len;
6428 /* done calculating parms using name_len of file name,
6429 now use name_len to calculate length of ea name
6430 we are going to create in the inode xattrs */
6431 if (ea_name == NULL)
6434 name_len = strnlen(ea_name, 255);
6436 count = sizeof(*parm_data) + ea_value_len + name_len;
6437 pSMB->MaxParameterCount = cpu_to_le16(2);
6438 /* BB find max SMB PDU from sess */
6439 pSMB->MaxDataCount = cpu_to_le16(1000);
6440 pSMB->MaxSetupCount = 0;
6444 pSMB->Reserved2 = 0;
6445 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6446 InformationLevel) - 4;
6447 offset = param_offset + params;
6448 pSMB->InformationLevel =
6449 cpu_to_le16(SMB_SET_FILE_EA);
6451 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6452 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6453 pSMB->DataOffset = cpu_to_le16(offset);
6454 pSMB->SetupCount = 1;
6455 pSMB->Reserved3 = 0;
6456 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6457 byte_count = 3 /* pad */ + params + count;
6458 pSMB->DataCount = cpu_to_le16(count);
6459 parm_data->list_len = cpu_to_le32(count);
6460 parm_data->list[0].EA_flags = 0;
6461 /* we checked above that name len is less than 255 */
6462 parm_data->list[0].name_len = (__u8)name_len;
6463 /* EA names are always ASCII */
6465 strncpy(parm_data->list[0].name, ea_name, name_len);
6466 parm_data->list[0].name[name_len] = 0;
6467 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6468 /* caller ensures that ea_value_len is less than 64K but
6469 we need to ensure that it fits within the smb */
6471 /*BB add length check to see if it would fit in
6472 negotiated SMB buffer size BB */
6473 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6475 memcpy(parm_data->list[0].name+name_len+1,
6476 ea_value, ea_value_len);
6478 pSMB->TotalDataCount = pSMB->DataCount;
6479 pSMB->ParameterCount = cpu_to_le16(params);
6480 pSMB->TotalParameterCount = pSMB->ParameterCount;
6481 pSMB->Reserved4 = 0;
6482 inc_rfc1001_len(pSMB, byte_count);
6483 pSMB->ByteCount = cpu_to_le16(byte_count);
6484 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6485 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6487 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6489 cifs_buf_release(pSMB);