4 * Copyright (C) International Business Machines Corp., 2002,2010
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for constructing the SMB PDUs themselves
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
25 /* These are mostly routines that operate on a pathname, or on a tree id */
26 /* (mounted volume), but there are eight handle based routines which must be */
27 /* treated slightly differently for reconnection purposes since we never */
28 /* want to reuse a stale file handle and only the caller knows the file info */
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <linux/uaccess.h>
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
46 #include "smbdirect.h"
47 #ifdef CONFIG_CIFS_DFS_UPCALL
48 #include "dfs_cache.h"
51 #ifdef CONFIG_CIFS_POSIX
56 #ifdef CONFIG_CIFS_WEAK_PW_HASH
57 {LANMAN_PROT, "\2LM1.2X002"},
58 {LANMAN2_PROT, "\2LANMAN2.1"},
59 #endif /* weak password hashing for legacy clients */
60 {CIFS_PROT, "\2NT LM 0.12"},
61 {POSIX_PROT, "\2POSIX 2"},
69 #ifdef CONFIG_CIFS_WEAK_PW_HASH
70 {LANMAN_PROT, "\2LM1.2X002"},
71 {LANMAN2_PROT, "\2LANMAN2.1"},
72 #endif /* weak password hashing for legacy clients */
73 {CIFS_PROT, "\2NT LM 0.12"},
78 /* define the number of elements in the cifs dialect array */
79 #ifdef CONFIG_CIFS_POSIX
80 #ifdef CONFIG_CIFS_WEAK_PW_HASH
81 #define CIFS_NUM_PROT 4
83 #define CIFS_NUM_PROT 2
84 #endif /* CIFS_WEAK_PW_HASH */
86 #ifdef CONFIG_CIFS_WEAK_PW_HASH
87 #define CIFS_NUM_PROT 3
89 #define CIFS_NUM_PROT 1
90 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
91 #endif /* CIFS_POSIX */
94 * Mark as invalid, all open files on tree connections since they
95 * were closed when session to server was lost.
98 cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
100 struct cifsFileInfo *open_file = NULL;
101 struct list_head *tmp;
102 struct list_head *tmp1;
104 /* list all files open on tree connection and mark them invalid */
105 spin_lock(&tcon->open_file_lock);
106 list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
107 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
108 open_file->invalidHandle = true;
109 open_file->oplock_break_cancelled = true;
111 spin_unlock(&tcon->open_file_lock);
113 mutex_lock(&tcon->crfid.fid_mutex);
114 tcon->crfid.is_valid = false;
115 memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
116 mutex_unlock(&tcon->crfid.fid_mutex);
119 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
124 #ifdef CONFIG_CIFS_DFS_UPCALL
125 static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
126 struct cifs_tcon *tcon)
129 struct dfs_cache_tgt_list tl;
130 struct dfs_cache_tgt_iterator *it = NULL;
132 const char *tcp_host;
134 const char *dfs_host;
137 tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
142 snprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
143 tcon->ses->server->hostname);
144 rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
148 if (!tcon->dfs_path) {
149 rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
153 rc = dfs_cache_noreq_find(tcon->dfs_path + 1, NULL, &tl);
157 extract_unc_hostname(tcon->ses->server->hostname, &tcp_host,
160 for (it = dfs_cache_get_tgt_iterator(&tl); it;
161 it = dfs_cache_get_next_tgt(&tl, it)) {
162 const char *tgt = dfs_cache_get_tgt_name(it);
164 extract_unc_hostname(tgt, &dfs_host, &dfs_host_len);
166 if (dfs_host_len != tcp_host_len
167 || strncasecmp(dfs_host, tcp_host, dfs_host_len) != 0) {
168 cifs_dbg(FYI, "%s: skipping %.*s, doesn't match %.*s",
170 (int)dfs_host_len, dfs_host,
171 (int)tcp_host_len, tcp_host);
175 snprintf(tree, MAX_TREE_SIZE, "\\%s", tgt);
177 rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
186 rc = dfs_cache_noreq_update_tgthint(tcon->dfs_path + 1,
191 dfs_cache_free_tgts(&tl);
197 static inline int __cifs_reconnect_tcon(const struct nls_table *nlsc,
198 struct cifs_tcon *tcon)
200 return CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
204 /* reconnect the socket, tcon, and smb session if needed */
206 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
209 struct cifs_ses *ses;
210 struct TCP_Server_Info *server;
211 struct nls_table *nls_codepage;
215 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
216 * tcp and smb session status done differently for those three - in the
223 server = ses->server;
226 * only tree disconnect, open, and write, (and ulogoff which does not
227 * have tcon) are allowed as we start force umount
229 if (tcon->tidStatus == CifsExiting) {
230 if (smb_command != SMB_COM_WRITE_ANDX &&
231 smb_command != SMB_COM_OPEN_ANDX &&
232 smb_command != SMB_COM_TREE_DISCONNECT) {
233 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
239 retries = server->nr_targets;
242 * Give demultiplex thread up to 10 seconds to each target available for
243 * reconnect -- should be greater than cifs socket timeout which is 7
246 while (server->tcpStatus == CifsNeedReconnect) {
247 rc = wait_event_interruptible_timeout(server->response_q,
248 (server->tcpStatus != CifsNeedReconnect),
251 cifs_dbg(FYI, "%s: aborting reconnect due to a received"
252 " signal by the process\n", __func__);
256 /* are we still trying to reconnect? */
257 if (server->tcpStatus != CifsNeedReconnect)
264 * on "soft" mounts we wait once. Hard mounts keep
265 * retrying until process is killed or server comes
269 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
272 retries = server->nr_targets;
275 if (!ses->need_reconnect && !tcon->need_reconnect)
278 nls_codepage = load_nls_default();
281 * need to prevent multiple threads trying to simultaneously
282 * reconnect the same SMB session
284 mutex_lock(&ses->session_mutex);
287 * Recheck after acquire mutex. If another thread is negotiating
288 * and the server never sends an answer the socket will be closed
289 * and tcpStatus set to reconnect.
291 if (server->tcpStatus == CifsNeedReconnect) {
293 mutex_unlock(&ses->session_mutex);
297 rc = cifs_negotiate_protocol(0, ses);
298 if (rc == 0 && ses->need_reconnect)
299 rc = cifs_setup_session(0, ses, nls_codepage);
301 /* do we need to reconnect tcon? */
302 if (rc || !tcon->need_reconnect) {
303 mutex_unlock(&ses->session_mutex);
307 cifs_mark_open_files_invalid(tcon);
308 rc = __cifs_reconnect_tcon(nls_codepage, tcon);
309 mutex_unlock(&ses->session_mutex);
310 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
313 printk_once(KERN_WARNING "reconnect tcon failed rc = %d\n", rc);
317 atomic_inc(&tconInfoReconnectCount);
319 /* tell server Unix caps we support */
320 if (ses->capabilities & CAP_UNIX)
321 reset_cifs_unix_caps(0, tcon, NULL, NULL);
324 * Removed call to reopen open files here. It is safer (and faster) to
325 * reopen files one at a time as needed in read and write.
327 * FIXME: what about file locks? don't we need to reclaim them ASAP?
332 * Check if handle based operation so we know whether we can continue
333 * or not without returning to caller to reset file handle
335 switch (smb_command) {
336 case SMB_COM_READ_ANDX:
337 case SMB_COM_WRITE_ANDX:
339 case SMB_COM_FIND_CLOSE2:
340 case SMB_COM_LOCKING_ANDX:
344 unload_nls(nls_codepage);
348 /* Allocate and return pointer to an SMB request buffer, and set basic
349 SMB information in the SMB header. If the return code is zero, this
350 function must have filled in request_buf pointer */
352 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
357 rc = cifs_reconnect_tcon(tcon, smb_command);
361 *request_buf = cifs_small_buf_get();
362 if (*request_buf == NULL) {
363 /* BB should we add a retry in here if not a writepage? */
367 header_assemble((struct smb_hdr *) *request_buf, smb_command,
371 cifs_stats_inc(&tcon->num_smbs_sent);
377 small_smb_init_no_tc(const int smb_command, const int wct,
378 struct cifs_ses *ses, void **request_buf)
381 struct smb_hdr *buffer;
383 rc = small_smb_init(smb_command, wct, NULL, request_buf);
387 buffer = (struct smb_hdr *)*request_buf;
388 buffer->Mid = get_next_mid(ses->server);
389 if (ses->capabilities & CAP_UNICODE)
390 buffer->Flags2 |= SMBFLG2_UNICODE;
391 if (ses->capabilities & CAP_STATUS32)
392 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
394 /* uid, tid can stay at zero as set in header assemble */
396 /* BB add support for turning on the signing when
397 this function is used after 1st of session setup requests */
402 /* If the return code is zero, this function must fill in request_buf pointer */
404 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
405 void **request_buf, void **response_buf)
407 *request_buf = cifs_buf_get();
408 if (*request_buf == NULL) {
409 /* BB should we add a retry in here if not a writepage? */
412 /* Although the original thought was we needed the response buf for */
413 /* potential retries of smb operations it turns out we can determine */
414 /* from the mid flags when the request buffer can be resent without */
415 /* having to use a second distinct buffer for the response */
417 *response_buf = *request_buf;
419 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
423 cifs_stats_inc(&tcon->num_smbs_sent);
428 /* If the return code is zero, this function must fill in request_buf pointer */
430 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
431 void **request_buf, void **response_buf)
435 rc = cifs_reconnect_tcon(tcon, smb_command);
439 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
443 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
444 void **request_buf, void **response_buf)
446 if (tcon->ses->need_reconnect || tcon->need_reconnect)
449 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
452 static int validate_t2(struct smb_t2_rsp *pSMB)
454 unsigned int total_size;
456 /* check for plausible wct */
457 if (pSMB->hdr.WordCount < 10)
460 /* check for parm and data offset going beyond end of smb */
461 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
462 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
465 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
466 if (total_size >= 512)
469 /* check that bcc is at least as big as parms + data, and that it is
470 * less than negotiated smb buffer
472 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
473 if (total_size > get_bcc(&pSMB->hdr) ||
474 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
479 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
480 sizeof(struct smb_t2_rsp) + 16);
485 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
489 char *guid = pSMBr->u.extended_response.GUID;
490 struct TCP_Server_Info *server = ses->server;
492 count = get_bcc(&pSMBr->hdr);
493 if (count < SMB1_CLIENT_GUID_SIZE)
496 spin_lock(&cifs_tcp_ses_lock);
497 if (server->srv_count > 1) {
498 spin_unlock(&cifs_tcp_ses_lock);
499 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
500 cifs_dbg(FYI, "server UID changed\n");
501 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
504 spin_unlock(&cifs_tcp_ses_lock);
505 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
508 if (count == SMB1_CLIENT_GUID_SIZE) {
509 server->sec_ntlmssp = true;
511 count -= SMB1_CLIENT_GUID_SIZE;
512 rc = decode_negTokenInit(
513 pSMBr->u.extended_response.SecurityBlob, count, server);
522 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
524 bool srv_sign_required = server->sec_mode & server->vals->signing_required;
525 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
526 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
529 * Is signing required by mnt options? If not then check
530 * global_secflags to see if it is there.
532 if (!mnt_sign_required)
533 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
537 * If signing is required then it's automatically enabled too,
538 * otherwise, check to see if the secflags allow it.
540 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
541 (global_secflags & CIFSSEC_MAY_SIGN);
543 /* If server requires signing, does client allow it? */
544 if (srv_sign_required) {
545 if (!mnt_sign_enabled) {
546 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!");
552 /* If client requires signing, does server allow it? */
553 if (mnt_sign_required) {
554 if (!srv_sign_enabled) {
555 cifs_dbg(VFS, "Server does not support signing!");
561 if (cifs_rdma_enabled(server) && server->sign)
562 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled");
567 #ifdef CONFIG_CIFS_WEAK_PW_HASH
569 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
572 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
574 if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
577 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
578 server->maxReq = min_t(unsigned int,
579 le16_to_cpu(rsp->MaxMpxCount),
581 set_credits(server, server->maxReq);
582 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
583 /* even though we do not use raw we might as well set this
584 accurately, in case we ever find a need for it */
585 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
586 server->max_rw = 0xFF00;
587 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
589 server->max_rw = 0;/* do not need to use raw anyway */
590 server->capabilities = CAP_MPX_MODE;
592 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
594 /* OS/2 often does not set timezone therefore
595 * we must use server time to calc time zone.
596 * Could deviate slightly from the right zone.
597 * Smallest defined timezone difference is 15 minutes
598 * (i.e. Nepal). Rounding up/down is done to match
601 int val, seconds, remain, result;
602 struct timespec64 ts;
603 time64_t utc = ktime_get_real_seconds();
604 ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
605 rsp->SrvTime.Time, 0);
606 cifs_dbg(FYI, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
609 val = (int)(utc - ts.tv_sec);
611 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
612 remain = seconds % MIN_TZ_ADJ;
613 if (remain >= (MIN_TZ_ADJ / 2))
614 result += MIN_TZ_ADJ;
617 server->timeAdj = result;
619 server->timeAdj = (int)tmp;
620 server->timeAdj *= 60; /* also in seconds */
622 cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
625 /* BB get server time for time conversions and add
626 code to use it and timezone since this is not UTC */
628 if (rsp->EncryptionKeyLength ==
629 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
630 memcpy(server->cryptkey, rsp->EncryptionKey,
631 CIFS_CRYPTO_KEY_SIZE);
632 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
633 return -EIO; /* need cryptkey unless plain text */
636 cifs_dbg(FYI, "LANMAN negotiated\n");
641 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
643 cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
649 should_set_ext_sec_flag(enum securityEnum sectype)
656 if (global_secflags &
657 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
666 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
669 NEGOTIATE_RSP *pSMBr;
673 struct TCP_Server_Info *server = ses->server;
677 WARN(1, "%s: server is NULL!\n", __func__);
681 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
682 (void **) &pSMB, (void **) &pSMBr);
686 pSMB->hdr.Mid = get_next_mid(server);
687 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
689 if (should_set_ext_sec_flag(ses->sectype)) {
690 cifs_dbg(FYI, "Requesting extended security.");
691 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
696 * We know that all the name entries in the protocols array
697 * are short (< 16 bytes anyway) and are NUL terminated.
699 for (i = 0; i < CIFS_NUM_PROT; i++) {
700 size_t len = strlen(protocols[i].name) + 1;
702 memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
705 inc_rfc1001_len(pSMB, count);
706 pSMB->ByteCount = cpu_to_le16(count);
708 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
709 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
713 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
714 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
715 /* Check wct = 1 error case */
716 if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
717 /* core returns wct = 1, but we do not ask for core - otherwise
718 small wct just comes when dialect index is -1 indicating we
719 could not negotiate a common dialect */
722 } else if (pSMBr->hdr.WordCount == 13) {
723 server->negflavor = CIFS_NEGFLAVOR_LANMAN;
724 rc = decode_lanman_negprot_rsp(server, pSMBr);
726 } else if (pSMBr->hdr.WordCount != 17) {
731 /* else wct == 17, NTLM or better */
733 server->sec_mode = pSMBr->SecurityMode;
734 if ((server->sec_mode & SECMODE_USER) == 0)
735 cifs_dbg(FYI, "share mode security\n");
737 /* one byte, so no need to convert this or EncryptionKeyLen from
739 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
741 set_credits(server, server->maxReq);
742 /* probably no need to store and check maxvcs */
743 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
744 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
745 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
746 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
747 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
748 server->timeAdj *= 60;
750 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
751 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
752 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
753 CIFS_CRYPTO_KEY_SIZE);
754 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
755 server->capabilities & CAP_EXTENDED_SECURITY) {
756 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
757 rc = decode_ext_sec_blob(ses, pSMBr);
758 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
759 rc = -EIO; /* no crypt key only if plain text pwd */
761 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
762 server->capabilities &= ~CAP_EXTENDED_SECURITY;
767 rc = cifs_enable_signing(server, ses->sign);
769 cifs_buf_release(pSMB);
771 cifs_dbg(FYI, "negprot rc %d\n", rc);
776 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
778 struct smb_hdr *smb_buffer;
781 cifs_dbg(FYI, "In tree disconnect\n");
783 /* BB: do we need to check this? These should never be NULL. */
784 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
788 * No need to return error on this operation if tid invalidated and
789 * closed on server already e.g. due to tcp session crashing. Also,
790 * the tcon is no longer on the list, so no need to take lock before
793 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
796 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
797 (void **)&smb_buffer);
801 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
802 cifs_small_buf_release(smb_buffer);
804 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
806 /* No need to return error on this operation if tid invalidated and
807 closed on server already e.g. due to tcp session crashing */
815 * This is a no-op for now. We're not really interested in the reply, but
816 * rather in the fact that the server sent one and that server->lstrp
819 * FIXME: maybe we should consider checking that the reply matches request?
822 cifs_echo_callback(struct mid_q_entry *mid)
824 struct TCP_Server_Info *server = mid->callback_data;
826 DeleteMidQEntry(mid);
827 add_credits(server, 1, CIFS_ECHO_OP);
831 CIFSSMBEcho(struct TCP_Server_Info *server)
836 struct smb_rqst rqst = { .rq_iov = iov,
839 cifs_dbg(FYI, "In echo request\n");
841 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
845 if (server->capabilities & CAP_UNICODE)
846 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
848 /* set up echo request */
849 smb->hdr.Tid = 0xffff;
850 smb->hdr.WordCount = 1;
851 put_unaligned_le16(1, &smb->EchoCount);
852 put_bcc(1, &smb->hdr);
854 inc_rfc1001_len(smb, 3);
857 iov[0].iov_base = smb;
858 iov[1].iov_len = get_rfc1002_length(smb);
859 iov[1].iov_base = (char *)smb + 4;
861 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
862 server, CIFS_ASYNC_OP | CIFS_ECHO_OP);
864 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
866 cifs_small_buf_release(smb);
872 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
874 LOGOFF_ANDX_REQ *pSMB;
877 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
880 * BB: do we need to check validity of ses and server? They should
881 * always be valid since we have an active reference. If not, that
882 * should probably be a BUG()
884 if (!ses || !ses->server)
887 mutex_lock(&ses->session_mutex);
888 if (ses->need_reconnect)
889 goto session_already_dead; /* no need to send SMBlogoff if uid
890 already closed due to reconnect */
891 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
893 mutex_unlock(&ses->session_mutex);
897 pSMB->hdr.Mid = get_next_mid(ses->server);
899 if (ses->server->sign)
900 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
902 pSMB->hdr.Uid = ses->Suid;
904 pSMB->AndXCommand = 0xFF;
905 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
906 cifs_small_buf_release(pSMB);
907 session_already_dead:
908 mutex_unlock(&ses->session_mutex);
910 /* if session dead then we do not need to do ulogoff,
911 since server closed smb session, no sense reporting
919 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
920 const char *fileName, __u16 type,
921 const struct nls_table *nls_codepage, int remap)
923 TRANSACTION2_SPI_REQ *pSMB = NULL;
924 TRANSACTION2_SPI_RSP *pSMBr = NULL;
925 struct unlink_psx_rq *pRqD;
928 int bytes_returned = 0;
929 __u16 params, param_offset, offset, byte_count;
931 cifs_dbg(FYI, "In POSIX delete\n");
933 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
938 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
940 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
941 PATH_MAX, nls_codepage, remap);
942 name_len++; /* trailing null */
944 } else { /* BB add path length overrun check */
945 name_len = strnlen(fileName, PATH_MAX);
946 name_len++; /* trailing null */
947 strncpy(pSMB->FileName, fileName, name_len);
950 params = 6 + name_len;
951 pSMB->MaxParameterCount = cpu_to_le16(2);
952 pSMB->MaxDataCount = 0; /* BB double check this with jra */
953 pSMB->MaxSetupCount = 0;
958 param_offset = offsetof(struct smb_com_transaction2_spi_req,
959 InformationLevel) - 4;
960 offset = param_offset + params;
962 /* Setup pointer to Request Data (inode type) */
963 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
964 pRqD->type = cpu_to_le16(type);
965 pSMB->ParameterOffset = cpu_to_le16(param_offset);
966 pSMB->DataOffset = cpu_to_le16(offset);
967 pSMB->SetupCount = 1;
969 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
970 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
972 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
973 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
974 pSMB->ParameterCount = cpu_to_le16(params);
975 pSMB->TotalParameterCount = pSMB->ParameterCount;
976 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
978 inc_rfc1001_len(pSMB, byte_count);
979 pSMB->ByteCount = cpu_to_le16(byte_count);
980 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
981 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
983 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
984 cifs_buf_release(pSMB);
986 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
995 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
996 struct cifs_sb_info *cifs_sb)
998 DELETE_FILE_REQ *pSMB = NULL;
999 DELETE_FILE_RSP *pSMBr = NULL;
1003 int remap = cifs_remap(cifs_sb);
1006 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
1011 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1012 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
1013 PATH_MAX, cifs_sb->local_nls,
1015 name_len++; /* trailing null */
1017 } else { /* BB improve check for buffer overruns BB */
1018 name_len = strnlen(name, PATH_MAX);
1019 name_len++; /* trailing null */
1020 strncpy(pSMB->fileName, name, name_len);
1022 pSMB->SearchAttributes =
1023 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
1024 pSMB->BufferFormat = 0x04;
1025 inc_rfc1001_len(pSMB, name_len + 1);
1026 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1027 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1028 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1029 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
1031 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
1033 cifs_buf_release(pSMB);
1041 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
1042 struct cifs_sb_info *cifs_sb)
1044 DELETE_DIRECTORY_REQ *pSMB = NULL;
1045 DELETE_DIRECTORY_RSP *pSMBr = NULL;
1049 int remap = cifs_remap(cifs_sb);
1051 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
1053 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
1058 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1059 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1060 PATH_MAX, cifs_sb->local_nls,
1062 name_len++; /* trailing null */
1064 } else { /* BB improve check for buffer overruns BB */
1065 name_len = strnlen(name, PATH_MAX);
1066 name_len++; /* trailing null */
1067 strncpy(pSMB->DirName, name, name_len);
1070 pSMB->BufferFormat = 0x04;
1071 inc_rfc1001_len(pSMB, name_len + 1);
1072 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1073 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1074 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1075 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
1077 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
1079 cifs_buf_release(pSMB);
1086 CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
1087 struct cifs_sb_info *cifs_sb)
1090 CREATE_DIRECTORY_REQ *pSMB = NULL;
1091 CREATE_DIRECTORY_RSP *pSMBr = NULL;
1094 int remap = cifs_remap(cifs_sb);
1096 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
1098 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
1103 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1104 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1105 PATH_MAX, cifs_sb->local_nls,
1107 name_len++; /* trailing null */
1109 } else { /* BB improve check for buffer overruns BB */
1110 name_len = strnlen(name, PATH_MAX);
1111 name_len++; /* trailing null */
1112 strncpy(pSMB->DirName, name, name_len);
1115 pSMB->BufferFormat = 0x04;
1116 inc_rfc1001_len(pSMB, name_len + 1);
1117 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1118 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1119 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1120 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1122 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
1124 cifs_buf_release(pSMB);
1131 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1132 __u32 posix_flags, __u64 mode, __u16 *netfid,
1133 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1134 const char *name, const struct nls_table *nls_codepage,
1137 TRANSACTION2_SPI_REQ *pSMB = NULL;
1138 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1141 int bytes_returned = 0;
1142 __u16 params, param_offset, offset, byte_count, count;
1143 OPEN_PSX_REQ *pdata;
1144 OPEN_PSX_RSP *psx_rsp;
1146 cifs_dbg(FYI, "In POSIX Create\n");
1148 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1153 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1155 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1156 PATH_MAX, nls_codepage, remap);
1157 name_len++; /* trailing null */
1159 } else { /* BB improve the check for buffer overruns BB */
1160 name_len = strnlen(name, PATH_MAX);
1161 name_len++; /* trailing null */
1162 strncpy(pSMB->FileName, name, name_len);
1165 params = 6 + name_len;
1166 count = sizeof(OPEN_PSX_REQ);
1167 pSMB->MaxParameterCount = cpu_to_le16(2);
1168 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1169 pSMB->MaxSetupCount = 0;
1173 pSMB->Reserved2 = 0;
1174 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1175 InformationLevel) - 4;
1176 offset = param_offset + params;
1177 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1178 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1179 pdata->Permissions = cpu_to_le64(mode);
1180 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1181 pdata->OpenFlags = cpu_to_le32(*pOplock);
1182 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1183 pSMB->DataOffset = cpu_to_le16(offset);
1184 pSMB->SetupCount = 1;
1185 pSMB->Reserved3 = 0;
1186 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1187 byte_count = 3 /* pad */ + params + count;
1189 pSMB->DataCount = cpu_to_le16(count);
1190 pSMB->ParameterCount = cpu_to_le16(params);
1191 pSMB->TotalDataCount = pSMB->DataCount;
1192 pSMB->TotalParameterCount = pSMB->ParameterCount;
1193 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1194 pSMB->Reserved4 = 0;
1195 inc_rfc1001_len(pSMB, byte_count);
1196 pSMB->ByteCount = cpu_to_le16(byte_count);
1197 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1198 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1200 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1201 goto psx_create_err;
1204 cifs_dbg(FYI, "copying inode info\n");
1205 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1207 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1208 rc = -EIO; /* bad smb */
1209 goto psx_create_err;
1212 /* copy return information to pRetData */
1213 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1214 + le16_to_cpu(pSMBr->t2.DataOffset));
1216 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1218 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1219 /* Let caller know file was created so we can set the mode. */
1220 /* Do we care about the CreateAction in any other cases? */
1221 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1222 *pOplock |= CIFS_CREATE_ACTION;
1223 /* check to make sure response data is there */
1224 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1225 pRetData->Type = cpu_to_le32(-1); /* unknown */
1226 cifs_dbg(NOISY, "unknown type\n");
1228 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1229 + sizeof(FILE_UNIX_BASIC_INFO)) {
1230 cifs_dbg(VFS, "Open response data too small\n");
1231 pRetData->Type = cpu_to_le32(-1);
1232 goto psx_create_err;
1234 memcpy((char *) pRetData,
1235 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1236 sizeof(FILE_UNIX_BASIC_INFO));
1240 cifs_buf_release(pSMB);
1242 if (posix_flags & SMB_O_DIRECTORY)
1243 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1245 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1253 static __u16 convert_disposition(int disposition)
1257 switch (disposition) {
1258 case FILE_SUPERSEDE:
1259 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1262 ofun = SMBOPEN_OAPPEND;
1265 ofun = SMBOPEN_OCREATE;
1268 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1270 case FILE_OVERWRITE:
1271 ofun = SMBOPEN_OTRUNC;
1273 case FILE_OVERWRITE_IF:
1274 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1277 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1278 ofun = SMBOPEN_OAPPEND; /* regular open */
1284 access_flags_to_smbopen_mode(const int access_flags)
1286 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1288 if (masked_flags == GENERIC_READ)
1289 return SMBOPEN_READ;
1290 else if (masked_flags == GENERIC_WRITE)
1291 return SMBOPEN_WRITE;
1293 /* just go for read/write */
1294 return SMBOPEN_READWRITE;
1298 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1299 const char *fileName, const int openDisposition,
1300 const int access_flags, const int create_options, __u16 *netfid,
1301 int *pOplock, FILE_ALL_INFO *pfile_info,
1302 const struct nls_table *nls_codepage, int remap)
1305 OPENX_REQ *pSMB = NULL;
1306 OPENX_RSP *pSMBr = NULL;
1312 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1317 pSMB->AndXCommand = 0xFF; /* none */
1319 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1320 count = 1; /* account for one byte pad to word boundary */
1322 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1323 fileName, PATH_MAX, nls_codepage, remap);
1324 name_len++; /* trailing null */
1326 } else { /* BB improve check for buffer overruns BB */
1327 count = 0; /* no pad */
1328 name_len = strnlen(fileName, PATH_MAX);
1329 name_len++; /* trailing null */
1330 strncpy(pSMB->fileName, fileName, name_len);
1332 if (*pOplock & REQ_OPLOCK)
1333 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1334 else if (*pOplock & REQ_BATCHOPLOCK)
1335 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1337 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1338 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1339 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1340 /* set file as system file if special file such
1341 as fifo and server expecting SFU style and
1342 no Unix extensions */
1344 if (create_options & CREATE_OPTION_SPECIAL)
1345 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1346 else /* BB FIXME BB */
1347 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1349 if (create_options & CREATE_OPTION_READONLY)
1350 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1353 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1354 CREATE_OPTIONS_MASK); */
1355 /* BB FIXME END BB */
1357 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1358 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1360 inc_rfc1001_len(pSMB, count);
1362 pSMB->ByteCount = cpu_to_le16(count);
1363 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1364 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1365 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1367 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1369 /* BB verify if wct == 15 */
1371 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1373 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1374 /* Let caller know file was created so we can set the mode. */
1375 /* Do we care about the CreateAction in any other cases? */
1377 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1378 *pOplock |= CIFS_CREATE_ACTION; */
1382 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1383 pfile_info->LastAccessTime = 0; /* BB fixme */
1384 pfile_info->LastWriteTime = 0; /* BB fixme */
1385 pfile_info->ChangeTime = 0; /* BB fixme */
1386 pfile_info->Attributes =
1387 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1388 /* the file_info buf is endian converted by caller */
1389 pfile_info->AllocationSize =
1390 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1391 pfile_info->EndOfFile = pfile_info->AllocationSize;
1392 pfile_info->NumberOfLinks = cpu_to_le32(1);
1393 pfile_info->DeletePending = 0;
1397 cifs_buf_release(pSMB);
1404 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1408 OPEN_REQ *req = NULL;
1409 OPEN_RSP *rsp = NULL;
1413 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1414 struct cifs_tcon *tcon = oparms->tcon;
1415 int remap = cifs_remap(cifs_sb);
1416 const struct nls_table *nls = cifs_sb->local_nls;
1417 int create_options = oparms->create_options;
1418 int desired_access = oparms->desired_access;
1419 int disposition = oparms->disposition;
1420 const char *path = oparms->path;
1423 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1428 /* no commands go after this */
1429 req->AndXCommand = 0xFF;
1431 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1432 /* account for one byte pad to word boundary */
1434 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1435 path, PATH_MAX, nls, remap);
1439 req->NameLength = cpu_to_le16(name_len);
1441 /* BB improve check for buffer overruns BB */
1444 name_len = strnlen(path, PATH_MAX);
1447 req->NameLength = cpu_to_le16(name_len);
1448 strncpy(req->fileName, path, name_len);
1451 if (*oplock & REQ_OPLOCK)
1452 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1453 else if (*oplock & REQ_BATCHOPLOCK)
1454 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1456 req->DesiredAccess = cpu_to_le32(desired_access);
1457 req->AllocationSize = 0;
1460 * Set file as system file if special file such as fifo and server
1461 * expecting SFU style and no Unix extensions.
1463 if (create_options & CREATE_OPTION_SPECIAL)
1464 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1466 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1469 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1470 * sensitive checks for other servers such as Samba.
1472 if (tcon->ses->capabilities & CAP_UNIX)
1473 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1475 if (create_options & CREATE_OPTION_READONLY)
1476 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1478 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1479 req->CreateDisposition = cpu_to_le32(disposition);
1480 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1482 /* BB Expirement with various impersonation levels and verify */
1483 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1484 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1487 inc_rfc1001_len(req, count);
1489 req->ByteCount = cpu_to_le16(count);
1490 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1491 (struct smb_hdr *)rsp, &bytes_returned, 0);
1492 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1494 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1495 cifs_buf_release(req);
1501 /* 1 byte no need to le_to_cpu */
1502 *oplock = rsp->OplockLevel;
1503 /* cifs fid stays in le */
1504 oparms->fid->netfid = rsp->Fid;
1506 /* Let caller know file was created so we can set the mode. */
1507 /* Do we care about the CreateAction in any other cases? */
1508 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1509 *oplock |= CIFS_CREATE_ACTION;
1512 /* copy from CreationTime to Attributes */
1513 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1514 /* the file_info buf is endian converted by caller */
1515 buf->AllocationSize = rsp->AllocationSize;
1516 buf->EndOfFile = rsp->EndOfFile;
1517 buf->NumberOfLinks = cpu_to_le32(1);
1518 buf->DeletePending = 0;
1521 cifs_buf_release(req);
1526 * Discard any remaining data in the current SMB. To do this, we borrow the
1530 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1532 unsigned int rfclen = server->pdu_size;
1533 int remaining = rfclen + server->vals->header_preamble_size -
1536 while (remaining > 0) {
1539 length = cifs_read_from_socket(server, server->bigbuf,
1540 min_t(unsigned int, remaining,
1541 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1544 server->total_read += length;
1545 remaining -= length;
1552 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1555 struct cifs_readdata *rdata = mid->callback_data;
1557 length = cifs_discard_remaining_data(server);
1558 dequeue_mid(mid, rdata->result);
1559 mid->resp_buf = server->smallbuf;
1560 server->smallbuf = NULL;
1565 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1568 unsigned int data_offset, data_len;
1569 struct cifs_readdata *rdata = mid->callback_data;
1570 char *buf = server->smallbuf;
1571 unsigned int buflen = server->pdu_size +
1572 server->vals->header_preamble_size;
1573 bool use_rdma_mr = false;
1575 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1576 __func__, mid->mid, rdata->offset, rdata->bytes);
1579 * read the rest of READ_RSP header (sans Data array), or whatever we
1580 * can if there's not enough data. At this point, we've read down to
1583 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1584 HEADER_SIZE(server) + 1;
1586 length = cifs_read_from_socket(server,
1587 buf + HEADER_SIZE(server) - 1, len);
1590 server->total_read += length;
1592 if (server->ops->is_session_expired &&
1593 server->ops->is_session_expired(buf)) {
1594 cifs_reconnect(server);
1595 wake_up(&server->response_q);
1599 if (server->ops->is_status_pending &&
1600 server->ops->is_status_pending(buf, server, 0)) {
1601 cifs_discard_remaining_data(server);
1605 /* Was the SMB read successful? */
1606 rdata->result = server->ops->map_error(buf, false);
1607 if (rdata->result != 0) {
1608 cifs_dbg(FYI, "%s: server returned error %d\n",
1609 __func__, rdata->result);
1610 return cifs_readv_discard(server, mid);
1613 /* Is there enough to get to the rest of the READ_RSP header? */
1614 if (server->total_read < server->vals->read_rsp_size) {
1615 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1616 __func__, server->total_read,
1617 server->vals->read_rsp_size);
1618 rdata->result = -EIO;
1619 return cifs_readv_discard(server, mid);
1622 data_offset = server->ops->read_data_offset(buf) +
1623 server->vals->header_preamble_size;
1624 if (data_offset < server->total_read) {
1626 * win2k8 sometimes sends an offset of 0 when the read
1627 * is beyond the EOF. Treat it as if the data starts just after
1630 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1631 __func__, data_offset);
1632 data_offset = server->total_read;
1633 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1634 /* data_offset is beyond the end of smallbuf */
1635 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1636 __func__, data_offset);
1637 rdata->result = -EIO;
1638 return cifs_readv_discard(server, mid);
1641 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1642 __func__, server->total_read, data_offset);
1644 len = data_offset - server->total_read;
1646 /* read any junk before data into the rest of smallbuf */
1647 length = cifs_read_from_socket(server,
1648 buf + server->total_read, len);
1651 server->total_read += length;
1654 /* set up first iov for signature check */
1655 rdata->iov[0].iov_base = buf;
1656 rdata->iov[0].iov_len = 4;
1657 rdata->iov[1].iov_base = buf + 4;
1658 rdata->iov[1].iov_len = server->total_read - 4;
1659 cifs_dbg(FYI, "0: iov_base=%p iov_len=%u\n",
1660 rdata->iov[0].iov_base, server->total_read);
1662 /* how much data is in the response? */
1663 #ifdef CONFIG_CIFS_SMB_DIRECT
1664 use_rdma_mr = rdata->mr;
1666 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1667 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1668 /* data_len is corrupt -- discard frame */
1669 rdata->result = -EIO;
1670 return cifs_readv_discard(server, mid);
1673 length = rdata->read_into_pages(server, rdata, data_len);
1677 server->total_read += length;
1679 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1680 server->total_read, buflen, data_len);
1682 /* discard anything left over */
1683 if (server->total_read < buflen)
1684 return cifs_readv_discard(server, mid);
1686 dequeue_mid(mid, false);
1687 mid->resp_buf = server->smallbuf;
1688 server->smallbuf = NULL;
1693 cifs_readv_callback(struct mid_q_entry *mid)
1695 struct cifs_readdata *rdata = mid->callback_data;
1696 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1697 struct TCP_Server_Info *server = tcon->ses->server;
1698 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1700 .rq_pages = rdata->pages,
1701 .rq_offset = rdata->page_offset,
1702 .rq_npages = rdata->nr_pages,
1703 .rq_pagesz = rdata->pagesz,
1704 .rq_tailsz = rdata->tailsz };
1706 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1707 __func__, mid->mid, mid->mid_state, rdata->result,
1710 switch (mid->mid_state) {
1711 case MID_RESPONSE_RECEIVED:
1712 /* result already set, check signature */
1716 rc = cifs_verify_signature(&rqst, server,
1717 mid->sequence_number);
1719 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1722 /* FIXME: should this be counted toward the initiating task? */
1723 task_io_account_read(rdata->got_bytes);
1724 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1726 case MID_REQUEST_SUBMITTED:
1727 case MID_RETRY_NEEDED:
1728 rdata->result = -EAGAIN;
1729 if (server->sign && rdata->got_bytes)
1730 /* reset bytes number since we can not check a sign */
1731 rdata->got_bytes = 0;
1732 /* FIXME: should this be counted toward the initiating task? */
1733 task_io_account_read(rdata->got_bytes);
1734 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1737 rdata->result = -EIO;
1740 queue_work(cifsiod_wq, &rdata->work);
1741 DeleteMidQEntry(mid);
1742 add_credits(server, 1, 0);
1745 /* cifs_async_readv - send an async write, and set up mid to handle result */
1747 cifs_async_readv(struct cifs_readdata *rdata)
1750 READ_REQ *smb = NULL;
1752 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1753 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1756 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1757 __func__, rdata->offset, rdata->bytes);
1759 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1762 wct = 10; /* old style read */
1763 if ((rdata->offset >> 32) > 0) {
1764 /* can not handle this big offset for old */
1769 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1773 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1774 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1776 smb->AndXCommand = 0xFF; /* none */
1777 smb->Fid = rdata->cfile->fid.netfid;
1778 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1780 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1782 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1783 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1787 /* old style read */
1788 struct smb_com_readx_req *smbr =
1789 (struct smb_com_readx_req *)smb;
1790 smbr->ByteCount = 0;
1793 /* 4 for RFC1001 length + 1 for BCC */
1794 rdata->iov[0].iov_base = smb;
1795 rdata->iov[0].iov_len = 4;
1796 rdata->iov[1].iov_base = (char *)smb + 4;
1797 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1799 kref_get(&rdata->refcount);
1800 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1801 cifs_readv_callback, NULL, rdata, 0);
1804 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1806 kref_put(&rdata->refcount, cifs_readdata_release);
1808 cifs_small_buf_release(smb);
1813 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1814 unsigned int *nbytes, char **buf, int *pbuf_type)
1817 READ_REQ *pSMB = NULL;
1818 READ_RSP *pSMBr = NULL;
1819 char *pReadData = NULL;
1821 int resp_buf_type = 0;
1823 struct kvec rsp_iov;
1824 __u32 pid = io_parms->pid;
1825 __u16 netfid = io_parms->netfid;
1826 __u64 offset = io_parms->offset;
1827 struct cifs_tcon *tcon = io_parms->tcon;
1828 unsigned int count = io_parms->length;
1830 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1831 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1834 wct = 10; /* old style read */
1835 if ((offset >> 32) > 0) {
1836 /* can not handle this big offset for old */
1842 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1846 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1847 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1849 /* tcon and ses pointer are checked in smb_init */
1850 if (tcon->ses->server == NULL)
1851 return -ECONNABORTED;
1853 pSMB->AndXCommand = 0xFF; /* none */
1855 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1857 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1859 pSMB->Remaining = 0;
1860 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1861 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1863 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1865 /* old style read */
1866 struct smb_com_readx_req *pSMBW =
1867 (struct smb_com_readx_req *)pSMB;
1868 pSMBW->ByteCount = 0;
1871 iov[0].iov_base = (char *)pSMB;
1872 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1873 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1874 CIFS_LOG_ERROR, &rsp_iov);
1875 cifs_small_buf_release(pSMB);
1876 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1877 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1879 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1881 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1882 data_length = data_length << 16;
1883 data_length += le16_to_cpu(pSMBr->DataLength);
1884 *nbytes = data_length;
1886 /*check that DataLength would not go beyond end of SMB */
1887 if ((data_length > CIFSMaxBufSize)
1888 || (data_length > count)) {
1889 cifs_dbg(FYI, "bad length %d for count %d\n",
1890 data_length, count);
1894 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1895 le16_to_cpu(pSMBr->DataOffset);
1896 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1897 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1899 }*/ /* can not use copy_to_user when using page cache*/
1901 memcpy(*buf, pReadData, data_length);
1906 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1907 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1908 /* return buffer to caller to free */
1909 *buf = rsp_iov.iov_base;
1910 if (resp_buf_type == CIFS_SMALL_BUFFER)
1911 *pbuf_type = CIFS_SMALL_BUFFER;
1912 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1913 *pbuf_type = CIFS_LARGE_BUFFER;
1914 } /* else no valid buffer on return - leave as null */
1916 /* Note: On -EAGAIN error only caller can retry on handle based calls
1917 since file handle passed in no longer valid */
1923 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1924 unsigned int *nbytes, const char *buf)
1927 WRITE_REQ *pSMB = NULL;
1928 WRITE_RSP *pSMBr = NULL;
1929 int bytes_returned, wct;
1932 __u32 pid = io_parms->pid;
1933 __u16 netfid = io_parms->netfid;
1934 __u64 offset = io_parms->offset;
1935 struct cifs_tcon *tcon = io_parms->tcon;
1936 unsigned int count = io_parms->length;
1940 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1941 if (tcon->ses == NULL)
1942 return -ECONNABORTED;
1944 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1948 if ((offset >> 32) > 0) {
1949 /* can not handle big offset for old srv */
1954 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1959 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1960 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1962 /* tcon and ses pointer are checked in smb_init */
1963 if (tcon->ses->server == NULL)
1964 return -ECONNABORTED;
1966 pSMB->AndXCommand = 0xFF; /* none */
1968 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1970 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1972 pSMB->Reserved = 0xFFFFFFFF;
1973 pSMB->WriteMode = 0;
1974 pSMB->Remaining = 0;
1976 /* Can increase buffer size if buffer is big enough in some cases ie we
1977 can send more if LARGE_WRITE_X capability returned by the server and if
1978 our buffer is big enough or if we convert to iovecs on socket writes
1979 and eliminate the copy to the CIFS buffer */
1980 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1981 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1983 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1987 if (bytes_sent > count)
1990 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1992 memcpy(pSMB->Data, buf, bytes_sent);
1993 else if (count != 0) {
1995 cifs_buf_release(pSMB);
1997 } /* else setting file size with write of zero bytes */
1999 byte_count = bytes_sent + 1; /* pad */
2000 else /* wct == 12 */
2001 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
2003 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
2004 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
2005 inc_rfc1001_len(pSMB, byte_count);
2008 pSMB->ByteCount = cpu_to_le16(byte_count);
2009 else { /* old style write has byte count 4 bytes earlier
2011 struct smb_com_writex_req *pSMBW =
2012 (struct smb_com_writex_req *)pSMB;
2013 pSMBW->ByteCount = cpu_to_le16(byte_count);
2016 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2017 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2018 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2020 cifs_dbg(FYI, "Send error in write = %d\n", rc);
2022 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2023 *nbytes = (*nbytes) << 16;
2024 *nbytes += le16_to_cpu(pSMBr->Count);
2027 * Mask off high 16 bits when bytes written as returned by the
2028 * server is greater than bytes requested by the client. Some
2029 * OS/2 servers are known to set incorrect CountHigh values.
2031 if (*nbytes > count)
2035 cifs_buf_release(pSMB);
2037 /* Note: On -EAGAIN error only caller can retry on handle based calls
2038 since file handle passed in no longer valid */
2044 cifs_writedata_release(struct kref *refcount)
2046 struct cifs_writedata *wdata = container_of(refcount,
2047 struct cifs_writedata, refcount);
2048 #ifdef CONFIG_CIFS_SMB_DIRECT
2050 smbd_deregister_mr(wdata->mr);
2056 cifsFileInfo_put(wdata->cfile);
2058 kvfree(wdata->pages);
2063 * Write failed with a retryable error. Resend the write request. It's also
2064 * possible that the page was redirtied so re-clean the page.
2067 cifs_writev_requeue(struct cifs_writedata *wdata)
2070 struct inode *inode = d_inode(wdata->cfile->dentry);
2071 struct TCP_Server_Info *server;
2072 unsigned int rest_len;
2074 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
2076 rest_len = wdata->bytes;
2078 struct cifs_writedata *wdata2;
2079 unsigned int j, nr_pages, wsize, tailsz, cur_len;
2081 wsize = server->ops->wp_retry_size(inode);
2082 if (wsize < rest_len) {
2083 nr_pages = wsize / PAGE_SIZE;
2088 cur_len = nr_pages * PAGE_SIZE;
2091 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
2093 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
2096 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
2102 for (j = 0; j < nr_pages; j++) {
2103 wdata2->pages[j] = wdata->pages[i + j];
2104 lock_page(wdata2->pages[j]);
2105 clear_page_dirty_for_io(wdata2->pages[j]);
2108 wdata2->sync_mode = wdata->sync_mode;
2109 wdata2->nr_pages = nr_pages;
2110 wdata2->offset = page_offset(wdata2->pages[0]);
2111 wdata2->pagesz = PAGE_SIZE;
2112 wdata2->tailsz = tailsz;
2113 wdata2->bytes = cur_len;
2115 wdata2->cfile = find_writable_file(CIFS_I(inode), false);
2116 if (!wdata2->cfile) {
2117 cifs_dbg(VFS, "No writable handles for inode\n");
2121 wdata2->pid = wdata2->cfile->pid;
2122 rc = server->ops->async_writev(wdata2, cifs_writedata_release);
2124 for (j = 0; j < nr_pages; j++) {
2125 unlock_page(wdata2->pages[j]);
2126 if (rc != 0 && !is_retryable_error(rc)) {
2127 SetPageError(wdata2->pages[j]);
2128 end_page_writeback(wdata2->pages[j]);
2129 put_page(wdata2->pages[j]);
2134 kref_put(&wdata2->refcount, cifs_writedata_release);
2135 if (is_retryable_error(rc))
2140 rest_len -= cur_len;
2142 } while (i < wdata->nr_pages);
2144 if (rc != 0 && !is_retryable_error(rc))
2145 mapping_set_error(inode->i_mapping, rc);
2146 kref_put(&wdata->refcount, cifs_writedata_release);
2150 cifs_writev_complete(struct work_struct *work)
2152 struct cifs_writedata *wdata = container_of(work,
2153 struct cifs_writedata, work);
2154 struct inode *inode = d_inode(wdata->cfile->dentry);
2157 if (wdata->result == 0) {
2158 spin_lock(&inode->i_lock);
2159 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2160 spin_unlock(&inode->i_lock);
2161 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2163 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2164 return cifs_writev_requeue(wdata);
2166 for (i = 0; i < wdata->nr_pages; i++) {
2167 struct page *page = wdata->pages[i];
2168 if (wdata->result == -EAGAIN)
2169 __set_page_dirty_nobuffers(page);
2170 else if (wdata->result < 0)
2172 end_page_writeback(page);
2175 if (wdata->result != -EAGAIN)
2176 mapping_set_error(inode->i_mapping, wdata->result);
2177 kref_put(&wdata->refcount, cifs_writedata_release);
2180 struct cifs_writedata *
2181 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2183 struct page **pages =
2184 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2186 return cifs_writedata_direct_alloc(pages, complete);
2191 struct cifs_writedata *
2192 cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2194 struct cifs_writedata *wdata;
2196 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2197 if (wdata != NULL) {
2198 wdata->pages = pages;
2199 kref_init(&wdata->refcount);
2200 INIT_LIST_HEAD(&wdata->list);
2201 init_completion(&wdata->done);
2202 INIT_WORK(&wdata->work, complete);
2208 * Check the mid_state and signature on received buffer (if any), and queue the
2209 * workqueue completion task.
2212 cifs_writev_callback(struct mid_q_entry *mid)
2214 struct cifs_writedata *wdata = mid->callback_data;
2215 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2216 unsigned int written;
2217 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2219 switch (mid->mid_state) {
2220 case MID_RESPONSE_RECEIVED:
2221 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2222 if (wdata->result != 0)
2225 written = le16_to_cpu(smb->CountHigh);
2227 written += le16_to_cpu(smb->Count);
2229 * Mask off high 16 bits when bytes written as returned
2230 * by the server is greater than bytes requested by the
2231 * client. OS/2 servers are known to set incorrect
2234 if (written > wdata->bytes)
2237 if (written < wdata->bytes)
2238 wdata->result = -ENOSPC;
2240 wdata->bytes = written;
2242 case MID_REQUEST_SUBMITTED:
2243 case MID_RETRY_NEEDED:
2244 wdata->result = -EAGAIN;
2247 wdata->result = -EIO;
2251 queue_work(cifsiod_wq, &wdata->work);
2252 DeleteMidQEntry(mid);
2253 add_credits(tcon->ses->server, 1, 0);
2256 /* cifs_async_writev - send an async write, and set up mid to handle result */
2258 cifs_async_writev(struct cifs_writedata *wdata,
2259 void (*release)(struct kref *kref))
2262 WRITE_REQ *smb = NULL;
2264 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2266 struct smb_rqst rqst = { };
2268 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2272 if (wdata->offset >> 32 > 0) {
2273 /* can not handle big offset for old srv */
2278 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2280 goto async_writev_out;
2282 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2283 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2285 smb->AndXCommand = 0xFF; /* none */
2286 smb->Fid = wdata->cfile->fid.netfid;
2287 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2289 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2290 smb->Reserved = 0xFFFFFFFF;
2295 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2297 /* 4 for RFC1001 length + 1 for BCC */
2299 iov[0].iov_base = smb;
2300 iov[1].iov_len = get_rfc1002_length(smb) + 1;
2301 iov[1].iov_base = (char *)smb + 4;
2305 rqst.rq_pages = wdata->pages;
2306 rqst.rq_offset = wdata->page_offset;
2307 rqst.rq_npages = wdata->nr_pages;
2308 rqst.rq_pagesz = wdata->pagesz;
2309 rqst.rq_tailsz = wdata->tailsz;
2311 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2312 wdata->offset, wdata->bytes);
2314 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2315 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2318 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2319 put_bcc(wdata->bytes + 1, &smb->hdr);
2322 struct smb_com_writex_req *smbw =
2323 (struct smb_com_writex_req *)smb;
2324 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2325 put_bcc(wdata->bytes + 5, &smbw->hdr);
2326 iov[1].iov_len += 4; /* pad bigger by four bytes */
2329 kref_get(&wdata->refcount);
2330 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2331 cifs_writev_callback, NULL, wdata, 0);
2334 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2336 kref_put(&wdata->refcount, release);
2339 cifs_small_buf_release(smb);
2344 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2345 unsigned int *nbytes, struct kvec *iov, int n_vec)
2348 WRITE_REQ *pSMB = NULL;
2351 int resp_buf_type = 0;
2352 __u32 pid = io_parms->pid;
2353 __u16 netfid = io_parms->netfid;
2354 __u64 offset = io_parms->offset;
2355 struct cifs_tcon *tcon = io_parms->tcon;
2356 unsigned int count = io_parms->length;
2357 struct kvec rsp_iov;
2361 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2363 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2367 if ((offset >> 32) > 0) {
2368 /* can not handle big offset for old srv */
2372 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2376 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2377 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2379 /* tcon and ses pointer are checked in smb_init */
2380 if (tcon->ses->server == NULL)
2381 return -ECONNABORTED;
2383 pSMB->AndXCommand = 0xFF; /* none */
2385 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2387 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2388 pSMB->Reserved = 0xFFFFFFFF;
2389 pSMB->WriteMode = 0;
2390 pSMB->Remaining = 0;
2393 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2395 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2396 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2397 /* header + 1 byte pad */
2398 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2400 inc_rfc1001_len(pSMB, count + 1);
2401 else /* wct == 12 */
2402 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2404 pSMB->ByteCount = cpu_to_le16(count + 1);
2405 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2406 struct smb_com_writex_req *pSMBW =
2407 (struct smb_com_writex_req *)pSMB;
2408 pSMBW->ByteCount = cpu_to_le16(count + 5);
2410 iov[0].iov_base = pSMB;
2412 iov[0].iov_len = smb_hdr_len + 4;
2413 else /* wct == 12 pad bigger by four bytes */
2414 iov[0].iov_len = smb_hdr_len + 8;
2416 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2418 cifs_small_buf_release(pSMB);
2419 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2421 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2422 } else if (resp_buf_type == 0) {
2423 /* presumably this can not happen, but best to be safe */
2426 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2427 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2428 *nbytes = (*nbytes) << 16;
2429 *nbytes += le16_to_cpu(pSMBr->Count);
2432 * Mask off high 16 bits when bytes written as returned by the
2433 * server is greater than bytes requested by the client. OS/2
2434 * servers are known to set incorrect CountHigh values.
2436 if (*nbytes > count)
2440 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2442 /* Note: On -EAGAIN error only caller can retry on handle based calls
2443 since file handle passed in no longer valid */
2448 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2449 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2450 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2453 LOCK_REQ *pSMB = NULL;
2455 struct kvec rsp_iov;
2459 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2460 num_lock, num_unlock);
2462 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2467 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2468 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2469 pSMB->LockType = lock_type;
2470 pSMB->AndXCommand = 0xFF; /* none */
2471 pSMB->Fid = netfid; /* netfid stays le */
2473 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2474 inc_rfc1001_len(pSMB, count);
2475 pSMB->ByteCount = cpu_to_le16(count);
2477 iov[0].iov_base = (char *)pSMB;
2478 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2479 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2480 iov[1].iov_base = (char *)buf;
2481 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2483 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2484 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP,
2486 cifs_small_buf_release(pSMB);
2488 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2494 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2495 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2496 const __u64 offset, const __u32 numUnlock,
2497 const __u32 numLock, const __u8 lockType,
2498 const bool waitFlag, const __u8 oplock_level)
2501 LOCK_REQ *pSMB = NULL;
2502 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2507 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2508 (int)waitFlag, numLock);
2509 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2514 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2515 /* no response expected */
2516 flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP;
2518 } else if (waitFlag) {
2519 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2520 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2525 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2526 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2527 pSMB->LockType = lockType;
2528 pSMB->OplockLevel = oplock_level;
2529 pSMB->AndXCommand = 0xFF; /* none */
2530 pSMB->Fid = smb_file_id; /* netfid stays le */
2532 if ((numLock != 0) || (numUnlock != 0)) {
2533 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2534 /* BB where to store pid high? */
2535 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2536 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2537 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2538 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2539 count = sizeof(LOCKING_ANDX_RANGE);
2544 inc_rfc1001_len(pSMB, count);
2545 pSMB->ByteCount = cpu_to_le16(count);
2548 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2549 (struct smb_hdr *) pSMB, &bytes_returned);
2551 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2552 cifs_small_buf_release(pSMB);
2553 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2555 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2557 /* Note: On -EAGAIN error only caller can retry on handle based calls
2558 since file handle passed in no longer valid */
2563 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2564 const __u16 smb_file_id, const __u32 netpid,
2565 const loff_t start_offset, const __u64 len,
2566 struct file_lock *pLockData, const __u16 lock_type,
2567 const bool waitFlag)
2569 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2570 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2571 struct cifs_posix_lock *parm_data;
2574 int bytes_returned = 0;
2575 int resp_buf_type = 0;
2576 __u16 params, param_offset, offset, byte_count, count;
2578 struct kvec rsp_iov;
2580 cifs_dbg(FYI, "Posix Lock\n");
2582 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2587 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2590 pSMB->MaxSetupCount = 0;
2593 pSMB->Reserved2 = 0;
2594 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2595 offset = param_offset + params;
2597 count = sizeof(struct cifs_posix_lock);
2598 pSMB->MaxParameterCount = cpu_to_le16(2);
2599 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2600 pSMB->SetupCount = 1;
2601 pSMB->Reserved3 = 0;
2603 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2605 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2606 byte_count = 3 /* pad */ + params + count;
2607 pSMB->DataCount = cpu_to_le16(count);
2608 pSMB->ParameterCount = cpu_to_le16(params);
2609 pSMB->TotalDataCount = pSMB->DataCount;
2610 pSMB->TotalParameterCount = pSMB->ParameterCount;
2611 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2612 parm_data = (struct cifs_posix_lock *)
2613 (((char *) &pSMB->hdr.Protocol) + offset);
2615 parm_data->lock_type = cpu_to_le16(lock_type);
2617 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2618 parm_data->lock_flags = cpu_to_le16(1);
2619 pSMB->Timeout = cpu_to_le32(-1);
2623 parm_data->pid = cpu_to_le32(netpid);
2624 parm_data->start = cpu_to_le64(start_offset);
2625 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2627 pSMB->DataOffset = cpu_to_le16(offset);
2628 pSMB->Fid = smb_file_id;
2629 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2630 pSMB->Reserved4 = 0;
2631 inc_rfc1001_len(pSMB, byte_count);
2632 pSMB->ByteCount = cpu_to_le16(byte_count);
2634 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2635 (struct smb_hdr *) pSMBr, &bytes_returned);
2637 iov[0].iov_base = (char *)pSMB;
2638 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2639 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2640 &resp_buf_type, timeout, &rsp_iov);
2641 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2643 cifs_small_buf_release(pSMB);
2646 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2647 } else if (pLockData) {
2648 /* lock structure can be returned on get */
2651 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2653 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2654 rc = -EIO; /* bad smb */
2657 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2658 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2659 if (data_count < sizeof(struct cifs_posix_lock)) {
2663 parm_data = (struct cifs_posix_lock *)
2664 ((char *)&pSMBr->hdr.Protocol + data_offset);
2665 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2666 pLockData->fl_type = F_UNLCK;
2668 if (parm_data->lock_type ==
2669 cpu_to_le16(CIFS_RDLCK))
2670 pLockData->fl_type = F_RDLCK;
2671 else if (parm_data->lock_type ==
2672 cpu_to_le16(CIFS_WRLCK))
2673 pLockData->fl_type = F_WRLCK;
2675 pLockData->fl_start = le64_to_cpu(parm_data->start);
2676 pLockData->fl_end = pLockData->fl_start +
2677 le64_to_cpu(parm_data->length) - 1;
2678 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2683 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2685 /* Note: On -EAGAIN error only caller can retry on handle based calls
2686 since file handle passed in no longer valid */
2693 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2696 CLOSE_REQ *pSMB = NULL;
2697 cifs_dbg(FYI, "In CIFSSMBClose\n");
2699 /* do not retry on dead session on close */
2700 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2706 pSMB->FileID = (__u16) smb_file_id;
2707 pSMB->LastWriteTime = 0xFFFFFFFF;
2708 pSMB->ByteCount = 0;
2709 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2710 cifs_small_buf_release(pSMB);
2711 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2714 /* EINTR is expected when user ctl-c to kill app */
2715 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2719 /* Since session is dead, file will be closed on server already */
2727 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2730 FLUSH_REQ *pSMB = NULL;
2731 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2733 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2737 pSMB->FileID = (__u16) smb_file_id;
2738 pSMB->ByteCount = 0;
2739 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2740 cifs_small_buf_release(pSMB);
2741 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2743 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2749 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2750 const char *from_name, const char *to_name,
2751 struct cifs_sb_info *cifs_sb)
2754 RENAME_REQ *pSMB = NULL;
2755 RENAME_RSP *pSMBr = NULL;
2757 int name_len, name_len2;
2759 int remap = cifs_remap(cifs_sb);
2761 cifs_dbg(FYI, "In CIFSSMBRename\n");
2763 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2768 pSMB->BufferFormat = 0x04;
2769 pSMB->SearchAttributes =
2770 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2773 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2774 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2775 from_name, PATH_MAX,
2776 cifs_sb->local_nls, remap);
2777 name_len++; /* trailing null */
2779 pSMB->OldFileName[name_len] = 0x04; /* pad */
2780 /* protocol requires ASCII signature byte on Unicode string */
2781 pSMB->OldFileName[name_len + 1] = 0x00;
2783 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2784 to_name, PATH_MAX, cifs_sb->local_nls,
2786 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2787 name_len2 *= 2; /* convert to bytes */
2788 } else { /* BB improve the check for buffer overruns BB */
2789 name_len = strnlen(from_name, PATH_MAX);
2790 name_len++; /* trailing null */
2791 strncpy(pSMB->OldFileName, from_name, name_len);
2792 name_len2 = strnlen(to_name, PATH_MAX);
2793 name_len2++; /* trailing null */
2794 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2795 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
2796 name_len2++; /* trailing null */
2797 name_len2++; /* signature byte */
2800 count = 1 /* 1st signature byte */ + name_len + name_len2;
2801 inc_rfc1001_len(pSMB, count);
2802 pSMB->ByteCount = cpu_to_le16(count);
2804 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2805 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2806 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2808 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2810 cifs_buf_release(pSMB);
2818 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2819 int netfid, const char *target_name,
2820 const struct nls_table *nls_codepage, int remap)
2822 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2823 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2824 struct set_file_rename *rename_info;
2826 char dummy_string[30];
2828 int bytes_returned = 0;
2830 __u16 params, param_offset, offset, count, byte_count;
2832 cifs_dbg(FYI, "Rename to File by handle\n");
2833 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2839 pSMB->MaxSetupCount = 0;
2843 pSMB->Reserved2 = 0;
2844 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2845 offset = param_offset + params;
2847 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2848 rename_info = (struct set_file_rename *) data_offset;
2849 pSMB->MaxParameterCount = cpu_to_le16(2);
2850 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2851 pSMB->SetupCount = 1;
2852 pSMB->Reserved3 = 0;
2853 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2854 byte_count = 3 /* pad */ + params;
2855 pSMB->ParameterCount = cpu_to_le16(params);
2856 pSMB->TotalParameterCount = pSMB->ParameterCount;
2857 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2858 pSMB->DataOffset = cpu_to_le16(offset);
2859 /* construct random name ".cifs_tmp<inodenum><mid>" */
2860 rename_info->overwrite = cpu_to_le32(1);
2861 rename_info->root_fid = 0;
2862 /* unicode only call */
2863 if (target_name == NULL) {
2864 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2866 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2867 dummy_string, 24, nls_codepage, remap);
2870 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2871 target_name, PATH_MAX, nls_codepage,
2874 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2875 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2876 byte_count += count;
2877 pSMB->DataCount = cpu_to_le16(count);
2878 pSMB->TotalDataCount = pSMB->DataCount;
2880 pSMB->InformationLevel =
2881 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2882 pSMB->Reserved4 = 0;
2883 inc_rfc1001_len(pSMB, byte_count);
2884 pSMB->ByteCount = cpu_to_le16(byte_count);
2885 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2886 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2887 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2889 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2892 cifs_buf_release(pSMB);
2894 /* Note: On -EAGAIN error only caller can retry on handle based calls
2895 since file handle passed in no longer valid */
2901 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2902 const char *fromName, const __u16 target_tid, const char *toName,
2903 const int flags, const struct nls_table *nls_codepage, int remap)
2906 COPY_REQ *pSMB = NULL;
2907 COPY_RSP *pSMBr = NULL;
2909 int name_len, name_len2;
2912 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2914 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2919 pSMB->BufferFormat = 0x04;
2920 pSMB->Tid2 = target_tid;
2922 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2924 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2925 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2926 fromName, PATH_MAX, nls_codepage,
2928 name_len++; /* trailing null */
2930 pSMB->OldFileName[name_len] = 0x04; /* pad */
2931 /* protocol requires ASCII signature byte on Unicode string */
2932 pSMB->OldFileName[name_len + 1] = 0x00;
2934 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2935 toName, PATH_MAX, nls_codepage, remap);
2936 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2937 name_len2 *= 2; /* convert to bytes */
2938 } else { /* BB improve the check for buffer overruns BB */
2939 name_len = strnlen(fromName, PATH_MAX);
2940 name_len++; /* trailing null */
2941 strncpy(pSMB->OldFileName, fromName, name_len);
2942 name_len2 = strnlen(toName, PATH_MAX);
2943 name_len2++; /* trailing null */
2944 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2945 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2946 name_len2++; /* trailing null */
2947 name_len2++; /* signature byte */
2950 count = 1 /* 1st signature byte */ + name_len + name_len2;
2951 inc_rfc1001_len(pSMB, count);
2952 pSMB->ByteCount = cpu_to_le16(count);
2954 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2955 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2957 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2958 rc, le16_to_cpu(pSMBr->CopyCount));
2960 cifs_buf_release(pSMB);
2969 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2970 const char *fromName, const char *toName,
2971 const struct nls_table *nls_codepage, int remap)
2973 TRANSACTION2_SPI_REQ *pSMB = NULL;
2974 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2977 int name_len_target;
2979 int bytes_returned = 0;
2980 __u16 params, param_offset, offset, byte_count;
2982 cifs_dbg(FYI, "In Symlink Unix style\n");
2984 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2989 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2991 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2992 /* find define for this maxpathcomponent */
2993 PATH_MAX, nls_codepage, remap);
2994 name_len++; /* trailing null */
2997 } else { /* BB improve the check for buffer overruns BB */
2998 name_len = strnlen(fromName, PATH_MAX);
2999 name_len++; /* trailing null */
3000 strncpy(pSMB->FileName, fromName, name_len);
3002 params = 6 + name_len;
3003 pSMB->MaxSetupCount = 0;
3007 pSMB->Reserved2 = 0;
3008 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3009 InformationLevel) - 4;
3010 offset = param_offset + params;
3012 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
3013 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3015 cifsConvertToUTF16((__le16 *) data_offset, toName,
3016 /* find define for this maxpathcomponent */
3017 PATH_MAX, nls_codepage, remap);
3018 name_len_target++; /* trailing null */
3019 name_len_target *= 2;
3020 } else { /* BB improve the check for buffer overruns BB */
3021 name_len_target = strnlen(toName, PATH_MAX);
3022 name_len_target++; /* trailing null */
3023 strncpy(data_offset, toName, name_len_target);
3026 pSMB->MaxParameterCount = cpu_to_le16(2);
3027 /* BB find exact max on data count below from sess */
3028 pSMB->MaxDataCount = cpu_to_le16(1000);
3029 pSMB->SetupCount = 1;
3030 pSMB->Reserved3 = 0;
3031 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3032 byte_count = 3 /* pad */ + params + name_len_target;
3033 pSMB->DataCount = cpu_to_le16(name_len_target);
3034 pSMB->ParameterCount = cpu_to_le16(params);
3035 pSMB->TotalDataCount = pSMB->DataCount;
3036 pSMB->TotalParameterCount = pSMB->ParameterCount;
3037 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3038 pSMB->DataOffset = cpu_to_le16(offset);
3039 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
3040 pSMB->Reserved4 = 0;
3041 inc_rfc1001_len(pSMB, byte_count);
3042 pSMB->ByteCount = cpu_to_le16(byte_count);
3043 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3044 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3045 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
3047 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
3050 cifs_buf_release(pSMB);
3053 goto createSymLinkRetry;
3059 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3060 const char *fromName, const char *toName,
3061 const struct nls_table *nls_codepage, int remap)
3063 TRANSACTION2_SPI_REQ *pSMB = NULL;
3064 TRANSACTION2_SPI_RSP *pSMBr = NULL;
3067 int name_len_target;
3069 int bytes_returned = 0;
3070 __u16 params, param_offset, offset, byte_count;
3072 cifs_dbg(FYI, "In Create Hard link Unix style\n");
3073 createHardLinkRetry:
3074 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3079 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3080 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
3081 PATH_MAX, nls_codepage, remap);
3082 name_len++; /* trailing null */
3085 } else { /* BB improve the check for buffer overruns BB */
3086 name_len = strnlen(toName, PATH_MAX);
3087 name_len++; /* trailing null */
3088 strncpy(pSMB->FileName, toName, name_len);
3090 params = 6 + name_len;
3091 pSMB->MaxSetupCount = 0;
3095 pSMB->Reserved2 = 0;
3096 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3097 InformationLevel) - 4;
3098 offset = param_offset + params;
3100 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
3101 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3103 cifsConvertToUTF16((__le16 *) data_offset, fromName,
3104 PATH_MAX, nls_codepage, remap);
3105 name_len_target++; /* trailing null */
3106 name_len_target *= 2;
3107 } else { /* BB improve the check for buffer overruns BB */
3108 name_len_target = strnlen(fromName, PATH_MAX);
3109 name_len_target++; /* trailing null */
3110 strncpy(data_offset, fromName, name_len_target);
3113 pSMB->MaxParameterCount = cpu_to_le16(2);
3114 /* BB find exact max on data count below from sess*/
3115 pSMB->MaxDataCount = cpu_to_le16(1000);
3116 pSMB->SetupCount = 1;
3117 pSMB->Reserved3 = 0;
3118 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3119 byte_count = 3 /* pad */ + params + name_len_target;
3120 pSMB->ParameterCount = cpu_to_le16(params);
3121 pSMB->TotalParameterCount = pSMB->ParameterCount;
3122 pSMB->DataCount = cpu_to_le16(name_len_target);
3123 pSMB->TotalDataCount = pSMB->DataCount;
3124 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3125 pSMB->DataOffset = cpu_to_le16(offset);
3126 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3127 pSMB->Reserved4 = 0;
3128 inc_rfc1001_len(pSMB, byte_count);
3129 pSMB->ByteCount = cpu_to_le16(byte_count);
3130 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3131 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3132 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3134 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3137 cifs_buf_release(pSMB);
3139 goto createHardLinkRetry;
3145 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3146 const char *from_name, const char *to_name,
3147 struct cifs_sb_info *cifs_sb)
3150 NT_RENAME_REQ *pSMB = NULL;
3151 RENAME_RSP *pSMBr = NULL;
3153 int name_len, name_len2;
3155 int remap = cifs_remap(cifs_sb);
3157 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3158 winCreateHardLinkRetry:
3160 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3165 pSMB->SearchAttributes =
3166 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3168 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3169 pSMB->ClusterCount = 0;
3171 pSMB->BufferFormat = 0x04;
3173 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3175 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3176 PATH_MAX, cifs_sb->local_nls, remap);
3177 name_len++; /* trailing null */
3180 /* protocol specifies ASCII buffer format (0x04) for unicode */
3181 pSMB->OldFileName[name_len] = 0x04;
3182 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3184 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3185 to_name, PATH_MAX, cifs_sb->local_nls,
3187 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3188 name_len2 *= 2; /* convert to bytes */
3189 } else { /* BB improve the check for buffer overruns BB */
3190 name_len = strnlen(from_name, PATH_MAX);
3191 name_len++; /* trailing null */
3192 strncpy(pSMB->OldFileName, from_name, name_len);
3193 name_len2 = strnlen(to_name, PATH_MAX);
3194 name_len2++; /* trailing null */
3195 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3196 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
3197 name_len2++; /* trailing null */
3198 name_len2++; /* signature byte */
3201 count = 1 /* string type byte */ + name_len + name_len2;
3202 inc_rfc1001_len(pSMB, count);
3203 pSMB->ByteCount = cpu_to_le16(count);
3205 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3206 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3207 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3209 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3211 cifs_buf_release(pSMB);
3213 goto winCreateHardLinkRetry;
3219 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3220 const unsigned char *searchName, char **symlinkinfo,
3221 const struct nls_table *nls_codepage, int remap)
3223 /* SMB_QUERY_FILE_UNIX_LINK */
3224 TRANSACTION2_QPI_REQ *pSMB = NULL;
3225 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3229 __u16 params, byte_count;
3232 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3235 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3240 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3242 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3243 searchName, PATH_MAX, nls_codepage,
3245 name_len++; /* trailing null */
3247 } else { /* BB improve the check for buffer overruns BB */
3248 name_len = strnlen(searchName, PATH_MAX);
3249 name_len++; /* trailing null */
3250 strncpy(pSMB->FileName, searchName, name_len);
3253 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3254 pSMB->TotalDataCount = 0;
3255 pSMB->MaxParameterCount = cpu_to_le16(2);
3256 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3257 pSMB->MaxSetupCount = 0;
3261 pSMB->Reserved2 = 0;
3262 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3263 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3264 pSMB->DataCount = 0;
3265 pSMB->DataOffset = 0;
3266 pSMB->SetupCount = 1;
3267 pSMB->Reserved3 = 0;
3268 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3269 byte_count = params + 1 /* pad */ ;
3270 pSMB->TotalParameterCount = cpu_to_le16(params);
3271 pSMB->ParameterCount = pSMB->TotalParameterCount;
3272 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3273 pSMB->Reserved4 = 0;
3274 inc_rfc1001_len(pSMB, byte_count);
3275 pSMB->ByteCount = cpu_to_le16(byte_count);
3277 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3278 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3280 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3282 /* decode response */
3284 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3285 /* BB also check enough total bytes returned */
3286 if (rc || get_bcc(&pSMBr->hdr) < 2)
3290 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3292 data_start = ((char *) &pSMBr->hdr.Protocol) +
3293 le16_to_cpu(pSMBr->t2.DataOffset);
3295 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3300 /* BB FIXME investigate remapping reserved chars here */
3301 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3302 count, is_unicode, nls_codepage);
3307 cifs_buf_release(pSMB);
3309 goto querySymLinkRetry;
3314 * Recent Windows versions now create symlinks more frequently
3315 * and they use the "reparse point" mechanism below. We can of course
3316 * do symlinks nicely to Samba and other servers which support the
3317 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3318 * "MF" symlinks optionally, but for recent Windows we really need to
3319 * reenable the code below and fix the cifs_symlink callers to handle this.
3320 * In the interim this code has been moved to its own config option so
3321 * it is not compiled in by default until callers fixed up and more tested.
3324 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3325 __u16 fid, char **symlinkinfo,
3326 const struct nls_table *nls_codepage)
3330 struct smb_com_transaction_ioctl_req *pSMB;
3331 struct smb_com_transaction_ioctl_rsp *pSMBr;
3333 unsigned int sub_len;
3335 struct reparse_symlink_data *reparse_buf;
3336 struct reparse_posix_data *posix_buf;
3337 __u32 data_offset, data_count;
3340 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3341 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3346 pSMB->TotalParameterCount = 0 ;
3347 pSMB->TotalDataCount = 0;
3348 pSMB->MaxParameterCount = cpu_to_le32(2);
3349 /* BB find exact data count max from sess structure BB */
3350 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3351 pSMB->MaxSetupCount = 4;
3353 pSMB->ParameterOffset = 0;
3354 pSMB->DataCount = 0;
3355 pSMB->DataOffset = 0;
3356 pSMB->SetupCount = 4;
3357 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3358 pSMB->ParameterCount = pSMB->TotalParameterCount;
3359 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3360 pSMB->IsFsctl = 1; /* FSCTL */
3361 pSMB->IsRootFlag = 0;
3362 pSMB->Fid = fid; /* file handle always le */
3363 pSMB->ByteCount = 0;
3365 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3366 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3368 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3372 data_offset = le32_to_cpu(pSMBr->DataOffset);
3373 data_count = le32_to_cpu(pSMBr->DataCount);
3374 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3375 /* BB also check enough total bytes returned */
3376 rc = -EIO; /* bad smb */
3379 if (!data_count || (data_count > 2048)) {
3381 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3384 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3385 reparse_buf = (struct reparse_symlink_data *)
3386 ((char *)&pSMBr->hdr.Protocol + data_offset);
3387 if ((char *)reparse_buf >= end_of_smb) {
3391 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3392 cifs_dbg(FYI, "NFS style reparse tag\n");
3393 posix_buf = (struct reparse_posix_data *)reparse_buf;
3395 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3396 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3397 le64_to_cpu(posix_buf->InodeType));
3402 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3403 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3404 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3408 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3409 sub_len, is_unicode, nls_codepage);
3411 } else if (reparse_buf->ReparseTag !=
3412 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3417 /* Reparse tag is NTFS symlink */
3418 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3419 reparse_buf->PathBuffer;
3420 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3421 if (sub_start + sub_len > end_of_smb) {
3422 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3426 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3431 /* BB FIXME investigate remapping reserved chars here */
3432 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3437 cifs_buf_release(pSMB);
3440 * Note: On -EAGAIN error only caller can retry on handle based calls
3441 * since file handle passed in no longer valid.
3447 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3452 struct smb_com_transaction_compr_ioctl_req *pSMB;
3453 struct smb_com_transaction_ioctl_rsp *pSMBr;
3455 cifs_dbg(FYI, "Set compression for %u\n", fid);
3456 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3461 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3463 pSMB->TotalParameterCount = 0;
3464 pSMB->TotalDataCount = cpu_to_le32(2);
3465 pSMB->MaxParameterCount = 0;
3466 pSMB->MaxDataCount = 0;
3467 pSMB->MaxSetupCount = 4;
3469 pSMB->ParameterOffset = 0;
3470 pSMB->DataCount = cpu_to_le32(2);
3472 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3473 compression_state) - 4); /* 84 */
3474 pSMB->SetupCount = 4;
3475 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3476 pSMB->ParameterCount = 0;
3477 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3478 pSMB->IsFsctl = 1; /* FSCTL */
3479 pSMB->IsRootFlag = 0;
3480 pSMB->Fid = fid; /* file handle always le */
3481 /* 3 byte pad, followed by 2 byte compress state */
3482 pSMB->ByteCount = cpu_to_le16(5);
3483 inc_rfc1001_len(pSMB, 5);
3485 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3486 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3488 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3490 cifs_buf_release(pSMB);
3493 * Note: On -EAGAIN error only caller can retry on handle based calls
3494 * since file handle passed in no longer valid.
3500 #ifdef CONFIG_CIFS_POSIX
3502 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3503 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3504 struct cifs_posix_ace *cifs_ace)
3506 /* u8 cifs fields do not need le conversion */
3507 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3508 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3509 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3511 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3512 ace->e_perm, ace->e_tag, ace->e_id);
3518 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3519 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3520 const int acl_type, const int size_of_data_area)
3525 struct cifs_posix_ace *pACE;
3526 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3527 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3529 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3532 if (acl_type == ACL_TYPE_ACCESS) {
3533 count = le16_to_cpu(cifs_acl->access_entry_count);
3534 pACE = &cifs_acl->ace_array[0];
3535 size = sizeof(struct cifs_posix_acl);
3536 size += sizeof(struct cifs_posix_ace) * count;
3537 /* check if we would go beyond end of SMB */
3538 if (size_of_data_area < size) {
3539 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3540 size_of_data_area, size);
3543 } else if (acl_type == ACL_TYPE_DEFAULT) {
3544 count = le16_to_cpu(cifs_acl->access_entry_count);
3545 size = sizeof(struct cifs_posix_acl);
3546 size += sizeof(struct cifs_posix_ace) * count;
3547 /* skip past access ACEs to get to default ACEs */
3548 pACE = &cifs_acl->ace_array[count];
3549 count = le16_to_cpu(cifs_acl->default_entry_count);
3550 size += sizeof(struct cifs_posix_ace) * count;
3551 /* check if we would go beyond end of SMB */
3552 if (size_of_data_area < size)
3559 size = posix_acl_xattr_size(count);
3560 if ((buflen == 0) || (local_acl == NULL)) {
3561 /* used to query ACL EA size */
3562 } else if (size > buflen) {
3564 } else /* buffer big enough */ {
3565 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3567 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3568 for (i = 0; i < count ; i++) {
3569 cifs_convert_ace(&ace[i], pACE);
3576 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3577 const struct posix_acl_xattr_entry *local_ace)
3579 __u16 rc = 0; /* 0 = ACL converted ok */
3581 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3582 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3583 /* BB is there a better way to handle the large uid? */
3584 if (local_ace->e_id == cpu_to_le32(-1)) {
3585 /* Probably no need to le convert -1 on any arch but can not hurt */
3586 cifs_ace->cifs_uid = cpu_to_le64(-1);
3588 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3590 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3591 ace->e_perm, ace->e_tag, ace->e_id);
3596 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3597 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3598 const int buflen, const int acl_type)
3601 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3602 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3603 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3607 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3610 count = posix_acl_xattr_count((size_t)buflen);
3611 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3612 count, buflen, le32_to_cpu(local_acl->a_version));
3613 if (le32_to_cpu(local_acl->a_version) != 2) {
3614 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3615 le32_to_cpu(local_acl->a_version));
3618 cifs_acl->version = cpu_to_le16(1);
3619 if (acl_type == ACL_TYPE_ACCESS) {
3620 cifs_acl->access_entry_count = cpu_to_le16(count);
3621 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3622 } else if (acl_type == ACL_TYPE_DEFAULT) {
3623 cifs_acl->default_entry_count = cpu_to_le16(count);
3624 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3626 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3629 for (i = 0; i < count; i++) {
3630 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3632 /* ACE not converted */
3637 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3638 rc += sizeof(struct cifs_posix_acl);
3639 /* BB add check to make sure ACL does not overflow SMB */
3645 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3646 const unsigned char *searchName,
3647 char *acl_inf, const int buflen, const int acl_type,
3648 const struct nls_table *nls_codepage, int remap)
3650 /* SMB_QUERY_POSIX_ACL */
3651 TRANSACTION2_QPI_REQ *pSMB = NULL;
3652 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3656 __u16 params, byte_count;
3658 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3661 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3666 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3668 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3669 searchName, PATH_MAX, nls_codepage,
3671 name_len++; /* trailing null */
3673 pSMB->FileName[name_len] = 0;
3674 pSMB->FileName[name_len+1] = 0;
3675 } else { /* BB improve the check for buffer overruns BB */
3676 name_len = strnlen(searchName, PATH_MAX);
3677 name_len++; /* trailing null */
3678 strncpy(pSMB->FileName, searchName, name_len);
3681 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3682 pSMB->TotalDataCount = 0;
3683 pSMB->MaxParameterCount = cpu_to_le16(2);
3684 /* BB find exact max data count below from sess structure BB */
3685 pSMB->MaxDataCount = cpu_to_le16(4000);
3686 pSMB->MaxSetupCount = 0;
3690 pSMB->Reserved2 = 0;
3691 pSMB->ParameterOffset = cpu_to_le16(
3692 offsetof(struct smb_com_transaction2_qpi_req,
3693 InformationLevel) - 4);
3694 pSMB->DataCount = 0;
3695 pSMB->DataOffset = 0;
3696 pSMB->SetupCount = 1;
3697 pSMB->Reserved3 = 0;
3698 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3699 byte_count = params + 1 /* pad */ ;
3700 pSMB->TotalParameterCount = cpu_to_le16(params);
3701 pSMB->ParameterCount = pSMB->TotalParameterCount;
3702 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3703 pSMB->Reserved4 = 0;
3704 inc_rfc1001_len(pSMB, byte_count);
3705 pSMB->ByteCount = cpu_to_le16(byte_count);
3707 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3708 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3709 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3711 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3713 /* decode response */
3715 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3716 /* BB also check enough total bytes returned */
3717 if (rc || get_bcc(&pSMBr->hdr) < 2)
3718 rc = -EIO; /* bad smb */
3720 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3721 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3722 rc = cifs_copy_posix_acl(acl_inf,
3723 (char *)&pSMBr->hdr.Protocol+data_offset,
3724 buflen, acl_type, count);
3727 cifs_buf_release(pSMB);
3734 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3735 const unsigned char *fileName,
3736 const char *local_acl, const int buflen,
3738 const struct nls_table *nls_codepage, int remap)
3740 struct smb_com_transaction2_spi_req *pSMB = NULL;
3741 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3745 int bytes_returned = 0;
3746 __u16 params, byte_count, data_count, param_offset, offset;
3748 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3750 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3754 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3756 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3757 PATH_MAX, nls_codepage, remap);
3758 name_len++; /* trailing null */
3760 } else { /* BB improve the check for buffer overruns BB */
3761 name_len = strnlen(fileName, PATH_MAX);
3762 name_len++; /* trailing null */
3763 strncpy(pSMB->FileName, fileName, name_len);
3765 params = 6 + name_len;
3766 pSMB->MaxParameterCount = cpu_to_le16(2);
3767 /* BB find max SMB size from sess */
3768 pSMB->MaxDataCount = cpu_to_le16(1000);
3769 pSMB->MaxSetupCount = 0;
3773 pSMB->Reserved2 = 0;
3774 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3775 InformationLevel) - 4;
3776 offset = param_offset + params;
3777 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3778 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3780 /* convert to on the wire format for POSIX ACL */
3781 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3783 if (data_count == 0) {
3785 goto setACLerrorExit;
3787 pSMB->DataOffset = cpu_to_le16(offset);
3788 pSMB->SetupCount = 1;
3789 pSMB->Reserved3 = 0;
3790 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3791 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3792 byte_count = 3 /* pad */ + params + data_count;
3793 pSMB->DataCount = cpu_to_le16(data_count);
3794 pSMB->TotalDataCount = pSMB->DataCount;
3795 pSMB->ParameterCount = cpu_to_le16(params);
3796 pSMB->TotalParameterCount = pSMB->ParameterCount;
3797 pSMB->Reserved4 = 0;
3798 inc_rfc1001_len(pSMB, byte_count);
3799 pSMB->ByteCount = cpu_to_le16(byte_count);
3800 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3801 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3803 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3806 cifs_buf_release(pSMB);
3812 /* BB fix tabs in this function FIXME BB */
3814 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3815 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3818 struct smb_t2_qfi_req *pSMB = NULL;
3819 struct smb_t2_qfi_rsp *pSMBr = NULL;
3821 __u16 params, byte_count;
3823 cifs_dbg(FYI, "In GetExtAttr\n");
3828 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3833 params = 2 /* level */ + 2 /* fid */;
3834 pSMB->t2.TotalDataCount = 0;
3835 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3836 /* BB find exact max data count below from sess structure BB */
3837 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3838 pSMB->t2.MaxSetupCount = 0;
3839 pSMB->t2.Reserved = 0;
3841 pSMB->t2.Timeout = 0;
3842 pSMB->t2.Reserved2 = 0;
3843 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3845 pSMB->t2.DataCount = 0;
3846 pSMB->t2.DataOffset = 0;
3847 pSMB->t2.SetupCount = 1;
3848 pSMB->t2.Reserved3 = 0;
3849 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3850 byte_count = params + 1 /* pad */ ;
3851 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3852 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3853 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3856 inc_rfc1001_len(pSMB, byte_count);
3857 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3859 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3860 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3862 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3864 /* decode response */
3865 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3866 /* BB also check enough total bytes returned */
3867 if (rc || get_bcc(&pSMBr->hdr) < 2)
3868 /* If rc should we check for EOPNOSUPP and
3869 disable the srvino flag? or in caller? */
3870 rc = -EIO; /* bad smb */
3872 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3873 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3874 struct file_chattr_info *pfinfo;
3875 /* BB Do we need a cast or hash here ? */
3877 cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n");
3881 pfinfo = (struct file_chattr_info *)
3882 (data_offset + (char *) &pSMBr->hdr.Protocol);
3883 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3884 *pMask = le64_to_cpu(pfinfo->mask);
3888 cifs_buf_release(pSMB);
3890 goto GetExtAttrRetry;
3894 #endif /* CONFIG_POSIX */
3896 #ifdef CONFIG_CIFS_ACL
3898 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3899 * all NT TRANSACTS that we init here have total parm and data under about 400
3900 * bytes (to fit in small cifs buffer size), which is the case so far, it
3901 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3902 * returned setup area) and MaxParameterCount (returned parms size) must be set
3906 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3907 const int parm_len, struct cifs_tcon *tcon,
3912 struct smb_com_ntransact_req *pSMB;
3914 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3918 *ret_buf = (void *)pSMB;
3920 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3921 pSMB->TotalDataCount = 0;
3922 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3923 pSMB->ParameterCount = pSMB->TotalParameterCount;
3924 pSMB->DataCount = pSMB->TotalDataCount;
3925 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3926 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3927 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3928 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3929 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3930 pSMB->SubCommand = cpu_to_le16(sub_command);
3935 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3936 __u32 *pparmlen, __u32 *pdatalen)
3939 __u32 data_count, data_offset, parm_count, parm_offset;
3940 struct smb_com_ntransact_rsp *pSMBr;
3949 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3951 bcc = get_bcc(&pSMBr->hdr);
3952 end_of_smb = 2 /* sizeof byte count */ + bcc +
3953 (char *)&pSMBr->ByteCount;
3955 data_offset = le32_to_cpu(pSMBr->DataOffset);
3956 data_count = le32_to_cpu(pSMBr->DataCount);
3957 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3958 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3960 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3961 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3963 /* should we also check that parm and data areas do not overlap? */
3964 if (*ppparm > end_of_smb) {
3965 cifs_dbg(FYI, "parms start after end of smb\n");
3967 } else if (parm_count + *ppparm > end_of_smb) {
3968 cifs_dbg(FYI, "parm end after end of smb\n");
3970 } else if (*ppdata > end_of_smb) {
3971 cifs_dbg(FYI, "data starts after end of smb\n");
3973 } else if (data_count + *ppdata > end_of_smb) {
3974 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3975 *ppdata, data_count, (data_count + *ppdata),
3978 } else if (parm_count + data_count > bcc) {
3979 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3982 *pdatalen = data_count;
3983 *pparmlen = parm_count;
3987 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3989 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3990 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3994 QUERY_SEC_DESC_REQ *pSMB;
3996 struct kvec rsp_iov;
3998 cifs_dbg(FYI, "GetCifsACL\n");
4003 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
4004 8 /* parm len */, tcon, (void **) &pSMB);
4008 pSMB->MaxParameterCount = cpu_to_le32(4);
4009 /* BB TEST with big acls that might need to be e.g. larger than 16K */
4010 pSMB->MaxSetupCount = 0;
4011 pSMB->Fid = fid; /* file handle always le */
4012 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
4014 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
4015 inc_rfc1001_len(pSMB, 11);
4016 iov[0].iov_base = (char *)pSMB;
4017 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
4019 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
4021 cifs_small_buf_release(pSMB);
4022 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
4024 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
4025 } else { /* decode response */
4029 struct smb_com_ntransact_rsp *pSMBr;
4032 /* validate_nttransact */
4033 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
4034 &pdata, &parm_len, pbuflen);
4037 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
4039 cifs_dbg(FYI, "smb %p parm %p data %p\n",
4040 pSMBr, parm, *acl_inf);
4042 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
4043 rc = -EIO; /* bad smb */
4048 /* BB check that data area is minimum length and as big as acl_len */
4050 acl_len = le32_to_cpu(*parm);
4051 if (acl_len != *pbuflen) {
4052 cifs_dbg(VFS, "acl length %d does not match %d\n",
4054 if (*pbuflen > acl_len)
4058 /* check if buffer is big enough for the acl
4059 header followed by the smallest SID */
4060 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
4061 (*pbuflen >= 64 * 1024)) {
4062 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
4066 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
4067 if (*acl_inf == NULL) {
4074 free_rsp_buf(buf_type, rsp_iov.iov_base);
4079 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
4080 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
4082 __u16 byte_count, param_count, data_count, param_offset, data_offset;
4084 int bytes_returned = 0;
4085 SET_SEC_DESC_REQ *pSMB = NULL;
4089 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
4093 pSMB->MaxSetupCount = 0;
4097 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
4098 data_count = acllen;
4099 data_offset = param_offset + param_count;
4100 byte_count = 3 /* pad */ + param_count;
4102 pSMB->DataCount = cpu_to_le32(data_count);
4103 pSMB->TotalDataCount = pSMB->DataCount;
4104 pSMB->MaxParameterCount = cpu_to_le32(4);
4105 pSMB->MaxDataCount = cpu_to_le32(16384);
4106 pSMB->ParameterCount = cpu_to_le32(param_count);
4107 pSMB->ParameterOffset = cpu_to_le32(param_offset);
4108 pSMB->TotalParameterCount = pSMB->ParameterCount;
4109 pSMB->DataOffset = cpu_to_le32(data_offset);
4110 pSMB->SetupCount = 0;
4111 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
4112 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
4114 pSMB->Fid = fid; /* file handle always le */
4115 pSMB->Reserved2 = 0;
4116 pSMB->AclFlags = cpu_to_le32(aclflag);
4118 if (pntsd && acllen) {
4119 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
4120 data_offset, pntsd, acllen);
4121 inc_rfc1001_len(pSMB, byte_count + data_count);
4123 inc_rfc1001_len(pSMB, byte_count);
4125 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4126 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4128 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4129 bytes_returned, rc);
4131 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
4132 cifs_buf_release(pSMB);
4135 goto setCifsAclRetry;
4140 #endif /* CONFIG_CIFS_ACL */
4142 /* Legacy Query Path Information call for lookup to old servers such
4145 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
4146 const char *search_name, FILE_ALL_INFO *data,
4147 const struct nls_table *nls_codepage, int remap)
4149 QUERY_INFORMATION_REQ *pSMB;
4150 QUERY_INFORMATION_RSP *pSMBr;
4155 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4157 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4162 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4164 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4165 search_name, PATH_MAX, nls_codepage,
4167 name_len++; /* trailing null */
4170 name_len = strnlen(search_name, PATH_MAX);
4171 name_len++; /* trailing null */
4172 strncpy(pSMB->FileName, search_name, name_len);
4174 pSMB->BufferFormat = 0x04;
4175 name_len++; /* account for buffer type byte */
4176 inc_rfc1001_len(pSMB, (__u16)name_len);
4177 pSMB->ByteCount = cpu_to_le16(name_len);
4179 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4180 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4182 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4184 struct timespec64 ts;
4185 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4187 /* decode response */
4188 /* BB FIXME - add time zone adjustment BB */
4189 memset(data, 0, sizeof(FILE_ALL_INFO));
4192 /* decode time fields */
4193 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4194 data->LastWriteTime = data->ChangeTime;
4195 data->LastAccessTime = 0;
4196 data->AllocationSize =
4197 cpu_to_le64(le32_to_cpu(pSMBr->size));
4198 data->EndOfFile = data->AllocationSize;
4200 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4202 rc = -EIO; /* bad buffer passed in */
4204 cifs_buf_release(pSMB);
4213 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4214 u16 netfid, FILE_ALL_INFO *pFindData)
4216 struct smb_t2_qfi_req *pSMB = NULL;
4217 struct smb_t2_qfi_rsp *pSMBr = NULL;
4220 __u16 params, byte_count;
4223 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4228 params = 2 /* level */ + 2 /* fid */;
4229 pSMB->t2.TotalDataCount = 0;
4230 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4231 /* BB find exact max data count below from sess structure BB */
4232 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4233 pSMB->t2.MaxSetupCount = 0;
4234 pSMB->t2.Reserved = 0;
4236 pSMB->t2.Timeout = 0;
4237 pSMB->t2.Reserved2 = 0;
4238 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4240 pSMB->t2.DataCount = 0;
4241 pSMB->t2.DataOffset = 0;
4242 pSMB->t2.SetupCount = 1;
4243 pSMB->t2.Reserved3 = 0;
4244 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4245 byte_count = params + 1 /* pad */ ;
4246 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4247 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4248 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4251 inc_rfc1001_len(pSMB, byte_count);
4252 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4254 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4255 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4257 cifs_dbg(FYI, "Send error in QFileInfo = %d", rc);
4258 } else { /* decode response */
4259 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4261 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4263 else if (get_bcc(&pSMBr->hdr) < 40)
4264 rc = -EIO; /* bad smb */
4265 else if (pFindData) {
4266 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4267 memcpy((char *) pFindData,
4268 (char *) &pSMBr->hdr.Protocol +
4269 data_offset, sizeof(FILE_ALL_INFO));
4273 cifs_buf_release(pSMB);
4275 goto QFileInfoRetry;
4281 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4282 const char *search_name, FILE_ALL_INFO *data,
4283 int legacy /* old style infolevel */,
4284 const struct nls_table *nls_codepage, int remap)
4286 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4287 TRANSACTION2_QPI_REQ *pSMB = NULL;
4288 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4292 __u16 params, byte_count;
4294 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4296 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4301 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4303 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4304 PATH_MAX, nls_codepage, remap);
4305 name_len++; /* trailing null */
4307 } else { /* BB improve the check for buffer overruns BB */
4308 name_len = strnlen(search_name, PATH_MAX);
4309 name_len++; /* trailing null */
4310 strncpy(pSMB->FileName, search_name, name_len);
4313 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4314 pSMB->TotalDataCount = 0;
4315 pSMB->MaxParameterCount = cpu_to_le16(2);
4316 /* BB find exact max SMB PDU from sess structure BB */
4317 pSMB->MaxDataCount = cpu_to_le16(4000);
4318 pSMB->MaxSetupCount = 0;
4322 pSMB->Reserved2 = 0;
4323 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4324 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4325 pSMB->DataCount = 0;
4326 pSMB->DataOffset = 0;
4327 pSMB->SetupCount = 1;
4328 pSMB->Reserved3 = 0;
4329 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4330 byte_count = params + 1 /* pad */ ;
4331 pSMB->TotalParameterCount = cpu_to_le16(params);
4332 pSMB->ParameterCount = pSMB->TotalParameterCount;
4334 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4336 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4337 pSMB->Reserved4 = 0;
4338 inc_rfc1001_len(pSMB, byte_count);
4339 pSMB->ByteCount = cpu_to_le16(byte_count);
4341 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4342 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4344 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4345 } else { /* decode response */
4346 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4348 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4350 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4351 rc = -EIO; /* bad smb */
4352 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4353 rc = -EIO; /* 24 or 26 expected but we do not read
4357 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4360 * On legacy responses we do not read the last field,
4361 * EAsize, fortunately since it varies by subdialect and
4362 * also note it differs on Set vs Get, ie two bytes or 4
4363 * bytes depending but we don't care here.
4366 size = sizeof(FILE_INFO_STANDARD);
4368 size = sizeof(FILE_ALL_INFO);
4369 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4374 cifs_buf_release(pSMB);
4376 goto QPathInfoRetry;
4382 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4383 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4385 struct smb_t2_qfi_req *pSMB = NULL;
4386 struct smb_t2_qfi_rsp *pSMBr = NULL;
4389 __u16 params, byte_count;
4392 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4397 params = 2 /* level */ + 2 /* fid */;
4398 pSMB->t2.TotalDataCount = 0;
4399 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4400 /* BB find exact max data count below from sess structure BB */
4401 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4402 pSMB->t2.MaxSetupCount = 0;
4403 pSMB->t2.Reserved = 0;
4405 pSMB->t2.Timeout = 0;
4406 pSMB->t2.Reserved2 = 0;
4407 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4409 pSMB->t2.DataCount = 0;
4410 pSMB->t2.DataOffset = 0;
4411 pSMB->t2.SetupCount = 1;
4412 pSMB->t2.Reserved3 = 0;
4413 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4414 byte_count = params + 1 /* pad */ ;
4415 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4416 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4417 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4420 inc_rfc1001_len(pSMB, byte_count);
4421 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4423 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4424 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4426 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d", rc);
4427 } else { /* decode response */
4428 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4430 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4431 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4432 rc = -EIO; /* bad smb */
4434 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4435 memcpy((char *) pFindData,
4436 (char *) &pSMBr->hdr.Protocol +
4438 sizeof(FILE_UNIX_BASIC_INFO));
4442 cifs_buf_release(pSMB);
4444 goto UnixQFileInfoRetry;
4450 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4451 const unsigned char *searchName,
4452 FILE_UNIX_BASIC_INFO *pFindData,
4453 const struct nls_table *nls_codepage, int remap)
4455 /* SMB_QUERY_FILE_UNIX_BASIC */
4456 TRANSACTION2_QPI_REQ *pSMB = NULL;
4457 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4459 int bytes_returned = 0;
4461 __u16 params, byte_count;
4463 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4465 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4470 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4472 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4473 PATH_MAX, nls_codepage, remap);
4474 name_len++; /* trailing null */
4476 } else { /* BB improve the check for buffer overruns BB */
4477 name_len = strnlen(searchName, PATH_MAX);
4478 name_len++; /* trailing null */
4479 strncpy(pSMB->FileName, searchName, name_len);
4482 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4483 pSMB->TotalDataCount = 0;
4484 pSMB->MaxParameterCount = cpu_to_le16(2);
4485 /* BB find exact max SMB PDU from sess structure BB */
4486 pSMB->MaxDataCount = cpu_to_le16(4000);
4487 pSMB->MaxSetupCount = 0;
4491 pSMB->Reserved2 = 0;
4492 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4493 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4494 pSMB->DataCount = 0;
4495 pSMB->DataOffset = 0;
4496 pSMB->SetupCount = 1;
4497 pSMB->Reserved3 = 0;
4498 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4499 byte_count = params + 1 /* pad */ ;
4500 pSMB->TotalParameterCount = cpu_to_le16(params);
4501 pSMB->ParameterCount = pSMB->TotalParameterCount;
4502 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4503 pSMB->Reserved4 = 0;
4504 inc_rfc1001_len(pSMB, byte_count);
4505 pSMB->ByteCount = cpu_to_le16(byte_count);
4507 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4508 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4510 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d", rc);
4511 } else { /* decode response */
4512 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4514 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4515 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4516 rc = -EIO; /* bad smb */
4518 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4519 memcpy((char *) pFindData,
4520 (char *) &pSMBr->hdr.Protocol +
4522 sizeof(FILE_UNIX_BASIC_INFO));
4525 cifs_buf_release(pSMB);
4527 goto UnixQPathInfoRetry;
4532 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4534 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4535 const char *searchName, struct cifs_sb_info *cifs_sb,
4536 __u16 *pnetfid, __u16 search_flags,
4537 struct cifs_search_info *psrch_inf, bool msearch)
4539 /* level 257 SMB_ */
4540 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4541 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4542 T2_FFIRST_RSP_PARMS *parms;
4544 int bytes_returned = 0;
4545 int name_len, remap;
4546 __u16 params, byte_count;
4547 struct nls_table *nls_codepage;
4549 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4552 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4557 nls_codepage = cifs_sb->local_nls;
4558 remap = cifs_remap(cifs_sb);
4560 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4562 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4563 PATH_MAX, nls_codepage, remap);
4564 /* We can not add the asterik earlier in case
4565 it got remapped to 0xF03A as if it were part of the
4566 directory name instead of a wildcard */
4569 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4570 pSMB->FileName[name_len+1] = 0;
4571 pSMB->FileName[name_len+2] = '*';
4572 pSMB->FileName[name_len+3] = 0;
4573 name_len += 4; /* now the trailing null */
4574 /* null terminate just in case */
4575 pSMB->FileName[name_len] = 0;
4576 pSMB->FileName[name_len+1] = 0;
4579 } else { /* BB add check for overrun of SMB buf BB */
4580 name_len = strnlen(searchName, PATH_MAX);
4581 /* BB fix here and in unicode clause above ie
4582 if (name_len > buffersize-header)
4583 free buffer exit; BB */
4584 strncpy(pSMB->FileName, searchName, name_len);
4586 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4587 pSMB->FileName[name_len+1] = '*';
4588 pSMB->FileName[name_len+2] = 0;
4593 params = 12 + name_len /* includes null */ ;
4594 pSMB->TotalDataCount = 0; /* no EAs */
4595 pSMB->MaxParameterCount = cpu_to_le16(10);
4596 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4597 pSMB->MaxSetupCount = 0;
4601 pSMB->Reserved2 = 0;
4602 byte_count = params + 1 /* pad */ ;
4603 pSMB->TotalParameterCount = cpu_to_le16(params);
4604 pSMB->ParameterCount = pSMB->TotalParameterCount;
4605 pSMB->ParameterOffset = cpu_to_le16(
4606 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4608 pSMB->DataCount = 0;
4609 pSMB->DataOffset = 0;
4610 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4611 pSMB->Reserved3 = 0;
4612 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4613 pSMB->SearchAttributes =
4614 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4616 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4617 pSMB->SearchFlags = cpu_to_le16(search_flags);
4618 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4620 /* BB what should we set StorageType to? Does it matter? BB */
4621 pSMB->SearchStorageType = 0;
4622 inc_rfc1001_len(pSMB, byte_count);
4623 pSMB->ByteCount = cpu_to_le16(byte_count);
4625 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4626 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4627 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4629 if (rc) {/* BB add logic to retry regular search if Unix search
4630 rejected unexpectedly by server */
4631 /* BB Add code to handle unsupported level rc */
4632 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4634 cifs_buf_release(pSMB);
4636 /* BB eventually could optimize out free and realloc of buf */
4639 goto findFirstRetry;
4640 } else { /* decode response */
4641 /* BB remember to free buffer if error BB */
4642 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4646 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4647 psrch_inf->unicode = true;
4649 psrch_inf->unicode = false;
4651 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4652 psrch_inf->smallBuf = 0;
4653 psrch_inf->srch_entries_start =
4654 (char *) &pSMBr->hdr.Protocol +
4655 le16_to_cpu(pSMBr->t2.DataOffset);
4656 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4657 le16_to_cpu(pSMBr->t2.ParameterOffset));
4659 if (parms->EndofSearch)
4660 psrch_inf->endOfSearch = true;
4662 psrch_inf->endOfSearch = false;
4664 psrch_inf->entries_in_buffer =
4665 le16_to_cpu(parms->SearchCount);
4666 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4667 psrch_inf->entries_in_buffer;
4668 lnoff = le16_to_cpu(parms->LastNameOffset);
4669 if (CIFSMaxBufSize < lnoff) {
4670 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4671 psrch_inf->last_entry = NULL;
4675 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4679 *pnetfid = parms->SearchHandle;
4681 cifs_buf_release(pSMB);
4688 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4689 __u16 searchHandle, __u16 search_flags,
4690 struct cifs_search_info *psrch_inf)
4692 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4693 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4694 T2_FNEXT_RSP_PARMS *parms;
4695 char *response_data;
4698 unsigned int name_len;
4699 __u16 params, byte_count;
4701 cifs_dbg(FYI, "In FindNext\n");
4703 if (psrch_inf->endOfSearch)
4706 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4711 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4713 pSMB->TotalDataCount = 0; /* no EAs */
4714 pSMB->MaxParameterCount = cpu_to_le16(8);
4715 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4716 pSMB->MaxSetupCount = 0;
4720 pSMB->Reserved2 = 0;
4721 pSMB->ParameterOffset = cpu_to_le16(
4722 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4723 pSMB->DataCount = 0;
4724 pSMB->DataOffset = 0;
4725 pSMB->SetupCount = 1;
4726 pSMB->Reserved3 = 0;
4727 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4728 pSMB->SearchHandle = searchHandle; /* always kept as le */
4730 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4731 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4732 pSMB->ResumeKey = psrch_inf->resume_key;
4733 pSMB->SearchFlags = cpu_to_le16(search_flags);
4735 name_len = psrch_inf->resume_name_len;
4737 if (name_len < PATH_MAX) {
4738 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4739 byte_count += name_len;
4740 /* 14 byte parm len above enough for 2 byte null terminator */
4741 pSMB->ResumeFileName[name_len] = 0;
4742 pSMB->ResumeFileName[name_len+1] = 0;
4745 goto FNext2_err_exit;
4747 byte_count = params + 1 /* pad */ ;
4748 pSMB->TotalParameterCount = cpu_to_le16(params);
4749 pSMB->ParameterCount = pSMB->TotalParameterCount;
4750 inc_rfc1001_len(pSMB, byte_count);
4751 pSMB->ByteCount = cpu_to_le16(byte_count);
4753 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4754 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4755 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4758 psrch_inf->endOfSearch = true;
4759 cifs_buf_release(pSMB);
4760 rc = 0; /* search probably was closed at end of search*/
4762 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4763 } else { /* decode response */
4764 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4769 /* BB fixme add lock for file (srch_info) struct here */
4770 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4771 psrch_inf->unicode = true;
4773 psrch_inf->unicode = false;
4774 response_data = (char *) &pSMBr->hdr.Protocol +
4775 le16_to_cpu(pSMBr->t2.ParameterOffset);
4776 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4777 response_data = (char *)&pSMBr->hdr.Protocol +
4778 le16_to_cpu(pSMBr->t2.DataOffset);
4779 if (psrch_inf->smallBuf)
4780 cifs_small_buf_release(
4781 psrch_inf->ntwrk_buf_start);
4783 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4784 psrch_inf->srch_entries_start = response_data;
4785 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4786 psrch_inf->smallBuf = 0;
4787 if (parms->EndofSearch)
4788 psrch_inf->endOfSearch = true;
4790 psrch_inf->endOfSearch = false;
4791 psrch_inf->entries_in_buffer =
4792 le16_to_cpu(parms->SearchCount);
4793 psrch_inf->index_of_last_entry +=
4794 psrch_inf->entries_in_buffer;
4795 lnoff = le16_to_cpu(parms->LastNameOffset);
4796 if (CIFSMaxBufSize < lnoff) {
4797 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4798 psrch_inf->last_entry = NULL;
4801 psrch_inf->last_entry =
4802 psrch_inf->srch_entries_start + lnoff;
4804 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4805 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4807 /* BB fixme add unlock here */
4812 /* BB On error, should we leave previous search buf (and count and
4813 last entry fields) intact or free the previous one? */
4815 /* Note: On -EAGAIN error only caller can retry on handle based calls
4816 since file handle passed in no longer valid */
4819 cifs_buf_release(pSMB);
4824 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4825 const __u16 searchHandle)
4828 FINDCLOSE_REQ *pSMB = NULL;
4830 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4831 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4833 /* no sense returning error if session restarted
4834 as file handle has been closed */
4840 pSMB->FileID = searchHandle;
4841 pSMB->ByteCount = 0;
4842 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4843 cifs_small_buf_release(pSMB);
4845 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4847 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4849 /* Since session is dead, search handle closed on server already */
4857 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4858 const char *search_name, __u64 *inode_number,
4859 const struct nls_table *nls_codepage, int remap)
4862 TRANSACTION2_QPI_REQ *pSMB = NULL;
4863 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4864 int name_len, bytes_returned;
4865 __u16 params, byte_count;
4867 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4871 GetInodeNumberRetry:
4872 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4877 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4879 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4880 search_name, PATH_MAX, nls_codepage,
4882 name_len++; /* trailing null */
4884 } else { /* BB improve the check for buffer overruns BB */
4885 name_len = strnlen(search_name, PATH_MAX);
4886 name_len++; /* trailing null */
4887 strncpy(pSMB->FileName, search_name, name_len);
4890 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4891 pSMB->TotalDataCount = 0;
4892 pSMB->MaxParameterCount = cpu_to_le16(2);
4893 /* BB find exact max data count below from sess structure BB */
4894 pSMB->MaxDataCount = cpu_to_le16(4000);
4895 pSMB->MaxSetupCount = 0;
4899 pSMB->Reserved2 = 0;
4900 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4901 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4902 pSMB->DataCount = 0;
4903 pSMB->DataOffset = 0;
4904 pSMB->SetupCount = 1;
4905 pSMB->Reserved3 = 0;
4906 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4907 byte_count = params + 1 /* pad */ ;
4908 pSMB->TotalParameterCount = cpu_to_le16(params);
4909 pSMB->ParameterCount = pSMB->TotalParameterCount;
4910 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4911 pSMB->Reserved4 = 0;
4912 inc_rfc1001_len(pSMB, byte_count);
4913 pSMB->ByteCount = cpu_to_le16(byte_count);
4915 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4916 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4918 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4920 /* decode response */
4921 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4922 /* BB also check enough total bytes returned */
4923 if (rc || get_bcc(&pSMBr->hdr) < 2)
4924 /* If rc should we check for EOPNOSUPP and
4925 disable the srvino flag? or in caller? */
4926 rc = -EIO; /* bad smb */
4928 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4929 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4930 struct file_internal_info *pfinfo;
4931 /* BB Do we need a cast or hash here ? */
4933 cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n");
4935 goto GetInodeNumOut;
4937 pfinfo = (struct file_internal_info *)
4938 (data_offset + (char *) &pSMBr->hdr.Protocol);
4939 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4943 cifs_buf_release(pSMB);
4945 goto GetInodeNumberRetry;
4950 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4951 const char *search_name, struct dfs_info3_param **target_nodes,
4952 unsigned int *num_of_nodes,
4953 const struct nls_table *nls_codepage, int remap)
4955 /* TRANS2_GET_DFS_REFERRAL */
4956 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4957 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4961 __u16 params, byte_count;
4963 *target_nodes = NULL;
4965 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4966 if (ses == NULL || ses->tcon_ipc == NULL)
4970 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4975 /* server pointer checked in called function,
4976 but should never be null here anyway */
4977 pSMB->hdr.Mid = get_next_mid(ses->server);
4978 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4979 pSMB->hdr.Uid = ses->Suid;
4980 if (ses->capabilities & CAP_STATUS32)
4981 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4982 if (ses->capabilities & CAP_DFS)
4983 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4985 if (ses->capabilities & CAP_UNICODE) {
4986 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4988 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4989 search_name, PATH_MAX, nls_codepage,
4991 name_len++; /* trailing null */
4993 } else { /* BB improve the check for buffer overruns BB */
4994 name_len = strnlen(search_name, PATH_MAX);
4995 name_len++; /* trailing null */
4996 strncpy(pSMB->RequestFileName, search_name, name_len);
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 */
5649 } else { /* BB improve the check for buffer overruns BB */
5650 name_len = strnlen(file_name, PATH_MAX);
5651 name_len++; /* trailing null */
5652 strncpy(pSMB->FileName, file_name, name_len);
5654 params = 6 + name_len;
5655 data_count = sizeof(struct file_end_of_file_info);
5656 pSMB->MaxParameterCount = cpu_to_le16(2);
5657 pSMB->MaxDataCount = cpu_to_le16(4100);
5658 pSMB->MaxSetupCount = 0;
5662 pSMB->Reserved2 = 0;
5663 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5664 InformationLevel) - 4;
5665 offset = param_offset + params;
5666 if (set_allocation) {
5667 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5668 pSMB->InformationLevel =
5669 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5671 pSMB->InformationLevel =
5672 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5673 } else /* Set File Size */ {
5674 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5675 pSMB->InformationLevel =
5676 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5678 pSMB->InformationLevel =
5679 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5683 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5685 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5686 pSMB->DataOffset = cpu_to_le16(offset);
5687 pSMB->SetupCount = 1;
5688 pSMB->Reserved3 = 0;
5689 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5690 byte_count = 3 /* pad */ + params + data_count;
5691 pSMB->DataCount = cpu_to_le16(data_count);
5692 pSMB->TotalDataCount = pSMB->DataCount;
5693 pSMB->ParameterCount = cpu_to_le16(params);
5694 pSMB->TotalParameterCount = pSMB->ParameterCount;
5695 pSMB->Reserved4 = 0;
5696 inc_rfc1001_len(pSMB, byte_count);
5697 parm_data->FileSize = cpu_to_le64(size);
5698 pSMB->ByteCount = cpu_to_le16(byte_count);
5699 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5700 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5702 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5704 cifs_buf_release(pSMB);
5713 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5714 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5716 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5717 struct file_end_of_file_info *parm_data;
5719 __u16 params, param_offset, offset, byte_count, count;
5721 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5723 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5728 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5729 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5732 pSMB->MaxSetupCount = 0;
5736 pSMB->Reserved2 = 0;
5737 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5738 offset = param_offset + params;
5740 count = sizeof(struct file_end_of_file_info);
5741 pSMB->MaxParameterCount = cpu_to_le16(2);
5742 /* BB find exact max SMB PDU from sess structure BB */
5743 pSMB->MaxDataCount = cpu_to_le16(1000);
5744 pSMB->SetupCount = 1;
5745 pSMB->Reserved3 = 0;
5746 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5747 byte_count = 3 /* pad */ + params + count;
5748 pSMB->DataCount = cpu_to_le16(count);
5749 pSMB->ParameterCount = cpu_to_le16(params);
5750 pSMB->TotalDataCount = pSMB->DataCount;
5751 pSMB->TotalParameterCount = pSMB->ParameterCount;
5752 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5754 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5756 pSMB->DataOffset = cpu_to_le16(offset);
5757 parm_data->FileSize = cpu_to_le64(size);
5758 pSMB->Fid = cfile->fid.netfid;
5759 if (set_allocation) {
5760 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5761 pSMB->InformationLevel =
5762 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5764 pSMB->InformationLevel =
5765 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5766 } else /* Set File Size */ {
5767 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5768 pSMB->InformationLevel =
5769 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5771 pSMB->InformationLevel =
5772 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5774 pSMB->Reserved4 = 0;
5775 inc_rfc1001_len(pSMB, byte_count);
5776 pSMB->ByteCount = cpu_to_le16(byte_count);
5777 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5778 cifs_small_buf_release(pSMB);
5780 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5784 /* Note: On -EAGAIN error only caller can retry on handle based calls
5785 since file handle passed in no longer valid */
5790 /* Some legacy servers such as NT4 require that the file times be set on
5791 an open handle, rather than by pathname - this is awkward due to
5792 potential access conflicts on the open, but it is unavoidable for these
5793 old servers since the only other choice is to go from 100 nanosecond DCE
5794 time and resort to the original setpathinfo level which takes the ancient
5795 DOS time format with 2 second granularity */
5797 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5798 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5800 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5803 __u16 params, param_offset, offset, byte_count, count;
5805 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5806 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5811 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5812 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5815 pSMB->MaxSetupCount = 0;
5819 pSMB->Reserved2 = 0;
5820 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5821 offset = param_offset + params;
5823 data_offset = (char *)pSMB +
5824 offsetof(struct smb_hdr, Protocol) + offset;
5826 count = sizeof(FILE_BASIC_INFO);
5827 pSMB->MaxParameterCount = cpu_to_le16(2);
5828 /* BB find max SMB PDU from sess */
5829 pSMB->MaxDataCount = cpu_to_le16(1000);
5830 pSMB->SetupCount = 1;
5831 pSMB->Reserved3 = 0;
5832 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5833 byte_count = 3 /* pad */ + params + count;
5834 pSMB->DataCount = cpu_to_le16(count);
5835 pSMB->ParameterCount = cpu_to_le16(params);
5836 pSMB->TotalDataCount = pSMB->DataCount;
5837 pSMB->TotalParameterCount = pSMB->ParameterCount;
5838 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5839 pSMB->DataOffset = cpu_to_le16(offset);
5841 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5842 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5844 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5845 pSMB->Reserved4 = 0;
5846 inc_rfc1001_len(pSMB, byte_count);
5847 pSMB->ByteCount = cpu_to_le16(byte_count);
5848 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5849 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5850 cifs_small_buf_release(pSMB);
5852 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5855 /* Note: On -EAGAIN error only caller can retry on handle based calls
5856 since file handle passed in no longer valid */
5862 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5863 bool delete_file, __u16 fid, __u32 pid_of_opener)
5865 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5868 __u16 params, param_offset, offset, byte_count, count;
5870 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5871 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5876 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5877 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5880 pSMB->MaxSetupCount = 0;
5884 pSMB->Reserved2 = 0;
5885 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5886 offset = param_offset + params;
5888 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5891 pSMB->MaxParameterCount = cpu_to_le16(2);
5892 /* BB find max SMB PDU from sess */
5893 pSMB->MaxDataCount = cpu_to_le16(1000);
5894 pSMB->SetupCount = 1;
5895 pSMB->Reserved3 = 0;
5896 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5897 byte_count = 3 /* pad */ + params + count;
5898 pSMB->DataCount = cpu_to_le16(count);
5899 pSMB->ParameterCount = cpu_to_le16(params);
5900 pSMB->TotalDataCount = pSMB->DataCount;
5901 pSMB->TotalParameterCount = pSMB->ParameterCount;
5902 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5903 pSMB->DataOffset = cpu_to_le16(offset);
5905 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5906 pSMB->Reserved4 = 0;
5907 inc_rfc1001_len(pSMB, byte_count);
5908 pSMB->ByteCount = cpu_to_le16(byte_count);
5909 *data_offset = delete_file ? 1 : 0;
5910 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5911 cifs_small_buf_release(pSMB);
5913 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5919 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5920 const char *fileName, const FILE_BASIC_INFO *data,
5921 const struct nls_table *nls_codepage, int remap)
5923 TRANSACTION2_SPI_REQ *pSMB = NULL;
5924 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5927 int bytes_returned = 0;
5929 __u16 params, param_offset, offset, byte_count, count;
5931 cifs_dbg(FYI, "In SetTimes\n");
5934 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5939 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5941 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5942 PATH_MAX, nls_codepage, remap);
5943 name_len++; /* trailing null */
5945 } else { /* BB improve the check for buffer overruns BB */
5946 name_len = strnlen(fileName, PATH_MAX);
5947 name_len++; /* trailing null */
5948 strncpy(pSMB->FileName, fileName, name_len);
5951 params = 6 + name_len;
5952 count = sizeof(FILE_BASIC_INFO);
5953 pSMB->MaxParameterCount = cpu_to_le16(2);
5954 /* BB find max SMB PDU from sess structure BB */
5955 pSMB->MaxDataCount = cpu_to_le16(1000);
5956 pSMB->MaxSetupCount = 0;
5960 pSMB->Reserved2 = 0;
5961 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5962 InformationLevel) - 4;
5963 offset = param_offset + params;
5964 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5965 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5966 pSMB->DataOffset = cpu_to_le16(offset);
5967 pSMB->SetupCount = 1;
5968 pSMB->Reserved3 = 0;
5969 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5970 byte_count = 3 /* pad */ + params + count;
5972 pSMB->DataCount = cpu_to_le16(count);
5973 pSMB->ParameterCount = cpu_to_le16(params);
5974 pSMB->TotalDataCount = pSMB->DataCount;
5975 pSMB->TotalParameterCount = pSMB->ParameterCount;
5976 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5977 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5979 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5980 pSMB->Reserved4 = 0;
5981 inc_rfc1001_len(pSMB, byte_count);
5982 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5983 pSMB->ByteCount = cpu_to_le16(byte_count);
5984 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5985 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5987 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5989 cifs_buf_release(pSMB);
5997 /* Can not be used to set time stamps yet (due to old DOS time format) */
5998 /* Can be used to set attributes */
5999 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
6000 handling it anyway and NT4 was what we thought it would be needed for
6001 Do not delete it until we prove whether needed for Win9x though */
6003 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
6004 __u16 dos_attrs, const struct nls_table *nls_codepage)
6006 SETATTR_REQ *pSMB = NULL;
6007 SETATTR_RSP *pSMBr = NULL;
6012 cifs_dbg(FYI, "In SetAttrLegacy\n");
6015 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
6020 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6022 ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
6023 PATH_MAX, nls_codepage);
6024 name_len++; /* trailing null */
6026 } else { /* BB improve the check for buffer overruns BB */
6027 name_len = strnlen(fileName, PATH_MAX);
6028 name_len++; /* trailing null */
6029 strncpy(pSMB->fileName, fileName, name_len);
6031 pSMB->attr = cpu_to_le16(dos_attrs);
6032 pSMB->BufferFormat = 0x04;
6033 inc_rfc1001_len(pSMB, name_len + 1);
6034 pSMB->ByteCount = cpu_to_le16(name_len + 1);
6035 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6036 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6038 cifs_dbg(FYI, "Error in LegacySetAttr = %d\n", rc);
6040 cifs_buf_release(pSMB);
6043 goto SetAttrLgcyRetry;
6047 #endif /* temporarily unneeded SetAttr legacy function */
6050 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
6051 const struct cifs_unix_set_info_args *args)
6053 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
6054 u64 mode = args->mode;
6056 if (uid_valid(args->uid))
6057 uid = from_kuid(&init_user_ns, args->uid);
6058 if (gid_valid(args->gid))
6059 gid = from_kgid(&init_user_ns, args->gid);
6062 * Samba server ignores set of file size to zero due to bugs in some
6063 * older clients, but we should be precise - we use SetFileSize to
6064 * set file size and do not want to truncate file size to zero
6065 * accidentally as happened on one Samba server beta by putting
6066 * zero instead of -1 here
6068 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
6069 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
6070 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
6071 data_offset->LastAccessTime = cpu_to_le64(args->atime);
6072 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
6073 data_offset->Uid = cpu_to_le64(uid);
6074 data_offset->Gid = cpu_to_le64(gid);
6075 /* better to leave device as zero when it is */
6076 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
6077 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
6078 data_offset->Permissions = cpu_to_le64(mode);
6081 data_offset->Type = cpu_to_le32(UNIX_FILE);
6082 else if (S_ISDIR(mode))
6083 data_offset->Type = cpu_to_le32(UNIX_DIR);
6084 else if (S_ISLNK(mode))
6085 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
6086 else if (S_ISCHR(mode))
6087 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
6088 else if (S_ISBLK(mode))
6089 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
6090 else if (S_ISFIFO(mode))
6091 data_offset->Type = cpu_to_le32(UNIX_FIFO);
6092 else if (S_ISSOCK(mode))
6093 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
6097 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
6098 const struct cifs_unix_set_info_args *args,
6099 u16 fid, u32 pid_of_opener)
6101 struct smb_com_transaction2_sfi_req *pSMB = NULL;
6104 u16 params, param_offset, offset, byte_count, count;
6106 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
6107 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
6112 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
6113 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
6116 pSMB->MaxSetupCount = 0;
6120 pSMB->Reserved2 = 0;
6121 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
6122 offset = param_offset + params;
6124 data_offset = (char *)pSMB +
6125 offsetof(struct smb_hdr, Protocol) + offset;
6127 count = sizeof(FILE_UNIX_BASIC_INFO);
6129 pSMB->MaxParameterCount = cpu_to_le16(2);
6130 /* BB find max SMB PDU from sess */
6131 pSMB->MaxDataCount = cpu_to_le16(1000);
6132 pSMB->SetupCount = 1;
6133 pSMB->Reserved3 = 0;
6134 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
6135 byte_count = 3 /* pad */ + params + count;
6136 pSMB->DataCount = cpu_to_le16(count);
6137 pSMB->ParameterCount = cpu_to_le16(params);
6138 pSMB->TotalDataCount = pSMB->DataCount;
6139 pSMB->TotalParameterCount = pSMB->ParameterCount;
6140 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6141 pSMB->DataOffset = cpu_to_le16(offset);
6143 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6144 pSMB->Reserved4 = 0;
6145 inc_rfc1001_len(pSMB, byte_count);
6146 pSMB->ByteCount = cpu_to_le16(byte_count);
6148 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
6150 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
6151 cifs_small_buf_release(pSMB);
6153 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
6156 /* Note: On -EAGAIN error only caller can retry on handle based calls
6157 since file handle passed in no longer valid */
6163 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
6164 const char *file_name,
6165 const struct cifs_unix_set_info_args *args,
6166 const struct nls_table *nls_codepage, int remap)
6168 TRANSACTION2_SPI_REQ *pSMB = NULL;
6169 TRANSACTION2_SPI_RSP *pSMBr = NULL;
6172 int bytes_returned = 0;
6173 FILE_UNIX_BASIC_INFO *data_offset;
6174 __u16 params, param_offset, offset, count, byte_count;
6176 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
6178 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6183 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6185 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6186 PATH_MAX, nls_codepage, remap);
6187 name_len++; /* trailing null */
6189 } else { /* BB improve the check for buffer overruns BB */
6190 name_len = strnlen(file_name, PATH_MAX);
6191 name_len++; /* trailing null */
6192 strncpy(pSMB->FileName, file_name, name_len);
6195 params = 6 + name_len;
6196 count = sizeof(FILE_UNIX_BASIC_INFO);
6197 pSMB->MaxParameterCount = cpu_to_le16(2);
6198 /* BB find max SMB PDU from sess structure BB */
6199 pSMB->MaxDataCount = cpu_to_le16(1000);
6200 pSMB->MaxSetupCount = 0;
6204 pSMB->Reserved2 = 0;
6205 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6206 InformationLevel) - 4;
6207 offset = param_offset + params;
6209 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6211 memset(data_offset, 0, count);
6212 pSMB->DataOffset = cpu_to_le16(offset);
6213 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6214 pSMB->SetupCount = 1;
6215 pSMB->Reserved3 = 0;
6216 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6217 byte_count = 3 /* pad */ + params + count;
6218 pSMB->ParameterCount = cpu_to_le16(params);
6219 pSMB->DataCount = cpu_to_le16(count);
6220 pSMB->TotalParameterCount = pSMB->ParameterCount;
6221 pSMB->TotalDataCount = pSMB->DataCount;
6222 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6223 pSMB->Reserved4 = 0;
6224 inc_rfc1001_len(pSMB, byte_count);
6226 cifs_fill_unix_set_info(data_offset, args);
6228 pSMB->ByteCount = cpu_to_le16(byte_count);
6229 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6230 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6232 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6234 cifs_buf_release(pSMB);
6240 #ifdef CONFIG_CIFS_XATTR
6242 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6243 * function used by listxattr and getxattr type calls. When ea_name is set,
6244 * it looks for that attribute name and stuffs that value into the EAData
6245 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6246 * buffer. In both cases, the return value is either the length of the
6247 * resulting data or a negative error code. If EAData is a NULL pointer then
6248 * the data isn't copied to it, but the length is returned.
6251 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6252 const unsigned char *searchName, const unsigned char *ea_name,
6253 char *EAData, size_t buf_size,
6254 struct cifs_sb_info *cifs_sb)
6256 /* BB assumes one setup word */
6257 TRANSACTION2_QPI_REQ *pSMB = NULL;
6258 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6259 int remap = cifs_remap(cifs_sb);
6260 struct nls_table *nls_codepage = cifs_sb->local_nls;
6264 struct fealist *ea_response_data;
6265 struct fea *temp_fea;
6268 __u16 params, byte_count, data_offset;
6269 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6271 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6273 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6278 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6280 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6281 PATH_MAX, nls_codepage, remap);
6282 list_len++; /* trailing null */
6284 } else { /* BB improve the check for buffer overruns BB */
6285 list_len = strnlen(searchName, PATH_MAX);
6286 list_len++; /* trailing null */
6287 strncpy(pSMB->FileName, searchName, list_len);
6290 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6291 pSMB->TotalDataCount = 0;
6292 pSMB->MaxParameterCount = cpu_to_le16(2);
6293 /* BB find exact max SMB PDU from sess structure BB */
6294 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6295 pSMB->MaxSetupCount = 0;
6299 pSMB->Reserved2 = 0;
6300 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6301 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6302 pSMB->DataCount = 0;
6303 pSMB->DataOffset = 0;
6304 pSMB->SetupCount = 1;
6305 pSMB->Reserved3 = 0;
6306 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6307 byte_count = params + 1 /* pad */ ;
6308 pSMB->TotalParameterCount = cpu_to_le16(params);
6309 pSMB->ParameterCount = pSMB->TotalParameterCount;
6310 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6311 pSMB->Reserved4 = 0;
6312 inc_rfc1001_len(pSMB, byte_count);
6313 pSMB->ByteCount = cpu_to_le16(byte_count);
6315 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6316 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6318 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6323 /* BB also check enough total bytes returned */
6324 /* BB we need to improve the validity checking
6325 of these trans2 responses */
6327 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6328 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6329 rc = -EIO; /* bad smb */
6333 /* check that length of list is not more than bcc */
6334 /* check that each entry does not go beyond length
6336 /* check that each element of each entry does not
6337 go beyond end of list */
6338 /* validate_trans2_offsets() */
6339 /* BB check if start of smb + data_offset > &bcc+ bcc */
6341 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6342 ea_response_data = (struct fealist *)
6343 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6345 list_len = le32_to_cpu(ea_response_data->list_len);
6346 cifs_dbg(FYI, "ea length %d\n", list_len);
6347 if (list_len <= 8) {
6348 cifs_dbg(FYI, "empty EA list returned from server\n");
6349 /* didn't find the named attribute */
6355 /* make sure list_len doesn't go past end of SMB */
6356 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6357 if ((char *)ea_response_data + list_len > end_of_smb) {
6358 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6363 /* account for ea list len */
6365 temp_fea = ea_response_data->list;
6366 temp_ptr = (char *)temp_fea;
6367 while (list_len > 0) {
6368 unsigned int name_len;
6373 /* make sure we can read name_len and value_len */
6375 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6380 name_len = temp_fea->name_len;
6381 value_len = le16_to_cpu(temp_fea->value_len);
6382 list_len -= name_len + 1 + value_len;
6384 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6390 if (ea_name_len == name_len &&
6391 memcmp(ea_name, temp_ptr, name_len) == 0) {
6392 temp_ptr += name_len + 1;
6396 if ((size_t)value_len > buf_size) {
6400 memcpy(EAData, temp_ptr, value_len);
6404 /* account for prefix user. and trailing null */
6405 rc += (5 + 1 + name_len);
6406 if (rc < (int) buf_size) {
6407 memcpy(EAData, "user.", 5);
6409 memcpy(EAData, temp_ptr, name_len);
6411 /* null terminate name */
6414 } else if (buf_size == 0) {
6415 /* skip copy - calc size only */
6417 /* stop before overrun buffer */
6422 temp_ptr += name_len + 1 + value_len;
6423 temp_fea = (struct fea *)temp_ptr;
6426 /* didn't find the named attribute */
6431 cifs_buf_release(pSMB);
6439 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6440 const char *fileName, const char *ea_name, const void *ea_value,
6441 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6442 struct cifs_sb_info *cifs_sb)
6444 struct smb_com_transaction2_spi_req *pSMB = NULL;
6445 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6446 struct fealist *parm_data;
6449 int bytes_returned = 0;
6450 __u16 params, param_offset, byte_count, offset, count;
6451 int remap = cifs_remap(cifs_sb);
6453 cifs_dbg(FYI, "In SetEA\n");
6455 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6460 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6462 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6463 PATH_MAX, nls_codepage, remap);
6464 name_len++; /* trailing null */
6466 } else { /* BB improve the check for buffer overruns BB */
6467 name_len = strnlen(fileName, PATH_MAX);
6468 name_len++; /* trailing null */
6469 strncpy(pSMB->FileName, fileName, name_len);
6472 params = 6 + name_len;
6474 /* done calculating parms using name_len of file name,
6475 now use name_len to calculate length of ea name
6476 we are going to create in the inode xattrs */
6477 if (ea_name == NULL)
6480 name_len = strnlen(ea_name, 255);
6482 count = sizeof(*parm_data) + ea_value_len + name_len;
6483 pSMB->MaxParameterCount = cpu_to_le16(2);
6484 /* BB find max SMB PDU from sess */
6485 pSMB->MaxDataCount = cpu_to_le16(1000);
6486 pSMB->MaxSetupCount = 0;
6490 pSMB->Reserved2 = 0;
6491 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6492 InformationLevel) - 4;
6493 offset = param_offset + params;
6494 pSMB->InformationLevel =
6495 cpu_to_le16(SMB_SET_FILE_EA);
6497 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6498 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6499 pSMB->DataOffset = cpu_to_le16(offset);
6500 pSMB->SetupCount = 1;
6501 pSMB->Reserved3 = 0;
6502 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6503 byte_count = 3 /* pad */ + params + count;
6504 pSMB->DataCount = cpu_to_le16(count);
6505 parm_data->list_len = cpu_to_le32(count);
6506 parm_data->list[0].EA_flags = 0;
6507 /* we checked above that name len is less than 255 */
6508 parm_data->list[0].name_len = (__u8)name_len;
6509 /* EA names are always ASCII */
6511 strncpy(parm_data->list[0].name, ea_name, name_len);
6512 parm_data->list[0].name[name_len] = 0;
6513 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6514 /* caller ensures that ea_value_len is less than 64K but
6515 we need to ensure that it fits within the smb */
6517 /*BB add length check to see if it would fit in
6518 negotiated SMB buffer size BB */
6519 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6521 memcpy(parm_data->list[0].name+name_len+1,
6522 ea_value, ea_value_len);
6524 pSMB->TotalDataCount = pSMB->DataCount;
6525 pSMB->ParameterCount = cpu_to_le16(params);
6526 pSMB->TotalParameterCount = pSMB->ParameterCount;
6527 pSMB->Reserved4 = 0;
6528 inc_rfc1001_len(pSMB, byte_count);
6529 pSMB->ByteCount = cpu_to_le16(byte_count);
6530 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6531 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6533 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6535 cifs_buf_release(pSMB);
6544 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6546 * Years ago the kernel added a "dnotify" function for Samba server,
6547 * to allow network clients (such as Windows) to display updated
6548 * lists of files in directory listings automatically when
6549 * files are added by one user when another user has the
6550 * same directory open on their desktop. The Linux cifs kernel
6551 * client hooked into the kernel side of this interface for
6552 * the same reason, but ironically when the VFS moved from
6553 * "dnotify" to "inotify" it became harder to plug in Linux
6554 * network file system clients (the most obvious use case
6555 * for notify interfaces is when multiple users can update
6556 * the contents of the same directory - exactly what network
6557 * file systems can do) although the server (Samba) could
6558 * still use it. For the short term we leave the worker
6559 * function ifdeffed out (below) until inotify is fixed
6560 * in the VFS to make it easier to plug in network file
6561 * system clients. If inotify turns out to be permanently
6562 * incompatible for network fs clients, we could instead simply
6563 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6565 int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
6566 const int notify_subdirs, const __u16 netfid,
6567 __u32 filter, struct file *pfile, int multishot,
6568 const struct nls_table *nls_codepage)
6571 struct smb_com_transaction_change_notify_req *pSMB = NULL;
6572 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6573 struct dir_notify_req *dnotify_req;
6576 cifs_dbg(FYI, "In CIFSSMBNotify for file handle %d\n", (int)netfid);
6577 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6582 pSMB->TotalParameterCount = 0 ;
6583 pSMB->TotalDataCount = 0;
6584 pSMB->MaxParameterCount = cpu_to_le32(2);
6585 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6586 pSMB->MaxSetupCount = 4;
6588 pSMB->ParameterOffset = 0;
6589 pSMB->DataCount = 0;
6590 pSMB->DataOffset = 0;
6591 pSMB->SetupCount = 4; /* single byte does not need le conversion */
6592 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6593 pSMB->ParameterCount = pSMB->TotalParameterCount;
6595 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6596 pSMB->Reserved2 = 0;
6597 pSMB->CompletionFilter = cpu_to_le32(filter);
6598 pSMB->Fid = netfid; /* file handle always le */
6599 pSMB->ByteCount = 0;
6601 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6602 (struct smb_hdr *)pSMBr, &bytes_returned,
6605 cifs_dbg(FYI, "Error in Notify = %d\n", rc);
6607 /* Add file to outstanding requests */
6608 /* BB change to kmem cache alloc */
6609 dnotify_req = kmalloc(
6610 sizeof(struct dir_notify_req),
6613 dnotify_req->Pid = pSMB->hdr.Pid;
6614 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6615 dnotify_req->Mid = pSMB->hdr.Mid;
6616 dnotify_req->Tid = pSMB->hdr.Tid;
6617 dnotify_req->Uid = pSMB->hdr.Uid;
6618 dnotify_req->netfid = netfid;
6619 dnotify_req->pfile = pfile;
6620 dnotify_req->filter = filter;
6621 dnotify_req->multishot = multishot;
6622 spin_lock(&GlobalMid_Lock);
6623 list_add_tail(&dnotify_req->lhead,
6624 &GlobalDnotifyReqList);
6625 spin_unlock(&GlobalMid_Lock);
6629 cifs_buf_release(pSMB);
6632 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */