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 TCP_Server_Info *server = tcon->ses->server;
133 struct dfs_cache_tgt_list tl;
134 struct dfs_cache_tgt_iterator *it = NULL;
136 const char *tcp_host;
138 const char *dfs_host;
141 tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
145 if (!tcon->dfs_path) {
147 scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
149 rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
151 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(server->hostname, &tcp_host, &tcp_host_len);
162 for (it = dfs_cache_get_tgt_iterator(&tl); it;
163 it = dfs_cache_get_next_tgt(&tl, it)) {
164 const char *share, *prefix;
165 size_t share_len, prefix_len;
168 rc = dfs_cache_get_tgt_share(it, &share, &share_len, &prefix,
171 cifs_dbg(VFS, "%s: failed to parse target share %d\n",
176 extract_unc_hostname(share, &dfs_host, &dfs_host_len);
178 if (dfs_host_len != tcp_host_len
179 || strncasecmp(dfs_host, tcp_host, dfs_host_len) != 0) {
180 cifs_dbg(FYI, "%s: %.*s doesn't match %.*s\n",
182 (int)dfs_host_len, dfs_host,
183 (int)tcp_host_len, tcp_host);
185 rc = match_target_ip(server, dfs_host, dfs_host_len,
188 cifs_dbg(VFS, "%s: failed to match target ip: %d\n",
194 cifs_dbg(FYI, "%s: skipping target\n", __func__);
200 scnprintf(tree, MAX_TREE_SIZE, "\\\\%.*s\\IPC$",
201 (int)share_len, share);
202 rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
204 scnprintf(tree, MAX_TREE_SIZE, "\\%.*s", (int)share_len,
206 rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
208 rc = update_super_prepath(tcon, prefix,
219 rc = dfs_cache_noreq_update_tgthint(tcon->dfs_path + 1,
224 dfs_cache_free_tgts(&tl);
230 static inline int __cifs_reconnect_tcon(const struct nls_table *nlsc,
231 struct cifs_tcon *tcon)
233 return CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
237 /* reconnect the socket, tcon, and smb session if needed */
239 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
242 struct cifs_ses *ses;
243 struct TCP_Server_Info *server;
244 struct nls_table *nls_codepage;
248 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
249 * tcp and smb session status done differently for those three - in the
256 server = ses->server;
259 * only tree disconnect, open, and write, (and ulogoff which does not
260 * have tcon) are allowed as we start force umount
262 if (tcon->tidStatus == CifsExiting) {
263 if (smb_command != SMB_COM_WRITE_ANDX &&
264 smb_command != SMB_COM_OPEN_ANDX &&
265 smb_command != SMB_COM_TREE_DISCONNECT) {
266 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
272 retries = server->nr_targets;
275 * Give demultiplex thread up to 10 seconds to each target available for
276 * reconnect -- should be greater than cifs socket timeout which is 7
279 while (server->tcpStatus == CifsNeedReconnect) {
280 rc = wait_event_interruptible_timeout(server->response_q,
281 (server->tcpStatus != CifsNeedReconnect),
284 cifs_dbg(FYI, "%s: aborting reconnect due to a received signal by the process\n",
289 /* are we still trying to reconnect? */
290 if (server->tcpStatus != CifsNeedReconnect)
293 if (retries && --retries)
297 * on "soft" mounts we wait once. Hard mounts keep
298 * retrying until process is killed or server comes
302 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
305 retries = server->nr_targets;
308 if (!ses->need_reconnect && !tcon->need_reconnect)
311 nls_codepage = load_nls_default();
314 * need to prevent multiple threads trying to simultaneously
315 * reconnect the same SMB session
317 mutex_lock(&ses->session_mutex);
320 * Recheck after acquire mutex. If another thread is negotiating
321 * and the server never sends an answer the socket will be closed
322 * and tcpStatus set to reconnect.
324 if (server->tcpStatus == CifsNeedReconnect) {
326 mutex_unlock(&ses->session_mutex);
330 rc = cifs_negotiate_protocol(0, ses);
331 if (rc == 0 && ses->need_reconnect)
332 rc = cifs_setup_session(0, ses, nls_codepage);
334 /* do we need to reconnect tcon? */
335 if (rc || !tcon->need_reconnect) {
336 mutex_unlock(&ses->session_mutex);
340 cifs_mark_open_files_invalid(tcon);
341 rc = __cifs_reconnect_tcon(nls_codepage, tcon);
342 mutex_unlock(&ses->session_mutex);
343 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
346 pr_warn_once("reconnect tcon failed rc = %d\n", rc);
350 atomic_inc(&tconInfoReconnectCount);
352 /* tell server Unix caps we support */
354 reset_cifs_unix_caps(0, tcon, NULL, NULL);
357 * Removed call to reopen open files here. It is safer (and faster) to
358 * reopen files one at a time as needed in read and write.
360 * FIXME: what about file locks? don't we need to reclaim them ASAP?
365 * Check if handle based operation so we know whether we can continue
366 * or not without returning to caller to reset file handle
368 switch (smb_command) {
369 case SMB_COM_READ_ANDX:
370 case SMB_COM_WRITE_ANDX:
372 case SMB_COM_FIND_CLOSE2:
373 case SMB_COM_LOCKING_ANDX:
377 unload_nls(nls_codepage);
381 /* Allocate and return pointer to an SMB request buffer, and set basic
382 SMB information in the SMB header. If the return code is zero, this
383 function must have filled in request_buf pointer */
385 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
390 rc = cifs_reconnect_tcon(tcon, smb_command);
394 *request_buf = cifs_small_buf_get();
395 if (*request_buf == NULL) {
396 /* BB should we add a retry in here if not a writepage? */
400 header_assemble((struct smb_hdr *) *request_buf, smb_command,
404 cifs_stats_inc(&tcon->num_smbs_sent);
410 small_smb_init_no_tc(const int smb_command, const int wct,
411 struct cifs_ses *ses, void **request_buf)
414 struct smb_hdr *buffer;
416 rc = small_smb_init(smb_command, wct, NULL, request_buf);
420 buffer = (struct smb_hdr *)*request_buf;
421 buffer->Mid = get_next_mid(ses->server);
422 if (ses->capabilities & CAP_UNICODE)
423 buffer->Flags2 |= SMBFLG2_UNICODE;
424 if (ses->capabilities & CAP_STATUS32)
425 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
427 /* uid, tid can stay at zero as set in header assemble */
429 /* BB add support for turning on the signing when
430 this function is used after 1st of session setup requests */
435 /* If the return code is zero, this function must fill in request_buf pointer */
437 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
438 void **request_buf, void **response_buf)
440 *request_buf = cifs_buf_get();
441 if (*request_buf == NULL) {
442 /* BB should we add a retry in here if not a writepage? */
445 /* Although the original thought was we needed the response buf for */
446 /* potential retries of smb operations it turns out we can determine */
447 /* from the mid flags when the request buffer can be resent without */
448 /* having to use a second distinct buffer for the response */
450 *response_buf = *request_buf;
452 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
456 cifs_stats_inc(&tcon->num_smbs_sent);
461 /* If the return code is zero, this function must fill in request_buf pointer */
463 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
464 void **request_buf, void **response_buf)
468 rc = cifs_reconnect_tcon(tcon, smb_command);
472 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
476 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
477 void **request_buf, void **response_buf)
479 if (tcon->ses->need_reconnect || tcon->need_reconnect)
482 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
485 static int validate_t2(struct smb_t2_rsp *pSMB)
487 unsigned int total_size;
489 /* check for plausible wct */
490 if (pSMB->hdr.WordCount < 10)
493 /* check for parm and data offset going beyond end of smb */
494 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
495 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
498 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
499 if (total_size >= 512)
502 /* check that bcc is at least as big as parms + data, and that it is
503 * less than negotiated smb buffer
505 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
506 if (total_size > get_bcc(&pSMB->hdr) ||
507 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
512 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
513 sizeof(struct smb_t2_rsp) + 16);
518 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
522 char *guid = pSMBr->u.extended_response.GUID;
523 struct TCP_Server_Info *server = ses->server;
525 count = get_bcc(&pSMBr->hdr);
526 if (count < SMB1_CLIENT_GUID_SIZE)
529 spin_lock(&cifs_tcp_ses_lock);
530 if (server->srv_count > 1) {
531 spin_unlock(&cifs_tcp_ses_lock);
532 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
533 cifs_dbg(FYI, "server UID changed\n");
534 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
537 spin_unlock(&cifs_tcp_ses_lock);
538 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
541 if (count == SMB1_CLIENT_GUID_SIZE) {
542 server->sec_ntlmssp = true;
544 count -= SMB1_CLIENT_GUID_SIZE;
545 rc = decode_negTokenInit(
546 pSMBr->u.extended_response.SecurityBlob, count, server);
555 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
557 bool srv_sign_required = server->sec_mode & server->vals->signing_required;
558 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
559 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
562 * Is signing required by mnt options? If not then check
563 * global_secflags to see if it is there.
565 if (!mnt_sign_required)
566 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
570 * If signing is required then it's automatically enabled too,
571 * otherwise, check to see if the secflags allow it.
573 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
574 (global_secflags & CIFSSEC_MAY_SIGN);
576 /* If server requires signing, does client allow it? */
577 if (srv_sign_required) {
578 if (!mnt_sign_enabled) {
579 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!\n");
585 /* If client requires signing, does server allow it? */
586 if (mnt_sign_required) {
587 if (!srv_sign_enabled) {
588 cifs_dbg(VFS, "Server does not support signing!\n");
594 if (cifs_rdma_enabled(server) && server->sign)
595 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled\n");
600 #ifdef CONFIG_CIFS_WEAK_PW_HASH
602 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
605 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
607 if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
610 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
611 server->maxReq = min_t(unsigned int,
612 le16_to_cpu(rsp->MaxMpxCount),
614 set_credits(server, server->maxReq);
615 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
616 /* set up max_read for readpages check */
617 server->max_read = server->maxBuf;
618 /* even though we do not use raw we might as well set this
619 accurately, in case we ever find a need for it */
620 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
621 server->max_rw = 0xFF00;
622 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
624 server->max_rw = 0;/* do not need to use raw anyway */
625 server->capabilities = CAP_MPX_MODE;
627 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
629 /* OS/2 often does not set timezone therefore
630 * we must use server time to calc time zone.
631 * Could deviate slightly from the right zone.
632 * Smallest defined timezone difference is 15 minutes
633 * (i.e. Nepal). Rounding up/down is done to match
636 int val, seconds, remain, result;
637 struct timespec64 ts;
638 time64_t utc = ktime_get_real_seconds();
639 ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
640 rsp->SrvTime.Time, 0);
641 cifs_dbg(FYI, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
644 val = (int)(utc - ts.tv_sec);
646 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
647 remain = seconds % MIN_TZ_ADJ;
648 if (remain >= (MIN_TZ_ADJ / 2))
649 result += MIN_TZ_ADJ;
652 server->timeAdj = result;
654 server->timeAdj = (int)tmp;
655 server->timeAdj *= 60; /* also in seconds */
657 cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
660 /* BB get server time for time conversions and add
661 code to use it and timezone since this is not UTC */
663 if (rsp->EncryptionKeyLength ==
664 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
665 memcpy(server->cryptkey, rsp->EncryptionKey,
666 CIFS_CRYPTO_KEY_SIZE);
667 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
668 return -EIO; /* need cryptkey unless plain text */
671 cifs_dbg(FYI, "LANMAN negotiated\n");
676 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
678 cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
684 should_set_ext_sec_flag(enum securityEnum sectype)
691 if (global_secflags &
692 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
701 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
704 NEGOTIATE_RSP *pSMBr;
708 struct TCP_Server_Info *server = ses->server;
712 WARN(1, "%s: server is NULL!\n", __func__);
716 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
717 (void **) &pSMB, (void **) &pSMBr);
721 pSMB->hdr.Mid = get_next_mid(server);
722 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
724 if (should_set_ext_sec_flag(ses->sectype)) {
725 cifs_dbg(FYI, "Requesting extended security\n");
726 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
731 * We know that all the name entries in the protocols array
732 * are short (< 16 bytes anyway) and are NUL terminated.
734 for (i = 0; i < CIFS_NUM_PROT; i++) {
735 size_t len = strlen(protocols[i].name) + 1;
737 memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
740 inc_rfc1001_len(pSMB, count);
741 pSMB->ByteCount = cpu_to_le16(count);
743 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
744 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
748 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
749 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
750 /* Check wct = 1 error case */
751 if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
752 /* core returns wct = 1, but we do not ask for core - otherwise
753 small wct just comes when dialect index is -1 indicating we
754 could not negotiate a common dialect */
757 } else if (pSMBr->hdr.WordCount == 13) {
758 server->negflavor = CIFS_NEGFLAVOR_LANMAN;
759 rc = decode_lanman_negprot_rsp(server, pSMBr);
761 } else if (pSMBr->hdr.WordCount != 17) {
766 /* else wct == 17, NTLM or better */
768 server->sec_mode = pSMBr->SecurityMode;
769 if ((server->sec_mode & SECMODE_USER) == 0)
770 cifs_dbg(FYI, "share mode security\n");
772 /* one byte, so no need to convert this or EncryptionKeyLen from
774 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
776 set_credits(server, server->maxReq);
777 /* probably no need to store and check maxvcs */
778 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
779 /* set up max_read for readpages check */
780 server->max_read = server->maxBuf;
781 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
782 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
783 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
784 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
785 server->timeAdj *= 60;
787 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
788 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
789 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
790 CIFS_CRYPTO_KEY_SIZE);
791 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
792 server->capabilities & CAP_EXTENDED_SECURITY) {
793 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
794 rc = decode_ext_sec_blob(ses, pSMBr);
795 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
796 rc = -EIO; /* no crypt key only if plain text pwd */
798 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
799 server->capabilities &= ~CAP_EXTENDED_SECURITY;
804 rc = cifs_enable_signing(server, ses->sign);
806 cifs_buf_release(pSMB);
808 cifs_dbg(FYI, "negprot rc %d\n", rc);
813 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
815 struct smb_hdr *smb_buffer;
818 cifs_dbg(FYI, "In tree disconnect\n");
820 /* BB: do we need to check this? These should never be NULL. */
821 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
825 * No need to return error on this operation if tid invalidated and
826 * closed on server already e.g. due to tcp session crashing. Also,
827 * the tcon is no longer on the list, so no need to take lock before
830 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
833 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
834 (void **)&smb_buffer);
838 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
839 cifs_small_buf_release(smb_buffer);
841 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
843 /* No need to return error on this operation if tid invalidated and
844 closed on server already e.g. due to tcp session crashing */
852 * This is a no-op for now. We're not really interested in the reply, but
853 * rather in the fact that the server sent one and that server->lstrp
856 * FIXME: maybe we should consider checking that the reply matches request?
859 cifs_echo_callback(struct mid_q_entry *mid)
861 struct TCP_Server_Info *server = mid->callback_data;
862 struct cifs_credits credits = { .value = 1, .instance = 0 };
864 DeleteMidQEntry(mid);
865 add_credits(server, &credits, CIFS_ECHO_OP);
869 CIFSSMBEcho(struct TCP_Server_Info *server)
874 struct smb_rqst rqst = { .rq_iov = iov,
877 cifs_dbg(FYI, "In echo request\n");
879 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
883 if (server->capabilities & CAP_UNICODE)
884 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
886 /* set up echo request */
887 smb->hdr.Tid = 0xffff;
888 smb->hdr.WordCount = 1;
889 put_unaligned_le16(1, &smb->EchoCount);
890 put_bcc(1, &smb->hdr);
892 inc_rfc1001_len(smb, 3);
895 iov[0].iov_base = smb;
896 iov[1].iov_len = get_rfc1002_length(smb);
897 iov[1].iov_base = (char *)smb + 4;
899 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
900 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
902 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
904 cifs_small_buf_release(smb);
910 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
912 LOGOFF_ANDX_REQ *pSMB;
915 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
918 * BB: do we need to check validity of ses and server? They should
919 * always be valid since we have an active reference. If not, that
920 * should probably be a BUG()
922 if (!ses || !ses->server)
925 mutex_lock(&ses->session_mutex);
926 if (ses->need_reconnect)
927 goto session_already_dead; /* no need to send SMBlogoff if uid
928 already closed due to reconnect */
929 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
931 mutex_unlock(&ses->session_mutex);
935 pSMB->hdr.Mid = get_next_mid(ses->server);
937 if (ses->server->sign)
938 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
940 pSMB->hdr.Uid = ses->Suid;
942 pSMB->AndXCommand = 0xFF;
943 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
944 cifs_small_buf_release(pSMB);
945 session_already_dead:
946 mutex_unlock(&ses->session_mutex);
948 /* if session dead then we do not need to do ulogoff,
949 since server closed smb session, no sense reporting
957 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
958 const char *fileName, __u16 type,
959 const struct nls_table *nls_codepage, int remap)
961 TRANSACTION2_SPI_REQ *pSMB = NULL;
962 TRANSACTION2_SPI_RSP *pSMBr = NULL;
963 struct unlink_psx_rq *pRqD;
966 int bytes_returned = 0;
967 __u16 params, param_offset, offset, byte_count;
969 cifs_dbg(FYI, "In POSIX delete\n");
971 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
976 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
978 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
979 PATH_MAX, nls_codepage, remap);
980 name_len++; /* trailing null */
983 name_len = copy_path_name(pSMB->FileName, fileName);
986 params = 6 + name_len;
987 pSMB->MaxParameterCount = cpu_to_le16(2);
988 pSMB->MaxDataCount = 0; /* BB double check this with jra */
989 pSMB->MaxSetupCount = 0;
994 param_offset = offsetof(struct smb_com_transaction2_spi_req,
995 InformationLevel) - 4;
996 offset = param_offset + params;
998 /* Setup pointer to Request Data (inode type) */
999 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
1000 pRqD->type = cpu_to_le16(type);
1001 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1002 pSMB->DataOffset = cpu_to_le16(offset);
1003 pSMB->SetupCount = 1;
1004 pSMB->Reserved3 = 0;
1005 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1006 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
1008 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
1009 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
1010 pSMB->ParameterCount = cpu_to_le16(params);
1011 pSMB->TotalParameterCount = pSMB->ParameterCount;
1012 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
1013 pSMB->Reserved4 = 0;
1014 inc_rfc1001_len(pSMB, byte_count);
1015 pSMB->ByteCount = cpu_to_le16(byte_count);
1016 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1017 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1019 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
1020 cifs_buf_release(pSMB);
1022 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
1031 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
1032 struct cifs_sb_info *cifs_sb)
1034 DELETE_FILE_REQ *pSMB = NULL;
1035 DELETE_FILE_RSP *pSMBr = NULL;
1039 int remap = cifs_remap(cifs_sb);
1042 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
1047 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1048 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
1049 PATH_MAX, cifs_sb->local_nls,
1051 name_len++; /* trailing null */
1054 name_len = copy_path_name(pSMB->fileName, name);
1056 pSMB->SearchAttributes =
1057 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
1058 pSMB->BufferFormat = 0x04;
1059 inc_rfc1001_len(pSMB, name_len + 1);
1060 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1061 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1062 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1063 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
1065 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
1067 cifs_buf_release(pSMB);
1075 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
1076 struct cifs_sb_info *cifs_sb)
1078 DELETE_DIRECTORY_REQ *pSMB = NULL;
1079 DELETE_DIRECTORY_RSP *pSMBr = NULL;
1083 int remap = cifs_remap(cifs_sb);
1085 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
1087 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
1092 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1093 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1094 PATH_MAX, cifs_sb->local_nls,
1096 name_len++; /* trailing null */
1099 name_len = copy_path_name(pSMB->DirName, name);
1102 pSMB->BufferFormat = 0x04;
1103 inc_rfc1001_len(pSMB, name_len + 1);
1104 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1105 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1106 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1107 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
1109 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
1111 cifs_buf_release(pSMB);
1118 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
1119 struct cifs_tcon *tcon, const char *name,
1120 struct cifs_sb_info *cifs_sb)
1123 CREATE_DIRECTORY_REQ *pSMB = NULL;
1124 CREATE_DIRECTORY_RSP *pSMBr = NULL;
1127 int remap = cifs_remap(cifs_sb);
1129 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
1131 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
1136 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1137 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1138 PATH_MAX, cifs_sb->local_nls,
1140 name_len++; /* trailing null */
1143 name_len = copy_path_name(pSMB->DirName, name);
1146 pSMB->BufferFormat = 0x04;
1147 inc_rfc1001_len(pSMB, name_len + 1);
1148 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1149 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1150 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1151 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1153 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
1155 cifs_buf_release(pSMB);
1162 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1163 __u32 posix_flags, __u64 mode, __u16 *netfid,
1164 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1165 const char *name, const struct nls_table *nls_codepage,
1168 TRANSACTION2_SPI_REQ *pSMB = NULL;
1169 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1172 int bytes_returned = 0;
1173 __u16 params, param_offset, offset, byte_count, count;
1174 OPEN_PSX_REQ *pdata;
1175 OPEN_PSX_RSP *psx_rsp;
1177 cifs_dbg(FYI, "In POSIX Create\n");
1179 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1184 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1186 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1187 PATH_MAX, nls_codepage, remap);
1188 name_len++; /* trailing null */
1191 name_len = copy_path_name(pSMB->FileName, name);
1194 params = 6 + name_len;
1195 count = sizeof(OPEN_PSX_REQ);
1196 pSMB->MaxParameterCount = cpu_to_le16(2);
1197 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1198 pSMB->MaxSetupCount = 0;
1202 pSMB->Reserved2 = 0;
1203 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1204 InformationLevel) - 4;
1205 offset = param_offset + params;
1206 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1207 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1208 pdata->Permissions = cpu_to_le64(mode);
1209 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1210 pdata->OpenFlags = cpu_to_le32(*pOplock);
1211 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1212 pSMB->DataOffset = cpu_to_le16(offset);
1213 pSMB->SetupCount = 1;
1214 pSMB->Reserved3 = 0;
1215 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1216 byte_count = 3 /* pad */ + params + count;
1218 pSMB->DataCount = cpu_to_le16(count);
1219 pSMB->ParameterCount = cpu_to_le16(params);
1220 pSMB->TotalDataCount = pSMB->DataCount;
1221 pSMB->TotalParameterCount = pSMB->ParameterCount;
1222 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1223 pSMB->Reserved4 = 0;
1224 inc_rfc1001_len(pSMB, byte_count);
1225 pSMB->ByteCount = cpu_to_le16(byte_count);
1226 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1227 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1229 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1230 goto psx_create_err;
1233 cifs_dbg(FYI, "copying inode info\n");
1234 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1236 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1237 rc = -EIO; /* bad smb */
1238 goto psx_create_err;
1241 /* copy return information to pRetData */
1242 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1243 + le16_to_cpu(pSMBr->t2.DataOffset));
1245 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1247 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1248 /* Let caller know file was created so we can set the mode. */
1249 /* Do we care about the CreateAction in any other cases? */
1250 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1251 *pOplock |= CIFS_CREATE_ACTION;
1252 /* check to make sure response data is there */
1253 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1254 pRetData->Type = cpu_to_le32(-1); /* unknown */
1255 cifs_dbg(NOISY, "unknown type\n");
1257 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1258 + sizeof(FILE_UNIX_BASIC_INFO)) {
1259 cifs_dbg(VFS, "Open response data too small\n");
1260 pRetData->Type = cpu_to_le32(-1);
1261 goto psx_create_err;
1263 memcpy((char *) pRetData,
1264 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1265 sizeof(FILE_UNIX_BASIC_INFO));
1269 cifs_buf_release(pSMB);
1271 if (posix_flags & SMB_O_DIRECTORY)
1272 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1274 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1282 static __u16 convert_disposition(int disposition)
1286 switch (disposition) {
1287 case FILE_SUPERSEDE:
1288 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1291 ofun = SMBOPEN_OAPPEND;
1294 ofun = SMBOPEN_OCREATE;
1297 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1299 case FILE_OVERWRITE:
1300 ofun = SMBOPEN_OTRUNC;
1302 case FILE_OVERWRITE_IF:
1303 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1306 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1307 ofun = SMBOPEN_OAPPEND; /* regular open */
1313 access_flags_to_smbopen_mode(const int access_flags)
1315 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1317 if (masked_flags == GENERIC_READ)
1318 return SMBOPEN_READ;
1319 else if (masked_flags == GENERIC_WRITE)
1320 return SMBOPEN_WRITE;
1322 /* just go for read/write */
1323 return SMBOPEN_READWRITE;
1327 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1328 const char *fileName, const int openDisposition,
1329 const int access_flags, const int create_options, __u16 *netfid,
1330 int *pOplock, FILE_ALL_INFO *pfile_info,
1331 const struct nls_table *nls_codepage, int remap)
1334 OPENX_REQ *pSMB = NULL;
1335 OPENX_RSP *pSMBr = NULL;
1341 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1346 pSMB->AndXCommand = 0xFF; /* none */
1348 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1349 count = 1; /* account for one byte pad to word boundary */
1351 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1352 fileName, PATH_MAX, nls_codepage, remap);
1353 name_len++; /* trailing null */
1356 count = 0; /* no pad */
1357 name_len = copy_path_name(pSMB->fileName, fileName);
1359 if (*pOplock & REQ_OPLOCK)
1360 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1361 else if (*pOplock & REQ_BATCHOPLOCK)
1362 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1364 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1365 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1366 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1367 /* set file as system file if special file such
1368 as fifo and server expecting SFU style and
1369 no Unix extensions */
1371 if (create_options & CREATE_OPTION_SPECIAL)
1372 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1373 else /* BB FIXME BB */
1374 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1376 if (create_options & CREATE_OPTION_READONLY)
1377 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1380 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1381 CREATE_OPTIONS_MASK); */
1382 /* BB FIXME END BB */
1384 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1385 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1387 inc_rfc1001_len(pSMB, count);
1389 pSMB->ByteCount = cpu_to_le16(count);
1390 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1391 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1392 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1394 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1396 /* BB verify if wct == 15 */
1398 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1400 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1401 /* Let caller know file was created so we can set the mode. */
1402 /* Do we care about the CreateAction in any other cases? */
1404 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1405 *pOplock |= CIFS_CREATE_ACTION; */
1409 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1410 pfile_info->LastAccessTime = 0; /* BB fixme */
1411 pfile_info->LastWriteTime = 0; /* BB fixme */
1412 pfile_info->ChangeTime = 0; /* BB fixme */
1413 pfile_info->Attributes =
1414 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1415 /* the file_info buf is endian converted by caller */
1416 pfile_info->AllocationSize =
1417 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1418 pfile_info->EndOfFile = pfile_info->AllocationSize;
1419 pfile_info->NumberOfLinks = cpu_to_le32(1);
1420 pfile_info->DeletePending = 0;
1424 cifs_buf_release(pSMB);
1431 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1435 OPEN_REQ *req = NULL;
1436 OPEN_RSP *rsp = NULL;
1440 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1441 struct cifs_tcon *tcon = oparms->tcon;
1442 int remap = cifs_remap(cifs_sb);
1443 const struct nls_table *nls = cifs_sb->local_nls;
1444 int create_options = oparms->create_options;
1445 int desired_access = oparms->desired_access;
1446 int disposition = oparms->disposition;
1447 const char *path = oparms->path;
1450 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1455 /* no commands go after this */
1456 req->AndXCommand = 0xFF;
1458 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1459 /* account for one byte pad to word boundary */
1461 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1462 path, PATH_MAX, nls, remap);
1466 req->NameLength = cpu_to_le16(name_len);
1468 /* BB improve check for buffer overruns BB */
1471 name_len = copy_path_name(req->fileName, path);
1472 req->NameLength = cpu_to_le16(name_len);
1475 if (*oplock & REQ_OPLOCK)
1476 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1477 else if (*oplock & REQ_BATCHOPLOCK)
1478 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1480 req->DesiredAccess = cpu_to_le32(desired_access);
1481 req->AllocationSize = 0;
1484 * Set file as system file if special file such as fifo and server
1485 * expecting SFU style and no Unix extensions.
1487 if (create_options & CREATE_OPTION_SPECIAL)
1488 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1490 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1493 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1494 * sensitive checks for other servers such as Samba.
1496 if (tcon->ses->capabilities & CAP_UNIX)
1497 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1499 if (create_options & CREATE_OPTION_READONLY)
1500 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1502 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1503 req->CreateDisposition = cpu_to_le32(disposition);
1504 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1506 /* BB Expirement with various impersonation levels and verify */
1507 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1508 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1511 inc_rfc1001_len(req, count);
1513 req->ByteCount = cpu_to_le16(count);
1514 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1515 (struct smb_hdr *)rsp, &bytes_returned, 0);
1516 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1518 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1519 cifs_buf_release(req);
1525 /* 1 byte no need to le_to_cpu */
1526 *oplock = rsp->OplockLevel;
1527 /* cifs fid stays in le */
1528 oparms->fid->netfid = rsp->Fid;
1529 oparms->fid->access = desired_access;
1531 /* Let caller know file was created so we can set the mode. */
1532 /* Do we care about the CreateAction in any other cases? */
1533 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1534 *oplock |= CIFS_CREATE_ACTION;
1537 /* copy from CreationTime to Attributes */
1538 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1539 /* the file_info buf is endian converted by caller */
1540 buf->AllocationSize = rsp->AllocationSize;
1541 buf->EndOfFile = rsp->EndOfFile;
1542 buf->NumberOfLinks = cpu_to_le32(1);
1543 buf->DeletePending = 0;
1546 cifs_buf_release(req);
1551 * Discard any remaining data in the current SMB. To do this, we borrow the
1555 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1557 unsigned int rfclen = server->pdu_size;
1558 int remaining = rfclen + server->vals->header_preamble_size -
1561 while (remaining > 0) {
1564 length = cifs_read_from_socket(server, server->bigbuf,
1565 min_t(unsigned int, remaining,
1566 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1569 server->total_read += length;
1570 remaining -= length;
1577 __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
1582 length = cifs_discard_remaining_data(server);
1583 dequeue_mid(mid, malformed);
1584 mid->resp_buf = server->smallbuf;
1585 server->smallbuf = NULL;
1590 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1592 struct cifs_readdata *rdata = mid->callback_data;
1594 return __cifs_readv_discard(server, mid, rdata->result);
1598 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1601 unsigned int data_offset, data_len;
1602 struct cifs_readdata *rdata = mid->callback_data;
1603 char *buf = server->smallbuf;
1604 unsigned int buflen = server->pdu_size +
1605 server->vals->header_preamble_size;
1606 bool use_rdma_mr = false;
1608 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1609 __func__, mid->mid, rdata->offset, rdata->bytes);
1612 * read the rest of READ_RSP header (sans Data array), or whatever we
1613 * can if there's not enough data. At this point, we've read down to
1616 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1617 HEADER_SIZE(server) + 1;
1619 length = cifs_read_from_socket(server,
1620 buf + HEADER_SIZE(server) - 1, len);
1623 server->total_read += length;
1625 if (server->ops->is_session_expired &&
1626 server->ops->is_session_expired(buf)) {
1627 cifs_reconnect(server);
1631 if (server->ops->is_status_pending &&
1632 server->ops->is_status_pending(buf, server)) {
1633 cifs_discard_remaining_data(server);
1637 /* set up first two iov for signature check and to get credits */
1638 rdata->iov[0].iov_base = buf;
1639 rdata->iov[0].iov_len = server->vals->header_preamble_size;
1640 rdata->iov[1].iov_base = buf + server->vals->header_preamble_size;
1641 rdata->iov[1].iov_len =
1642 server->total_read - server->vals->header_preamble_size;
1643 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1644 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1645 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
1646 rdata->iov[1].iov_base, rdata->iov[1].iov_len);
1648 /* Was the SMB read successful? */
1649 rdata->result = server->ops->map_error(buf, false);
1650 if (rdata->result != 0) {
1651 cifs_dbg(FYI, "%s: server returned error %d\n",
1652 __func__, rdata->result);
1653 /* normal error on read response */
1654 return __cifs_readv_discard(server, mid, false);
1657 /* Is there enough to get to the rest of the READ_RSP header? */
1658 if (server->total_read < server->vals->read_rsp_size) {
1659 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1660 __func__, server->total_read,
1661 server->vals->read_rsp_size);
1662 rdata->result = -EIO;
1663 return cifs_readv_discard(server, mid);
1666 data_offset = server->ops->read_data_offset(buf) +
1667 server->vals->header_preamble_size;
1668 if (data_offset < server->total_read) {
1670 * win2k8 sometimes sends an offset of 0 when the read
1671 * is beyond the EOF. Treat it as if the data starts just after
1674 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1675 __func__, data_offset);
1676 data_offset = server->total_read;
1677 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1678 /* data_offset is beyond the end of smallbuf */
1679 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1680 __func__, data_offset);
1681 rdata->result = -EIO;
1682 return cifs_readv_discard(server, mid);
1685 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1686 __func__, server->total_read, data_offset);
1688 len = data_offset - server->total_read;
1690 /* read any junk before data into the rest of smallbuf */
1691 length = cifs_read_from_socket(server,
1692 buf + server->total_read, len);
1695 server->total_read += length;
1698 /* how much data is in the response? */
1699 #ifdef CONFIG_CIFS_SMB_DIRECT
1700 use_rdma_mr = rdata->mr;
1702 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1703 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1704 /* data_len is corrupt -- discard frame */
1705 rdata->result = -EIO;
1706 return cifs_readv_discard(server, mid);
1709 length = rdata->read_into_pages(server, rdata, data_len);
1713 server->total_read += length;
1715 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1716 server->total_read, buflen, data_len);
1718 /* discard anything left over */
1719 if (server->total_read < buflen)
1720 return cifs_readv_discard(server, mid);
1722 dequeue_mid(mid, false);
1723 mid->resp_buf = server->smallbuf;
1724 server->smallbuf = NULL;
1729 cifs_readv_callback(struct mid_q_entry *mid)
1731 struct cifs_readdata *rdata = mid->callback_data;
1732 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1733 struct TCP_Server_Info *server = tcon->ses->server;
1734 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1736 .rq_pages = rdata->pages,
1737 .rq_offset = rdata->page_offset,
1738 .rq_npages = rdata->nr_pages,
1739 .rq_pagesz = rdata->pagesz,
1740 .rq_tailsz = rdata->tailsz };
1741 struct cifs_credits credits = { .value = 1, .instance = 0 };
1743 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1744 __func__, mid->mid, mid->mid_state, rdata->result,
1747 switch (mid->mid_state) {
1748 case MID_RESPONSE_RECEIVED:
1749 /* result already set, check signature */
1753 rc = cifs_verify_signature(&rqst, server,
1754 mid->sequence_number);
1756 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1759 /* FIXME: should this be counted toward the initiating task? */
1760 task_io_account_read(rdata->got_bytes);
1761 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1763 case MID_REQUEST_SUBMITTED:
1764 case MID_RETRY_NEEDED:
1765 rdata->result = -EAGAIN;
1766 if (server->sign && rdata->got_bytes)
1767 /* reset bytes number since we can not check a sign */
1768 rdata->got_bytes = 0;
1769 /* FIXME: should this be counted toward the initiating task? */
1770 task_io_account_read(rdata->got_bytes);
1771 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1774 rdata->result = -EIO;
1777 queue_work(cifsiod_wq, &rdata->work);
1778 DeleteMidQEntry(mid);
1779 add_credits(server, &credits, 0);
1782 /* cifs_async_readv - send an async write, and set up mid to handle result */
1784 cifs_async_readv(struct cifs_readdata *rdata)
1787 READ_REQ *smb = NULL;
1789 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1790 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1793 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1794 __func__, rdata->offset, rdata->bytes);
1796 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1799 wct = 10; /* old style read */
1800 if ((rdata->offset >> 32) > 0) {
1801 /* can not handle this big offset for old */
1806 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1810 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1811 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1813 smb->AndXCommand = 0xFF; /* none */
1814 smb->Fid = rdata->cfile->fid.netfid;
1815 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1817 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1819 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1820 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1824 /* old style read */
1825 struct smb_com_readx_req *smbr =
1826 (struct smb_com_readx_req *)smb;
1827 smbr->ByteCount = 0;
1830 /* 4 for RFC1001 length + 1 for BCC */
1831 rdata->iov[0].iov_base = smb;
1832 rdata->iov[0].iov_len = 4;
1833 rdata->iov[1].iov_base = (char *)smb + 4;
1834 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1836 kref_get(&rdata->refcount);
1837 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1838 cifs_readv_callback, NULL, rdata, 0, NULL);
1841 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1843 kref_put(&rdata->refcount, cifs_readdata_release);
1845 cifs_small_buf_release(smb);
1850 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1851 unsigned int *nbytes, char **buf, int *pbuf_type)
1854 READ_REQ *pSMB = NULL;
1855 READ_RSP *pSMBr = NULL;
1856 char *pReadData = NULL;
1858 int resp_buf_type = 0;
1860 struct kvec rsp_iov;
1861 __u32 pid = io_parms->pid;
1862 __u16 netfid = io_parms->netfid;
1863 __u64 offset = io_parms->offset;
1864 struct cifs_tcon *tcon = io_parms->tcon;
1865 unsigned int count = io_parms->length;
1867 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1868 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1871 wct = 10; /* old style read */
1872 if ((offset >> 32) > 0) {
1873 /* can not handle this big offset for old */
1879 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1883 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1884 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1886 /* tcon and ses pointer are checked in smb_init */
1887 if (tcon->ses->server == NULL)
1888 return -ECONNABORTED;
1890 pSMB->AndXCommand = 0xFF; /* none */
1892 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1894 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1896 pSMB->Remaining = 0;
1897 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1898 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1900 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1902 /* old style read */
1903 struct smb_com_readx_req *pSMBW =
1904 (struct smb_com_readx_req *)pSMB;
1905 pSMBW->ByteCount = 0;
1908 iov[0].iov_base = (char *)pSMB;
1909 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1910 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1911 CIFS_LOG_ERROR, &rsp_iov);
1912 cifs_small_buf_release(pSMB);
1913 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1914 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1916 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1918 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1919 data_length = data_length << 16;
1920 data_length += le16_to_cpu(pSMBr->DataLength);
1921 *nbytes = data_length;
1923 /*check that DataLength would not go beyond end of SMB */
1924 if ((data_length > CIFSMaxBufSize)
1925 || (data_length > count)) {
1926 cifs_dbg(FYI, "bad length %d for count %d\n",
1927 data_length, count);
1931 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1932 le16_to_cpu(pSMBr->DataOffset);
1933 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1934 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1936 }*/ /* can not use copy_to_user when using page cache*/
1938 memcpy(*buf, pReadData, data_length);
1943 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1944 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1945 /* return buffer to caller to free */
1946 *buf = rsp_iov.iov_base;
1947 if (resp_buf_type == CIFS_SMALL_BUFFER)
1948 *pbuf_type = CIFS_SMALL_BUFFER;
1949 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1950 *pbuf_type = CIFS_LARGE_BUFFER;
1951 } /* else no valid buffer on return - leave as null */
1953 /* Note: On -EAGAIN error only caller can retry on handle based calls
1954 since file handle passed in no longer valid */
1960 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1961 unsigned int *nbytes, const char *buf)
1964 WRITE_REQ *pSMB = NULL;
1965 WRITE_RSP *pSMBr = NULL;
1966 int bytes_returned, wct;
1969 __u32 pid = io_parms->pid;
1970 __u16 netfid = io_parms->netfid;
1971 __u64 offset = io_parms->offset;
1972 struct cifs_tcon *tcon = io_parms->tcon;
1973 unsigned int count = io_parms->length;
1977 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1978 if (tcon->ses == NULL)
1979 return -ECONNABORTED;
1981 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1985 if ((offset >> 32) > 0) {
1986 /* can not handle big offset for old srv */
1991 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1996 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1997 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1999 /* tcon and ses pointer are checked in smb_init */
2000 if (tcon->ses->server == NULL)
2001 return -ECONNABORTED;
2003 pSMB->AndXCommand = 0xFF; /* none */
2005 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2007 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2009 pSMB->Reserved = 0xFFFFFFFF;
2010 pSMB->WriteMode = 0;
2011 pSMB->Remaining = 0;
2013 /* Can increase buffer size if buffer is big enough in some cases ie we
2014 can send more if LARGE_WRITE_X capability returned by the server and if
2015 our buffer is big enough or if we convert to iovecs on socket writes
2016 and eliminate the copy to the CIFS buffer */
2017 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
2018 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
2020 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
2024 if (bytes_sent > count)
2027 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2029 memcpy(pSMB->Data, buf, bytes_sent);
2030 else if (count != 0) {
2032 cifs_buf_release(pSMB);
2034 } /* else setting file size with write of zero bytes */
2036 byte_count = bytes_sent + 1; /* pad */
2037 else /* wct == 12 */
2038 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
2040 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
2041 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
2042 inc_rfc1001_len(pSMB, byte_count);
2045 pSMB->ByteCount = cpu_to_le16(byte_count);
2046 else { /* old style write has byte count 4 bytes earlier
2048 struct smb_com_writex_req *pSMBW =
2049 (struct smb_com_writex_req *)pSMB;
2050 pSMBW->ByteCount = cpu_to_le16(byte_count);
2053 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2054 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2055 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2057 cifs_dbg(FYI, "Send error in write = %d\n", rc);
2059 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2060 *nbytes = (*nbytes) << 16;
2061 *nbytes += le16_to_cpu(pSMBr->Count);
2064 * Mask off high 16 bits when bytes written as returned by the
2065 * server is greater than bytes requested by the client. Some
2066 * OS/2 servers are known to set incorrect CountHigh values.
2068 if (*nbytes > count)
2072 cifs_buf_release(pSMB);
2074 /* Note: On -EAGAIN error only caller can retry on handle based calls
2075 since file handle passed in no longer valid */
2081 cifs_writedata_release(struct kref *refcount)
2083 struct cifs_writedata *wdata = container_of(refcount,
2084 struct cifs_writedata, refcount);
2085 #ifdef CONFIG_CIFS_SMB_DIRECT
2087 smbd_deregister_mr(wdata->mr);
2093 cifsFileInfo_put(wdata->cfile);
2095 kvfree(wdata->pages);
2100 * Write failed with a retryable error. Resend the write request. It's also
2101 * possible that the page was redirtied so re-clean the page.
2104 cifs_writev_requeue(struct cifs_writedata *wdata)
2107 struct inode *inode = d_inode(wdata->cfile->dentry);
2108 struct TCP_Server_Info *server;
2109 unsigned int rest_len;
2111 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
2113 rest_len = wdata->bytes;
2115 struct cifs_writedata *wdata2;
2116 unsigned int j, nr_pages, wsize, tailsz, cur_len;
2118 wsize = server->ops->wp_retry_size(inode);
2119 if (wsize < rest_len) {
2120 nr_pages = wsize / PAGE_SIZE;
2125 cur_len = nr_pages * PAGE_SIZE;
2128 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
2130 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
2133 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
2139 for (j = 0; j < nr_pages; j++) {
2140 wdata2->pages[j] = wdata->pages[i + j];
2141 lock_page(wdata2->pages[j]);
2142 clear_page_dirty_for_io(wdata2->pages[j]);
2145 wdata2->sync_mode = wdata->sync_mode;
2146 wdata2->nr_pages = nr_pages;
2147 wdata2->offset = page_offset(wdata2->pages[0]);
2148 wdata2->pagesz = PAGE_SIZE;
2149 wdata2->tailsz = tailsz;
2150 wdata2->bytes = cur_len;
2152 rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
2154 if (!wdata2->cfile) {
2155 cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
2157 if (!is_retryable_error(rc))
2160 wdata2->pid = wdata2->cfile->pid;
2161 rc = server->ops->async_writev(wdata2,
2162 cifs_writedata_release);
2165 for (j = 0; j < nr_pages; j++) {
2166 unlock_page(wdata2->pages[j]);
2167 if (rc != 0 && !is_retryable_error(rc)) {
2168 SetPageError(wdata2->pages[j]);
2169 end_page_writeback(wdata2->pages[j]);
2170 put_page(wdata2->pages[j]);
2174 kref_put(&wdata2->refcount, cifs_writedata_release);
2176 if (is_retryable_error(rc))
2182 rest_len -= cur_len;
2184 } while (i < wdata->nr_pages);
2186 /* cleanup remaining pages from the original wdata */
2187 for (; i < wdata->nr_pages; i++) {
2188 SetPageError(wdata->pages[i]);
2189 end_page_writeback(wdata->pages[i]);
2190 put_page(wdata->pages[i]);
2193 if (rc != 0 && !is_retryable_error(rc))
2194 mapping_set_error(inode->i_mapping, rc);
2195 kref_put(&wdata->refcount, cifs_writedata_release);
2199 cifs_writev_complete(struct work_struct *work)
2201 struct cifs_writedata *wdata = container_of(work,
2202 struct cifs_writedata, work);
2203 struct inode *inode = d_inode(wdata->cfile->dentry);
2206 if (wdata->result == 0) {
2207 spin_lock(&inode->i_lock);
2208 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2209 spin_unlock(&inode->i_lock);
2210 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2212 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2213 return cifs_writev_requeue(wdata);
2215 for (i = 0; i < wdata->nr_pages; i++) {
2216 struct page *page = wdata->pages[i];
2217 if (wdata->result == -EAGAIN)
2218 __set_page_dirty_nobuffers(page);
2219 else if (wdata->result < 0)
2221 end_page_writeback(page);
2224 if (wdata->result != -EAGAIN)
2225 mapping_set_error(inode->i_mapping, wdata->result);
2226 kref_put(&wdata->refcount, cifs_writedata_release);
2229 struct cifs_writedata *
2230 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2232 struct page **pages =
2233 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2235 return cifs_writedata_direct_alloc(pages, complete);
2240 struct cifs_writedata *
2241 cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2243 struct cifs_writedata *wdata;
2245 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2246 if (wdata != NULL) {
2247 wdata->pages = pages;
2248 kref_init(&wdata->refcount);
2249 INIT_LIST_HEAD(&wdata->list);
2250 init_completion(&wdata->done);
2251 INIT_WORK(&wdata->work, complete);
2257 * Check the mid_state and signature on received buffer (if any), and queue the
2258 * workqueue completion task.
2261 cifs_writev_callback(struct mid_q_entry *mid)
2263 struct cifs_writedata *wdata = mid->callback_data;
2264 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2265 unsigned int written;
2266 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2267 struct cifs_credits credits = { .value = 1, .instance = 0 };
2269 switch (mid->mid_state) {
2270 case MID_RESPONSE_RECEIVED:
2271 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2272 if (wdata->result != 0)
2275 written = le16_to_cpu(smb->CountHigh);
2277 written += le16_to_cpu(smb->Count);
2279 * Mask off high 16 bits when bytes written as returned
2280 * by the server is greater than bytes requested by the
2281 * client. OS/2 servers are known to set incorrect
2284 if (written > wdata->bytes)
2287 if (written < wdata->bytes)
2288 wdata->result = -ENOSPC;
2290 wdata->bytes = written;
2292 case MID_REQUEST_SUBMITTED:
2293 case MID_RETRY_NEEDED:
2294 wdata->result = -EAGAIN;
2297 wdata->result = -EIO;
2301 queue_work(cifsiod_wq, &wdata->work);
2302 DeleteMidQEntry(mid);
2303 add_credits(tcon->ses->server, &credits, 0);
2306 /* cifs_async_writev - send an async write, and set up mid to handle result */
2308 cifs_async_writev(struct cifs_writedata *wdata,
2309 void (*release)(struct kref *kref))
2312 WRITE_REQ *smb = NULL;
2314 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2316 struct smb_rqst rqst = { };
2318 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2322 if (wdata->offset >> 32 > 0) {
2323 /* can not handle big offset for old srv */
2328 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2330 goto async_writev_out;
2332 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2333 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2335 smb->AndXCommand = 0xFF; /* none */
2336 smb->Fid = wdata->cfile->fid.netfid;
2337 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2339 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2340 smb->Reserved = 0xFFFFFFFF;
2345 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2347 /* 4 for RFC1001 length + 1 for BCC */
2349 iov[0].iov_base = smb;
2350 iov[1].iov_len = get_rfc1002_length(smb) + 1;
2351 iov[1].iov_base = (char *)smb + 4;
2355 rqst.rq_pages = wdata->pages;
2356 rqst.rq_offset = wdata->page_offset;
2357 rqst.rq_npages = wdata->nr_pages;
2358 rqst.rq_pagesz = wdata->pagesz;
2359 rqst.rq_tailsz = wdata->tailsz;
2361 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2362 wdata->offset, wdata->bytes);
2364 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2365 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2368 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2369 put_bcc(wdata->bytes + 1, &smb->hdr);
2372 struct smb_com_writex_req *smbw =
2373 (struct smb_com_writex_req *)smb;
2374 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2375 put_bcc(wdata->bytes + 5, &smbw->hdr);
2376 iov[1].iov_len += 4; /* pad bigger by four bytes */
2379 kref_get(&wdata->refcount);
2380 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2381 cifs_writev_callback, NULL, wdata, 0, NULL);
2384 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2386 kref_put(&wdata->refcount, release);
2389 cifs_small_buf_release(smb);
2394 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2395 unsigned int *nbytes, struct kvec *iov, int n_vec)
2398 WRITE_REQ *pSMB = NULL;
2401 int resp_buf_type = 0;
2402 __u32 pid = io_parms->pid;
2403 __u16 netfid = io_parms->netfid;
2404 __u64 offset = io_parms->offset;
2405 struct cifs_tcon *tcon = io_parms->tcon;
2406 unsigned int count = io_parms->length;
2407 struct kvec rsp_iov;
2411 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2413 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2417 if ((offset >> 32) > 0) {
2418 /* can not handle big offset for old srv */
2422 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2426 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2427 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2429 /* tcon and ses pointer are checked in smb_init */
2430 if (tcon->ses->server == NULL)
2431 return -ECONNABORTED;
2433 pSMB->AndXCommand = 0xFF; /* none */
2435 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2437 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2438 pSMB->Reserved = 0xFFFFFFFF;
2439 pSMB->WriteMode = 0;
2440 pSMB->Remaining = 0;
2443 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2445 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2446 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2447 /* header + 1 byte pad */
2448 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2450 inc_rfc1001_len(pSMB, count + 1);
2451 else /* wct == 12 */
2452 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2454 pSMB->ByteCount = cpu_to_le16(count + 1);
2455 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2456 struct smb_com_writex_req *pSMBW =
2457 (struct smb_com_writex_req *)pSMB;
2458 pSMBW->ByteCount = cpu_to_le16(count + 5);
2460 iov[0].iov_base = pSMB;
2462 iov[0].iov_len = smb_hdr_len + 4;
2463 else /* wct == 12 pad bigger by four bytes */
2464 iov[0].iov_len = smb_hdr_len + 8;
2466 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2468 cifs_small_buf_release(pSMB);
2469 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2471 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2472 } else if (resp_buf_type == 0) {
2473 /* presumably this can not happen, but best to be safe */
2476 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2477 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2478 *nbytes = (*nbytes) << 16;
2479 *nbytes += le16_to_cpu(pSMBr->Count);
2482 * Mask off high 16 bits when bytes written as returned by the
2483 * server is greater than bytes requested by the client. OS/2
2484 * servers are known to set incorrect CountHigh values.
2486 if (*nbytes > count)
2490 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2492 /* Note: On -EAGAIN error only caller can retry on handle based calls
2493 since file handle passed in no longer valid */
2498 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2499 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2500 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2503 LOCK_REQ *pSMB = NULL;
2505 struct kvec rsp_iov;
2509 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2510 num_lock, num_unlock);
2512 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2517 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2518 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2519 pSMB->LockType = lock_type;
2520 pSMB->AndXCommand = 0xFF; /* none */
2521 pSMB->Fid = netfid; /* netfid stays le */
2523 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2524 inc_rfc1001_len(pSMB, count);
2525 pSMB->ByteCount = cpu_to_le16(count);
2527 iov[0].iov_base = (char *)pSMB;
2528 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2529 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2530 iov[1].iov_base = (char *)buf;
2531 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2533 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2534 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
2535 CIFS_NO_RSP_BUF, &rsp_iov);
2536 cifs_small_buf_release(pSMB);
2538 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2544 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2545 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2546 const __u64 offset, const __u32 numUnlock,
2547 const __u32 numLock, const __u8 lockType,
2548 const bool waitFlag, const __u8 oplock_level)
2551 LOCK_REQ *pSMB = NULL;
2552 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2557 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2558 (int)waitFlag, numLock);
2559 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2564 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2565 /* no response expected */
2566 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
2568 } else if (waitFlag) {
2569 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2570 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2575 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2576 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2577 pSMB->LockType = lockType;
2578 pSMB->OplockLevel = oplock_level;
2579 pSMB->AndXCommand = 0xFF; /* none */
2580 pSMB->Fid = smb_file_id; /* netfid stays le */
2582 if ((numLock != 0) || (numUnlock != 0)) {
2583 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2584 /* BB where to store pid high? */
2585 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2586 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2587 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2588 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2589 count = sizeof(LOCKING_ANDX_RANGE);
2594 inc_rfc1001_len(pSMB, count);
2595 pSMB->ByteCount = cpu_to_le16(count);
2598 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2599 (struct smb_hdr *) pSMB, &bytes_returned);
2601 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2602 cifs_small_buf_release(pSMB);
2603 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2605 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2607 /* Note: On -EAGAIN error only caller can retry on handle based calls
2608 since file handle passed in no longer valid */
2613 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2614 const __u16 smb_file_id, const __u32 netpid,
2615 const loff_t start_offset, const __u64 len,
2616 struct file_lock *pLockData, const __u16 lock_type,
2617 const bool waitFlag)
2619 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2620 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2621 struct cifs_posix_lock *parm_data;
2624 int bytes_returned = 0;
2625 int resp_buf_type = 0;
2626 __u16 params, param_offset, offset, byte_count, count;
2628 struct kvec rsp_iov;
2630 cifs_dbg(FYI, "Posix Lock\n");
2632 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2637 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2640 pSMB->MaxSetupCount = 0;
2643 pSMB->Reserved2 = 0;
2644 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2645 offset = param_offset + params;
2647 count = sizeof(struct cifs_posix_lock);
2648 pSMB->MaxParameterCount = cpu_to_le16(2);
2649 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2650 pSMB->SetupCount = 1;
2651 pSMB->Reserved3 = 0;
2653 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2655 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2656 byte_count = 3 /* pad */ + params + count;
2657 pSMB->DataCount = cpu_to_le16(count);
2658 pSMB->ParameterCount = cpu_to_le16(params);
2659 pSMB->TotalDataCount = pSMB->DataCount;
2660 pSMB->TotalParameterCount = pSMB->ParameterCount;
2661 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2662 parm_data = (struct cifs_posix_lock *)
2663 (((char *) &pSMB->hdr.Protocol) + offset);
2665 parm_data->lock_type = cpu_to_le16(lock_type);
2667 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2668 parm_data->lock_flags = cpu_to_le16(1);
2669 pSMB->Timeout = cpu_to_le32(-1);
2673 parm_data->pid = cpu_to_le32(netpid);
2674 parm_data->start = cpu_to_le64(start_offset);
2675 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2677 pSMB->DataOffset = cpu_to_le16(offset);
2678 pSMB->Fid = smb_file_id;
2679 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2680 pSMB->Reserved4 = 0;
2681 inc_rfc1001_len(pSMB, byte_count);
2682 pSMB->ByteCount = cpu_to_le16(byte_count);
2684 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2685 (struct smb_hdr *) pSMBr, &bytes_returned);
2687 iov[0].iov_base = (char *)pSMB;
2688 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2689 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2690 &resp_buf_type, timeout, &rsp_iov);
2691 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2693 cifs_small_buf_release(pSMB);
2696 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2697 } else if (pLockData) {
2698 /* lock structure can be returned on get */
2701 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2703 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2704 rc = -EIO; /* bad smb */
2707 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2708 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2709 if (data_count < sizeof(struct cifs_posix_lock)) {
2713 parm_data = (struct cifs_posix_lock *)
2714 ((char *)&pSMBr->hdr.Protocol + data_offset);
2715 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2716 pLockData->fl_type = F_UNLCK;
2718 if (parm_data->lock_type ==
2719 cpu_to_le16(CIFS_RDLCK))
2720 pLockData->fl_type = F_RDLCK;
2721 else if (parm_data->lock_type ==
2722 cpu_to_le16(CIFS_WRLCK))
2723 pLockData->fl_type = F_WRLCK;
2725 pLockData->fl_start = le64_to_cpu(parm_data->start);
2726 pLockData->fl_end = pLockData->fl_start +
2727 le64_to_cpu(parm_data->length) - 1;
2728 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2733 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2735 /* Note: On -EAGAIN error only caller can retry on handle based calls
2736 since file handle passed in no longer valid */
2743 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2746 CLOSE_REQ *pSMB = NULL;
2747 cifs_dbg(FYI, "In CIFSSMBClose\n");
2749 /* do not retry on dead session on close */
2750 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2756 pSMB->FileID = (__u16) smb_file_id;
2757 pSMB->LastWriteTime = 0xFFFFFFFF;
2758 pSMB->ByteCount = 0;
2759 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2760 cifs_small_buf_release(pSMB);
2761 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2764 /* EINTR is expected when user ctl-c to kill app */
2765 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2769 /* Since session is dead, file will be closed on server already */
2777 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2780 FLUSH_REQ *pSMB = NULL;
2781 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2783 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2787 pSMB->FileID = (__u16) smb_file_id;
2788 pSMB->ByteCount = 0;
2789 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2790 cifs_small_buf_release(pSMB);
2791 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2793 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2799 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2800 const char *from_name, const char *to_name,
2801 struct cifs_sb_info *cifs_sb)
2804 RENAME_REQ *pSMB = NULL;
2805 RENAME_RSP *pSMBr = NULL;
2807 int name_len, name_len2;
2809 int remap = cifs_remap(cifs_sb);
2811 cifs_dbg(FYI, "In CIFSSMBRename\n");
2813 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2818 pSMB->BufferFormat = 0x04;
2819 pSMB->SearchAttributes =
2820 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2823 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2824 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2825 from_name, PATH_MAX,
2826 cifs_sb->local_nls, remap);
2827 name_len++; /* trailing null */
2829 pSMB->OldFileName[name_len] = 0x04; /* pad */
2830 /* protocol requires ASCII signature byte on Unicode string */
2831 pSMB->OldFileName[name_len + 1] = 0x00;
2833 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2834 to_name, PATH_MAX, cifs_sb->local_nls,
2836 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2837 name_len2 *= 2; /* convert to bytes */
2839 name_len = copy_path_name(pSMB->OldFileName, from_name);
2840 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2841 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2842 name_len2++; /* signature byte */
2845 count = 1 /* 1st signature byte */ + name_len + name_len2;
2846 inc_rfc1001_len(pSMB, count);
2847 pSMB->ByteCount = cpu_to_le16(count);
2849 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2850 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2851 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2853 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2855 cifs_buf_release(pSMB);
2863 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2864 int netfid, const char *target_name,
2865 const struct nls_table *nls_codepage, int remap)
2867 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2868 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2869 struct set_file_rename *rename_info;
2871 char dummy_string[30];
2873 int bytes_returned = 0;
2875 __u16 params, param_offset, offset, count, byte_count;
2877 cifs_dbg(FYI, "Rename to File by handle\n");
2878 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2884 pSMB->MaxSetupCount = 0;
2888 pSMB->Reserved2 = 0;
2889 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2890 offset = param_offset + params;
2892 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2893 rename_info = (struct set_file_rename *) data_offset;
2894 pSMB->MaxParameterCount = cpu_to_le16(2);
2895 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2896 pSMB->SetupCount = 1;
2897 pSMB->Reserved3 = 0;
2898 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2899 byte_count = 3 /* pad */ + params;
2900 pSMB->ParameterCount = cpu_to_le16(params);
2901 pSMB->TotalParameterCount = pSMB->ParameterCount;
2902 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2903 pSMB->DataOffset = cpu_to_le16(offset);
2904 /* construct random name ".cifs_tmp<inodenum><mid>" */
2905 rename_info->overwrite = cpu_to_le32(1);
2906 rename_info->root_fid = 0;
2907 /* unicode only call */
2908 if (target_name == NULL) {
2909 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2911 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2912 dummy_string, 24, nls_codepage, remap);
2915 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2916 target_name, PATH_MAX, nls_codepage,
2919 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2920 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2921 byte_count += count;
2922 pSMB->DataCount = cpu_to_le16(count);
2923 pSMB->TotalDataCount = pSMB->DataCount;
2925 pSMB->InformationLevel =
2926 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2927 pSMB->Reserved4 = 0;
2928 inc_rfc1001_len(pSMB, byte_count);
2929 pSMB->ByteCount = cpu_to_le16(byte_count);
2930 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2931 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2932 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2934 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2937 cifs_buf_release(pSMB);
2939 /* Note: On -EAGAIN error only caller can retry on handle based calls
2940 since file handle passed in no longer valid */
2946 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2947 const char *fromName, const __u16 target_tid, const char *toName,
2948 const int flags, const struct nls_table *nls_codepage, int remap)
2951 COPY_REQ *pSMB = NULL;
2952 COPY_RSP *pSMBr = NULL;
2954 int name_len, name_len2;
2957 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2959 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2964 pSMB->BufferFormat = 0x04;
2965 pSMB->Tid2 = target_tid;
2967 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2969 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2970 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2971 fromName, PATH_MAX, nls_codepage,
2973 name_len++; /* trailing null */
2975 pSMB->OldFileName[name_len] = 0x04; /* pad */
2976 /* protocol requires ASCII signature byte on Unicode string */
2977 pSMB->OldFileName[name_len + 1] = 0x00;
2979 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2980 toName, PATH_MAX, nls_codepage, remap);
2981 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2982 name_len2 *= 2; /* convert to bytes */
2984 name_len = copy_path_name(pSMB->OldFileName, fromName);
2985 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2986 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2987 name_len2++; /* signature byte */
2990 count = 1 /* 1st signature byte */ + name_len + name_len2;
2991 inc_rfc1001_len(pSMB, count);
2992 pSMB->ByteCount = cpu_to_le16(count);
2994 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2995 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2997 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2998 rc, le16_to_cpu(pSMBr->CopyCount));
3000 cifs_buf_release(pSMB);
3009 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
3010 const char *fromName, const char *toName,
3011 const struct nls_table *nls_codepage, int remap)
3013 TRANSACTION2_SPI_REQ *pSMB = NULL;
3014 TRANSACTION2_SPI_RSP *pSMBr = NULL;
3017 int name_len_target;
3019 int bytes_returned = 0;
3020 __u16 params, param_offset, offset, byte_count;
3022 cifs_dbg(FYI, "In Symlink Unix style\n");
3024 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3029 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3031 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
3032 /* find define for this maxpathcomponent */
3033 PATH_MAX, nls_codepage, remap);
3034 name_len++; /* trailing null */
3038 name_len = copy_path_name(pSMB->FileName, fromName);
3040 params = 6 + name_len;
3041 pSMB->MaxSetupCount = 0;
3045 pSMB->Reserved2 = 0;
3046 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3047 InformationLevel) - 4;
3048 offset = param_offset + params;
3050 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
3051 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3053 cifsConvertToUTF16((__le16 *) data_offset, toName,
3054 /* find define for this maxpathcomponent */
3055 PATH_MAX, nls_codepage, remap);
3056 name_len_target++; /* trailing null */
3057 name_len_target *= 2;
3059 name_len_target = copy_path_name(data_offset, toName);
3062 pSMB->MaxParameterCount = cpu_to_le16(2);
3063 /* BB find exact max on data count below from sess */
3064 pSMB->MaxDataCount = cpu_to_le16(1000);
3065 pSMB->SetupCount = 1;
3066 pSMB->Reserved3 = 0;
3067 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3068 byte_count = 3 /* pad */ + params + name_len_target;
3069 pSMB->DataCount = cpu_to_le16(name_len_target);
3070 pSMB->ParameterCount = cpu_to_le16(params);
3071 pSMB->TotalDataCount = pSMB->DataCount;
3072 pSMB->TotalParameterCount = pSMB->ParameterCount;
3073 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3074 pSMB->DataOffset = cpu_to_le16(offset);
3075 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
3076 pSMB->Reserved4 = 0;
3077 inc_rfc1001_len(pSMB, byte_count);
3078 pSMB->ByteCount = cpu_to_le16(byte_count);
3079 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3080 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3081 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
3083 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
3086 cifs_buf_release(pSMB);
3089 goto createSymLinkRetry;
3095 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3096 const char *fromName, const char *toName,
3097 const struct nls_table *nls_codepage, int remap)
3099 TRANSACTION2_SPI_REQ *pSMB = NULL;
3100 TRANSACTION2_SPI_RSP *pSMBr = NULL;
3103 int name_len_target;
3105 int bytes_returned = 0;
3106 __u16 params, param_offset, offset, byte_count;
3108 cifs_dbg(FYI, "In Create Hard link Unix style\n");
3109 createHardLinkRetry:
3110 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3115 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3116 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
3117 PATH_MAX, nls_codepage, remap);
3118 name_len++; /* trailing null */
3122 name_len = copy_path_name(pSMB->FileName, toName);
3124 params = 6 + name_len;
3125 pSMB->MaxSetupCount = 0;
3129 pSMB->Reserved2 = 0;
3130 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3131 InformationLevel) - 4;
3132 offset = param_offset + params;
3134 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
3135 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3137 cifsConvertToUTF16((__le16 *) data_offset, fromName,
3138 PATH_MAX, nls_codepage, remap);
3139 name_len_target++; /* trailing null */
3140 name_len_target *= 2;
3142 name_len_target = copy_path_name(data_offset, fromName);
3145 pSMB->MaxParameterCount = cpu_to_le16(2);
3146 /* BB find exact max on data count below from sess*/
3147 pSMB->MaxDataCount = cpu_to_le16(1000);
3148 pSMB->SetupCount = 1;
3149 pSMB->Reserved3 = 0;
3150 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3151 byte_count = 3 /* pad */ + params + name_len_target;
3152 pSMB->ParameterCount = cpu_to_le16(params);
3153 pSMB->TotalParameterCount = pSMB->ParameterCount;
3154 pSMB->DataCount = cpu_to_le16(name_len_target);
3155 pSMB->TotalDataCount = pSMB->DataCount;
3156 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3157 pSMB->DataOffset = cpu_to_le16(offset);
3158 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3159 pSMB->Reserved4 = 0;
3160 inc_rfc1001_len(pSMB, byte_count);
3161 pSMB->ByteCount = cpu_to_le16(byte_count);
3162 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3163 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3164 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3166 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3169 cifs_buf_release(pSMB);
3171 goto createHardLinkRetry;
3177 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3178 const char *from_name, const char *to_name,
3179 struct cifs_sb_info *cifs_sb)
3182 NT_RENAME_REQ *pSMB = NULL;
3183 RENAME_RSP *pSMBr = NULL;
3185 int name_len, name_len2;
3187 int remap = cifs_remap(cifs_sb);
3189 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3190 winCreateHardLinkRetry:
3192 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3197 pSMB->SearchAttributes =
3198 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3200 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3201 pSMB->ClusterCount = 0;
3203 pSMB->BufferFormat = 0x04;
3205 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3207 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3208 PATH_MAX, cifs_sb->local_nls, remap);
3209 name_len++; /* trailing null */
3212 /* protocol specifies ASCII buffer format (0x04) for unicode */
3213 pSMB->OldFileName[name_len] = 0x04;
3214 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3216 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3217 to_name, PATH_MAX, cifs_sb->local_nls,
3219 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3220 name_len2 *= 2; /* convert to bytes */
3222 name_len = copy_path_name(pSMB->OldFileName, from_name);
3223 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3224 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
3225 name_len2++; /* signature byte */
3228 count = 1 /* string type byte */ + name_len + name_len2;
3229 inc_rfc1001_len(pSMB, count);
3230 pSMB->ByteCount = cpu_to_le16(count);
3232 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3233 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3234 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3236 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3238 cifs_buf_release(pSMB);
3240 goto winCreateHardLinkRetry;
3246 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3247 const unsigned char *searchName, char **symlinkinfo,
3248 const struct nls_table *nls_codepage, int remap)
3250 /* SMB_QUERY_FILE_UNIX_LINK */
3251 TRANSACTION2_QPI_REQ *pSMB = NULL;
3252 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3256 __u16 params, byte_count;
3259 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3262 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3267 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3269 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3270 searchName, PATH_MAX, nls_codepage,
3272 name_len++; /* trailing null */
3275 name_len = copy_path_name(pSMB->FileName, searchName);
3278 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3279 pSMB->TotalDataCount = 0;
3280 pSMB->MaxParameterCount = cpu_to_le16(2);
3281 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3282 pSMB->MaxSetupCount = 0;
3286 pSMB->Reserved2 = 0;
3287 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3288 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3289 pSMB->DataCount = 0;
3290 pSMB->DataOffset = 0;
3291 pSMB->SetupCount = 1;
3292 pSMB->Reserved3 = 0;
3293 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3294 byte_count = params + 1 /* pad */ ;
3295 pSMB->TotalParameterCount = cpu_to_le16(params);
3296 pSMB->ParameterCount = pSMB->TotalParameterCount;
3297 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3298 pSMB->Reserved4 = 0;
3299 inc_rfc1001_len(pSMB, byte_count);
3300 pSMB->ByteCount = cpu_to_le16(byte_count);
3302 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3303 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3305 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3307 /* decode response */
3309 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3310 /* BB also check enough total bytes returned */
3311 if (rc || get_bcc(&pSMBr->hdr) < 2)
3315 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3317 data_start = ((char *) &pSMBr->hdr.Protocol) +
3318 le16_to_cpu(pSMBr->t2.DataOffset);
3320 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3325 /* BB FIXME investigate remapping reserved chars here */
3326 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3327 count, is_unicode, nls_codepage);
3332 cifs_buf_release(pSMB);
3334 goto querySymLinkRetry;
3339 * Recent Windows versions now create symlinks more frequently
3340 * and they use the "reparse point" mechanism below. We can of course
3341 * do symlinks nicely to Samba and other servers which support the
3342 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3343 * "MF" symlinks optionally, but for recent Windows we really need to
3344 * reenable the code below and fix the cifs_symlink callers to handle this.
3345 * In the interim this code has been moved to its own config option so
3346 * it is not compiled in by default until callers fixed up and more tested.
3349 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3350 __u16 fid, char **symlinkinfo,
3351 const struct nls_table *nls_codepage)
3355 struct smb_com_transaction_ioctl_req *pSMB;
3356 struct smb_com_transaction_ioctl_rsp *pSMBr;
3358 unsigned int sub_len;
3360 struct reparse_symlink_data *reparse_buf;
3361 struct reparse_posix_data *posix_buf;
3362 __u32 data_offset, data_count;
3365 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3366 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3371 pSMB->TotalParameterCount = 0 ;
3372 pSMB->TotalDataCount = 0;
3373 pSMB->MaxParameterCount = cpu_to_le32(2);
3374 /* BB find exact data count max from sess structure BB */
3375 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3376 pSMB->MaxSetupCount = 4;
3378 pSMB->ParameterOffset = 0;
3379 pSMB->DataCount = 0;
3380 pSMB->DataOffset = 0;
3381 pSMB->SetupCount = 4;
3382 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3383 pSMB->ParameterCount = pSMB->TotalParameterCount;
3384 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3385 pSMB->IsFsctl = 1; /* FSCTL */
3386 pSMB->IsRootFlag = 0;
3387 pSMB->Fid = fid; /* file handle always le */
3388 pSMB->ByteCount = 0;
3390 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3391 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3393 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3397 data_offset = le32_to_cpu(pSMBr->DataOffset);
3398 data_count = le32_to_cpu(pSMBr->DataCount);
3399 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3400 /* BB also check enough total bytes returned */
3401 rc = -EIO; /* bad smb */
3404 if (!data_count || (data_count > 2048)) {
3406 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3409 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3410 reparse_buf = (struct reparse_symlink_data *)
3411 ((char *)&pSMBr->hdr.Protocol + data_offset);
3412 if ((char *)reparse_buf >= end_of_smb) {
3416 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3417 cifs_dbg(FYI, "NFS style reparse tag\n");
3418 posix_buf = (struct reparse_posix_data *)reparse_buf;
3420 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3421 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3422 le64_to_cpu(posix_buf->InodeType));
3427 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3428 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3429 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3433 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3434 sub_len, is_unicode, nls_codepage);
3436 } else if (reparse_buf->ReparseTag !=
3437 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3442 /* Reparse tag is NTFS symlink */
3443 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3444 reparse_buf->PathBuffer;
3445 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3446 if (sub_start + sub_len > end_of_smb) {
3447 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3451 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3456 /* BB FIXME investigate remapping reserved chars here */
3457 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3462 cifs_buf_release(pSMB);
3465 * Note: On -EAGAIN error only caller can retry on handle based calls
3466 * since file handle passed in no longer valid.
3472 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3477 struct smb_com_transaction_compr_ioctl_req *pSMB;
3478 struct smb_com_transaction_ioctl_rsp *pSMBr;
3480 cifs_dbg(FYI, "Set compression for %u\n", fid);
3481 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3486 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3488 pSMB->TotalParameterCount = 0;
3489 pSMB->TotalDataCount = cpu_to_le32(2);
3490 pSMB->MaxParameterCount = 0;
3491 pSMB->MaxDataCount = 0;
3492 pSMB->MaxSetupCount = 4;
3494 pSMB->ParameterOffset = 0;
3495 pSMB->DataCount = cpu_to_le32(2);
3497 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3498 compression_state) - 4); /* 84 */
3499 pSMB->SetupCount = 4;
3500 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3501 pSMB->ParameterCount = 0;
3502 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3503 pSMB->IsFsctl = 1; /* FSCTL */
3504 pSMB->IsRootFlag = 0;
3505 pSMB->Fid = fid; /* file handle always le */
3506 /* 3 byte pad, followed by 2 byte compress state */
3507 pSMB->ByteCount = cpu_to_le16(5);
3508 inc_rfc1001_len(pSMB, 5);
3510 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3511 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3513 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3515 cifs_buf_release(pSMB);
3518 * Note: On -EAGAIN error only caller can retry on handle based calls
3519 * since file handle passed in no longer valid.
3525 #ifdef CONFIG_CIFS_POSIX
3527 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3528 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3529 struct cifs_posix_ace *cifs_ace)
3531 /* u8 cifs fields do not need le conversion */
3532 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3533 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3534 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3536 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3537 ace->e_perm, ace->e_tag, ace->e_id);
3543 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3544 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3545 const int acl_type, const int size_of_data_area)
3550 struct cifs_posix_ace *pACE;
3551 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3552 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3554 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3557 if (acl_type == ACL_TYPE_ACCESS) {
3558 count = le16_to_cpu(cifs_acl->access_entry_count);
3559 pACE = &cifs_acl->ace_array[0];
3560 size = sizeof(struct cifs_posix_acl);
3561 size += sizeof(struct cifs_posix_ace) * count;
3562 /* check if we would go beyond end of SMB */
3563 if (size_of_data_area < size) {
3564 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3565 size_of_data_area, size);
3568 } else if (acl_type == ACL_TYPE_DEFAULT) {
3569 count = le16_to_cpu(cifs_acl->access_entry_count);
3570 size = sizeof(struct cifs_posix_acl);
3571 size += sizeof(struct cifs_posix_ace) * count;
3572 /* skip past access ACEs to get to default ACEs */
3573 pACE = &cifs_acl->ace_array[count];
3574 count = le16_to_cpu(cifs_acl->default_entry_count);
3575 size += sizeof(struct cifs_posix_ace) * count;
3576 /* check if we would go beyond end of SMB */
3577 if (size_of_data_area < size)
3584 size = posix_acl_xattr_size(count);
3585 if ((buflen == 0) || (local_acl == NULL)) {
3586 /* used to query ACL EA size */
3587 } else if (size > buflen) {
3589 } else /* buffer big enough */ {
3590 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3592 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3593 for (i = 0; i < count ; i++) {
3594 cifs_convert_ace(&ace[i], pACE);
3601 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3602 const struct posix_acl_xattr_entry *local_ace)
3604 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3605 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3606 /* BB is there a better way to handle the large uid? */
3607 if (local_ace->e_id == cpu_to_le32(-1)) {
3608 /* Probably no need to le convert -1 on any arch but can not hurt */
3609 cifs_ace->cifs_uid = cpu_to_le64(-1);
3611 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3613 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3614 ace->e_perm, ace->e_tag, ace->e_id);
3618 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3619 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3620 const int buflen, const int acl_type)
3623 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3624 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3625 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3629 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3632 count = posix_acl_xattr_count((size_t)buflen);
3633 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3634 count, buflen, le32_to_cpu(local_acl->a_version));
3635 if (le32_to_cpu(local_acl->a_version) != 2) {
3636 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3637 le32_to_cpu(local_acl->a_version));
3640 cifs_acl->version = cpu_to_le16(1);
3641 if (acl_type == ACL_TYPE_ACCESS) {
3642 cifs_acl->access_entry_count = cpu_to_le16(count);
3643 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3644 } else if (acl_type == ACL_TYPE_DEFAULT) {
3645 cifs_acl->default_entry_count = cpu_to_le16(count);
3646 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3648 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3651 for (i = 0; i < count; i++)
3652 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3654 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3655 rc += sizeof(struct cifs_posix_acl);
3656 /* BB add check to make sure ACL does not overflow SMB */
3662 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3663 const unsigned char *searchName,
3664 char *acl_inf, const int buflen, const int acl_type,
3665 const struct nls_table *nls_codepage, int remap)
3667 /* SMB_QUERY_POSIX_ACL */
3668 TRANSACTION2_QPI_REQ *pSMB = NULL;
3669 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3673 __u16 params, byte_count;
3675 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3678 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3683 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3685 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3686 searchName, PATH_MAX, nls_codepage,
3688 name_len++; /* trailing null */
3690 pSMB->FileName[name_len] = 0;
3691 pSMB->FileName[name_len+1] = 0;
3693 name_len = copy_path_name(pSMB->FileName, searchName);
3696 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3697 pSMB->TotalDataCount = 0;
3698 pSMB->MaxParameterCount = cpu_to_le16(2);
3699 /* BB find exact max data count below from sess structure BB */
3700 pSMB->MaxDataCount = cpu_to_le16(4000);
3701 pSMB->MaxSetupCount = 0;
3705 pSMB->Reserved2 = 0;
3706 pSMB->ParameterOffset = cpu_to_le16(
3707 offsetof(struct smb_com_transaction2_qpi_req,
3708 InformationLevel) - 4);
3709 pSMB->DataCount = 0;
3710 pSMB->DataOffset = 0;
3711 pSMB->SetupCount = 1;
3712 pSMB->Reserved3 = 0;
3713 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3714 byte_count = params + 1 /* pad */ ;
3715 pSMB->TotalParameterCount = cpu_to_le16(params);
3716 pSMB->ParameterCount = pSMB->TotalParameterCount;
3717 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3718 pSMB->Reserved4 = 0;
3719 inc_rfc1001_len(pSMB, byte_count);
3720 pSMB->ByteCount = cpu_to_le16(byte_count);
3722 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3723 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3724 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3726 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3728 /* decode response */
3730 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3731 /* BB also check enough total bytes returned */
3732 if (rc || get_bcc(&pSMBr->hdr) < 2)
3733 rc = -EIO; /* bad smb */
3735 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3736 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3737 rc = cifs_copy_posix_acl(acl_inf,
3738 (char *)&pSMBr->hdr.Protocol+data_offset,
3739 buflen, acl_type, count);
3742 cifs_buf_release(pSMB);
3749 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3750 const unsigned char *fileName,
3751 const char *local_acl, const int buflen,
3753 const struct nls_table *nls_codepage, int remap)
3755 struct smb_com_transaction2_spi_req *pSMB = NULL;
3756 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3760 int bytes_returned = 0;
3761 __u16 params, byte_count, data_count, param_offset, offset;
3763 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3765 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3769 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3771 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3772 PATH_MAX, nls_codepage, remap);
3773 name_len++; /* trailing null */
3776 name_len = copy_path_name(pSMB->FileName, fileName);
3778 params = 6 + name_len;
3779 pSMB->MaxParameterCount = cpu_to_le16(2);
3780 /* BB find max SMB size from sess */
3781 pSMB->MaxDataCount = cpu_to_le16(1000);
3782 pSMB->MaxSetupCount = 0;
3786 pSMB->Reserved2 = 0;
3787 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3788 InformationLevel) - 4;
3789 offset = param_offset + params;
3790 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3791 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3793 /* convert to on the wire format for POSIX ACL */
3794 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3796 if (data_count == 0) {
3798 goto setACLerrorExit;
3800 pSMB->DataOffset = cpu_to_le16(offset);
3801 pSMB->SetupCount = 1;
3802 pSMB->Reserved3 = 0;
3803 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3804 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3805 byte_count = 3 /* pad */ + params + data_count;
3806 pSMB->DataCount = cpu_to_le16(data_count);
3807 pSMB->TotalDataCount = pSMB->DataCount;
3808 pSMB->ParameterCount = cpu_to_le16(params);
3809 pSMB->TotalParameterCount = pSMB->ParameterCount;
3810 pSMB->Reserved4 = 0;
3811 inc_rfc1001_len(pSMB, byte_count);
3812 pSMB->ByteCount = cpu_to_le16(byte_count);
3813 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3814 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3816 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3819 cifs_buf_release(pSMB);
3825 /* BB fix tabs in this function FIXME BB */
3827 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3828 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3831 struct smb_t2_qfi_req *pSMB = NULL;
3832 struct smb_t2_qfi_rsp *pSMBr = NULL;
3834 __u16 params, byte_count;
3836 cifs_dbg(FYI, "In GetExtAttr\n");
3841 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3846 params = 2 /* level */ + 2 /* fid */;
3847 pSMB->t2.TotalDataCount = 0;
3848 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3849 /* BB find exact max data count below from sess structure BB */
3850 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3851 pSMB->t2.MaxSetupCount = 0;
3852 pSMB->t2.Reserved = 0;
3854 pSMB->t2.Timeout = 0;
3855 pSMB->t2.Reserved2 = 0;
3856 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3858 pSMB->t2.DataCount = 0;
3859 pSMB->t2.DataOffset = 0;
3860 pSMB->t2.SetupCount = 1;
3861 pSMB->t2.Reserved3 = 0;
3862 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3863 byte_count = params + 1 /* pad */ ;
3864 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3865 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3866 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3869 inc_rfc1001_len(pSMB, byte_count);
3870 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3872 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3873 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3875 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3877 /* decode response */
3878 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3879 /* BB also check enough total bytes returned */
3880 if (rc || get_bcc(&pSMBr->hdr) < 2)
3881 /* If rc should we check for EOPNOSUPP and
3882 disable the srvino flag? or in caller? */
3883 rc = -EIO; /* bad smb */
3885 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3886 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3887 struct file_chattr_info *pfinfo;
3888 /* BB Do we need a cast or hash here ? */
3890 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3894 pfinfo = (struct file_chattr_info *)
3895 (data_offset + (char *) &pSMBr->hdr.Protocol);
3896 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3897 *pMask = le64_to_cpu(pfinfo->mask);
3901 cifs_buf_release(pSMB);
3903 goto GetExtAttrRetry;
3907 #endif /* CONFIG_POSIX */
3910 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3911 * all NT TRANSACTS that we init here have total parm and data under about 400
3912 * bytes (to fit in small cifs buffer size), which is the case so far, it
3913 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3914 * returned setup area) and MaxParameterCount (returned parms size) must be set
3918 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3919 const int parm_len, struct cifs_tcon *tcon,
3924 struct smb_com_ntransact_req *pSMB;
3926 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3930 *ret_buf = (void *)pSMB;
3932 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3933 pSMB->TotalDataCount = 0;
3934 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3935 pSMB->ParameterCount = pSMB->TotalParameterCount;
3936 pSMB->DataCount = pSMB->TotalDataCount;
3937 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3938 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3939 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3940 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3941 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3942 pSMB->SubCommand = cpu_to_le16(sub_command);
3947 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3948 __u32 *pparmlen, __u32 *pdatalen)
3951 __u32 data_count, data_offset, parm_count, parm_offset;
3952 struct smb_com_ntransact_rsp *pSMBr;
3961 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3963 bcc = get_bcc(&pSMBr->hdr);
3964 end_of_smb = 2 /* sizeof byte count */ + bcc +
3965 (char *)&pSMBr->ByteCount;
3967 data_offset = le32_to_cpu(pSMBr->DataOffset);
3968 data_count = le32_to_cpu(pSMBr->DataCount);
3969 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3970 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3972 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3973 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3975 /* should we also check that parm and data areas do not overlap? */
3976 if (*ppparm > end_of_smb) {
3977 cifs_dbg(FYI, "parms start after end of smb\n");
3979 } else if (parm_count + *ppparm > end_of_smb) {
3980 cifs_dbg(FYI, "parm end after end of smb\n");
3982 } else if (*ppdata > end_of_smb) {
3983 cifs_dbg(FYI, "data starts after end of smb\n");
3985 } else if (data_count + *ppdata > end_of_smb) {
3986 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3987 *ppdata, data_count, (data_count + *ppdata),
3990 } else if (parm_count + data_count > bcc) {
3991 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3994 *pdatalen = data_count;
3995 *pparmlen = parm_count;
3999 /* Get Security Descriptor (by handle) from remote server for a file or dir */
4001 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
4002 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
4006 QUERY_SEC_DESC_REQ *pSMB;
4008 struct kvec rsp_iov;
4010 cifs_dbg(FYI, "GetCifsACL\n");
4015 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
4016 8 /* parm len */, tcon, (void **) &pSMB);
4020 pSMB->MaxParameterCount = cpu_to_le32(4);
4021 /* BB TEST with big acls that might need to be e.g. larger than 16K */
4022 pSMB->MaxSetupCount = 0;
4023 pSMB->Fid = fid; /* file handle always le */
4024 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
4026 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
4027 inc_rfc1001_len(pSMB, 11);
4028 iov[0].iov_base = (char *)pSMB;
4029 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
4031 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
4033 cifs_small_buf_release(pSMB);
4034 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
4036 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
4037 } else { /* decode response */
4041 struct smb_com_ntransact_rsp *pSMBr;
4044 /* validate_nttransact */
4045 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
4046 &pdata, &parm_len, pbuflen);
4049 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
4051 cifs_dbg(FYI, "smb %p parm %p data %p\n",
4052 pSMBr, parm, *acl_inf);
4054 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
4055 rc = -EIO; /* bad smb */
4060 /* BB check that data area is minimum length and as big as acl_len */
4062 acl_len = le32_to_cpu(*parm);
4063 if (acl_len != *pbuflen) {
4064 cifs_dbg(VFS, "acl length %d does not match %d\n",
4066 if (*pbuflen > acl_len)
4070 /* check if buffer is big enough for the acl
4071 header followed by the smallest SID */
4072 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
4073 (*pbuflen >= 64 * 1024)) {
4074 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
4078 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
4079 if (*acl_inf == NULL) {
4086 free_rsp_buf(buf_type, rsp_iov.iov_base);
4091 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
4092 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
4094 __u16 byte_count, param_count, data_count, param_offset, data_offset;
4096 int bytes_returned = 0;
4097 SET_SEC_DESC_REQ *pSMB = NULL;
4101 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
4105 pSMB->MaxSetupCount = 0;
4109 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
4110 data_count = acllen;
4111 data_offset = param_offset + param_count;
4112 byte_count = 3 /* pad */ + param_count;
4114 pSMB->DataCount = cpu_to_le32(data_count);
4115 pSMB->TotalDataCount = pSMB->DataCount;
4116 pSMB->MaxParameterCount = cpu_to_le32(4);
4117 pSMB->MaxDataCount = cpu_to_le32(16384);
4118 pSMB->ParameterCount = cpu_to_le32(param_count);
4119 pSMB->ParameterOffset = cpu_to_le32(param_offset);
4120 pSMB->TotalParameterCount = pSMB->ParameterCount;
4121 pSMB->DataOffset = cpu_to_le32(data_offset);
4122 pSMB->SetupCount = 0;
4123 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
4124 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
4126 pSMB->Fid = fid; /* file handle always le */
4127 pSMB->Reserved2 = 0;
4128 pSMB->AclFlags = cpu_to_le32(aclflag);
4130 if (pntsd && acllen) {
4131 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
4132 data_offset, pntsd, acllen);
4133 inc_rfc1001_len(pSMB, byte_count + data_count);
4135 inc_rfc1001_len(pSMB, byte_count);
4137 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4138 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4140 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4141 bytes_returned, rc);
4143 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
4144 cifs_buf_release(pSMB);
4147 goto setCifsAclRetry;
4153 /* Legacy Query Path Information call for lookup to old servers such
4156 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
4157 const char *search_name, FILE_ALL_INFO *data,
4158 const struct nls_table *nls_codepage, int remap)
4160 QUERY_INFORMATION_REQ *pSMB;
4161 QUERY_INFORMATION_RSP *pSMBr;
4166 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4168 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4173 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4175 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4176 search_name, PATH_MAX, nls_codepage,
4178 name_len++; /* trailing null */
4181 name_len = copy_path_name(pSMB->FileName, search_name);
4183 pSMB->BufferFormat = 0x04;
4184 name_len++; /* account for buffer type byte */
4185 inc_rfc1001_len(pSMB, (__u16)name_len);
4186 pSMB->ByteCount = cpu_to_le16(name_len);
4188 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4189 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4191 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4193 struct timespec64 ts;
4194 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4196 /* decode response */
4197 /* BB FIXME - add time zone adjustment BB */
4198 memset(data, 0, sizeof(FILE_ALL_INFO));
4201 /* decode time fields */
4202 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4203 data->LastWriteTime = data->ChangeTime;
4204 data->LastAccessTime = 0;
4205 data->AllocationSize =
4206 cpu_to_le64(le32_to_cpu(pSMBr->size));
4207 data->EndOfFile = data->AllocationSize;
4209 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4211 rc = -EIO; /* bad buffer passed in */
4213 cifs_buf_release(pSMB);
4222 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4223 u16 netfid, FILE_ALL_INFO *pFindData)
4225 struct smb_t2_qfi_req *pSMB = NULL;
4226 struct smb_t2_qfi_rsp *pSMBr = NULL;
4229 __u16 params, byte_count;
4232 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4237 params = 2 /* level */ + 2 /* fid */;
4238 pSMB->t2.TotalDataCount = 0;
4239 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4240 /* BB find exact max data count below from sess structure BB */
4241 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4242 pSMB->t2.MaxSetupCount = 0;
4243 pSMB->t2.Reserved = 0;
4245 pSMB->t2.Timeout = 0;
4246 pSMB->t2.Reserved2 = 0;
4247 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4249 pSMB->t2.DataCount = 0;
4250 pSMB->t2.DataOffset = 0;
4251 pSMB->t2.SetupCount = 1;
4252 pSMB->t2.Reserved3 = 0;
4253 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4254 byte_count = params + 1 /* pad */ ;
4255 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4256 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4257 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4260 inc_rfc1001_len(pSMB, byte_count);
4261 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4263 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4264 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4266 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
4267 } else { /* decode response */
4268 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4270 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4272 else if (get_bcc(&pSMBr->hdr) < 40)
4273 rc = -EIO; /* bad smb */
4274 else if (pFindData) {
4275 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4276 memcpy((char *) pFindData,
4277 (char *) &pSMBr->hdr.Protocol +
4278 data_offset, sizeof(FILE_ALL_INFO));
4282 cifs_buf_release(pSMB);
4284 goto QFileInfoRetry;
4290 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4291 const char *search_name, FILE_ALL_INFO *data,
4292 int legacy /* old style infolevel */,
4293 const struct nls_table *nls_codepage, int remap)
4295 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4296 TRANSACTION2_QPI_REQ *pSMB = NULL;
4297 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4301 __u16 params, byte_count;
4303 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4305 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4310 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4312 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4313 PATH_MAX, nls_codepage, remap);
4314 name_len++; /* trailing null */
4317 name_len = copy_path_name(pSMB->FileName, search_name);
4320 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4321 pSMB->TotalDataCount = 0;
4322 pSMB->MaxParameterCount = cpu_to_le16(2);
4323 /* BB find exact max SMB PDU from sess structure BB */
4324 pSMB->MaxDataCount = cpu_to_le16(4000);
4325 pSMB->MaxSetupCount = 0;
4329 pSMB->Reserved2 = 0;
4330 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4331 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4332 pSMB->DataCount = 0;
4333 pSMB->DataOffset = 0;
4334 pSMB->SetupCount = 1;
4335 pSMB->Reserved3 = 0;
4336 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4337 byte_count = params + 1 /* pad */ ;
4338 pSMB->TotalParameterCount = cpu_to_le16(params);
4339 pSMB->ParameterCount = pSMB->TotalParameterCount;
4341 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4343 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4344 pSMB->Reserved4 = 0;
4345 inc_rfc1001_len(pSMB, byte_count);
4346 pSMB->ByteCount = cpu_to_le16(byte_count);
4348 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4349 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4351 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4352 } else { /* decode response */
4353 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4355 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4357 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4358 rc = -EIO; /* bad smb */
4359 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4360 rc = -EIO; /* 24 or 26 expected but we do not read
4364 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4367 * On legacy responses we do not read the last field,
4368 * EAsize, fortunately since it varies by subdialect and
4369 * also note it differs on Set vs Get, ie two bytes or 4
4370 * bytes depending but we don't care here.
4373 size = sizeof(FILE_INFO_STANDARD);
4375 size = sizeof(FILE_ALL_INFO);
4376 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4381 cifs_buf_release(pSMB);
4383 goto QPathInfoRetry;
4389 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4390 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4392 struct smb_t2_qfi_req *pSMB = NULL;
4393 struct smb_t2_qfi_rsp *pSMBr = NULL;
4396 __u16 params, byte_count;
4399 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4404 params = 2 /* level */ + 2 /* fid */;
4405 pSMB->t2.TotalDataCount = 0;
4406 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4407 /* BB find exact max data count below from sess structure BB */
4408 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4409 pSMB->t2.MaxSetupCount = 0;
4410 pSMB->t2.Reserved = 0;
4412 pSMB->t2.Timeout = 0;
4413 pSMB->t2.Reserved2 = 0;
4414 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4416 pSMB->t2.DataCount = 0;
4417 pSMB->t2.DataOffset = 0;
4418 pSMB->t2.SetupCount = 1;
4419 pSMB->t2.Reserved3 = 0;
4420 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4421 byte_count = params + 1 /* pad */ ;
4422 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4423 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4424 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4427 inc_rfc1001_len(pSMB, byte_count);
4428 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4430 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4431 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4433 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
4434 } else { /* decode response */
4435 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4437 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4438 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4439 rc = -EIO; /* bad smb */
4441 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4442 memcpy((char *) pFindData,
4443 (char *) &pSMBr->hdr.Protocol +
4445 sizeof(FILE_UNIX_BASIC_INFO));
4449 cifs_buf_release(pSMB);
4451 goto UnixQFileInfoRetry;
4457 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4458 const unsigned char *searchName,
4459 FILE_UNIX_BASIC_INFO *pFindData,
4460 const struct nls_table *nls_codepage, int remap)
4462 /* SMB_QUERY_FILE_UNIX_BASIC */
4463 TRANSACTION2_QPI_REQ *pSMB = NULL;
4464 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4466 int bytes_returned = 0;
4468 __u16 params, byte_count;
4470 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4472 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4477 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4479 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4480 PATH_MAX, nls_codepage, remap);
4481 name_len++; /* trailing null */
4484 name_len = copy_path_name(pSMB->FileName, searchName);
4487 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4488 pSMB->TotalDataCount = 0;
4489 pSMB->MaxParameterCount = cpu_to_le16(2);
4490 /* BB find exact max SMB PDU from sess structure BB */
4491 pSMB->MaxDataCount = cpu_to_le16(4000);
4492 pSMB->MaxSetupCount = 0;
4496 pSMB->Reserved2 = 0;
4497 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4498 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4499 pSMB->DataCount = 0;
4500 pSMB->DataOffset = 0;
4501 pSMB->SetupCount = 1;
4502 pSMB->Reserved3 = 0;
4503 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4504 byte_count = params + 1 /* pad */ ;
4505 pSMB->TotalParameterCount = cpu_to_le16(params);
4506 pSMB->ParameterCount = pSMB->TotalParameterCount;
4507 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4508 pSMB->Reserved4 = 0;
4509 inc_rfc1001_len(pSMB, byte_count);
4510 pSMB->ByteCount = cpu_to_le16(byte_count);
4512 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4513 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4515 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
4516 } else { /* decode response */
4517 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4519 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4520 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4521 rc = -EIO; /* bad smb */
4523 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4524 memcpy((char *) pFindData,
4525 (char *) &pSMBr->hdr.Protocol +
4527 sizeof(FILE_UNIX_BASIC_INFO));
4530 cifs_buf_release(pSMB);
4532 goto UnixQPathInfoRetry;
4537 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4539 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4540 const char *searchName, struct cifs_sb_info *cifs_sb,
4541 __u16 *pnetfid, __u16 search_flags,
4542 struct cifs_search_info *psrch_inf, bool msearch)
4544 /* level 257 SMB_ */
4545 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4546 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4547 T2_FFIRST_RSP_PARMS *parms;
4549 int bytes_returned = 0;
4550 int name_len, remap;
4551 __u16 params, byte_count;
4552 struct nls_table *nls_codepage;
4554 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4557 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4562 nls_codepage = cifs_sb->local_nls;
4563 remap = cifs_remap(cifs_sb);
4565 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4567 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4568 PATH_MAX, nls_codepage, remap);
4569 /* We can not add the asterik earlier in case
4570 it got remapped to 0xF03A as if it were part of the
4571 directory name instead of a wildcard */
4574 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4575 pSMB->FileName[name_len+1] = 0;
4576 pSMB->FileName[name_len+2] = '*';
4577 pSMB->FileName[name_len+3] = 0;
4578 name_len += 4; /* now the trailing null */
4579 /* null terminate just in case */
4580 pSMB->FileName[name_len] = 0;
4581 pSMB->FileName[name_len+1] = 0;
4585 name_len = copy_path_name(pSMB->FileName, searchName);
4587 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4588 name_len = PATH_MAX-2;
4589 /* overwrite nul byte */
4590 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4591 pSMB->FileName[name_len] = '*';
4592 pSMB->FileName[name_len+1] = 0;
4597 params = 12 + name_len /* includes null */ ;
4598 pSMB->TotalDataCount = 0; /* no EAs */
4599 pSMB->MaxParameterCount = cpu_to_le16(10);
4600 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4601 pSMB->MaxSetupCount = 0;
4605 pSMB->Reserved2 = 0;
4606 byte_count = params + 1 /* pad */ ;
4607 pSMB->TotalParameterCount = cpu_to_le16(params);
4608 pSMB->ParameterCount = pSMB->TotalParameterCount;
4609 pSMB->ParameterOffset = cpu_to_le16(
4610 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4612 pSMB->DataCount = 0;
4613 pSMB->DataOffset = 0;
4614 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4615 pSMB->Reserved3 = 0;
4616 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4617 pSMB->SearchAttributes =
4618 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4620 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4621 pSMB->SearchFlags = cpu_to_le16(search_flags);
4622 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4624 /* BB what should we set StorageType to? Does it matter? BB */
4625 pSMB->SearchStorageType = 0;
4626 inc_rfc1001_len(pSMB, byte_count);
4627 pSMB->ByteCount = cpu_to_le16(byte_count);
4629 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4630 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4631 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4633 if (rc) {/* BB add logic to retry regular search if Unix search
4634 rejected unexpectedly by server */
4635 /* BB Add code to handle unsupported level rc */
4636 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4638 cifs_buf_release(pSMB);
4640 /* BB eventually could optimize out free and realloc of buf */
4643 goto findFirstRetry;
4644 } else { /* decode response */
4645 /* BB remember to free buffer if error BB */
4646 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4650 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4651 psrch_inf->unicode = true;
4653 psrch_inf->unicode = false;
4655 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4656 psrch_inf->smallBuf = false;
4657 psrch_inf->srch_entries_start =
4658 (char *) &pSMBr->hdr.Protocol +
4659 le16_to_cpu(pSMBr->t2.DataOffset);
4660 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4661 le16_to_cpu(pSMBr->t2.ParameterOffset));
4663 if (parms->EndofSearch)
4664 psrch_inf->endOfSearch = true;
4666 psrch_inf->endOfSearch = false;
4668 psrch_inf->entries_in_buffer =
4669 le16_to_cpu(parms->SearchCount);
4670 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4671 psrch_inf->entries_in_buffer;
4672 lnoff = le16_to_cpu(parms->LastNameOffset);
4673 if (CIFSMaxBufSize < lnoff) {
4674 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4675 psrch_inf->last_entry = NULL;
4679 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4683 *pnetfid = parms->SearchHandle;
4685 cifs_buf_release(pSMB);
4692 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4693 __u16 searchHandle, __u16 search_flags,
4694 struct cifs_search_info *psrch_inf)
4696 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4697 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4698 T2_FNEXT_RSP_PARMS *parms;
4699 char *response_data;
4702 unsigned int name_len;
4703 __u16 params, byte_count;
4705 cifs_dbg(FYI, "In FindNext\n");
4707 if (psrch_inf->endOfSearch)
4710 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4715 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4717 pSMB->TotalDataCount = 0; /* no EAs */
4718 pSMB->MaxParameterCount = cpu_to_le16(8);
4719 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4720 pSMB->MaxSetupCount = 0;
4724 pSMB->Reserved2 = 0;
4725 pSMB->ParameterOffset = cpu_to_le16(
4726 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4727 pSMB->DataCount = 0;
4728 pSMB->DataOffset = 0;
4729 pSMB->SetupCount = 1;
4730 pSMB->Reserved3 = 0;
4731 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4732 pSMB->SearchHandle = searchHandle; /* always kept as le */
4734 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4735 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4736 pSMB->ResumeKey = psrch_inf->resume_key;
4737 pSMB->SearchFlags = cpu_to_le16(search_flags);
4739 name_len = psrch_inf->resume_name_len;
4741 if (name_len < PATH_MAX) {
4742 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4743 byte_count += name_len;
4744 /* 14 byte parm len above enough for 2 byte null terminator */
4745 pSMB->ResumeFileName[name_len] = 0;
4746 pSMB->ResumeFileName[name_len+1] = 0;
4749 goto FNext2_err_exit;
4751 byte_count = params + 1 /* pad */ ;
4752 pSMB->TotalParameterCount = cpu_to_le16(params);
4753 pSMB->ParameterCount = pSMB->TotalParameterCount;
4754 inc_rfc1001_len(pSMB, byte_count);
4755 pSMB->ByteCount = cpu_to_le16(byte_count);
4757 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4758 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4759 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4762 psrch_inf->endOfSearch = true;
4763 cifs_buf_release(pSMB);
4764 rc = 0; /* search probably was closed at end of search*/
4766 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4767 } else { /* decode response */
4768 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4773 /* BB fixme add lock for file (srch_info) struct here */
4774 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4775 psrch_inf->unicode = true;
4777 psrch_inf->unicode = false;
4778 response_data = (char *) &pSMBr->hdr.Protocol +
4779 le16_to_cpu(pSMBr->t2.ParameterOffset);
4780 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4781 response_data = (char *)&pSMBr->hdr.Protocol +
4782 le16_to_cpu(pSMBr->t2.DataOffset);
4783 if (psrch_inf->smallBuf)
4784 cifs_small_buf_release(
4785 psrch_inf->ntwrk_buf_start);
4787 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4788 psrch_inf->srch_entries_start = response_data;
4789 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4790 psrch_inf->smallBuf = false;
4791 if (parms->EndofSearch)
4792 psrch_inf->endOfSearch = true;
4794 psrch_inf->endOfSearch = false;
4795 psrch_inf->entries_in_buffer =
4796 le16_to_cpu(parms->SearchCount);
4797 psrch_inf->index_of_last_entry +=
4798 psrch_inf->entries_in_buffer;
4799 lnoff = le16_to_cpu(parms->LastNameOffset);
4800 if (CIFSMaxBufSize < lnoff) {
4801 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4802 psrch_inf->last_entry = NULL;
4805 psrch_inf->last_entry =
4806 psrch_inf->srch_entries_start + lnoff;
4808 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4809 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4811 /* BB fixme add unlock here */
4816 /* BB On error, should we leave previous search buf (and count and
4817 last entry fields) intact or free the previous one? */
4819 /* Note: On -EAGAIN error only caller can retry on handle based calls
4820 since file handle passed in no longer valid */
4823 cifs_buf_release(pSMB);
4828 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4829 const __u16 searchHandle)
4832 FINDCLOSE_REQ *pSMB = NULL;
4834 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4835 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4837 /* no sense returning error if session restarted
4838 as file handle has been closed */
4844 pSMB->FileID = searchHandle;
4845 pSMB->ByteCount = 0;
4846 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4847 cifs_small_buf_release(pSMB);
4849 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4851 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4853 /* Since session is dead, search handle closed on server already */
4861 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4862 const char *search_name, __u64 *inode_number,
4863 const struct nls_table *nls_codepage, int remap)
4866 TRANSACTION2_QPI_REQ *pSMB = NULL;
4867 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4868 int name_len, bytes_returned;
4869 __u16 params, byte_count;
4871 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4875 GetInodeNumberRetry:
4876 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4881 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4883 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4884 search_name, PATH_MAX, nls_codepage,
4886 name_len++; /* trailing null */
4889 name_len = copy_path_name(pSMB->FileName, search_name);
4892 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4893 pSMB->TotalDataCount = 0;
4894 pSMB->MaxParameterCount = cpu_to_le16(2);
4895 /* BB find exact max data count below from sess structure BB */
4896 pSMB->MaxDataCount = cpu_to_le16(4000);
4897 pSMB->MaxSetupCount = 0;
4901 pSMB->Reserved2 = 0;
4902 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4903 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4904 pSMB->DataCount = 0;
4905 pSMB->DataOffset = 0;
4906 pSMB->SetupCount = 1;
4907 pSMB->Reserved3 = 0;
4908 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4909 byte_count = params + 1 /* pad */ ;
4910 pSMB->TotalParameterCount = cpu_to_le16(params);
4911 pSMB->ParameterCount = pSMB->TotalParameterCount;
4912 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4913 pSMB->Reserved4 = 0;
4914 inc_rfc1001_len(pSMB, byte_count);
4915 pSMB->ByteCount = cpu_to_le16(byte_count);
4917 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4918 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4920 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4922 /* decode response */
4923 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4924 /* BB also check enough total bytes returned */
4925 if (rc || get_bcc(&pSMBr->hdr) < 2)
4926 /* If rc should we check for EOPNOSUPP and
4927 disable the srvino flag? or in caller? */
4928 rc = -EIO; /* bad smb */
4930 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4931 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4932 struct file_internal_info *pfinfo;
4933 /* BB Do we need a cast or hash here ? */
4935 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4937 goto GetInodeNumOut;
4939 pfinfo = (struct file_internal_info *)
4940 (data_offset + (char *) &pSMBr->hdr.Protocol);
4941 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4945 cifs_buf_release(pSMB);
4947 goto GetInodeNumberRetry;
4952 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4953 const char *search_name, struct dfs_info3_param **target_nodes,
4954 unsigned int *num_of_nodes,
4955 const struct nls_table *nls_codepage, int remap)
4957 /* TRANS2_GET_DFS_REFERRAL */
4958 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4959 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4963 __u16 params, byte_count;
4965 *target_nodes = NULL;
4967 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4968 if (ses == NULL || ses->tcon_ipc == NULL)
4972 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4977 /* server pointer checked in called function,
4978 but should never be null here anyway */
4979 pSMB->hdr.Mid = get_next_mid(ses->server);
4980 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4981 pSMB->hdr.Uid = ses->Suid;
4982 if (ses->capabilities & CAP_STATUS32)
4983 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4984 if (ses->capabilities & CAP_DFS)
4985 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4987 if (ses->capabilities & CAP_UNICODE) {
4988 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4990 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4991 search_name, PATH_MAX, nls_codepage,
4993 name_len++; /* trailing null */
4995 } else { /* BB improve the check for buffer overruns BB */
4996 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4999 if (ses->server->sign)
5000 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
5002 pSMB->hdr.Uid = ses->Suid;
5004 params = 2 /* level */ + name_len /*includes null */ ;
5005 pSMB->TotalDataCount = 0;
5006 pSMB->DataCount = 0;
5007 pSMB->DataOffset = 0;
5008 pSMB->MaxParameterCount = 0;
5009 /* BB find exact max SMB PDU from sess structure BB */
5010 pSMB->MaxDataCount = cpu_to_le16(4000);
5011 pSMB->MaxSetupCount = 0;
5015 pSMB->Reserved2 = 0;
5016 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5017 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
5018 pSMB->SetupCount = 1;
5019 pSMB->Reserved3 = 0;
5020 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
5021 byte_count = params + 3 /* pad */ ;
5022 pSMB->ParameterCount = cpu_to_le16(params);
5023 pSMB->TotalParameterCount = pSMB->ParameterCount;
5024 pSMB->MaxReferralLevel = cpu_to_le16(3);
5025 inc_rfc1001_len(pSMB, byte_count);
5026 pSMB->ByteCount = cpu_to_le16(byte_count);
5028 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
5029 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5031 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
5034 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5036 /* BB Also check if enough total bytes returned? */
5037 if (rc || get_bcc(&pSMBr->hdr) < 17) {
5038 rc = -EIO; /* bad smb */
5042 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
5043 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
5045 /* parse returned result into more usable form */
5046 rc = parse_dfs_referrals(&pSMBr->dfs_data,
5047 le16_to_cpu(pSMBr->t2.DataCount),
5048 num_of_nodes, target_nodes, nls_codepage,
5050 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
5053 cifs_buf_release(pSMB);
5061 /* Query File System Info such as free space to old servers such as Win 9x */
5063 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
5064 struct kstatfs *FSData)
5066 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
5067 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5068 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5069 FILE_SYSTEM_ALLOC_INFO *response_data;
5071 int bytes_returned = 0;
5072 __u16 params, byte_count;
5074 cifs_dbg(FYI, "OldQFSInfo\n");
5076 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5081 params = 2; /* level */
5082 pSMB->TotalDataCount = 0;
5083 pSMB->MaxParameterCount = cpu_to_le16(2);
5084 pSMB->MaxDataCount = cpu_to_le16(1000);
5085 pSMB->MaxSetupCount = 0;
5089 pSMB->Reserved2 = 0;
5090 byte_count = params + 1 /* pad */ ;
5091 pSMB->TotalParameterCount = cpu_to_le16(params);
5092 pSMB->ParameterCount = pSMB->TotalParameterCount;
5093 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5094 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5095 pSMB->DataCount = 0;
5096 pSMB->DataOffset = 0;
5097 pSMB->SetupCount = 1;
5098 pSMB->Reserved3 = 0;
5099 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5100 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
5101 inc_rfc1001_len(pSMB, byte_count);
5102 pSMB->ByteCount = cpu_to_le16(byte_count);
5104 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5105 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5107 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5108 } else { /* decode response */
5109 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5111 if (rc || get_bcc(&pSMBr->hdr) < 18)
5112 rc = -EIO; /* bad smb */
5114 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5115 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
5116 get_bcc(&pSMBr->hdr), data_offset);
5118 response_data = (FILE_SYSTEM_ALLOC_INFO *)
5119 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5121 le16_to_cpu(response_data->BytesPerSector) *
5122 le32_to_cpu(response_data->
5123 SectorsPerAllocationUnit);
5125 * much prefer larger but if server doesn't report
5126 * a valid size than 4K is a reasonable minimum
5128 if (FSData->f_bsize < 512)
5129 FSData->f_bsize = 4096;
5132 le32_to_cpu(response_data->TotalAllocationUnits);
5133 FSData->f_bfree = FSData->f_bavail =
5134 le32_to_cpu(response_data->FreeAllocationUnits);
5135 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5136 (unsigned long long)FSData->f_blocks,
5137 (unsigned long long)FSData->f_bfree,
5141 cifs_buf_release(pSMB);
5144 goto oldQFSInfoRetry;
5150 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
5151 struct kstatfs *FSData)
5153 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5154 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5155 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5156 FILE_SYSTEM_INFO *response_data;
5158 int bytes_returned = 0;
5159 __u16 params, byte_count;
5161 cifs_dbg(FYI, "In QFSInfo\n");
5163 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5168 params = 2; /* level */
5169 pSMB->TotalDataCount = 0;
5170 pSMB->MaxParameterCount = cpu_to_le16(2);
5171 pSMB->MaxDataCount = cpu_to_le16(1000);
5172 pSMB->MaxSetupCount = 0;
5176 pSMB->Reserved2 = 0;
5177 byte_count = params + 1 /* pad */ ;
5178 pSMB->TotalParameterCount = cpu_to_le16(params);
5179 pSMB->ParameterCount = pSMB->TotalParameterCount;
5180 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5181 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5182 pSMB->DataCount = 0;
5183 pSMB->DataOffset = 0;
5184 pSMB->SetupCount = 1;
5185 pSMB->Reserved3 = 0;
5186 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5187 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5188 inc_rfc1001_len(pSMB, byte_count);
5189 pSMB->ByteCount = cpu_to_le16(byte_count);
5191 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5192 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5194 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5195 } else { /* decode response */
5196 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5198 if (rc || get_bcc(&pSMBr->hdr) < 24)
5199 rc = -EIO; /* bad smb */
5201 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5205 *) (((char *) &pSMBr->hdr.Protocol) +
5208 le32_to_cpu(response_data->BytesPerSector) *
5209 le32_to_cpu(response_data->
5210 SectorsPerAllocationUnit);
5212 * much prefer larger but if server doesn't report
5213 * a valid size than 4K is a reasonable minimum
5215 if (FSData->f_bsize < 512)
5216 FSData->f_bsize = 4096;
5219 le64_to_cpu(response_data->TotalAllocationUnits);
5220 FSData->f_bfree = FSData->f_bavail =
5221 le64_to_cpu(response_data->FreeAllocationUnits);
5222 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5223 (unsigned long long)FSData->f_blocks,
5224 (unsigned long long)FSData->f_bfree,
5228 cifs_buf_release(pSMB);
5237 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5239 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5240 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5241 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5242 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5244 int bytes_returned = 0;
5245 __u16 params, byte_count;
5247 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5249 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5254 params = 2; /* level */
5255 pSMB->TotalDataCount = 0;
5256 pSMB->MaxParameterCount = cpu_to_le16(2);
5257 /* BB find exact max SMB PDU from sess structure BB */
5258 pSMB->MaxDataCount = cpu_to_le16(1000);
5259 pSMB->MaxSetupCount = 0;
5263 pSMB->Reserved2 = 0;
5264 byte_count = params + 1 /* pad */ ;
5265 pSMB->TotalParameterCount = cpu_to_le16(params);
5266 pSMB->ParameterCount = pSMB->TotalParameterCount;
5267 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5268 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5269 pSMB->DataCount = 0;
5270 pSMB->DataOffset = 0;
5271 pSMB->SetupCount = 1;
5272 pSMB->Reserved3 = 0;
5273 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5274 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5275 inc_rfc1001_len(pSMB, byte_count);
5276 pSMB->ByteCount = cpu_to_le16(byte_count);
5278 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5279 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5281 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5282 } else { /* decode response */
5283 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5285 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5286 /* BB also check if enough bytes returned */
5287 rc = -EIO; /* bad smb */
5289 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5291 (FILE_SYSTEM_ATTRIBUTE_INFO
5292 *) (((char *) &pSMBr->hdr.Protocol) +
5294 memcpy(&tcon->fsAttrInfo, response_data,
5295 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5298 cifs_buf_release(pSMB);
5301 goto QFSAttributeRetry;
5307 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5309 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5310 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5311 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5312 FILE_SYSTEM_DEVICE_INFO *response_data;
5314 int bytes_returned = 0;
5315 __u16 params, byte_count;
5317 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5319 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5324 params = 2; /* level */
5325 pSMB->TotalDataCount = 0;
5326 pSMB->MaxParameterCount = cpu_to_le16(2);
5327 /* BB find exact max SMB PDU from sess structure BB */
5328 pSMB->MaxDataCount = cpu_to_le16(1000);
5329 pSMB->MaxSetupCount = 0;
5333 pSMB->Reserved2 = 0;
5334 byte_count = params + 1 /* pad */ ;
5335 pSMB->TotalParameterCount = cpu_to_le16(params);
5336 pSMB->ParameterCount = pSMB->TotalParameterCount;
5337 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5338 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5340 pSMB->DataCount = 0;
5341 pSMB->DataOffset = 0;
5342 pSMB->SetupCount = 1;
5343 pSMB->Reserved3 = 0;
5344 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5345 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5346 inc_rfc1001_len(pSMB, byte_count);
5347 pSMB->ByteCount = cpu_to_le16(byte_count);
5349 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5350 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5352 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5353 } else { /* decode response */
5354 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5356 if (rc || get_bcc(&pSMBr->hdr) <
5357 sizeof(FILE_SYSTEM_DEVICE_INFO))
5358 rc = -EIO; /* bad smb */
5360 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5362 (FILE_SYSTEM_DEVICE_INFO *)
5363 (((char *) &pSMBr->hdr.Protocol) +
5365 memcpy(&tcon->fsDevInfo, response_data,
5366 sizeof(FILE_SYSTEM_DEVICE_INFO));
5369 cifs_buf_release(pSMB);
5372 goto QFSDeviceRetry;
5378 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5380 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5381 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5382 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5383 FILE_SYSTEM_UNIX_INFO *response_data;
5385 int bytes_returned = 0;
5386 __u16 params, byte_count;
5388 cifs_dbg(FYI, "In QFSUnixInfo\n");
5390 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5391 (void **) &pSMB, (void **) &pSMBr);
5395 params = 2; /* level */
5396 pSMB->TotalDataCount = 0;
5397 pSMB->DataCount = 0;
5398 pSMB->DataOffset = 0;
5399 pSMB->MaxParameterCount = cpu_to_le16(2);
5400 /* BB find exact max SMB PDU from sess structure BB */
5401 pSMB->MaxDataCount = cpu_to_le16(100);
5402 pSMB->MaxSetupCount = 0;
5406 pSMB->Reserved2 = 0;
5407 byte_count = params + 1 /* pad */ ;
5408 pSMB->ParameterCount = cpu_to_le16(params);
5409 pSMB->TotalParameterCount = pSMB->ParameterCount;
5410 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5411 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5412 pSMB->SetupCount = 1;
5413 pSMB->Reserved3 = 0;
5414 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5415 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5416 inc_rfc1001_len(pSMB, byte_count);
5417 pSMB->ByteCount = cpu_to_le16(byte_count);
5419 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5420 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5422 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5423 } else { /* decode response */
5424 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5426 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5427 rc = -EIO; /* bad smb */
5429 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5431 (FILE_SYSTEM_UNIX_INFO
5432 *) (((char *) &pSMBr->hdr.Protocol) +
5434 memcpy(&tcon->fsUnixInfo, response_data,
5435 sizeof(FILE_SYSTEM_UNIX_INFO));
5438 cifs_buf_release(pSMB);
5448 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5450 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5451 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5452 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5454 int bytes_returned = 0;
5455 __u16 params, param_offset, offset, byte_count;
5457 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5459 /* BB switch to small buf init to save memory */
5460 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5461 (void **) &pSMB, (void **) &pSMBr);
5465 params = 4; /* 2 bytes zero followed by info level. */
5466 pSMB->MaxSetupCount = 0;
5470 pSMB->Reserved2 = 0;
5471 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5473 offset = param_offset + params;
5475 pSMB->MaxParameterCount = cpu_to_le16(4);
5476 /* BB find exact max SMB PDU from sess structure BB */
5477 pSMB->MaxDataCount = cpu_to_le16(100);
5478 pSMB->SetupCount = 1;
5479 pSMB->Reserved3 = 0;
5480 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5481 byte_count = 1 /* pad */ + params + 12;
5483 pSMB->DataCount = cpu_to_le16(12);
5484 pSMB->ParameterCount = cpu_to_le16(params);
5485 pSMB->TotalDataCount = pSMB->DataCount;
5486 pSMB->TotalParameterCount = pSMB->ParameterCount;
5487 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5488 pSMB->DataOffset = cpu_to_le16(offset);
5492 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5495 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5496 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5497 pSMB->ClientUnixCap = cpu_to_le64(cap);
5499 inc_rfc1001_len(pSMB, byte_count);
5500 pSMB->ByteCount = cpu_to_le16(byte_count);
5502 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5503 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5505 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5506 } else { /* decode response */
5507 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5509 rc = -EIO; /* bad smb */
5511 cifs_buf_release(pSMB);
5514 goto SETFSUnixRetry;
5522 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5523 struct kstatfs *FSData)
5525 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5526 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5527 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5528 FILE_SYSTEM_POSIX_INFO *response_data;
5530 int bytes_returned = 0;
5531 __u16 params, byte_count;
5533 cifs_dbg(FYI, "In QFSPosixInfo\n");
5535 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5540 params = 2; /* level */
5541 pSMB->TotalDataCount = 0;
5542 pSMB->DataCount = 0;
5543 pSMB->DataOffset = 0;
5544 pSMB->MaxParameterCount = cpu_to_le16(2);
5545 /* BB find exact max SMB PDU from sess structure BB */
5546 pSMB->MaxDataCount = cpu_to_le16(100);
5547 pSMB->MaxSetupCount = 0;
5551 pSMB->Reserved2 = 0;
5552 byte_count = params + 1 /* pad */ ;
5553 pSMB->ParameterCount = cpu_to_le16(params);
5554 pSMB->TotalParameterCount = pSMB->ParameterCount;
5555 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5556 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5557 pSMB->SetupCount = 1;
5558 pSMB->Reserved3 = 0;
5559 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5560 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5561 inc_rfc1001_len(pSMB, byte_count);
5562 pSMB->ByteCount = cpu_to_le16(byte_count);
5564 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5565 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5567 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5568 } else { /* decode response */
5569 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5571 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5572 rc = -EIO; /* bad smb */
5574 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5576 (FILE_SYSTEM_POSIX_INFO
5577 *) (((char *) &pSMBr->hdr.Protocol) +
5580 le32_to_cpu(response_data->BlockSize);
5582 * much prefer larger but if server doesn't report
5583 * a valid size than 4K is a reasonable minimum
5585 if (FSData->f_bsize < 512)
5586 FSData->f_bsize = 4096;
5589 le64_to_cpu(response_data->TotalBlocks);
5591 le64_to_cpu(response_data->BlocksAvail);
5592 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5593 FSData->f_bavail = FSData->f_bfree;
5596 le64_to_cpu(response_data->UserBlocksAvail);
5598 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5600 le64_to_cpu(response_data->TotalFileNodes);
5601 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5603 le64_to_cpu(response_data->FreeFileNodes);
5606 cifs_buf_release(pSMB);
5616 * We can not use write of zero bytes trick to set file size due to need for
5617 * large file support. Also note that this SetPathInfo is preferred to
5618 * SetFileInfo based method in next routine which is only needed to work around
5619 * a sharing violation bugin Samba which this routine can run into.
5622 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5623 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5624 bool set_allocation)
5626 struct smb_com_transaction2_spi_req *pSMB = NULL;
5627 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5628 struct file_end_of_file_info *parm_data;
5631 int bytes_returned = 0;
5632 int remap = cifs_remap(cifs_sb);
5634 __u16 params, byte_count, data_count, param_offset, offset;
5636 cifs_dbg(FYI, "In SetEOF\n");
5638 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5643 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5645 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5646 PATH_MAX, cifs_sb->local_nls, remap);
5647 name_len++; /* trailing null */
5650 name_len = copy_path_name(pSMB->FileName, file_name);
5652 params = 6 + name_len;
5653 data_count = sizeof(struct file_end_of_file_info);
5654 pSMB->MaxParameterCount = cpu_to_le16(2);
5655 pSMB->MaxDataCount = cpu_to_le16(4100);
5656 pSMB->MaxSetupCount = 0;
5660 pSMB->Reserved2 = 0;
5661 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5662 InformationLevel) - 4;
5663 offset = param_offset + params;
5664 if (set_allocation) {
5665 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5666 pSMB->InformationLevel =
5667 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5669 pSMB->InformationLevel =
5670 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5671 } else /* Set File Size */ {
5672 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5673 pSMB->InformationLevel =
5674 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5676 pSMB->InformationLevel =
5677 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5681 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5683 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5684 pSMB->DataOffset = cpu_to_le16(offset);
5685 pSMB->SetupCount = 1;
5686 pSMB->Reserved3 = 0;
5687 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5688 byte_count = 3 /* pad */ + params + data_count;
5689 pSMB->DataCount = cpu_to_le16(data_count);
5690 pSMB->TotalDataCount = pSMB->DataCount;
5691 pSMB->ParameterCount = cpu_to_le16(params);
5692 pSMB->TotalParameterCount = pSMB->ParameterCount;
5693 pSMB->Reserved4 = 0;
5694 inc_rfc1001_len(pSMB, byte_count);
5695 parm_data->FileSize = cpu_to_le64(size);
5696 pSMB->ByteCount = cpu_to_le16(byte_count);
5697 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5698 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5700 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5702 cifs_buf_release(pSMB);
5711 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5712 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5714 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5715 struct file_end_of_file_info *parm_data;
5717 __u16 params, param_offset, offset, byte_count, count;
5719 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5721 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5726 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5727 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5730 pSMB->MaxSetupCount = 0;
5734 pSMB->Reserved2 = 0;
5735 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5736 offset = param_offset + params;
5738 count = sizeof(struct file_end_of_file_info);
5739 pSMB->MaxParameterCount = cpu_to_le16(2);
5740 /* BB find exact max SMB PDU from sess structure BB */
5741 pSMB->MaxDataCount = cpu_to_le16(1000);
5742 pSMB->SetupCount = 1;
5743 pSMB->Reserved3 = 0;
5744 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5745 byte_count = 3 /* pad */ + params + count;
5746 pSMB->DataCount = cpu_to_le16(count);
5747 pSMB->ParameterCount = cpu_to_le16(params);
5748 pSMB->TotalDataCount = pSMB->DataCount;
5749 pSMB->TotalParameterCount = pSMB->ParameterCount;
5750 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5752 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5754 pSMB->DataOffset = cpu_to_le16(offset);
5755 parm_data->FileSize = cpu_to_le64(size);
5756 pSMB->Fid = cfile->fid.netfid;
5757 if (set_allocation) {
5758 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5759 pSMB->InformationLevel =
5760 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5762 pSMB->InformationLevel =
5763 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5764 } else /* Set File Size */ {
5765 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5766 pSMB->InformationLevel =
5767 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5769 pSMB->InformationLevel =
5770 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5772 pSMB->Reserved4 = 0;
5773 inc_rfc1001_len(pSMB, byte_count);
5774 pSMB->ByteCount = cpu_to_le16(byte_count);
5775 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5776 cifs_small_buf_release(pSMB);
5778 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5782 /* Note: On -EAGAIN error only caller can retry on handle based calls
5783 since file handle passed in no longer valid */
5788 /* Some legacy servers such as NT4 require that the file times be set on
5789 an open handle, rather than by pathname - this is awkward due to
5790 potential access conflicts on the open, but it is unavoidable for these
5791 old servers since the only other choice is to go from 100 nanosecond DCE
5792 time and resort to the original setpathinfo level which takes the ancient
5793 DOS time format with 2 second granularity */
5795 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5796 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5798 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5801 __u16 params, param_offset, offset, byte_count, count;
5803 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5804 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5809 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5810 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5813 pSMB->MaxSetupCount = 0;
5817 pSMB->Reserved2 = 0;
5818 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5819 offset = param_offset + params;
5821 data_offset = (char *)pSMB +
5822 offsetof(struct smb_hdr, Protocol) + offset;
5824 count = sizeof(FILE_BASIC_INFO);
5825 pSMB->MaxParameterCount = cpu_to_le16(2);
5826 /* BB find max SMB PDU from sess */
5827 pSMB->MaxDataCount = cpu_to_le16(1000);
5828 pSMB->SetupCount = 1;
5829 pSMB->Reserved3 = 0;
5830 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5831 byte_count = 3 /* pad */ + params + count;
5832 pSMB->DataCount = cpu_to_le16(count);
5833 pSMB->ParameterCount = cpu_to_le16(params);
5834 pSMB->TotalDataCount = pSMB->DataCount;
5835 pSMB->TotalParameterCount = pSMB->ParameterCount;
5836 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5837 pSMB->DataOffset = cpu_to_le16(offset);
5839 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5840 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5842 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5843 pSMB->Reserved4 = 0;
5844 inc_rfc1001_len(pSMB, byte_count);
5845 pSMB->ByteCount = cpu_to_le16(byte_count);
5846 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5847 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5848 cifs_small_buf_release(pSMB);
5850 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5853 /* Note: On -EAGAIN error only caller can retry on handle based calls
5854 since file handle passed in no longer valid */
5860 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5861 bool delete_file, __u16 fid, __u32 pid_of_opener)
5863 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5866 __u16 params, param_offset, offset, byte_count, count;
5868 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5869 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5874 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5875 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5878 pSMB->MaxSetupCount = 0;
5882 pSMB->Reserved2 = 0;
5883 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5884 offset = param_offset + params;
5886 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5889 pSMB->MaxParameterCount = cpu_to_le16(2);
5890 /* BB find max SMB PDU from sess */
5891 pSMB->MaxDataCount = cpu_to_le16(1000);
5892 pSMB->SetupCount = 1;
5893 pSMB->Reserved3 = 0;
5894 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5895 byte_count = 3 /* pad */ + params + count;
5896 pSMB->DataCount = cpu_to_le16(count);
5897 pSMB->ParameterCount = cpu_to_le16(params);
5898 pSMB->TotalDataCount = pSMB->DataCount;
5899 pSMB->TotalParameterCount = pSMB->ParameterCount;
5900 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5901 pSMB->DataOffset = cpu_to_le16(offset);
5903 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5904 pSMB->Reserved4 = 0;
5905 inc_rfc1001_len(pSMB, byte_count);
5906 pSMB->ByteCount = cpu_to_le16(byte_count);
5907 *data_offset = delete_file ? 1 : 0;
5908 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5909 cifs_small_buf_release(pSMB);
5911 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5917 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5918 const char *fileName, const FILE_BASIC_INFO *data,
5919 const struct nls_table *nls_codepage, int remap)
5921 TRANSACTION2_SPI_REQ *pSMB = NULL;
5922 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5925 int bytes_returned = 0;
5927 __u16 params, param_offset, offset, byte_count, count;
5929 cifs_dbg(FYI, "In SetTimes\n");
5932 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5937 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5939 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5940 PATH_MAX, nls_codepage, remap);
5941 name_len++; /* trailing null */
5944 name_len = copy_path_name(pSMB->FileName, fileName);
5947 params = 6 + name_len;
5948 count = sizeof(FILE_BASIC_INFO);
5949 pSMB->MaxParameterCount = cpu_to_le16(2);
5950 /* BB find max SMB PDU from sess structure BB */
5951 pSMB->MaxDataCount = cpu_to_le16(1000);
5952 pSMB->MaxSetupCount = 0;
5956 pSMB->Reserved2 = 0;
5957 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5958 InformationLevel) - 4;
5959 offset = param_offset + params;
5960 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5961 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5962 pSMB->DataOffset = cpu_to_le16(offset);
5963 pSMB->SetupCount = 1;
5964 pSMB->Reserved3 = 0;
5965 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5966 byte_count = 3 /* pad */ + params + count;
5968 pSMB->DataCount = cpu_to_le16(count);
5969 pSMB->ParameterCount = cpu_to_le16(params);
5970 pSMB->TotalDataCount = pSMB->DataCount;
5971 pSMB->TotalParameterCount = pSMB->ParameterCount;
5972 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5973 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5975 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5976 pSMB->Reserved4 = 0;
5977 inc_rfc1001_len(pSMB, byte_count);
5978 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5979 pSMB->ByteCount = cpu_to_le16(byte_count);
5980 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5981 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5983 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5985 cifs_buf_release(pSMB);
5993 /* Can not be used to set time stamps yet (due to old DOS time format) */
5994 /* Can be used to set attributes */
5995 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5996 handling it anyway and NT4 was what we thought it would be needed for
5997 Do not delete it until we prove whether needed for Win9x though */
5999 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
6000 __u16 dos_attrs, const struct nls_table *nls_codepage)
6002 SETATTR_REQ *pSMB = NULL;
6003 SETATTR_RSP *pSMBr = NULL;
6008 cifs_dbg(FYI, "In SetAttrLegacy\n");
6011 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
6016 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6018 ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
6019 PATH_MAX, nls_codepage);
6020 name_len++; /* trailing null */
6023 name_len = copy_path_name(pSMB->fileName, fileName);
6025 pSMB->attr = cpu_to_le16(dos_attrs);
6026 pSMB->BufferFormat = 0x04;
6027 inc_rfc1001_len(pSMB, name_len + 1);
6028 pSMB->ByteCount = cpu_to_le16(name_len + 1);
6029 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6030 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6032 cifs_dbg(FYI, "Error in LegacySetAttr = %d\n", rc);
6034 cifs_buf_release(pSMB);
6037 goto SetAttrLgcyRetry;
6041 #endif /* temporarily unneeded SetAttr legacy function */
6044 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
6045 const struct cifs_unix_set_info_args *args)
6047 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
6048 u64 mode = args->mode;
6050 if (uid_valid(args->uid))
6051 uid = from_kuid(&init_user_ns, args->uid);
6052 if (gid_valid(args->gid))
6053 gid = from_kgid(&init_user_ns, args->gid);
6056 * Samba server ignores set of file size to zero due to bugs in some
6057 * older clients, but we should be precise - we use SetFileSize to
6058 * set file size and do not want to truncate file size to zero
6059 * accidentally as happened on one Samba server beta by putting
6060 * zero instead of -1 here
6062 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
6063 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
6064 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
6065 data_offset->LastAccessTime = cpu_to_le64(args->atime);
6066 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
6067 data_offset->Uid = cpu_to_le64(uid);
6068 data_offset->Gid = cpu_to_le64(gid);
6069 /* better to leave device as zero when it is */
6070 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
6071 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
6072 data_offset->Permissions = cpu_to_le64(mode);
6075 data_offset->Type = cpu_to_le32(UNIX_FILE);
6076 else if (S_ISDIR(mode))
6077 data_offset->Type = cpu_to_le32(UNIX_DIR);
6078 else if (S_ISLNK(mode))
6079 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
6080 else if (S_ISCHR(mode))
6081 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
6082 else if (S_ISBLK(mode))
6083 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
6084 else if (S_ISFIFO(mode))
6085 data_offset->Type = cpu_to_le32(UNIX_FIFO);
6086 else if (S_ISSOCK(mode))
6087 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
6091 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
6092 const struct cifs_unix_set_info_args *args,
6093 u16 fid, u32 pid_of_opener)
6095 struct smb_com_transaction2_sfi_req *pSMB = NULL;
6098 u16 params, param_offset, offset, byte_count, count;
6100 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
6101 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
6106 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
6107 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
6110 pSMB->MaxSetupCount = 0;
6114 pSMB->Reserved2 = 0;
6115 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
6116 offset = param_offset + params;
6118 data_offset = (char *)pSMB +
6119 offsetof(struct smb_hdr, Protocol) + offset;
6121 count = sizeof(FILE_UNIX_BASIC_INFO);
6123 pSMB->MaxParameterCount = cpu_to_le16(2);
6124 /* BB find max SMB PDU from sess */
6125 pSMB->MaxDataCount = cpu_to_le16(1000);
6126 pSMB->SetupCount = 1;
6127 pSMB->Reserved3 = 0;
6128 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
6129 byte_count = 3 /* pad */ + params + count;
6130 pSMB->DataCount = cpu_to_le16(count);
6131 pSMB->ParameterCount = cpu_to_le16(params);
6132 pSMB->TotalDataCount = pSMB->DataCount;
6133 pSMB->TotalParameterCount = pSMB->ParameterCount;
6134 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6135 pSMB->DataOffset = cpu_to_le16(offset);
6137 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6138 pSMB->Reserved4 = 0;
6139 inc_rfc1001_len(pSMB, byte_count);
6140 pSMB->ByteCount = cpu_to_le16(byte_count);
6142 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
6144 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
6145 cifs_small_buf_release(pSMB);
6147 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
6150 /* Note: On -EAGAIN error only caller can retry on handle based calls
6151 since file handle passed in no longer valid */
6157 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
6158 const char *file_name,
6159 const struct cifs_unix_set_info_args *args,
6160 const struct nls_table *nls_codepage, int remap)
6162 TRANSACTION2_SPI_REQ *pSMB = NULL;
6163 TRANSACTION2_SPI_RSP *pSMBr = NULL;
6166 int bytes_returned = 0;
6167 FILE_UNIX_BASIC_INFO *data_offset;
6168 __u16 params, param_offset, offset, count, byte_count;
6170 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
6172 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6177 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6179 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6180 PATH_MAX, nls_codepage, remap);
6181 name_len++; /* trailing null */
6184 name_len = copy_path_name(pSMB->FileName, file_name);
6187 params = 6 + name_len;
6188 count = sizeof(FILE_UNIX_BASIC_INFO);
6189 pSMB->MaxParameterCount = cpu_to_le16(2);
6190 /* BB find max SMB PDU from sess structure BB */
6191 pSMB->MaxDataCount = cpu_to_le16(1000);
6192 pSMB->MaxSetupCount = 0;
6196 pSMB->Reserved2 = 0;
6197 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6198 InformationLevel) - 4;
6199 offset = param_offset + params;
6201 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6203 memset(data_offset, 0, count);
6204 pSMB->DataOffset = cpu_to_le16(offset);
6205 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6206 pSMB->SetupCount = 1;
6207 pSMB->Reserved3 = 0;
6208 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6209 byte_count = 3 /* pad */ + params + count;
6210 pSMB->ParameterCount = cpu_to_le16(params);
6211 pSMB->DataCount = cpu_to_le16(count);
6212 pSMB->TotalParameterCount = pSMB->ParameterCount;
6213 pSMB->TotalDataCount = pSMB->DataCount;
6214 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6215 pSMB->Reserved4 = 0;
6216 inc_rfc1001_len(pSMB, byte_count);
6218 cifs_fill_unix_set_info(data_offset, args);
6220 pSMB->ByteCount = cpu_to_le16(byte_count);
6221 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6222 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6224 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6226 cifs_buf_release(pSMB);
6232 #ifdef CONFIG_CIFS_XATTR
6234 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6235 * function used by listxattr and getxattr type calls. When ea_name is set,
6236 * it looks for that attribute name and stuffs that value into the EAData
6237 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6238 * buffer. In both cases, the return value is either the length of the
6239 * resulting data or a negative error code. If EAData is a NULL pointer then
6240 * the data isn't copied to it, but the length is returned.
6243 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6244 const unsigned char *searchName, const unsigned char *ea_name,
6245 char *EAData, size_t buf_size,
6246 struct cifs_sb_info *cifs_sb)
6248 /* BB assumes one setup word */
6249 TRANSACTION2_QPI_REQ *pSMB = NULL;
6250 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6251 int remap = cifs_remap(cifs_sb);
6252 struct nls_table *nls_codepage = cifs_sb->local_nls;
6256 struct fealist *ea_response_data;
6257 struct fea *temp_fea;
6260 __u16 params, byte_count, data_offset;
6261 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6263 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6265 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6270 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6272 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6273 PATH_MAX, nls_codepage, remap);
6274 list_len++; /* trailing null */
6277 list_len = copy_path_name(pSMB->FileName, searchName);
6280 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6281 pSMB->TotalDataCount = 0;
6282 pSMB->MaxParameterCount = cpu_to_le16(2);
6283 /* BB find exact max SMB PDU from sess structure BB */
6284 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6285 pSMB->MaxSetupCount = 0;
6289 pSMB->Reserved2 = 0;
6290 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6291 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6292 pSMB->DataCount = 0;
6293 pSMB->DataOffset = 0;
6294 pSMB->SetupCount = 1;
6295 pSMB->Reserved3 = 0;
6296 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6297 byte_count = params + 1 /* pad */ ;
6298 pSMB->TotalParameterCount = cpu_to_le16(params);
6299 pSMB->ParameterCount = pSMB->TotalParameterCount;
6300 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6301 pSMB->Reserved4 = 0;
6302 inc_rfc1001_len(pSMB, byte_count);
6303 pSMB->ByteCount = cpu_to_le16(byte_count);
6305 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6306 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6308 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6313 /* BB also check enough total bytes returned */
6314 /* BB we need to improve the validity checking
6315 of these trans2 responses */
6317 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6318 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6319 rc = -EIO; /* bad smb */
6323 /* check that length of list is not more than bcc */
6324 /* check that each entry does not go beyond length
6326 /* check that each element of each entry does not
6327 go beyond end of list */
6328 /* validate_trans2_offsets() */
6329 /* BB check if start of smb + data_offset > &bcc+ bcc */
6331 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6332 ea_response_data = (struct fealist *)
6333 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6335 list_len = le32_to_cpu(ea_response_data->list_len);
6336 cifs_dbg(FYI, "ea length %d\n", list_len);
6337 if (list_len <= 8) {
6338 cifs_dbg(FYI, "empty EA list returned from server\n");
6339 /* didn't find the named attribute */
6345 /* make sure list_len doesn't go past end of SMB */
6346 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6347 if ((char *)ea_response_data + list_len > end_of_smb) {
6348 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6353 /* account for ea list len */
6355 temp_fea = ea_response_data->list;
6356 temp_ptr = (char *)temp_fea;
6357 while (list_len > 0) {
6358 unsigned int name_len;
6363 /* make sure we can read name_len and value_len */
6365 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6370 name_len = temp_fea->name_len;
6371 value_len = le16_to_cpu(temp_fea->value_len);
6372 list_len -= name_len + 1 + value_len;
6374 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6380 if (ea_name_len == name_len &&
6381 memcmp(ea_name, temp_ptr, name_len) == 0) {
6382 temp_ptr += name_len + 1;
6386 if ((size_t)value_len > buf_size) {
6390 memcpy(EAData, temp_ptr, value_len);
6394 /* account for prefix user. and trailing null */
6395 rc += (5 + 1 + name_len);
6396 if (rc < (int) buf_size) {
6397 memcpy(EAData, "user.", 5);
6399 memcpy(EAData, temp_ptr, name_len);
6401 /* null terminate name */
6404 } else if (buf_size == 0) {
6405 /* skip copy - calc size only */
6407 /* stop before overrun buffer */
6412 temp_ptr += name_len + 1 + value_len;
6413 temp_fea = (struct fea *)temp_ptr;
6416 /* didn't find the named attribute */
6421 cifs_buf_release(pSMB);
6429 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6430 const char *fileName, const char *ea_name, const void *ea_value,
6431 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6432 struct cifs_sb_info *cifs_sb)
6434 struct smb_com_transaction2_spi_req *pSMB = NULL;
6435 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6436 struct fealist *parm_data;
6439 int bytes_returned = 0;
6440 __u16 params, param_offset, byte_count, offset, count;
6441 int remap = cifs_remap(cifs_sb);
6443 cifs_dbg(FYI, "In SetEA\n");
6445 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6450 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6452 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6453 PATH_MAX, nls_codepage, remap);
6454 name_len++; /* trailing null */
6457 name_len = copy_path_name(pSMB->FileName, fileName);
6460 params = 6 + name_len;
6462 /* done calculating parms using name_len of file name,
6463 now use name_len to calculate length of ea name
6464 we are going to create in the inode xattrs */
6465 if (ea_name == NULL)
6468 name_len = strnlen(ea_name, 255);
6470 count = sizeof(*parm_data) + ea_value_len + name_len;
6471 pSMB->MaxParameterCount = cpu_to_le16(2);
6472 /* BB find max SMB PDU from sess */
6473 pSMB->MaxDataCount = cpu_to_le16(1000);
6474 pSMB->MaxSetupCount = 0;
6478 pSMB->Reserved2 = 0;
6479 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6480 InformationLevel) - 4;
6481 offset = param_offset + params;
6482 pSMB->InformationLevel =
6483 cpu_to_le16(SMB_SET_FILE_EA);
6485 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6486 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6487 pSMB->DataOffset = cpu_to_le16(offset);
6488 pSMB->SetupCount = 1;
6489 pSMB->Reserved3 = 0;
6490 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6491 byte_count = 3 /* pad */ + params + count;
6492 pSMB->DataCount = cpu_to_le16(count);
6493 parm_data->list_len = cpu_to_le32(count);
6494 parm_data->list[0].EA_flags = 0;
6495 /* we checked above that name len is less than 255 */
6496 parm_data->list[0].name_len = (__u8)name_len;
6497 /* EA names are always ASCII */
6499 strncpy(parm_data->list[0].name, ea_name, name_len);
6500 parm_data->list[0].name[name_len] = 0;
6501 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6502 /* caller ensures that ea_value_len is less than 64K but
6503 we need to ensure that it fits within the smb */
6505 /*BB add length check to see if it would fit in
6506 negotiated SMB buffer size BB */
6507 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6509 memcpy(parm_data->list[0].name+name_len+1,
6510 ea_value, ea_value_len);
6512 pSMB->TotalDataCount = pSMB->DataCount;
6513 pSMB->ParameterCount = cpu_to_le16(params);
6514 pSMB->TotalParameterCount = pSMB->ParameterCount;
6515 pSMB->Reserved4 = 0;
6516 inc_rfc1001_len(pSMB, byte_count);
6517 pSMB->ByteCount = cpu_to_le16(byte_count);
6518 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6519 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6521 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6523 cifs_buf_release(pSMB);