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 <asm/uaccess.h>
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
47 #ifdef CONFIG_CIFS_POSIX
52 #ifdef CONFIG_CIFS_WEAK_PW_HASH
53 {LANMAN_PROT, "\2LM1.2X002"},
54 {LANMAN2_PROT, "\2LANMAN2.1"},
55 #endif /* weak password hashing for legacy clients */
56 {CIFS_PROT, "\2NT LM 0.12"},
57 {POSIX_PROT, "\2POSIX 2"},
65 #ifdef CONFIG_CIFS_WEAK_PW_HASH
66 {LANMAN_PROT, "\2LM1.2X002"},
67 {LANMAN2_PROT, "\2LANMAN2.1"},
68 #endif /* weak password hashing for legacy clients */
69 {CIFS_PROT, "\2NT LM 0.12"},
74 /* define the number of elements in the cifs dialect array */
75 #ifdef CONFIG_CIFS_POSIX
76 #ifdef CONFIG_CIFS_WEAK_PW_HASH
77 #define CIFS_NUM_PROT 4
79 #define CIFS_NUM_PROT 2
80 #endif /* CIFS_WEAK_PW_HASH */
82 #ifdef CONFIG_CIFS_WEAK_PW_HASH
83 #define CIFS_NUM_PROT 3
85 #define CIFS_NUM_PROT 1
86 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
87 #endif /* CIFS_POSIX */
90 * Mark as invalid, all open files on tree connections since they
91 * were closed when session to server was lost.
94 cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
96 struct cifsFileInfo *open_file = NULL;
97 struct list_head *tmp;
98 struct list_head *tmp1;
100 /* list all files open on tree connection and mark them invalid */
101 spin_lock(&cifs_file_list_lock);
102 list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
103 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
104 open_file->invalidHandle = true;
105 open_file->oplock_break_cancelled = true;
107 spin_unlock(&cifs_file_list_lock);
109 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
114 /* reconnect the socket, tcon, and smb session if needed */
116 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
119 struct cifs_ses *ses;
120 struct TCP_Server_Info *server;
121 struct nls_table *nls_codepage;
124 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
125 * tcp and smb session status done differently for those three - in the
132 server = ses->server;
135 * only tree disconnect, open, and write, (and ulogoff which does not
136 * have tcon) are allowed as we start force umount
138 if (tcon->tidStatus == CifsExiting) {
139 if (smb_command != SMB_COM_WRITE_ANDX &&
140 smb_command != SMB_COM_OPEN_ANDX &&
141 smb_command != SMB_COM_TREE_DISCONNECT) {
142 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
149 * Give demultiplex thread up to 10 seconds to reconnect, should be
150 * greater than cifs socket timeout which is 7 seconds
152 while (server->tcpStatus == CifsNeedReconnect) {
153 wait_event_interruptible_timeout(server->response_q,
154 (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
156 /* are we still trying to reconnect? */
157 if (server->tcpStatus != CifsNeedReconnect)
161 * on "soft" mounts we wait once. Hard mounts keep
162 * retrying until process is killed or server comes
166 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
171 if (!ses->need_reconnect && !tcon->need_reconnect)
174 nls_codepage = load_nls_default();
177 * need to prevent multiple threads trying to simultaneously
178 * reconnect the same SMB session
180 mutex_lock(&ses->session_mutex);
181 rc = cifs_negotiate_protocol(0, ses);
182 if (rc == 0 && ses->need_reconnect)
183 rc = cifs_setup_session(0, ses, nls_codepage);
185 /* do we need to reconnect tcon? */
186 if (rc || !tcon->need_reconnect) {
187 mutex_unlock(&ses->session_mutex);
191 cifs_mark_open_files_invalid(tcon);
192 rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
193 mutex_unlock(&ses->session_mutex);
194 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
200 * FIXME: check if wsize needs updated due to negotiated smb buffer
203 atomic_inc(&tconInfoReconnectCount);
205 /* tell server Unix caps we support */
206 if (ses->capabilities & CAP_UNIX)
207 reset_cifs_unix_caps(0, tcon, NULL, NULL);
210 * Removed call to reopen open files here. It is safer (and faster) to
211 * reopen files one at a time as needed in read and write.
213 * FIXME: what about file locks? don't we need to reclaim them ASAP?
218 * Check if handle based operation so we know whether we can continue
219 * or not without returning to caller to reset file handle
221 switch (smb_command) {
222 case SMB_COM_READ_ANDX:
223 case SMB_COM_WRITE_ANDX:
225 case SMB_COM_FIND_CLOSE2:
226 case SMB_COM_LOCKING_ANDX:
230 unload_nls(nls_codepage);
234 /* Allocate and return pointer to an SMB request buffer, and set basic
235 SMB information in the SMB header. If the return code is zero, this
236 function must have filled in request_buf pointer */
238 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
243 rc = cifs_reconnect_tcon(tcon, smb_command);
247 *request_buf = cifs_small_buf_get();
248 if (*request_buf == NULL) {
249 /* BB should we add a retry in here if not a writepage? */
253 header_assemble((struct smb_hdr *) *request_buf, smb_command,
257 cifs_stats_inc(&tcon->num_smbs_sent);
263 small_smb_init_no_tc(const int smb_command, const int wct,
264 struct cifs_ses *ses, void **request_buf)
267 struct smb_hdr *buffer;
269 rc = small_smb_init(smb_command, wct, NULL, request_buf);
273 buffer = (struct smb_hdr *)*request_buf;
274 buffer->Mid = get_next_mid(ses->server);
275 if (ses->capabilities & CAP_UNICODE)
276 buffer->Flags2 |= SMBFLG2_UNICODE;
277 if (ses->capabilities & CAP_STATUS32)
278 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
280 /* uid, tid can stay at zero as set in header assemble */
282 /* BB add support for turning on the signing when
283 this function is used after 1st of session setup requests */
288 /* If the return code is zero, this function must fill in request_buf pointer */
290 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
291 void **request_buf, void **response_buf)
293 *request_buf = cifs_buf_get();
294 if (*request_buf == NULL) {
295 /* BB should we add a retry in here if not a writepage? */
298 /* Although the original thought was we needed the response buf for */
299 /* potential retries of smb operations it turns out we can determine */
300 /* from the mid flags when the request buffer can be resent without */
301 /* having to use a second distinct buffer for the response */
303 *response_buf = *request_buf;
305 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
309 cifs_stats_inc(&tcon->num_smbs_sent);
314 /* If the return code is zero, this function must fill in request_buf pointer */
316 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
317 void **request_buf, void **response_buf)
321 rc = cifs_reconnect_tcon(tcon, smb_command);
325 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
329 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
330 void **request_buf, void **response_buf)
332 if (tcon->ses->need_reconnect || tcon->need_reconnect)
335 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
338 static int validate_t2(struct smb_t2_rsp *pSMB)
340 unsigned int total_size;
342 /* check for plausible wct */
343 if (pSMB->hdr.WordCount < 10)
346 /* check for parm and data offset going beyond end of smb */
347 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
348 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
351 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
352 if (total_size >= 512)
355 /* check that bcc is at least as big as parms + data, and that it is
356 * less than negotiated smb buffer
358 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
359 if (total_size > get_bcc(&pSMB->hdr) ||
360 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
365 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
366 sizeof(struct smb_t2_rsp) + 16);
371 decode_ext_sec_blob(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
375 char *guid = pSMBr->u.extended_response.GUID;
377 count = get_bcc(&pSMBr->hdr);
378 if (count < SMB1_CLIENT_GUID_SIZE)
381 spin_lock(&cifs_tcp_ses_lock);
382 if (server->srv_count > 1) {
383 spin_unlock(&cifs_tcp_ses_lock);
384 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
385 cifs_dbg(FYI, "server UID changed\n");
386 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
389 spin_unlock(&cifs_tcp_ses_lock);
390 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
393 if (count == SMB1_CLIENT_GUID_SIZE) {
394 server->secType = RawNTLMSSP;
396 count -= SMB1_CLIENT_GUID_SIZE;
397 rc = decode_negTokenInit(
398 pSMBr->u.extended_response.SecurityBlob, count, server);
402 /* Make sure server supports what we want to use */
403 switch(server->secType) {
405 if (!server->sec_kerberos && !server->sec_mskerberos)
409 if (!server->sec_ntlmssp)
421 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
423 bool srv_sign_required = server->sec_mode & SECMODE_SIGN_REQUIRED;
424 bool srv_sign_enabled = server->sec_mode & SECMODE_SIGN_ENABLED;
425 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
428 * Is signing required by mnt options? If not then check
429 * global_secflags to see if it is there.
431 if (!mnt_sign_required)
432 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
436 * If signing is required then it's automatically enabled too,
437 * otherwise, check to see if the secflags allow it.
439 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
440 (global_secflags & CIFSSEC_MAY_SIGN);
442 /* If server requires signing, does client allow it? */
443 if (srv_sign_required) {
444 if (!mnt_sign_enabled) {
445 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!");
451 /* If client requires signing, does server allow it? */
452 if (mnt_sign_required) {
453 if (!srv_sign_enabled) {
454 cifs_dbg(VFS, "Server does not support signing!");
463 #ifdef CONFIG_CIFS_WEAK_PW_HASH
465 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr,
466 unsigned int secFlags)
469 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
471 if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
474 if ((secFlags & CIFSSEC_MAY_LANMAN) || (secFlags & CIFSSEC_MAY_PLNTXT))
475 server->secType = LANMAN;
477 cifs_dbg(VFS, "mount failed weak security disabled in /proc/fs/cifs/SecurityFlags\n");
480 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
481 server->maxReq = min_t(unsigned int,
482 le16_to_cpu(rsp->MaxMpxCount),
484 set_credits(server, server->maxReq);
485 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
486 server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
487 /* even though we do not use raw we might as well set this
488 accurately, in case we ever find a need for it */
489 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
490 server->max_rw = 0xFF00;
491 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
493 server->max_rw = 0;/* do not need to use raw anyway */
494 server->capabilities = CAP_MPX_MODE;
496 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
498 /* OS/2 often does not set timezone therefore
499 * we must use server time to calc time zone.
500 * Could deviate slightly from the right zone.
501 * Smallest defined timezone difference is 15 minutes
502 * (i.e. Nepal). Rounding up/down is done to match
505 int val, seconds, remain, result;
506 struct timespec ts, utc;
508 ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
509 rsp->SrvTime.Time, 0);
510 cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
511 (int)ts.tv_sec, (int)utc.tv_sec,
512 (int)(utc.tv_sec - ts.tv_sec));
513 val = (int)(utc.tv_sec - ts.tv_sec);
515 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
516 remain = seconds % MIN_TZ_ADJ;
517 if (remain >= (MIN_TZ_ADJ / 2))
518 result += MIN_TZ_ADJ;
521 server->timeAdj = result;
523 server->timeAdj = (int)tmp;
524 server->timeAdj *= 60; /* also in seconds */
526 cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
529 /* BB get server time for time conversions and add
530 code to use it and timezone since this is not UTC */
532 if (rsp->EncryptionKeyLength ==
533 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
534 memcpy(server->cryptkey, rsp->EncryptionKey,
535 CIFS_CRYPTO_KEY_SIZE);
536 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
537 return -EIO; /* need cryptkey unless plain text */
540 cifs_dbg(FYI, "LANMAN negotiated\n");
545 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr,
546 unsigned int secFlags)
548 cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
554 should_set_ext_sec_flag(unsigned int secFlags)
556 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
558 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5)
560 else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
562 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP)
568 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
571 NEGOTIATE_RSP *pSMBr;
575 struct TCP_Server_Info *server = ses->server;
577 unsigned int secFlags;
580 WARN(1, "%s: server is NULL!\n", __func__);
584 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
585 (void **) &pSMB, (void **) &pSMBr);
589 /* if any of auth flags (ie not sign or seal) are overriden use them */
590 if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
591 secFlags = ses->overrideSecFlg; /* BB FIXME fix sign flags? */
592 else /* if override flags set only sign/seal OR them with global auth */
593 secFlags = global_secflags | ses->overrideSecFlg;
595 cifs_dbg(FYI, "secFlags 0x%x\n", secFlags);
597 pSMB->hdr.Mid = get_next_mid(server);
598 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
600 if (should_set_ext_sec_flag(secFlags)) {
601 cifs_dbg(FYI, "Requesting extended security.");
602 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
606 for (i = 0; i < CIFS_NUM_PROT; i++) {
607 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
608 count += strlen(protocols[i].name) + 1;
609 /* null at end of source and target buffers anyway */
611 inc_rfc1001_len(pSMB, count);
612 pSMB->ByteCount = cpu_to_le16(count);
614 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
615 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
619 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
620 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
621 /* Check wct = 1 error case */
622 if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
623 /* core returns wct = 1, but we do not ask for core - otherwise
624 small wct just comes when dialect index is -1 indicating we
625 could not negotiate a common dialect */
628 } else if (pSMBr->hdr.WordCount == 13) {
629 server->negflavor = CIFS_NEGFLAVOR_LANMAN;
630 rc = decode_lanman_negprot_rsp(server, pSMBr, secFlags);
632 } else if (pSMBr->hdr.WordCount != 17) {
637 /* else wct == 17, NTLM or better */
639 server->sec_mode = pSMBr->SecurityMode;
640 if ((server->sec_mode & SECMODE_USER) == 0)
641 cifs_dbg(FYI, "share mode security\n");
643 if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
644 #ifdef CONFIG_CIFS_WEAK_PW_HASH
645 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
646 #endif /* CIFS_WEAK_PW_HASH */
647 cifs_dbg(VFS, "Server requests plain text password but client support disabled\n");
649 if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
650 server->secType = NTLMv2;
651 else if (secFlags & CIFSSEC_MAY_NTLM)
652 server->secType = NTLM;
653 else if (secFlags & CIFSSEC_MAY_NTLMV2)
654 server->secType = NTLMv2;
655 else if (secFlags & CIFSSEC_MAY_KRB5)
656 server->secType = Kerberos;
657 else if (secFlags & CIFSSEC_MAY_NTLMSSP)
658 server->secType = RawNTLMSSP;
659 else if (secFlags & CIFSSEC_MAY_LANMAN)
660 server->secType = LANMAN;
663 cifs_dbg(VFS, "Invalid security type\n");
666 /* else ... any others ...? */
668 /* one byte, so no need to convert this or EncryptionKeyLen from
670 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
672 set_credits(server, server->maxReq);
673 /* probably no need to store and check maxvcs */
674 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
675 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
676 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
677 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
678 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
679 server->timeAdj *= 60;
681 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
682 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
683 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
684 CIFS_CRYPTO_KEY_SIZE);
685 } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
686 server->capabilities & CAP_EXTENDED_SECURITY) &&
687 (pSMBr->EncryptionKeyLength == 0)) {
688 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
689 rc = decode_ext_sec_blob(server, pSMBr);
690 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
691 rc = -EIO; /* no crypt key only if plain text pwd */
693 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
694 server->capabilities &= ~CAP_EXTENDED_SECURITY;
699 rc = cifs_enable_signing(server, ses->sign);
701 cifs_buf_release(pSMB);
703 cifs_dbg(FYI, "negprot rc %d\n", rc);
708 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
710 struct smb_hdr *smb_buffer;
713 cifs_dbg(FYI, "In tree disconnect\n");
715 /* BB: do we need to check this? These should never be NULL. */
716 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
720 * No need to return error on this operation if tid invalidated and
721 * closed on server already e.g. due to tcp session crashing. Also,
722 * the tcon is no longer on the list, so no need to take lock before
725 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
728 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
729 (void **)&smb_buffer);
733 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
735 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
737 /* No need to return error on this operation if tid invalidated and
738 closed on server already e.g. due to tcp session crashing */
746 * This is a no-op for now. We're not really interested in the reply, but
747 * rather in the fact that the server sent one and that server->lstrp
750 * FIXME: maybe we should consider checking that the reply matches request?
753 cifs_echo_callback(struct mid_q_entry *mid)
755 struct TCP_Server_Info *server = mid->callback_data;
757 DeleteMidQEntry(mid);
758 add_credits(server, 1, CIFS_ECHO_OP);
762 CIFSSMBEcho(struct TCP_Server_Info *server)
767 struct smb_rqst rqst = { .rq_iov = &iov,
770 cifs_dbg(FYI, "In echo request\n");
772 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
776 /* set up echo request */
777 smb->hdr.Tid = 0xffff;
778 smb->hdr.WordCount = 1;
779 put_unaligned_le16(1, &smb->EchoCount);
780 put_bcc(1, &smb->hdr);
782 inc_rfc1001_len(smb, 3);
784 iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
786 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback,
787 server, CIFS_ASYNC_OP | CIFS_ECHO_OP);
789 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
791 cifs_small_buf_release(smb);
797 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
799 LOGOFF_ANDX_REQ *pSMB;
802 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
805 * BB: do we need to check validity of ses and server? They should
806 * always be valid since we have an active reference. If not, that
807 * should probably be a BUG()
809 if (!ses || !ses->server)
812 mutex_lock(&ses->session_mutex);
813 if (ses->need_reconnect)
814 goto session_already_dead; /* no need to send SMBlogoff if uid
815 already closed due to reconnect */
816 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
818 mutex_unlock(&ses->session_mutex);
822 pSMB->hdr.Mid = get_next_mid(ses->server);
824 if (ses->server->sign)
825 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
827 pSMB->hdr.Uid = ses->Suid;
829 pSMB->AndXCommand = 0xFF;
830 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
831 session_already_dead:
832 mutex_unlock(&ses->session_mutex);
834 /* if session dead then we do not need to do ulogoff,
835 since server closed smb session, no sense reporting
843 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
844 const char *fileName, __u16 type,
845 const struct nls_table *nls_codepage, int remap)
847 TRANSACTION2_SPI_REQ *pSMB = NULL;
848 TRANSACTION2_SPI_RSP *pSMBr = NULL;
849 struct unlink_psx_rq *pRqD;
852 int bytes_returned = 0;
853 __u16 params, param_offset, offset, byte_count;
855 cifs_dbg(FYI, "In POSIX delete\n");
857 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
862 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
864 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
865 PATH_MAX, nls_codepage, remap);
866 name_len++; /* trailing null */
868 } else { /* BB add path length overrun check */
869 name_len = strnlen(fileName, PATH_MAX);
870 name_len++; /* trailing null */
871 strncpy(pSMB->FileName, fileName, name_len);
874 params = 6 + name_len;
875 pSMB->MaxParameterCount = cpu_to_le16(2);
876 pSMB->MaxDataCount = 0; /* BB double check this with jra */
877 pSMB->MaxSetupCount = 0;
882 param_offset = offsetof(struct smb_com_transaction2_spi_req,
883 InformationLevel) - 4;
884 offset = param_offset + params;
886 /* Setup pointer to Request Data (inode type) */
887 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
888 pRqD->type = cpu_to_le16(type);
889 pSMB->ParameterOffset = cpu_to_le16(param_offset);
890 pSMB->DataOffset = cpu_to_le16(offset);
891 pSMB->SetupCount = 1;
893 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
894 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
896 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
897 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
898 pSMB->ParameterCount = cpu_to_le16(params);
899 pSMB->TotalParameterCount = pSMB->ParameterCount;
900 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
902 inc_rfc1001_len(pSMB, byte_count);
903 pSMB->ByteCount = cpu_to_le16(byte_count);
904 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
905 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
907 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
908 cifs_buf_release(pSMB);
910 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
919 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
920 struct cifs_sb_info *cifs_sb)
922 DELETE_FILE_REQ *pSMB = NULL;
923 DELETE_FILE_RSP *pSMBr = NULL;
927 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
930 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
935 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
936 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
937 PATH_MAX, cifs_sb->local_nls,
939 name_len++; /* trailing null */
941 } else { /* BB improve check for buffer overruns BB */
942 name_len = strnlen(name, PATH_MAX);
943 name_len++; /* trailing null */
944 strncpy(pSMB->fileName, name, name_len);
946 pSMB->SearchAttributes =
947 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
948 pSMB->BufferFormat = 0x04;
949 inc_rfc1001_len(pSMB, name_len + 1);
950 pSMB->ByteCount = cpu_to_le16(name_len + 1);
951 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
952 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
953 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
955 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
957 cifs_buf_release(pSMB);
965 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
966 struct cifs_sb_info *cifs_sb)
968 DELETE_DIRECTORY_REQ *pSMB = NULL;
969 DELETE_DIRECTORY_RSP *pSMBr = NULL;
973 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
975 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
977 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
982 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
983 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
984 PATH_MAX, cifs_sb->local_nls,
986 name_len++; /* trailing null */
988 } else { /* BB improve check for buffer overruns BB */
989 name_len = strnlen(name, PATH_MAX);
990 name_len++; /* trailing null */
991 strncpy(pSMB->DirName, name, name_len);
994 pSMB->BufferFormat = 0x04;
995 inc_rfc1001_len(pSMB, name_len + 1);
996 pSMB->ByteCount = cpu_to_le16(name_len + 1);
997 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
998 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
999 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
1001 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
1003 cifs_buf_release(pSMB);
1010 CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
1011 struct cifs_sb_info *cifs_sb)
1014 CREATE_DIRECTORY_REQ *pSMB = NULL;
1015 CREATE_DIRECTORY_RSP *pSMBr = NULL;
1018 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
1020 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
1022 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
1027 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1028 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1029 PATH_MAX, cifs_sb->local_nls,
1031 name_len++; /* trailing null */
1033 } else { /* BB improve check for buffer overruns BB */
1034 name_len = strnlen(name, PATH_MAX);
1035 name_len++; /* trailing null */
1036 strncpy(pSMB->DirName, name, name_len);
1039 pSMB->BufferFormat = 0x04;
1040 inc_rfc1001_len(pSMB, name_len + 1);
1041 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1042 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1043 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1044 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1046 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
1048 cifs_buf_release(pSMB);
1055 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1056 __u32 posix_flags, __u64 mode, __u16 *netfid,
1057 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1058 const char *name, const struct nls_table *nls_codepage,
1061 TRANSACTION2_SPI_REQ *pSMB = NULL;
1062 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1065 int bytes_returned = 0;
1066 __u16 params, param_offset, offset, byte_count, count;
1067 OPEN_PSX_REQ *pdata;
1068 OPEN_PSX_RSP *psx_rsp;
1070 cifs_dbg(FYI, "In POSIX Create\n");
1072 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1077 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1079 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1080 PATH_MAX, nls_codepage, remap);
1081 name_len++; /* trailing null */
1083 } else { /* BB improve the check for buffer overruns BB */
1084 name_len = strnlen(name, PATH_MAX);
1085 name_len++; /* trailing null */
1086 strncpy(pSMB->FileName, name, name_len);
1089 params = 6 + name_len;
1090 count = sizeof(OPEN_PSX_REQ);
1091 pSMB->MaxParameterCount = cpu_to_le16(2);
1092 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1093 pSMB->MaxSetupCount = 0;
1097 pSMB->Reserved2 = 0;
1098 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1099 InformationLevel) - 4;
1100 offset = param_offset + params;
1101 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1102 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1103 pdata->Permissions = cpu_to_le64(mode);
1104 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1105 pdata->OpenFlags = cpu_to_le32(*pOplock);
1106 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1107 pSMB->DataOffset = cpu_to_le16(offset);
1108 pSMB->SetupCount = 1;
1109 pSMB->Reserved3 = 0;
1110 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1111 byte_count = 3 /* pad */ + params + count;
1113 pSMB->DataCount = cpu_to_le16(count);
1114 pSMB->ParameterCount = cpu_to_le16(params);
1115 pSMB->TotalDataCount = pSMB->DataCount;
1116 pSMB->TotalParameterCount = pSMB->ParameterCount;
1117 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1118 pSMB->Reserved4 = 0;
1119 inc_rfc1001_len(pSMB, byte_count);
1120 pSMB->ByteCount = cpu_to_le16(byte_count);
1121 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1122 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1124 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1125 goto psx_create_err;
1128 cifs_dbg(FYI, "copying inode info\n");
1129 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1131 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1132 rc = -EIO; /* bad smb */
1133 goto psx_create_err;
1136 /* copy return information to pRetData */
1137 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1138 + le16_to_cpu(pSMBr->t2.DataOffset));
1140 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1142 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1143 /* Let caller know file was created so we can set the mode. */
1144 /* Do we care about the CreateAction in any other cases? */
1145 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1146 *pOplock |= CIFS_CREATE_ACTION;
1147 /* check to make sure response data is there */
1148 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1149 pRetData->Type = cpu_to_le32(-1); /* unknown */
1150 cifs_dbg(NOISY, "unknown type\n");
1152 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1153 + sizeof(FILE_UNIX_BASIC_INFO)) {
1154 cifs_dbg(VFS, "Open response data too small\n");
1155 pRetData->Type = cpu_to_le32(-1);
1156 goto psx_create_err;
1158 memcpy((char *) pRetData,
1159 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1160 sizeof(FILE_UNIX_BASIC_INFO));
1164 cifs_buf_release(pSMB);
1166 if (posix_flags & SMB_O_DIRECTORY)
1167 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1169 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1177 static __u16 convert_disposition(int disposition)
1181 switch (disposition) {
1182 case FILE_SUPERSEDE:
1183 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1186 ofun = SMBOPEN_OAPPEND;
1189 ofun = SMBOPEN_OCREATE;
1192 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1194 case FILE_OVERWRITE:
1195 ofun = SMBOPEN_OTRUNC;
1197 case FILE_OVERWRITE_IF:
1198 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1201 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1202 ofun = SMBOPEN_OAPPEND; /* regular open */
1208 access_flags_to_smbopen_mode(const int access_flags)
1210 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1212 if (masked_flags == GENERIC_READ)
1213 return SMBOPEN_READ;
1214 else if (masked_flags == GENERIC_WRITE)
1215 return SMBOPEN_WRITE;
1217 /* just go for read/write */
1218 return SMBOPEN_READWRITE;
1222 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1223 const char *fileName, const int openDisposition,
1224 const int access_flags, const int create_options, __u16 *netfid,
1225 int *pOplock, FILE_ALL_INFO *pfile_info,
1226 const struct nls_table *nls_codepage, int remap)
1229 OPENX_REQ *pSMB = NULL;
1230 OPENX_RSP *pSMBr = NULL;
1236 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1241 pSMB->AndXCommand = 0xFF; /* none */
1243 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1244 count = 1; /* account for one byte pad to word boundary */
1246 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1247 fileName, PATH_MAX, nls_codepage, remap);
1248 name_len++; /* trailing null */
1250 } else { /* BB improve check for buffer overruns BB */
1251 count = 0; /* no pad */
1252 name_len = strnlen(fileName, PATH_MAX);
1253 name_len++; /* trailing null */
1254 strncpy(pSMB->fileName, fileName, name_len);
1256 if (*pOplock & REQ_OPLOCK)
1257 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1258 else if (*pOplock & REQ_BATCHOPLOCK)
1259 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1261 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1262 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1263 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1264 /* set file as system file if special file such
1265 as fifo and server expecting SFU style and
1266 no Unix extensions */
1268 if (create_options & CREATE_OPTION_SPECIAL)
1269 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1270 else /* BB FIXME BB */
1271 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1273 if (create_options & CREATE_OPTION_READONLY)
1274 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1277 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1278 CREATE_OPTIONS_MASK); */
1279 /* BB FIXME END BB */
1281 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1282 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1284 inc_rfc1001_len(pSMB, count);
1286 pSMB->ByteCount = cpu_to_le16(count);
1287 /* long_op set to 1 to allow for oplock break timeouts */
1288 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1289 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1290 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1292 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1294 /* BB verify if wct == 15 */
1296 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1298 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1299 /* Let caller know file was created so we can set the mode. */
1300 /* Do we care about the CreateAction in any other cases? */
1302 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1303 *pOplock |= CIFS_CREATE_ACTION; */
1307 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1308 pfile_info->LastAccessTime = 0; /* BB fixme */
1309 pfile_info->LastWriteTime = 0; /* BB fixme */
1310 pfile_info->ChangeTime = 0; /* BB fixme */
1311 pfile_info->Attributes =
1312 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1313 /* the file_info buf is endian converted by caller */
1314 pfile_info->AllocationSize =
1315 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1316 pfile_info->EndOfFile = pfile_info->AllocationSize;
1317 pfile_info->NumberOfLinks = cpu_to_le32(1);
1318 pfile_info->DeletePending = 0;
1322 cifs_buf_release(pSMB);
1329 CIFSSMBOpen(const unsigned int xid, struct cifs_tcon *tcon,
1330 const char *fileName, const int openDisposition,
1331 const int access_flags, const int create_options, __u16 *netfid,
1332 int *pOplock, FILE_ALL_INFO *pfile_info,
1333 const struct nls_table *nls_codepage, int remap)
1336 OPEN_REQ *pSMB = NULL;
1337 OPEN_RSP *pSMBr = NULL;
1343 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **) &pSMB,
1348 pSMB->AndXCommand = 0xFF; /* none */
1350 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1351 count = 1; /* account for one byte pad to word boundary */
1353 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1354 fileName, PATH_MAX, nls_codepage, remap);
1355 name_len++; /* trailing null */
1357 pSMB->NameLength = cpu_to_le16(name_len);
1358 } else { /* BB improve check for buffer overruns BB */
1359 count = 0; /* no pad */
1360 name_len = strnlen(fileName, PATH_MAX);
1361 name_len++; /* trailing null */
1362 pSMB->NameLength = cpu_to_le16(name_len);
1363 strncpy(pSMB->fileName, fileName, name_len);
1365 if (*pOplock & REQ_OPLOCK)
1366 pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1367 else if (*pOplock & REQ_BATCHOPLOCK)
1368 pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1369 pSMB->DesiredAccess = cpu_to_le32(access_flags);
1370 pSMB->AllocationSize = 0;
1371 /* set file as system file if special file such
1372 as fifo and server expecting SFU style and
1373 no Unix extensions */
1374 if (create_options & CREATE_OPTION_SPECIAL)
1375 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1377 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1379 /* XP does not handle ATTR_POSIX_SEMANTICS */
1380 /* but it helps speed up case sensitive checks for other
1381 servers such as Samba */
1382 if (tcon->ses->capabilities & CAP_UNIX)
1383 pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1385 if (create_options & CREATE_OPTION_READONLY)
1386 pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1388 pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1389 pSMB->CreateDisposition = cpu_to_le32(openDisposition);
1390 pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1391 /* BB Expirement with various impersonation levels and verify */
1392 pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1393 pSMB->SecurityFlags =
1394 SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
1397 inc_rfc1001_len(pSMB, count);
1399 pSMB->ByteCount = cpu_to_le16(count);
1400 /* long_op set to 1 to allow for oplock break timeouts */
1401 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1402 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1403 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1405 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1407 *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
1408 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1409 /* Let caller know file was created so we can set the mode. */
1410 /* Do we care about the CreateAction in any other cases? */
1411 if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1412 *pOplock |= CIFS_CREATE_ACTION;
1414 memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
1415 36 /* CreationTime to Attributes */);
1416 /* the file_info buf is endian converted by caller */
1417 pfile_info->AllocationSize = pSMBr->AllocationSize;
1418 pfile_info->EndOfFile = pSMBr->EndOfFile;
1419 pfile_info->NumberOfLinks = cpu_to_le32(1);
1420 pfile_info->DeletePending = 0;
1424 cifs_buf_release(pSMB);
1431 * Discard any remaining data in the current SMB. To do this, we borrow the
1435 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1437 unsigned int rfclen = get_rfc1002_length(server->smallbuf);
1438 int remaining = rfclen + 4 - server->total_read;
1439 struct cifs_readdata *rdata = mid->callback_data;
1441 while (remaining > 0) {
1444 length = cifs_read_from_socket(server, server->bigbuf,
1445 min_t(unsigned int, remaining,
1446 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1449 server->total_read += length;
1450 remaining -= length;
1453 dequeue_mid(mid, rdata->result);
1458 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1461 unsigned int data_offset, data_len;
1462 struct cifs_readdata *rdata = mid->callback_data;
1463 char *buf = server->smallbuf;
1464 unsigned int buflen = get_rfc1002_length(buf) + 4;
1466 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1467 __func__, mid->mid, rdata->offset, rdata->bytes);
1470 * read the rest of READ_RSP header (sans Data array), or whatever we
1471 * can if there's not enough data. At this point, we've read down to
1474 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1475 HEADER_SIZE(server) + 1;
1477 rdata->iov.iov_base = buf + HEADER_SIZE(server) - 1;
1478 rdata->iov.iov_len = len;
1480 length = cifs_readv_from_socket(server, &rdata->iov, 1, len);
1483 server->total_read += length;
1485 /* Was the SMB read successful? */
1486 rdata->result = server->ops->map_error(buf, false);
1487 if (rdata->result != 0) {
1488 cifs_dbg(FYI, "%s: server returned error %d\n",
1489 __func__, rdata->result);
1490 return cifs_readv_discard(server, mid);
1493 /* Is there enough to get to the rest of the READ_RSP header? */
1494 if (server->total_read < server->vals->read_rsp_size) {
1495 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1496 __func__, server->total_read,
1497 server->vals->read_rsp_size);
1498 rdata->result = -EIO;
1499 return cifs_readv_discard(server, mid);
1502 data_offset = server->ops->read_data_offset(buf) + 4;
1503 if (data_offset < server->total_read) {
1505 * win2k8 sometimes sends an offset of 0 when the read
1506 * is beyond the EOF. Treat it as if the data starts just after
1509 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1510 __func__, data_offset);
1511 data_offset = server->total_read;
1512 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1513 /* data_offset is beyond the end of smallbuf */
1514 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1515 __func__, data_offset);
1516 rdata->result = -EIO;
1517 return cifs_readv_discard(server, mid);
1520 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1521 __func__, server->total_read, data_offset);
1523 len = data_offset - server->total_read;
1525 /* read any junk before data into the rest of smallbuf */
1526 rdata->iov.iov_base = buf + server->total_read;
1527 rdata->iov.iov_len = len;
1528 length = cifs_readv_from_socket(server, &rdata->iov, 1, len);
1531 server->total_read += length;
1534 /* set up first iov for signature check */
1535 rdata->iov.iov_base = buf;
1536 rdata->iov.iov_len = server->total_read;
1537 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1538 rdata->iov.iov_base, rdata->iov.iov_len);
1540 /* how much data is in the response? */
1541 data_len = server->ops->read_data_length(buf);
1542 if (data_offset + data_len > buflen) {
1543 /* data_len is corrupt -- discard frame */
1544 rdata->result = -EIO;
1545 return cifs_readv_discard(server, mid);
1548 length = rdata->read_into_pages(server, rdata, data_len);
1552 server->total_read += length;
1553 rdata->bytes = length;
1555 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1556 server->total_read, buflen, data_len);
1558 /* discard anything left over */
1559 if (server->total_read < buflen)
1560 return cifs_readv_discard(server, mid);
1562 dequeue_mid(mid, false);
1567 cifs_readv_callback(struct mid_q_entry *mid)
1569 struct cifs_readdata *rdata = mid->callback_data;
1570 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1571 struct TCP_Server_Info *server = tcon->ses->server;
1572 struct smb_rqst rqst = { .rq_iov = &rdata->iov,
1574 .rq_pages = rdata->pages,
1575 .rq_npages = rdata->nr_pages,
1576 .rq_pagesz = rdata->pagesz,
1577 .rq_tailsz = rdata->tailsz };
1579 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1580 __func__, mid->mid, mid->mid_state, rdata->result,
1583 switch (mid->mid_state) {
1584 case MID_RESPONSE_RECEIVED:
1585 /* result already set, check signature */
1589 rc = cifs_verify_signature(&rqst, server,
1590 mid->sequence_number);
1592 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1595 /* FIXME: should this be counted toward the initiating task? */
1596 task_io_account_read(rdata->bytes);
1597 cifs_stats_bytes_read(tcon, rdata->bytes);
1599 case MID_REQUEST_SUBMITTED:
1600 case MID_RETRY_NEEDED:
1601 rdata->result = -EAGAIN;
1604 rdata->result = -EIO;
1607 queue_work(cifsiod_wq, &rdata->work);
1608 DeleteMidQEntry(mid);
1609 add_credits(server, 1, 0);
1612 /* cifs_async_readv - send an async write, and set up mid to handle result */
1614 cifs_async_readv(struct cifs_readdata *rdata)
1617 READ_REQ *smb = NULL;
1619 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1620 struct smb_rqst rqst = { .rq_iov = &rdata->iov,
1623 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1624 __func__, rdata->offset, rdata->bytes);
1626 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1629 wct = 10; /* old style read */
1630 if ((rdata->offset >> 32) > 0) {
1631 /* can not handle this big offset for old */
1636 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1640 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1641 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1643 smb->AndXCommand = 0xFF; /* none */
1644 smb->Fid = rdata->cfile->fid.netfid;
1645 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1647 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1649 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1650 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1654 /* old style read */
1655 struct smb_com_readx_req *smbr =
1656 (struct smb_com_readx_req *)smb;
1657 smbr->ByteCount = 0;
1660 /* 4 for RFC1001 length + 1 for BCC */
1661 rdata->iov.iov_base = smb;
1662 rdata->iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
1664 kref_get(&rdata->refcount);
1665 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1666 cifs_readv_callback, rdata, 0);
1669 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1671 kref_put(&rdata->refcount, cifs_readdata_release);
1673 cifs_small_buf_release(smb);
1678 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1679 unsigned int *nbytes, char **buf, int *pbuf_type)
1682 READ_REQ *pSMB = NULL;
1683 READ_RSP *pSMBr = NULL;
1684 char *pReadData = NULL;
1686 int resp_buf_type = 0;
1688 __u32 pid = io_parms->pid;
1689 __u16 netfid = io_parms->netfid;
1690 __u64 offset = io_parms->offset;
1691 struct cifs_tcon *tcon = io_parms->tcon;
1692 unsigned int count = io_parms->length;
1694 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1695 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1698 wct = 10; /* old style read */
1699 if ((offset >> 32) > 0) {
1700 /* can not handle this big offset for old */
1706 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1710 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1711 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1713 /* tcon and ses pointer are checked in smb_init */
1714 if (tcon->ses->server == NULL)
1715 return -ECONNABORTED;
1717 pSMB->AndXCommand = 0xFF; /* none */
1719 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1721 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1723 pSMB->Remaining = 0;
1724 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1725 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1727 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1729 /* old style read */
1730 struct smb_com_readx_req *pSMBW =
1731 (struct smb_com_readx_req *)pSMB;
1732 pSMBW->ByteCount = 0;
1735 iov[0].iov_base = (char *)pSMB;
1736 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1737 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1738 &resp_buf_type, CIFS_LOG_ERROR);
1739 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1740 pSMBr = (READ_RSP *)iov[0].iov_base;
1742 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1744 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1745 data_length = data_length << 16;
1746 data_length += le16_to_cpu(pSMBr->DataLength);
1747 *nbytes = data_length;
1749 /*check that DataLength would not go beyond end of SMB */
1750 if ((data_length > CIFSMaxBufSize)
1751 || (data_length > count)) {
1752 cifs_dbg(FYI, "bad length %d for count %d\n",
1753 data_length, count);
1757 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1758 le16_to_cpu(pSMBr->DataOffset);
1759 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1760 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1762 }*/ /* can not use copy_to_user when using page cache*/
1764 memcpy(*buf, pReadData, data_length);
1768 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1770 if (resp_buf_type == CIFS_SMALL_BUFFER)
1771 cifs_small_buf_release(iov[0].iov_base);
1772 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1773 cifs_buf_release(iov[0].iov_base);
1774 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1775 /* return buffer to caller to free */
1776 *buf = iov[0].iov_base;
1777 if (resp_buf_type == CIFS_SMALL_BUFFER)
1778 *pbuf_type = CIFS_SMALL_BUFFER;
1779 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1780 *pbuf_type = CIFS_LARGE_BUFFER;
1781 } /* else no valid buffer on return - leave as null */
1783 /* Note: On -EAGAIN error only caller can retry on handle based calls
1784 since file handle passed in no longer valid */
1790 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1791 unsigned int *nbytes, const char *buf,
1792 const char __user *ubuf, const int long_op)
1795 WRITE_REQ *pSMB = NULL;
1796 WRITE_RSP *pSMBr = NULL;
1797 int bytes_returned, wct;
1800 __u32 pid = io_parms->pid;
1801 __u16 netfid = io_parms->netfid;
1802 __u64 offset = io_parms->offset;
1803 struct cifs_tcon *tcon = io_parms->tcon;
1804 unsigned int count = io_parms->length;
1808 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1809 if (tcon->ses == NULL)
1810 return -ECONNABORTED;
1812 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1816 if ((offset >> 32) > 0) {
1817 /* can not handle big offset for old srv */
1822 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1827 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1828 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1830 /* tcon and ses pointer are checked in smb_init */
1831 if (tcon->ses->server == NULL)
1832 return -ECONNABORTED;
1834 pSMB->AndXCommand = 0xFF; /* none */
1836 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1838 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1840 pSMB->Reserved = 0xFFFFFFFF;
1841 pSMB->WriteMode = 0;
1842 pSMB->Remaining = 0;
1844 /* Can increase buffer size if buffer is big enough in some cases ie we
1845 can send more if LARGE_WRITE_X capability returned by the server and if
1846 our buffer is big enough or if we convert to iovecs on socket writes
1847 and eliminate the copy to the CIFS buffer */
1848 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1849 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1851 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1855 if (bytes_sent > count)
1858 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1860 memcpy(pSMB->Data, buf, bytes_sent);
1862 if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
1863 cifs_buf_release(pSMB);
1866 } else if (count != 0) {
1868 cifs_buf_release(pSMB);
1870 } /* else setting file size with write of zero bytes */
1872 byte_count = bytes_sent + 1; /* pad */
1873 else /* wct == 12 */
1874 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1876 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1877 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1878 inc_rfc1001_len(pSMB, byte_count);
1881 pSMB->ByteCount = cpu_to_le16(byte_count);
1882 else { /* old style write has byte count 4 bytes earlier
1884 struct smb_com_writex_req *pSMBW =
1885 (struct smb_com_writex_req *)pSMB;
1886 pSMBW->ByteCount = cpu_to_le16(byte_count);
1889 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1890 (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
1891 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1893 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1895 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1896 *nbytes = (*nbytes) << 16;
1897 *nbytes += le16_to_cpu(pSMBr->Count);
1900 * Mask off high 16 bits when bytes written as returned by the
1901 * server is greater than bytes requested by the client. Some
1902 * OS/2 servers are known to set incorrect CountHigh values.
1904 if (*nbytes > count)
1908 cifs_buf_release(pSMB);
1910 /* Note: On -EAGAIN error only caller can retry on handle based calls
1911 since file handle passed in no longer valid */
1917 cifs_writedata_release(struct kref *refcount)
1919 struct cifs_writedata *wdata = container_of(refcount,
1920 struct cifs_writedata, refcount);
1923 cifsFileInfo_put(wdata->cfile);
1929 * Write failed with a retryable error. Resend the write request. It's also
1930 * possible that the page was redirtied so re-clean the page.
1933 cifs_writev_requeue(struct cifs_writedata *wdata)
1936 struct inode *inode = wdata->cfile->dentry->d_inode;
1937 struct TCP_Server_Info *server;
1939 for (i = 0; i < wdata->nr_pages; i++) {
1940 lock_page(wdata->pages[i]);
1941 clear_page_dirty_for_io(wdata->pages[i]);
1945 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1946 rc = server->ops->async_writev(wdata);
1947 } while (rc == -EAGAIN);
1949 for (i = 0; i < wdata->nr_pages; i++) {
1950 unlock_page(wdata->pages[i]);
1952 SetPageError(wdata->pages[i]);
1953 end_page_writeback(wdata->pages[i]);
1954 page_cache_release(wdata->pages[i]);
1958 mapping_set_error(inode->i_mapping, rc);
1959 kref_put(&wdata->refcount, cifs_writedata_release);
1963 cifs_writev_complete(struct work_struct *work)
1965 struct cifs_writedata *wdata = container_of(work,
1966 struct cifs_writedata, work);
1967 struct inode *inode = wdata->cfile->dentry->d_inode;
1970 if (wdata->result == 0) {
1971 spin_lock(&inode->i_lock);
1972 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
1973 spin_unlock(&inode->i_lock);
1974 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
1976 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
1977 return cifs_writev_requeue(wdata);
1979 for (i = 0; i < wdata->nr_pages; i++) {
1980 struct page *page = wdata->pages[i];
1981 if (wdata->result == -EAGAIN)
1982 __set_page_dirty_nobuffers(page);
1983 else if (wdata->result < 0)
1985 end_page_writeback(page);
1986 page_cache_release(page);
1988 if (wdata->result != -EAGAIN)
1989 mapping_set_error(inode->i_mapping, wdata->result);
1990 kref_put(&wdata->refcount, cifs_writedata_release);
1993 struct cifs_writedata *
1994 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
1996 struct cifs_writedata *wdata;
1998 /* this would overflow */
1999 if (nr_pages == 0) {
2000 cifs_dbg(VFS, "%s: called with nr_pages == 0!\n", __func__);
2004 /* writedata + number of page pointers */
2005 wdata = kzalloc(sizeof(*wdata) +
2006 sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
2007 if (wdata != NULL) {
2008 kref_init(&wdata->refcount);
2009 INIT_LIST_HEAD(&wdata->list);
2010 init_completion(&wdata->done);
2011 INIT_WORK(&wdata->work, complete);
2017 * Check the mid_state and signature on received buffer (if any), and queue the
2018 * workqueue completion task.
2021 cifs_writev_callback(struct mid_q_entry *mid)
2023 struct cifs_writedata *wdata = mid->callback_data;
2024 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2025 unsigned int written;
2026 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2028 switch (mid->mid_state) {
2029 case MID_RESPONSE_RECEIVED:
2030 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2031 if (wdata->result != 0)
2034 written = le16_to_cpu(smb->CountHigh);
2036 written += le16_to_cpu(smb->Count);
2038 * Mask off high 16 bits when bytes written as returned
2039 * by the server is greater than bytes requested by the
2040 * client. OS/2 servers are known to set incorrect
2043 if (written > wdata->bytes)
2046 if (written < wdata->bytes)
2047 wdata->result = -ENOSPC;
2049 wdata->bytes = written;
2051 case MID_REQUEST_SUBMITTED:
2052 case MID_RETRY_NEEDED:
2053 wdata->result = -EAGAIN;
2056 wdata->result = -EIO;
2060 queue_work(cifsiod_wq, &wdata->work);
2061 DeleteMidQEntry(mid);
2062 add_credits(tcon->ses->server, 1, 0);
2065 /* cifs_async_writev - send an async write, and set up mid to handle result */
2067 cifs_async_writev(struct cifs_writedata *wdata)
2070 WRITE_REQ *smb = NULL;
2072 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2074 struct smb_rqst rqst = { };
2076 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2080 if (wdata->offset >> 32 > 0) {
2081 /* can not handle big offset for old srv */
2086 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2088 goto async_writev_out;
2090 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2091 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2093 smb->AndXCommand = 0xFF; /* none */
2094 smb->Fid = wdata->cfile->fid.netfid;
2095 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2097 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2098 smb->Reserved = 0xFFFFFFFF;
2103 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2105 /* 4 for RFC1001 length + 1 for BCC */
2106 iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
2111 rqst.rq_pages = wdata->pages;
2112 rqst.rq_npages = wdata->nr_pages;
2113 rqst.rq_pagesz = wdata->pagesz;
2114 rqst.rq_tailsz = wdata->tailsz;
2116 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2117 wdata->offset, wdata->bytes);
2119 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2120 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2123 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2124 put_bcc(wdata->bytes + 1, &smb->hdr);
2127 struct smb_com_writex_req *smbw =
2128 (struct smb_com_writex_req *)smb;
2129 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2130 put_bcc(wdata->bytes + 5, &smbw->hdr);
2131 iov.iov_len += 4; /* pad bigger by four bytes */
2134 kref_get(&wdata->refcount);
2135 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2136 cifs_writev_callback, wdata, 0);
2139 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2141 kref_put(&wdata->refcount, cifs_writedata_release);
2144 cifs_small_buf_release(smb);
2149 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2150 unsigned int *nbytes, struct kvec *iov, int n_vec)
2153 WRITE_REQ *pSMB = NULL;
2156 int resp_buf_type = 0;
2157 __u32 pid = io_parms->pid;
2158 __u16 netfid = io_parms->netfid;
2159 __u64 offset = io_parms->offset;
2160 struct cifs_tcon *tcon = io_parms->tcon;
2161 unsigned int count = io_parms->length;
2165 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2167 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2171 if ((offset >> 32) > 0) {
2172 /* can not handle big offset for old srv */
2176 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2180 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2181 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2183 /* tcon and ses pointer are checked in smb_init */
2184 if (tcon->ses->server == NULL)
2185 return -ECONNABORTED;
2187 pSMB->AndXCommand = 0xFF; /* none */
2189 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2191 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2192 pSMB->Reserved = 0xFFFFFFFF;
2193 pSMB->WriteMode = 0;
2194 pSMB->Remaining = 0;
2197 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2199 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2200 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2201 /* header + 1 byte pad */
2202 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2204 inc_rfc1001_len(pSMB, count + 1);
2205 else /* wct == 12 */
2206 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2208 pSMB->ByteCount = cpu_to_le16(count + 1);
2209 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2210 struct smb_com_writex_req *pSMBW =
2211 (struct smb_com_writex_req *)pSMB;
2212 pSMBW->ByteCount = cpu_to_le16(count + 5);
2214 iov[0].iov_base = pSMB;
2216 iov[0].iov_len = smb_hdr_len + 4;
2217 else /* wct == 12 pad bigger by four bytes */
2218 iov[0].iov_len = smb_hdr_len + 8;
2221 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0);
2222 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2224 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2225 } else if (resp_buf_type == 0) {
2226 /* presumably this can not happen, but best to be safe */
2229 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base;
2230 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2231 *nbytes = (*nbytes) << 16;
2232 *nbytes += le16_to_cpu(pSMBr->Count);
2235 * Mask off high 16 bits when bytes written as returned by the
2236 * server is greater than bytes requested by the client. OS/2
2237 * servers are known to set incorrect CountHigh values.
2239 if (*nbytes > count)
2243 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2244 if (resp_buf_type == CIFS_SMALL_BUFFER)
2245 cifs_small_buf_release(iov[0].iov_base);
2246 else if (resp_buf_type == CIFS_LARGE_BUFFER)
2247 cifs_buf_release(iov[0].iov_base);
2249 /* Note: On -EAGAIN error only caller can retry on handle based calls
2250 since file handle passed in no longer valid */
2255 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2256 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2257 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2260 LOCK_REQ *pSMB = NULL;
2265 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2266 num_lock, num_unlock);
2268 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2273 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2274 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2275 pSMB->LockType = lock_type;
2276 pSMB->AndXCommand = 0xFF; /* none */
2277 pSMB->Fid = netfid; /* netfid stays le */
2279 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2280 inc_rfc1001_len(pSMB, count);
2281 pSMB->ByteCount = cpu_to_le16(count);
2283 iov[0].iov_base = (char *)pSMB;
2284 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2285 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2286 iov[1].iov_base = (char *)buf;
2287 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2289 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2290 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
2292 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2298 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2299 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2300 const __u64 offset, const __u32 numUnlock,
2301 const __u32 numLock, const __u8 lockType,
2302 const bool waitFlag, const __u8 oplock_level)
2305 LOCK_REQ *pSMB = NULL;
2306 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2311 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2312 (int)waitFlag, numLock);
2313 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2318 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2319 /* no response expected */
2320 flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP;
2322 } else if (waitFlag) {
2323 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2324 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2329 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2330 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2331 pSMB->LockType = lockType;
2332 pSMB->OplockLevel = oplock_level;
2333 pSMB->AndXCommand = 0xFF; /* none */
2334 pSMB->Fid = smb_file_id; /* netfid stays le */
2336 if ((numLock != 0) || (numUnlock != 0)) {
2337 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2338 /* BB where to store pid high? */
2339 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2340 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2341 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2342 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2343 count = sizeof(LOCKING_ANDX_RANGE);
2348 inc_rfc1001_len(pSMB, count);
2349 pSMB->ByteCount = cpu_to_le16(count);
2352 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2353 (struct smb_hdr *) pSMB, &bytes_returned);
2354 cifs_small_buf_release(pSMB);
2356 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2357 /* SMB buffer freed by function above */
2359 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2361 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2363 /* Note: On -EAGAIN error only caller can retry on handle based calls
2364 since file handle passed in no longer valid */
2369 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2370 const __u16 smb_file_id, const __u32 netpid,
2371 const loff_t start_offset, const __u64 len,
2372 struct file_lock *pLockData, const __u16 lock_type,
2373 const bool waitFlag)
2375 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2376 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2377 struct cifs_posix_lock *parm_data;
2380 int bytes_returned = 0;
2381 int resp_buf_type = 0;
2382 __u16 params, param_offset, offset, byte_count, count;
2385 cifs_dbg(FYI, "Posix Lock\n");
2387 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2392 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2395 pSMB->MaxSetupCount = 0;
2398 pSMB->Reserved2 = 0;
2399 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2400 offset = param_offset + params;
2402 count = sizeof(struct cifs_posix_lock);
2403 pSMB->MaxParameterCount = cpu_to_le16(2);
2404 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2405 pSMB->SetupCount = 1;
2406 pSMB->Reserved3 = 0;
2408 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2410 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2411 byte_count = 3 /* pad */ + params + count;
2412 pSMB->DataCount = cpu_to_le16(count);
2413 pSMB->ParameterCount = cpu_to_le16(params);
2414 pSMB->TotalDataCount = pSMB->DataCount;
2415 pSMB->TotalParameterCount = pSMB->ParameterCount;
2416 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2417 parm_data = (struct cifs_posix_lock *)
2418 (((char *) &pSMB->hdr.Protocol) + offset);
2420 parm_data->lock_type = cpu_to_le16(lock_type);
2422 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2423 parm_data->lock_flags = cpu_to_le16(1);
2424 pSMB->Timeout = cpu_to_le32(-1);
2428 parm_data->pid = cpu_to_le32(netpid);
2429 parm_data->start = cpu_to_le64(start_offset);
2430 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2432 pSMB->DataOffset = cpu_to_le16(offset);
2433 pSMB->Fid = smb_file_id;
2434 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2435 pSMB->Reserved4 = 0;
2436 inc_rfc1001_len(pSMB, byte_count);
2437 pSMB->ByteCount = cpu_to_le16(byte_count);
2439 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2440 (struct smb_hdr *) pSMBr, &bytes_returned);
2442 iov[0].iov_base = (char *)pSMB;
2443 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2444 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2445 &resp_buf_type, timeout);
2446 pSMB = NULL; /* request buf already freed by SendReceive2. Do
2447 not try to free it twice below on exit */
2448 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
2452 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2453 } else if (pLockData) {
2454 /* lock structure can be returned on get */
2457 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2459 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2460 rc = -EIO; /* bad smb */
2463 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2464 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2465 if (data_count < sizeof(struct cifs_posix_lock)) {
2469 parm_data = (struct cifs_posix_lock *)
2470 ((char *)&pSMBr->hdr.Protocol + data_offset);
2471 if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
2472 pLockData->fl_type = F_UNLCK;
2474 if (parm_data->lock_type ==
2475 __constant_cpu_to_le16(CIFS_RDLCK))
2476 pLockData->fl_type = F_RDLCK;
2477 else if (parm_data->lock_type ==
2478 __constant_cpu_to_le16(CIFS_WRLCK))
2479 pLockData->fl_type = F_WRLCK;
2481 pLockData->fl_start = le64_to_cpu(parm_data->start);
2482 pLockData->fl_end = pLockData->fl_start +
2483 le64_to_cpu(parm_data->length) - 1;
2484 pLockData->fl_pid = le32_to_cpu(parm_data->pid);
2490 cifs_small_buf_release(pSMB);
2492 if (resp_buf_type == CIFS_SMALL_BUFFER)
2493 cifs_small_buf_release(iov[0].iov_base);
2494 else if (resp_buf_type == CIFS_LARGE_BUFFER)
2495 cifs_buf_release(iov[0].iov_base);
2497 /* Note: On -EAGAIN error only caller can retry on handle based calls
2498 since file handle passed in no longer valid */
2505 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2508 CLOSE_REQ *pSMB = NULL;
2509 cifs_dbg(FYI, "In CIFSSMBClose\n");
2511 /* do not retry on dead session on close */
2512 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2518 pSMB->FileID = (__u16) smb_file_id;
2519 pSMB->LastWriteTime = 0xFFFFFFFF;
2520 pSMB->ByteCount = 0;
2521 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2522 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2525 /* EINTR is expected when user ctl-c to kill app */
2526 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2530 /* Since session is dead, file will be closed on server already */
2538 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2541 FLUSH_REQ *pSMB = NULL;
2542 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2544 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2548 pSMB->FileID = (__u16) smb_file_id;
2549 pSMB->ByteCount = 0;
2550 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2551 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2553 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2559 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2560 const char *from_name, const char *to_name,
2561 struct cifs_sb_info *cifs_sb)
2564 RENAME_REQ *pSMB = NULL;
2565 RENAME_RSP *pSMBr = NULL;
2567 int name_len, name_len2;
2569 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
2571 cifs_dbg(FYI, "In CIFSSMBRename\n");
2573 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2578 pSMB->BufferFormat = 0x04;
2579 pSMB->SearchAttributes =
2580 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2583 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2584 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2585 from_name, PATH_MAX,
2586 cifs_sb->local_nls, remap);
2587 name_len++; /* trailing null */
2589 pSMB->OldFileName[name_len] = 0x04; /* pad */
2590 /* protocol requires ASCII signature byte on Unicode string */
2591 pSMB->OldFileName[name_len + 1] = 0x00;
2593 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2594 to_name, PATH_MAX, cifs_sb->local_nls,
2596 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2597 name_len2 *= 2; /* convert to bytes */
2598 } else { /* BB improve the check for buffer overruns BB */
2599 name_len = strnlen(from_name, PATH_MAX);
2600 name_len++; /* trailing null */
2601 strncpy(pSMB->OldFileName, from_name, name_len);
2602 name_len2 = strnlen(to_name, PATH_MAX);
2603 name_len2++; /* trailing null */
2604 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2605 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
2606 name_len2++; /* trailing null */
2607 name_len2++; /* signature byte */
2610 count = 1 /* 1st signature byte */ + name_len + name_len2;
2611 inc_rfc1001_len(pSMB, count);
2612 pSMB->ByteCount = cpu_to_le16(count);
2614 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2615 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2616 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2618 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2620 cifs_buf_release(pSMB);
2628 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2629 int netfid, const char *target_name,
2630 const struct nls_table *nls_codepage, int remap)
2632 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2633 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2634 struct set_file_rename *rename_info;
2636 char dummy_string[30];
2638 int bytes_returned = 0;
2640 __u16 params, param_offset, offset, count, byte_count;
2642 cifs_dbg(FYI, "Rename to File by handle\n");
2643 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2649 pSMB->MaxSetupCount = 0;
2653 pSMB->Reserved2 = 0;
2654 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2655 offset = param_offset + params;
2657 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2658 rename_info = (struct set_file_rename *) data_offset;
2659 pSMB->MaxParameterCount = cpu_to_le16(2);
2660 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2661 pSMB->SetupCount = 1;
2662 pSMB->Reserved3 = 0;
2663 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2664 byte_count = 3 /* pad */ + params;
2665 pSMB->ParameterCount = cpu_to_le16(params);
2666 pSMB->TotalParameterCount = pSMB->ParameterCount;
2667 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2668 pSMB->DataOffset = cpu_to_le16(offset);
2669 /* construct random name ".cifs_tmp<inodenum><mid>" */
2670 rename_info->overwrite = cpu_to_le32(1);
2671 rename_info->root_fid = 0;
2672 /* unicode only call */
2673 if (target_name == NULL) {
2674 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2676 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2677 dummy_string, 24, nls_codepage, remap);
2680 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2681 target_name, PATH_MAX, nls_codepage,
2684 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2685 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2686 byte_count += count;
2687 pSMB->DataCount = cpu_to_le16(count);
2688 pSMB->TotalDataCount = pSMB->DataCount;
2690 pSMB->InformationLevel =
2691 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2692 pSMB->Reserved4 = 0;
2693 inc_rfc1001_len(pSMB, byte_count);
2694 pSMB->ByteCount = cpu_to_le16(byte_count);
2695 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2696 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2697 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2699 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2702 cifs_buf_release(pSMB);
2704 /* Note: On -EAGAIN error only caller can retry on handle based calls
2705 since file handle passed in no longer valid */
2711 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2712 const char *fromName, const __u16 target_tid, const char *toName,
2713 const int flags, const struct nls_table *nls_codepage, int remap)
2716 COPY_REQ *pSMB = NULL;
2717 COPY_RSP *pSMBr = NULL;
2719 int name_len, name_len2;
2722 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2724 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2729 pSMB->BufferFormat = 0x04;
2730 pSMB->Tid2 = target_tid;
2732 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2734 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2735 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2736 fromName, PATH_MAX, nls_codepage,
2738 name_len++; /* trailing null */
2740 pSMB->OldFileName[name_len] = 0x04; /* pad */
2741 /* protocol requires ASCII signature byte on Unicode string */
2742 pSMB->OldFileName[name_len + 1] = 0x00;
2744 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2745 toName, PATH_MAX, nls_codepage, remap);
2746 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2747 name_len2 *= 2; /* convert to bytes */
2748 } else { /* BB improve the check for buffer overruns BB */
2749 name_len = strnlen(fromName, PATH_MAX);
2750 name_len++; /* trailing null */
2751 strncpy(pSMB->OldFileName, fromName, name_len);
2752 name_len2 = strnlen(toName, PATH_MAX);
2753 name_len2++; /* trailing null */
2754 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2755 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2756 name_len2++; /* trailing null */
2757 name_len2++; /* signature byte */
2760 count = 1 /* 1st signature byte */ + name_len + name_len2;
2761 inc_rfc1001_len(pSMB, count);
2762 pSMB->ByteCount = cpu_to_le16(count);
2764 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2765 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2767 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2768 rc, le16_to_cpu(pSMBr->CopyCount));
2770 cifs_buf_release(pSMB);
2779 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2780 const char *fromName, const char *toName,
2781 const struct nls_table *nls_codepage)
2783 TRANSACTION2_SPI_REQ *pSMB = NULL;
2784 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2787 int name_len_target;
2789 int bytes_returned = 0;
2790 __u16 params, param_offset, offset, byte_count;
2792 cifs_dbg(FYI, "In Symlink Unix style\n");
2794 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2799 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2801 cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName,
2802 /* find define for this maxpathcomponent */
2803 PATH_MAX, nls_codepage);
2804 name_len++; /* trailing null */
2807 } else { /* BB improve the check for buffer overruns BB */
2808 name_len = strnlen(fromName, PATH_MAX);
2809 name_len++; /* trailing null */
2810 strncpy(pSMB->FileName, fromName, name_len);
2812 params = 6 + name_len;
2813 pSMB->MaxSetupCount = 0;
2817 pSMB->Reserved2 = 0;
2818 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2819 InformationLevel) - 4;
2820 offset = param_offset + params;
2822 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2823 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2825 cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX
2826 /* find define for this maxpathcomponent */
2828 name_len_target++; /* trailing null */
2829 name_len_target *= 2;
2830 } else { /* BB improve the check for buffer overruns BB */
2831 name_len_target = strnlen(toName, PATH_MAX);
2832 name_len_target++; /* trailing null */
2833 strncpy(data_offset, toName, name_len_target);
2836 pSMB->MaxParameterCount = cpu_to_le16(2);
2837 /* BB find exact max on data count below from sess */
2838 pSMB->MaxDataCount = cpu_to_le16(1000);
2839 pSMB->SetupCount = 1;
2840 pSMB->Reserved3 = 0;
2841 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2842 byte_count = 3 /* pad */ + params + name_len_target;
2843 pSMB->DataCount = cpu_to_le16(name_len_target);
2844 pSMB->ParameterCount = cpu_to_le16(params);
2845 pSMB->TotalDataCount = pSMB->DataCount;
2846 pSMB->TotalParameterCount = pSMB->ParameterCount;
2847 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2848 pSMB->DataOffset = cpu_to_le16(offset);
2849 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2850 pSMB->Reserved4 = 0;
2851 inc_rfc1001_len(pSMB, byte_count);
2852 pSMB->ByteCount = cpu_to_le16(byte_count);
2853 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2854 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2855 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2857 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2860 cifs_buf_release(pSMB);
2863 goto createSymLinkRetry;
2869 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2870 const char *fromName, const char *toName,
2871 const struct nls_table *nls_codepage, int remap)
2873 TRANSACTION2_SPI_REQ *pSMB = NULL;
2874 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2877 int name_len_target;
2879 int bytes_returned = 0;
2880 __u16 params, param_offset, offset, byte_count;
2882 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2883 createHardLinkRetry:
2884 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2889 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2890 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2891 PATH_MAX, nls_codepage, remap);
2892 name_len++; /* trailing null */
2895 } else { /* BB improve the check for buffer overruns BB */
2896 name_len = strnlen(toName, PATH_MAX);
2897 name_len++; /* trailing null */
2898 strncpy(pSMB->FileName, toName, name_len);
2900 params = 6 + name_len;
2901 pSMB->MaxSetupCount = 0;
2905 pSMB->Reserved2 = 0;
2906 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2907 InformationLevel) - 4;
2908 offset = param_offset + params;
2910 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2911 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2913 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2914 PATH_MAX, nls_codepage, remap);
2915 name_len_target++; /* trailing null */
2916 name_len_target *= 2;
2917 } else { /* BB improve the check for buffer overruns BB */
2918 name_len_target = strnlen(fromName, PATH_MAX);
2919 name_len_target++; /* trailing null */
2920 strncpy(data_offset, fromName, name_len_target);
2923 pSMB->MaxParameterCount = cpu_to_le16(2);
2924 /* BB find exact max on data count below from sess*/
2925 pSMB->MaxDataCount = cpu_to_le16(1000);
2926 pSMB->SetupCount = 1;
2927 pSMB->Reserved3 = 0;
2928 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2929 byte_count = 3 /* pad */ + params + name_len_target;
2930 pSMB->ParameterCount = cpu_to_le16(params);
2931 pSMB->TotalParameterCount = pSMB->ParameterCount;
2932 pSMB->DataCount = cpu_to_le16(name_len_target);
2933 pSMB->TotalDataCount = pSMB->DataCount;
2934 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2935 pSMB->DataOffset = cpu_to_le16(offset);
2936 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2937 pSMB->Reserved4 = 0;
2938 inc_rfc1001_len(pSMB, byte_count);
2939 pSMB->ByteCount = cpu_to_le16(byte_count);
2940 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2941 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2942 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2944 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2947 cifs_buf_release(pSMB);
2949 goto createHardLinkRetry;
2955 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2956 const char *from_name, const char *to_name,
2957 struct cifs_sb_info *cifs_sb)
2960 NT_RENAME_REQ *pSMB = NULL;
2961 RENAME_RSP *pSMBr = NULL;
2963 int name_len, name_len2;
2965 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
2967 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2968 winCreateHardLinkRetry:
2970 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2975 pSMB->SearchAttributes =
2976 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2978 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2979 pSMB->ClusterCount = 0;
2981 pSMB->BufferFormat = 0x04;
2983 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2985 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2986 PATH_MAX, cifs_sb->local_nls, remap);
2987 name_len++; /* trailing null */
2990 /* protocol specifies ASCII buffer format (0x04) for unicode */
2991 pSMB->OldFileName[name_len] = 0x04;
2992 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2994 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2995 to_name, PATH_MAX, cifs_sb->local_nls,
2997 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2998 name_len2 *= 2; /* convert to bytes */
2999 } else { /* BB improve the check for buffer overruns BB */
3000 name_len = strnlen(from_name, PATH_MAX);
3001 name_len++; /* trailing null */
3002 strncpy(pSMB->OldFileName, from_name, name_len);
3003 name_len2 = strnlen(to_name, PATH_MAX);
3004 name_len2++; /* trailing null */
3005 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3006 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
3007 name_len2++; /* trailing null */
3008 name_len2++; /* signature byte */
3011 count = 1 /* string type byte */ + name_len + name_len2;
3012 inc_rfc1001_len(pSMB, count);
3013 pSMB->ByteCount = cpu_to_le16(count);
3015 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3016 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3017 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3019 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3021 cifs_buf_release(pSMB);
3023 goto winCreateHardLinkRetry;
3029 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3030 const unsigned char *searchName, char **symlinkinfo,
3031 const struct nls_table *nls_codepage)
3033 /* SMB_QUERY_FILE_UNIX_LINK */
3034 TRANSACTION2_QPI_REQ *pSMB = NULL;
3035 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3039 __u16 params, byte_count;
3042 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3045 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3050 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3052 cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName,
3053 PATH_MAX, nls_codepage);
3054 name_len++; /* trailing null */
3056 } else { /* BB improve the check for buffer overruns BB */
3057 name_len = strnlen(searchName, PATH_MAX);
3058 name_len++; /* trailing null */
3059 strncpy(pSMB->FileName, searchName, name_len);
3062 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3063 pSMB->TotalDataCount = 0;
3064 pSMB->MaxParameterCount = cpu_to_le16(2);
3065 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3066 pSMB->MaxSetupCount = 0;
3070 pSMB->Reserved2 = 0;
3071 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3072 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3073 pSMB->DataCount = 0;
3074 pSMB->DataOffset = 0;
3075 pSMB->SetupCount = 1;
3076 pSMB->Reserved3 = 0;
3077 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3078 byte_count = params + 1 /* pad */ ;
3079 pSMB->TotalParameterCount = cpu_to_le16(params);
3080 pSMB->ParameterCount = pSMB->TotalParameterCount;
3081 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3082 pSMB->Reserved4 = 0;
3083 inc_rfc1001_len(pSMB, byte_count);
3084 pSMB->ByteCount = cpu_to_le16(byte_count);
3086 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3087 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3089 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3091 /* decode response */
3093 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3094 /* BB also check enough total bytes returned */
3095 if (rc || get_bcc(&pSMBr->hdr) < 2)
3099 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3101 data_start = ((char *) &pSMBr->hdr.Protocol) +
3102 le16_to_cpu(pSMBr->t2.DataOffset);
3104 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3109 /* BB FIXME investigate remapping reserved chars here */
3110 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3111 count, is_unicode, nls_codepage);
3116 cifs_buf_release(pSMB);
3118 goto querySymLinkRetry;
3122 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3124 * Recent Windows versions now create symlinks more frequently
3125 * and they use the "reparse point" mechanism below. We can of course
3126 * do symlinks nicely to Samba and other servers which support the
3127 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3128 * "MF" symlinks optionally, but for recent Windows we really need to
3129 * reenable the code below and fix the cifs_symlink callers to handle this.
3130 * In the interim this code has been moved to its own config option so
3131 * it is not compiled in by default until callers fixed up and more tested.
3134 CIFSSMBQueryReparseLinkInfo(const unsigned int xid, struct cifs_tcon *tcon,
3135 const unsigned char *searchName,
3136 char *symlinkinfo, const int buflen, __u16 fid,
3137 const struct nls_table *nls_codepage)
3141 struct smb_com_transaction_ioctl_req *pSMB;
3142 struct smb_com_transaction_ioctl_rsp *pSMBr;
3144 cifs_dbg(FYI, "In Windows reparse style QueryLink for path %s\n",
3146 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3151 pSMB->TotalParameterCount = 0 ;
3152 pSMB->TotalDataCount = 0;
3153 pSMB->MaxParameterCount = cpu_to_le32(2);
3154 /* BB find exact data count max from sess structure BB */
3155 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3156 pSMB->MaxSetupCount = 4;
3158 pSMB->ParameterOffset = 0;
3159 pSMB->DataCount = 0;
3160 pSMB->DataOffset = 0;
3161 pSMB->SetupCount = 4;
3162 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3163 pSMB->ParameterCount = pSMB->TotalParameterCount;
3164 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3165 pSMB->IsFsctl = 1; /* FSCTL */
3166 pSMB->IsRootFlag = 0;
3167 pSMB->Fid = fid; /* file handle always le */
3168 pSMB->ByteCount = 0;
3170 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3171 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3173 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3174 } else { /* decode response */
3175 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
3176 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
3177 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3178 /* BB also check enough total bytes returned */
3179 rc = -EIO; /* bad smb */
3182 if (data_count && (data_count < 2048)) {
3183 char *end_of_smb = 2 /* sizeof byte count */ +
3184 get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3186 struct reparse_data *reparse_buf =
3187 (struct reparse_data *)
3188 ((char *)&pSMBr->hdr.Protocol
3190 if ((char *)reparse_buf >= end_of_smb) {
3194 if ((reparse_buf->LinkNamesBuf +
3195 reparse_buf->TargetNameOffset +
3196 reparse_buf->TargetNameLen) > end_of_smb) {
3197 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3202 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3203 cifs_from_ucs2(symlinkinfo, (__le16 *)
3204 (reparse_buf->LinkNamesBuf +
3205 reparse_buf->TargetNameOffset),
3207 reparse_buf->TargetNameLen,
3209 } else { /* ASCII names */
3210 strncpy(symlinkinfo,
3211 reparse_buf->LinkNamesBuf +
3212 reparse_buf->TargetNameOffset,
3213 min_t(const int, buflen,
3214 reparse_buf->TargetNameLen));
3218 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3220 symlinkinfo[buflen] = 0; /* just in case so the caller
3221 does not go off the end of the buffer */
3222 cifs_dbg(FYI, "readlink result - %s\n", symlinkinfo);
3226 cifs_buf_release(pSMB);
3228 /* Note: On -EAGAIN error only caller can retry on handle based calls
3229 since file handle passed in no longer valid */
3233 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3235 #ifdef CONFIG_CIFS_POSIX
3237 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3238 static void cifs_convert_ace(posix_acl_xattr_entry *ace,
3239 struct cifs_posix_ace *cifs_ace)
3241 /* u8 cifs fields do not need le conversion */
3242 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3243 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3244 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3246 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3247 ace->e_perm, ace->e_tag, ace->e_id);
3253 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3254 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3255 const int acl_type, const int size_of_data_area)
3260 struct cifs_posix_ace *pACE;
3261 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3262 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
3264 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3267 if (acl_type & ACL_TYPE_ACCESS) {
3268 count = le16_to_cpu(cifs_acl->access_entry_count);
3269 pACE = &cifs_acl->ace_array[0];
3270 size = sizeof(struct cifs_posix_acl);
3271 size += sizeof(struct cifs_posix_ace) * count;
3272 /* check if we would go beyond end of SMB */
3273 if (size_of_data_area < size) {
3274 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3275 size_of_data_area, size);
3278 } else if (acl_type & ACL_TYPE_DEFAULT) {
3279 count = le16_to_cpu(cifs_acl->access_entry_count);
3280 size = sizeof(struct cifs_posix_acl);
3281 size += sizeof(struct cifs_posix_ace) * count;
3282 /* skip past access ACEs to get to default ACEs */
3283 pACE = &cifs_acl->ace_array[count];
3284 count = le16_to_cpu(cifs_acl->default_entry_count);
3285 size += sizeof(struct cifs_posix_ace) * count;
3286 /* check if we would go beyond end of SMB */
3287 if (size_of_data_area < size)
3294 size = posix_acl_xattr_size(count);
3295 if ((buflen == 0) || (local_acl == NULL)) {
3296 /* used to query ACL EA size */
3297 } else if (size > buflen) {
3299 } else /* buffer big enough */ {
3300 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3301 for (i = 0; i < count ; i++) {
3302 cifs_convert_ace(&local_acl->a_entries[i], pACE);
3309 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3310 const posix_acl_xattr_entry *local_ace)
3312 __u16 rc = 0; /* 0 = ACL converted ok */
3314 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3315 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3316 /* BB is there a better way to handle the large uid? */
3317 if (local_ace->e_id == cpu_to_le32(-1)) {
3318 /* Probably no need to le convert -1 on any arch but can not hurt */
3319 cifs_ace->cifs_uid = cpu_to_le64(-1);
3321 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3323 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3324 ace->e_perm, ace->e_tag, ace->e_id);
3329 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3330 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3331 const int buflen, const int acl_type)
3334 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3335 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
3339 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3342 count = posix_acl_xattr_count((size_t)buflen);
3343 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3344 count, buflen, le32_to_cpu(local_acl->a_version));
3345 if (le32_to_cpu(local_acl->a_version) != 2) {
3346 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3347 le32_to_cpu(local_acl->a_version));
3350 cifs_acl->version = cpu_to_le16(1);
3351 if (acl_type == ACL_TYPE_ACCESS)
3352 cifs_acl->access_entry_count = cpu_to_le16(count);
3353 else if (acl_type == ACL_TYPE_DEFAULT)
3354 cifs_acl->default_entry_count = cpu_to_le16(count);
3356 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3359 for (i = 0; i < count; i++) {
3360 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3361 &local_acl->a_entries[i]);
3363 /* ACE not converted */
3368 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3369 rc += sizeof(struct cifs_posix_acl);
3370 /* BB add check to make sure ACL does not overflow SMB */
3376 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3377 const unsigned char *searchName,
3378 char *acl_inf, const int buflen, const int acl_type,
3379 const struct nls_table *nls_codepage, int remap)
3381 /* SMB_QUERY_POSIX_ACL */
3382 TRANSACTION2_QPI_REQ *pSMB = NULL;
3383 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3387 __u16 params, byte_count;
3389 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3392 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3397 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3399 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3400 searchName, PATH_MAX, nls_codepage,
3402 name_len++; /* trailing null */
3404 pSMB->FileName[name_len] = 0;
3405 pSMB->FileName[name_len+1] = 0;
3406 } else { /* BB improve the check for buffer overruns BB */
3407 name_len = strnlen(searchName, PATH_MAX);
3408 name_len++; /* trailing null */
3409 strncpy(pSMB->FileName, searchName, name_len);
3412 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3413 pSMB->TotalDataCount = 0;
3414 pSMB->MaxParameterCount = cpu_to_le16(2);
3415 /* BB find exact max data count below from sess structure BB */
3416 pSMB->MaxDataCount = cpu_to_le16(4000);
3417 pSMB->MaxSetupCount = 0;
3421 pSMB->Reserved2 = 0;
3422 pSMB->ParameterOffset = cpu_to_le16(
3423 offsetof(struct smb_com_transaction2_qpi_req,
3424 InformationLevel) - 4);
3425 pSMB->DataCount = 0;
3426 pSMB->DataOffset = 0;
3427 pSMB->SetupCount = 1;
3428 pSMB->Reserved3 = 0;
3429 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3430 byte_count = params + 1 /* pad */ ;
3431 pSMB->TotalParameterCount = cpu_to_le16(params);
3432 pSMB->ParameterCount = pSMB->TotalParameterCount;
3433 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3434 pSMB->Reserved4 = 0;
3435 inc_rfc1001_len(pSMB, byte_count);
3436 pSMB->ByteCount = cpu_to_le16(byte_count);
3438 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3439 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3440 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3442 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3444 /* decode response */
3446 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3447 /* BB also check enough total bytes returned */
3448 if (rc || get_bcc(&pSMBr->hdr) < 2)
3449 rc = -EIO; /* bad smb */
3451 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3452 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3453 rc = cifs_copy_posix_acl(acl_inf,
3454 (char *)&pSMBr->hdr.Protocol+data_offset,
3455 buflen, acl_type, count);
3458 cifs_buf_release(pSMB);
3465 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3466 const unsigned char *fileName,
3467 const char *local_acl, const int buflen,
3469 const struct nls_table *nls_codepage, int remap)
3471 struct smb_com_transaction2_spi_req *pSMB = NULL;
3472 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3476 int bytes_returned = 0;
3477 __u16 params, byte_count, data_count, param_offset, offset;
3479 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3481 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3485 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3487 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3488 PATH_MAX, nls_codepage, remap);
3489 name_len++; /* trailing null */
3491 } else { /* BB improve the check for buffer overruns BB */
3492 name_len = strnlen(fileName, PATH_MAX);
3493 name_len++; /* trailing null */
3494 strncpy(pSMB->FileName, fileName, name_len);
3496 params = 6 + name_len;
3497 pSMB->MaxParameterCount = cpu_to_le16(2);
3498 /* BB find max SMB size from sess */
3499 pSMB->MaxDataCount = cpu_to_le16(1000);
3500 pSMB->MaxSetupCount = 0;
3504 pSMB->Reserved2 = 0;
3505 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3506 InformationLevel) - 4;
3507 offset = param_offset + params;
3508 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3509 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3511 /* convert to on the wire format for POSIX ACL */
3512 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3514 if (data_count == 0) {
3516 goto setACLerrorExit;
3518 pSMB->DataOffset = cpu_to_le16(offset);
3519 pSMB->SetupCount = 1;
3520 pSMB->Reserved3 = 0;
3521 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3522 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3523 byte_count = 3 /* pad */ + params + data_count;
3524 pSMB->DataCount = cpu_to_le16(data_count);
3525 pSMB->TotalDataCount = pSMB->DataCount;
3526 pSMB->ParameterCount = cpu_to_le16(params);
3527 pSMB->TotalParameterCount = pSMB->ParameterCount;
3528 pSMB->Reserved4 = 0;
3529 inc_rfc1001_len(pSMB, byte_count);
3530 pSMB->ByteCount = cpu_to_le16(byte_count);
3531 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3532 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3534 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3537 cifs_buf_release(pSMB);
3543 /* BB fix tabs in this function FIXME BB */
3545 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3546 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3549 struct smb_t2_qfi_req *pSMB = NULL;
3550 struct smb_t2_qfi_rsp *pSMBr = NULL;
3552 __u16 params, byte_count;
3554 cifs_dbg(FYI, "In GetExtAttr\n");
3559 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3564 params = 2 /* level */ + 2 /* fid */;
3565 pSMB->t2.TotalDataCount = 0;
3566 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3567 /* BB find exact max data count below from sess structure BB */
3568 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3569 pSMB->t2.MaxSetupCount = 0;
3570 pSMB->t2.Reserved = 0;
3572 pSMB->t2.Timeout = 0;
3573 pSMB->t2.Reserved2 = 0;
3574 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3576 pSMB->t2.DataCount = 0;
3577 pSMB->t2.DataOffset = 0;
3578 pSMB->t2.SetupCount = 1;
3579 pSMB->t2.Reserved3 = 0;
3580 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3581 byte_count = params + 1 /* pad */ ;
3582 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3583 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3584 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3587 inc_rfc1001_len(pSMB, byte_count);
3588 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3590 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3591 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3593 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3595 /* decode response */
3596 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3597 /* BB also check enough total bytes returned */
3598 if (rc || get_bcc(&pSMBr->hdr) < 2)
3599 /* If rc should we check for EOPNOSUPP and
3600 disable the srvino flag? or in caller? */
3601 rc = -EIO; /* bad smb */
3603 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3604 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3605 struct file_chattr_info *pfinfo;
3606 /* BB Do we need a cast or hash here ? */
3608 cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n");
3612 pfinfo = (struct file_chattr_info *)
3613 (data_offset + (char *) &pSMBr->hdr.Protocol);
3614 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3615 *pMask = le64_to_cpu(pfinfo->mask);
3619 cifs_buf_release(pSMB);
3621 goto GetExtAttrRetry;
3625 #endif /* CONFIG_POSIX */
3627 #ifdef CONFIG_CIFS_ACL
3629 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3630 * all NT TRANSACTS that we init here have total parm and data under about 400
3631 * bytes (to fit in small cifs buffer size), which is the case so far, it
3632 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3633 * returned setup area) and MaxParameterCount (returned parms size) must be set
3637 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3638 const int parm_len, struct cifs_tcon *tcon,
3643 struct smb_com_ntransact_req *pSMB;
3645 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3649 *ret_buf = (void *)pSMB;
3651 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3652 pSMB->TotalDataCount = 0;
3653 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3654 pSMB->ParameterCount = pSMB->TotalParameterCount;
3655 pSMB->DataCount = pSMB->TotalDataCount;
3656 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3657 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3658 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3659 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3660 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3661 pSMB->SubCommand = cpu_to_le16(sub_command);
3666 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3667 __u32 *pparmlen, __u32 *pdatalen)
3670 __u32 data_count, data_offset, parm_count, parm_offset;
3671 struct smb_com_ntransact_rsp *pSMBr;
3680 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3682 bcc = get_bcc(&pSMBr->hdr);
3683 end_of_smb = 2 /* sizeof byte count */ + bcc +
3684 (char *)&pSMBr->ByteCount;
3686 data_offset = le32_to_cpu(pSMBr->DataOffset);
3687 data_count = le32_to_cpu(pSMBr->DataCount);
3688 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3689 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3691 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3692 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3694 /* should we also check that parm and data areas do not overlap? */
3695 if (*ppparm > end_of_smb) {
3696 cifs_dbg(FYI, "parms start after end of smb\n");
3698 } else if (parm_count + *ppparm > end_of_smb) {
3699 cifs_dbg(FYI, "parm end after end of smb\n");
3701 } else if (*ppdata > end_of_smb) {
3702 cifs_dbg(FYI, "data starts after end of smb\n");
3704 } else if (data_count + *ppdata > end_of_smb) {
3705 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3706 *ppdata, data_count, (data_count + *ppdata),
3709 } else if (parm_count + data_count > bcc) {
3710 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3713 *pdatalen = data_count;
3714 *pparmlen = parm_count;
3718 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3720 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3721 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3725 QUERY_SEC_DESC_REQ *pSMB;
3728 cifs_dbg(FYI, "GetCifsACL\n");
3733 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3734 8 /* parm len */, tcon, (void **) &pSMB);
3738 pSMB->MaxParameterCount = cpu_to_le32(4);
3739 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3740 pSMB->MaxSetupCount = 0;
3741 pSMB->Fid = fid; /* file handle always le */
3742 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3744 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3745 inc_rfc1001_len(pSMB, 11);
3746 iov[0].iov_base = (char *)pSMB;
3747 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3749 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3751 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3753 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3754 } else { /* decode response */
3758 struct smb_com_ntransact_rsp *pSMBr;
3761 /* validate_nttransact */
3762 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3763 &pdata, &parm_len, pbuflen);
3766 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3768 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3769 pSMBr, parm, *acl_inf);
3771 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3772 rc = -EIO; /* bad smb */
3777 /* BB check that data area is minimum length and as big as acl_len */
3779 acl_len = le32_to_cpu(*parm);
3780 if (acl_len != *pbuflen) {
3781 cifs_dbg(VFS, "acl length %d does not match %d\n",
3783 if (*pbuflen > acl_len)
3787 /* check if buffer is big enough for the acl
3788 header followed by the smallest SID */
3789 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3790 (*pbuflen >= 64 * 1024)) {
3791 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3795 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3796 if (*acl_inf == NULL) {
3803 if (buf_type == CIFS_SMALL_BUFFER)
3804 cifs_small_buf_release(iov[0].iov_base);
3805 else if (buf_type == CIFS_LARGE_BUFFER)
3806 cifs_buf_release(iov[0].iov_base);
3807 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3812 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3813 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3815 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3817 int bytes_returned = 0;
3818 SET_SEC_DESC_REQ *pSMB = NULL;
3822 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3826 pSMB->MaxSetupCount = 0;
3830 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3831 data_count = acllen;
3832 data_offset = param_offset + param_count;
3833 byte_count = 3 /* pad */ + param_count;
3835 pSMB->DataCount = cpu_to_le32(data_count);
3836 pSMB->TotalDataCount = pSMB->DataCount;
3837 pSMB->MaxParameterCount = cpu_to_le32(4);
3838 pSMB->MaxDataCount = cpu_to_le32(16384);
3839 pSMB->ParameterCount = cpu_to_le32(param_count);
3840 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3841 pSMB->TotalParameterCount = pSMB->ParameterCount;
3842 pSMB->DataOffset = cpu_to_le32(data_offset);
3843 pSMB->SetupCount = 0;
3844 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3845 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3847 pSMB->Fid = fid; /* file handle always le */
3848 pSMB->Reserved2 = 0;
3849 pSMB->AclFlags = cpu_to_le32(aclflag);
3851 if (pntsd && acllen) {
3852 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3853 data_offset, pntsd, acllen);
3854 inc_rfc1001_len(pSMB, byte_count + data_count);
3856 inc_rfc1001_len(pSMB, byte_count);
3858 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3859 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3861 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3862 bytes_returned, rc);
3864 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3865 cifs_buf_release(pSMB);
3868 goto setCifsAclRetry;
3873 #endif /* CONFIG_CIFS_ACL */
3875 /* Legacy Query Path Information call for lookup to old servers such
3878 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3879 const char *search_name, FILE_ALL_INFO *data,
3880 const struct nls_table *nls_codepage, int remap)
3882 QUERY_INFORMATION_REQ *pSMB;
3883 QUERY_INFORMATION_RSP *pSMBr;
3888 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3890 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3895 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3897 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3898 search_name, PATH_MAX, nls_codepage,
3900 name_len++; /* trailing null */
3903 name_len = strnlen(search_name, PATH_MAX);
3904 name_len++; /* trailing null */
3905 strncpy(pSMB->FileName, search_name, name_len);
3907 pSMB->BufferFormat = 0x04;
3908 name_len++; /* account for buffer type byte */
3909 inc_rfc1001_len(pSMB, (__u16)name_len);
3910 pSMB->ByteCount = cpu_to_le16(name_len);
3912 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3913 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3915 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3918 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3920 /* decode response */
3921 /* BB FIXME - add time zone adjustment BB */
3922 memset(data, 0, sizeof(FILE_ALL_INFO));
3925 /* decode time fields */
3926 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3927 data->LastWriteTime = data->ChangeTime;
3928 data->LastAccessTime = 0;
3929 data->AllocationSize =
3930 cpu_to_le64(le32_to_cpu(pSMBr->size));
3931 data->EndOfFile = data->AllocationSize;
3933 cpu_to_le32(le16_to_cpu(pSMBr->attr));
3935 rc = -EIO; /* bad buffer passed in */
3937 cifs_buf_release(pSMB);
3946 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3947 u16 netfid, FILE_ALL_INFO *pFindData)
3949 struct smb_t2_qfi_req *pSMB = NULL;
3950 struct smb_t2_qfi_rsp *pSMBr = NULL;
3953 __u16 params, byte_count;
3956 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3961 params = 2 /* level */ + 2 /* fid */;
3962 pSMB->t2.TotalDataCount = 0;
3963 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3964 /* BB find exact max data count below from sess structure BB */
3965 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3966 pSMB->t2.MaxSetupCount = 0;
3967 pSMB->t2.Reserved = 0;
3969 pSMB->t2.Timeout = 0;
3970 pSMB->t2.Reserved2 = 0;
3971 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3973 pSMB->t2.DataCount = 0;
3974 pSMB->t2.DataOffset = 0;
3975 pSMB->t2.SetupCount = 1;
3976 pSMB->t2.Reserved3 = 0;
3977 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3978 byte_count = params + 1 /* pad */ ;
3979 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3980 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3981 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3984 inc_rfc1001_len(pSMB, byte_count);
3986 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3987 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3989 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3990 } else { /* decode response */
3991 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3993 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3995 else if (get_bcc(&pSMBr->hdr) < 40)
3996 rc = -EIO; /* bad smb */
3997 else if (pFindData) {
3998 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3999 memcpy((char *) pFindData,
4000 (char *) &pSMBr->hdr.Protocol +
4001 data_offset, sizeof(FILE_ALL_INFO));
4005 cifs_buf_release(pSMB);
4007 goto QFileInfoRetry;
4013 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4014 const char *search_name, FILE_ALL_INFO *data,
4015 int legacy /* old style infolevel */,
4016 const struct nls_table *nls_codepage, int remap)
4018 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4019 TRANSACTION2_QPI_REQ *pSMB = NULL;
4020 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4024 __u16 params, byte_count;
4026 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4028 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4033 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4035 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4036 PATH_MAX, nls_codepage, remap);
4037 name_len++; /* trailing null */
4039 } else { /* BB improve the check for buffer overruns BB */
4040 name_len = strnlen(search_name, PATH_MAX);
4041 name_len++; /* trailing null */
4042 strncpy(pSMB->FileName, search_name, name_len);
4045 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4046 pSMB->TotalDataCount = 0;
4047 pSMB->MaxParameterCount = cpu_to_le16(2);
4048 /* BB find exact max SMB PDU from sess structure BB */
4049 pSMB->MaxDataCount = cpu_to_le16(4000);
4050 pSMB->MaxSetupCount = 0;
4054 pSMB->Reserved2 = 0;
4055 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4056 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4057 pSMB->DataCount = 0;
4058 pSMB->DataOffset = 0;
4059 pSMB->SetupCount = 1;
4060 pSMB->Reserved3 = 0;
4061 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4062 byte_count = params + 1 /* pad */ ;
4063 pSMB->TotalParameterCount = cpu_to_le16(params);
4064 pSMB->ParameterCount = pSMB->TotalParameterCount;
4066 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4068 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4069 pSMB->Reserved4 = 0;
4070 inc_rfc1001_len(pSMB, byte_count);
4071 pSMB->ByteCount = cpu_to_le16(byte_count);
4073 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4074 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4076 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4077 } else { /* decode response */
4078 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4080 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4082 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4083 rc = -EIO; /* bad smb */
4084 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4085 rc = -EIO; /* 24 or 26 expected but we do not read
4089 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4092 * On legacy responses we do not read the last field,
4093 * EAsize, fortunately since it varies by subdialect and
4094 * also note it differs on Set vs Get, ie two bytes or 4
4095 * bytes depending but we don't care here.
4098 size = sizeof(FILE_INFO_STANDARD);
4100 size = sizeof(FILE_ALL_INFO);
4101 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4106 cifs_buf_release(pSMB);
4108 goto QPathInfoRetry;
4114 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4115 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4117 struct smb_t2_qfi_req *pSMB = NULL;
4118 struct smb_t2_qfi_rsp *pSMBr = NULL;
4121 __u16 params, byte_count;
4124 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4129 params = 2 /* level */ + 2 /* fid */;
4130 pSMB->t2.TotalDataCount = 0;
4131 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4132 /* BB find exact max data count below from sess structure BB */
4133 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4134 pSMB->t2.MaxSetupCount = 0;
4135 pSMB->t2.Reserved = 0;
4137 pSMB->t2.Timeout = 0;
4138 pSMB->t2.Reserved2 = 0;
4139 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4141 pSMB->t2.DataCount = 0;
4142 pSMB->t2.DataOffset = 0;
4143 pSMB->t2.SetupCount = 1;
4144 pSMB->t2.Reserved3 = 0;
4145 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4146 byte_count = params + 1 /* pad */ ;
4147 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4148 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4149 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4152 inc_rfc1001_len(pSMB, byte_count);
4154 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4155 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4157 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4158 } else { /* decode response */
4159 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4161 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4162 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4163 rc = -EIO; /* bad smb */
4165 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4166 memcpy((char *) pFindData,
4167 (char *) &pSMBr->hdr.Protocol +
4169 sizeof(FILE_UNIX_BASIC_INFO));
4173 cifs_buf_release(pSMB);
4175 goto UnixQFileInfoRetry;
4181 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4182 const unsigned char *searchName,
4183 FILE_UNIX_BASIC_INFO *pFindData,
4184 const struct nls_table *nls_codepage, int remap)
4186 /* SMB_QUERY_FILE_UNIX_BASIC */
4187 TRANSACTION2_QPI_REQ *pSMB = NULL;
4188 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4190 int bytes_returned = 0;
4192 __u16 params, byte_count;
4194 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4196 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4201 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4203 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4204 PATH_MAX, nls_codepage, remap);
4205 name_len++; /* trailing null */
4207 } else { /* BB improve the check for buffer overruns BB */
4208 name_len = strnlen(searchName, PATH_MAX);
4209 name_len++; /* trailing null */
4210 strncpy(pSMB->FileName, searchName, name_len);
4213 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4214 pSMB->TotalDataCount = 0;
4215 pSMB->MaxParameterCount = cpu_to_le16(2);
4216 /* BB find exact max SMB PDU from sess structure BB */
4217 pSMB->MaxDataCount = cpu_to_le16(4000);
4218 pSMB->MaxSetupCount = 0;
4222 pSMB->Reserved2 = 0;
4223 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4224 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4225 pSMB->DataCount = 0;
4226 pSMB->DataOffset = 0;
4227 pSMB->SetupCount = 1;
4228 pSMB->Reserved3 = 0;
4229 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4230 byte_count = params + 1 /* pad */ ;
4231 pSMB->TotalParameterCount = cpu_to_le16(params);
4232 pSMB->ParameterCount = pSMB->TotalParameterCount;
4233 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4234 pSMB->Reserved4 = 0;
4235 inc_rfc1001_len(pSMB, byte_count);
4236 pSMB->ByteCount = cpu_to_le16(byte_count);
4238 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4239 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4241 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4242 } else { /* decode response */
4243 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4245 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4246 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4247 rc = -EIO; /* bad smb */
4249 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4250 memcpy((char *) pFindData,
4251 (char *) &pSMBr->hdr.Protocol +
4253 sizeof(FILE_UNIX_BASIC_INFO));
4256 cifs_buf_release(pSMB);
4258 goto UnixQPathInfoRetry;
4263 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4265 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4266 const char *searchName, struct cifs_sb_info *cifs_sb,
4267 __u16 *pnetfid, __u16 search_flags,
4268 struct cifs_search_info *psrch_inf, bool msearch)
4270 /* level 257 SMB_ */
4271 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4272 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4273 T2_FFIRST_RSP_PARMS *parms;
4275 int bytes_returned = 0;
4276 int name_len, remap;
4277 __u16 params, byte_count;
4278 struct nls_table *nls_codepage;
4280 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4283 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4288 nls_codepage = cifs_sb->local_nls;
4289 remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
4291 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4293 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4294 PATH_MAX, nls_codepage, remap);
4295 /* We can not add the asterik earlier in case
4296 it got remapped to 0xF03A as if it were part of the
4297 directory name instead of a wildcard */
4300 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4301 pSMB->FileName[name_len+1] = 0;
4302 pSMB->FileName[name_len+2] = '*';
4303 pSMB->FileName[name_len+3] = 0;
4304 name_len += 4; /* now the trailing null */
4305 /* null terminate just in case */
4306 pSMB->FileName[name_len] = 0;
4307 pSMB->FileName[name_len+1] = 0;
4310 } else { /* BB add check for overrun of SMB buf BB */
4311 name_len = strnlen(searchName, PATH_MAX);
4312 /* BB fix here and in unicode clause above ie
4313 if (name_len > buffersize-header)
4314 free buffer exit; BB */
4315 strncpy(pSMB->FileName, searchName, name_len);
4317 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4318 pSMB->FileName[name_len+1] = '*';
4319 pSMB->FileName[name_len+2] = 0;
4324 params = 12 + name_len /* includes null */ ;
4325 pSMB->TotalDataCount = 0; /* no EAs */
4326 pSMB->MaxParameterCount = cpu_to_le16(10);
4327 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4328 pSMB->MaxSetupCount = 0;
4332 pSMB->Reserved2 = 0;
4333 byte_count = params + 1 /* pad */ ;
4334 pSMB->TotalParameterCount = cpu_to_le16(params);
4335 pSMB->ParameterCount = pSMB->TotalParameterCount;
4336 pSMB->ParameterOffset = cpu_to_le16(
4337 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4339 pSMB->DataCount = 0;
4340 pSMB->DataOffset = 0;
4341 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4342 pSMB->Reserved3 = 0;
4343 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4344 pSMB->SearchAttributes =
4345 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4347 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4348 pSMB->SearchFlags = cpu_to_le16(search_flags);
4349 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4351 /* BB what should we set StorageType to? Does it matter? BB */
4352 pSMB->SearchStorageType = 0;
4353 inc_rfc1001_len(pSMB, byte_count);
4354 pSMB->ByteCount = cpu_to_le16(byte_count);
4356 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4357 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4358 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4360 if (rc) {/* BB add logic to retry regular search if Unix search
4361 rejected unexpectedly by server */
4362 /* BB Add code to handle unsupported level rc */
4363 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4365 cifs_buf_release(pSMB);
4367 /* BB eventually could optimize out free and realloc of buf */
4370 goto findFirstRetry;
4371 } else { /* decode response */
4372 /* BB remember to free buffer if error BB */
4373 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4377 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4378 psrch_inf->unicode = true;
4380 psrch_inf->unicode = false;
4382 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4383 psrch_inf->smallBuf = 0;
4384 psrch_inf->srch_entries_start =
4385 (char *) &pSMBr->hdr.Protocol +
4386 le16_to_cpu(pSMBr->t2.DataOffset);
4387 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4388 le16_to_cpu(pSMBr->t2.ParameterOffset));
4390 if (parms->EndofSearch)
4391 psrch_inf->endOfSearch = true;
4393 psrch_inf->endOfSearch = false;
4395 psrch_inf->entries_in_buffer =
4396 le16_to_cpu(parms->SearchCount);
4397 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4398 psrch_inf->entries_in_buffer;
4399 lnoff = le16_to_cpu(parms->LastNameOffset);
4400 if (CIFSMaxBufSize < lnoff) {
4401 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4402 psrch_inf->last_entry = NULL;
4406 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4410 *pnetfid = parms->SearchHandle;
4412 cifs_buf_release(pSMB);
4419 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4420 __u16 searchHandle, __u16 search_flags,
4421 struct cifs_search_info *psrch_inf)
4423 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4424 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4425 T2_FNEXT_RSP_PARMS *parms;
4426 char *response_data;
4429 unsigned int name_len;
4430 __u16 params, byte_count;
4432 cifs_dbg(FYI, "In FindNext\n");
4434 if (psrch_inf->endOfSearch)
4437 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4442 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4444 pSMB->TotalDataCount = 0; /* no EAs */
4445 pSMB->MaxParameterCount = cpu_to_le16(8);
4446 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4447 pSMB->MaxSetupCount = 0;
4451 pSMB->Reserved2 = 0;
4452 pSMB->ParameterOffset = cpu_to_le16(
4453 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4454 pSMB->DataCount = 0;
4455 pSMB->DataOffset = 0;
4456 pSMB->SetupCount = 1;
4457 pSMB->Reserved3 = 0;
4458 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4459 pSMB->SearchHandle = searchHandle; /* always kept as le */
4461 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4462 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4463 pSMB->ResumeKey = psrch_inf->resume_key;
4464 pSMB->SearchFlags = cpu_to_le16(search_flags);
4466 name_len = psrch_inf->resume_name_len;
4468 if (name_len < PATH_MAX) {
4469 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4470 byte_count += name_len;
4471 /* 14 byte parm len above enough for 2 byte null terminator */
4472 pSMB->ResumeFileName[name_len] = 0;
4473 pSMB->ResumeFileName[name_len+1] = 0;
4476 goto FNext2_err_exit;
4478 byte_count = params + 1 /* pad */ ;
4479 pSMB->TotalParameterCount = cpu_to_le16(params);
4480 pSMB->ParameterCount = pSMB->TotalParameterCount;
4481 inc_rfc1001_len(pSMB, byte_count);
4482 pSMB->ByteCount = cpu_to_le16(byte_count);
4484 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4485 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4486 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4489 psrch_inf->endOfSearch = true;
4490 cifs_buf_release(pSMB);
4491 rc = 0; /* search probably was closed at end of search*/
4493 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4494 } else { /* decode response */
4495 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4500 /* BB fixme add lock for file (srch_info) struct here */
4501 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4502 psrch_inf->unicode = true;
4504 psrch_inf->unicode = false;
4505 response_data = (char *) &pSMBr->hdr.Protocol +
4506 le16_to_cpu(pSMBr->t2.ParameterOffset);
4507 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4508 response_data = (char *)&pSMBr->hdr.Protocol +
4509 le16_to_cpu(pSMBr->t2.DataOffset);
4510 if (psrch_inf->smallBuf)
4511 cifs_small_buf_release(
4512 psrch_inf->ntwrk_buf_start);
4514 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4515 psrch_inf->srch_entries_start = response_data;
4516 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4517 psrch_inf->smallBuf = 0;
4518 if (parms->EndofSearch)
4519 psrch_inf->endOfSearch = true;
4521 psrch_inf->endOfSearch = false;
4522 psrch_inf->entries_in_buffer =
4523 le16_to_cpu(parms->SearchCount);
4524 psrch_inf->index_of_last_entry +=
4525 psrch_inf->entries_in_buffer;
4526 lnoff = le16_to_cpu(parms->LastNameOffset);
4527 if (CIFSMaxBufSize < lnoff) {
4528 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4529 psrch_inf->last_entry = NULL;
4532 psrch_inf->last_entry =
4533 psrch_inf->srch_entries_start + lnoff;
4535 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4536 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4538 /* BB fixme add unlock here */
4543 /* BB On error, should we leave previous search buf (and count and
4544 last entry fields) intact or free the previous one? */
4546 /* Note: On -EAGAIN error only caller can retry on handle based calls
4547 since file handle passed in no longer valid */
4550 cifs_buf_release(pSMB);
4555 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4556 const __u16 searchHandle)
4559 FINDCLOSE_REQ *pSMB = NULL;
4561 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4562 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4564 /* no sense returning error if session restarted
4565 as file handle has been closed */
4571 pSMB->FileID = searchHandle;
4572 pSMB->ByteCount = 0;
4573 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4575 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4577 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4579 /* Since session is dead, search handle closed on server already */
4587 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4588 const char *search_name, __u64 *inode_number,
4589 const struct nls_table *nls_codepage, int remap)
4592 TRANSACTION2_QPI_REQ *pSMB = NULL;
4593 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4594 int name_len, bytes_returned;
4595 __u16 params, byte_count;
4597 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4601 GetInodeNumberRetry:
4602 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4607 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4609 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4610 search_name, PATH_MAX, nls_codepage,
4612 name_len++; /* trailing null */
4614 } else { /* BB improve the check for buffer overruns BB */
4615 name_len = strnlen(search_name, PATH_MAX);
4616 name_len++; /* trailing null */
4617 strncpy(pSMB->FileName, search_name, name_len);
4620 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4621 pSMB->TotalDataCount = 0;
4622 pSMB->MaxParameterCount = cpu_to_le16(2);
4623 /* BB find exact max data count below from sess structure BB */
4624 pSMB->MaxDataCount = cpu_to_le16(4000);
4625 pSMB->MaxSetupCount = 0;
4629 pSMB->Reserved2 = 0;
4630 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4631 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4632 pSMB->DataCount = 0;
4633 pSMB->DataOffset = 0;
4634 pSMB->SetupCount = 1;
4635 pSMB->Reserved3 = 0;
4636 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4637 byte_count = params + 1 /* pad */ ;
4638 pSMB->TotalParameterCount = cpu_to_le16(params);
4639 pSMB->ParameterCount = pSMB->TotalParameterCount;
4640 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4641 pSMB->Reserved4 = 0;
4642 inc_rfc1001_len(pSMB, byte_count);
4643 pSMB->ByteCount = cpu_to_le16(byte_count);
4645 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4646 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4648 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4650 /* decode response */
4651 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4652 /* BB also check enough total bytes returned */
4653 if (rc || get_bcc(&pSMBr->hdr) < 2)
4654 /* If rc should we check for EOPNOSUPP and
4655 disable the srvino flag? or in caller? */
4656 rc = -EIO; /* bad smb */
4658 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4659 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4660 struct file_internal_info *pfinfo;
4661 /* BB Do we need a cast or hash here ? */
4663 cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n");
4665 goto GetInodeNumOut;
4667 pfinfo = (struct file_internal_info *)
4668 (data_offset + (char *) &pSMBr->hdr.Protocol);
4669 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4673 cifs_buf_release(pSMB);
4675 goto GetInodeNumberRetry;
4679 /* parses DFS refferal V3 structure
4680 * caller is responsible for freeing target_nodes
4683 * on failure - errno
4686 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4687 unsigned int *num_of_nodes,
4688 struct dfs_info3_param **target_nodes,
4689 const struct nls_table *nls_codepage, int remap,
4690 const char *searchName)
4695 struct dfs_referral_level_3 *ref;
4697 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4701 *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4703 if (*num_of_nodes < 1) {
4704 cifs_dbg(VFS, "num_referrals: must be at least > 0, but we get num_referrals = %d\n",
4707 goto parse_DFS_referrals_exit;
4710 ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4711 if (ref->VersionNumber != cpu_to_le16(3)) {
4712 cifs_dbg(VFS, "Referrals of V%d version are not supported, should be V3\n",
4713 le16_to_cpu(ref->VersionNumber));
4715 goto parse_DFS_referrals_exit;
4718 /* get the upper boundary of the resp buffer */
4719 data_end = (char *)(&(pSMBr->PathConsumed)) +
4720 le16_to_cpu(pSMBr->t2.DataCount);
4722 cifs_dbg(FYI, "num_referrals: %d dfs flags: 0x%x ...\n",
4723 *num_of_nodes, le32_to_cpu(pSMBr->DFSFlags));
4725 *target_nodes = kcalloc(*num_of_nodes, sizeof(struct dfs_info3_param),
4727 if (*target_nodes == NULL) {
4729 goto parse_DFS_referrals_exit;
4732 /* collect necessary data from referrals */
4733 for (i = 0; i < *num_of_nodes; i++) {
4736 struct dfs_info3_param *node = (*target_nodes)+i;
4738 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4740 __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4744 goto parse_DFS_referrals_exit;
4746 cifsConvertToUTF16((__le16 *) tmp, searchName,
4747 PATH_MAX, nls_codepage, remap);
4748 node->path_consumed = cifs_utf16_bytes(tmp,
4749 le16_to_cpu(pSMBr->PathConsumed),
4753 node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4755 node->server_type = le16_to_cpu(ref->ServerType);
4756 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4759 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4760 max_len = data_end - temp;
4761 node->path_name = cifs_strndup_from_utf16(temp, max_len,
4762 is_unicode, nls_codepage);
4763 if (!node->path_name) {
4765 goto parse_DFS_referrals_exit;
4768 /* copy link target UNC */
4769 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4770 max_len = data_end - temp;
4771 node->node_name = cifs_strndup_from_utf16(temp, max_len,
4772 is_unicode, nls_codepage);
4773 if (!node->node_name) {
4775 goto parse_DFS_referrals_exit;
4781 parse_DFS_referrals_exit:
4783 free_dfs_info_array(*target_nodes, *num_of_nodes);
4784 *target_nodes = NULL;
4791 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4792 const char *search_name, struct dfs_info3_param **target_nodes,
4793 unsigned int *num_of_nodes,
4794 const struct nls_table *nls_codepage, int remap)
4796 /* TRANS2_GET_DFS_REFERRAL */
4797 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4798 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4802 __u16 params, byte_count;
4804 *target_nodes = NULL;
4806 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4810 rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4815 /* server pointer checked in called function,
4816 but should never be null here anyway */
4817 pSMB->hdr.Mid = get_next_mid(ses->server);
4818 pSMB->hdr.Tid = ses->ipc_tid;
4819 pSMB->hdr.Uid = ses->Suid;
4820 if (ses->capabilities & CAP_STATUS32)
4821 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4822 if (ses->capabilities & CAP_DFS)
4823 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4825 if (ses->capabilities & CAP_UNICODE) {
4826 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4828 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4829 search_name, PATH_MAX, nls_codepage,
4831 name_len++; /* trailing null */
4833 } else { /* BB improve the check for buffer overruns BB */
4834 name_len = strnlen(search_name, PATH_MAX);
4835 name_len++; /* trailing null */
4836 strncpy(pSMB->RequestFileName, search_name, name_len);
4839 if (ses->server && ses->server->sign)
4840 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4842 pSMB->hdr.Uid = ses->Suid;
4844 params = 2 /* level */ + name_len /*includes null */ ;
4845 pSMB->TotalDataCount = 0;
4846 pSMB->DataCount = 0;
4847 pSMB->DataOffset = 0;
4848 pSMB->MaxParameterCount = 0;
4849 /* BB find exact max SMB PDU from sess structure BB */
4850 pSMB->MaxDataCount = cpu_to_le16(4000);
4851 pSMB->MaxSetupCount = 0;
4855 pSMB->Reserved2 = 0;
4856 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4857 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4858 pSMB->SetupCount = 1;
4859 pSMB->Reserved3 = 0;
4860 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4861 byte_count = params + 3 /* pad */ ;
4862 pSMB->ParameterCount = cpu_to_le16(params);
4863 pSMB->TotalParameterCount = pSMB->ParameterCount;
4864 pSMB->MaxReferralLevel = cpu_to_le16(3);
4865 inc_rfc1001_len(pSMB, byte_count);
4866 pSMB->ByteCount = cpu_to_le16(byte_count);
4868 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4869 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4871 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4874 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4876 /* BB Also check if enough total bytes returned? */
4877 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4878 rc = -EIO; /* bad smb */
4882 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4883 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4885 /* parse returned result into more usable form */
4886 rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4887 target_nodes, nls_codepage, remap,
4891 cifs_buf_release(pSMB);
4899 /* Query File System Info such as free space to old servers such as Win 9x */
4901 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4902 struct kstatfs *FSData)
4904 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4905 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4906 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4907 FILE_SYSTEM_ALLOC_INFO *response_data;
4909 int bytes_returned = 0;
4910 __u16 params, byte_count;
4912 cifs_dbg(FYI, "OldQFSInfo\n");
4914 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4919 params = 2; /* level */
4920 pSMB->TotalDataCount = 0;
4921 pSMB->MaxParameterCount = cpu_to_le16(2);
4922 pSMB->MaxDataCount = cpu_to_le16(1000);
4923 pSMB->MaxSetupCount = 0;
4927 pSMB->Reserved2 = 0;
4928 byte_count = params + 1 /* pad */ ;
4929 pSMB->TotalParameterCount = cpu_to_le16(params);
4930 pSMB->ParameterCount = pSMB->TotalParameterCount;
4931 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4932 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4933 pSMB->DataCount = 0;
4934 pSMB->DataOffset = 0;
4935 pSMB->SetupCount = 1;
4936 pSMB->Reserved3 = 0;
4937 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4938 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4939 inc_rfc1001_len(pSMB, byte_count);
4940 pSMB->ByteCount = cpu_to_le16(byte_count);
4942 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4943 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4945 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4946 } else { /* decode response */
4947 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4949 if (rc || get_bcc(&pSMBr->hdr) < 18)
4950 rc = -EIO; /* bad smb */
4952 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4953 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4954 get_bcc(&pSMBr->hdr), data_offset);
4956 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4957 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4959 le16_to_cpu(response_data->BytesPerSector) *
4960 le32_to_cpu(response_data->
4961 SectorsPerAllocationUnit);
4963 le32_to_cpu(response_data->TotalAllocationUnits);
4964 FSData->f_bfree = FSData->f_bavail =
4965 le32_to_cpu(response_data->FreeAllocationUnits);
4966 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4967 (unsigned long long)FSData->f_blocks,
4968 (unsigned long long)FSData->f_bfree,
4972 cifs_buf_release(pSMB);
4975 goto oldQFSInfoRetry;
4981 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4982 struct kstatfs *FSData)
4984 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4985 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4986 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4987 FILE_SYSTEM_INFO *response_data;
4989 int bytes_returned = 0;
4990 __u16 params, byte_count;
4992 cifs_dbg(FYI, "In QFSInfo\n");
4994 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4999 params = 2; /* level */
5000 pSMB->TotalDataCount = 0;
5001 pSMB->MaxParameterCount = cpu_to_le16(2);
5002 pSMB->MaxDataCount = cpu_to_le16(1000);
5003 pSMB->MaxSetupCount = 0;
5007 pSMB->Reserved2 = 0;
5008 byte_count = params + 1 /* pad */ ;
5009 pSMB->TotalParameterCount = cpu_to_le16(params);
5010 pSMB->ParameterCount = pSMB->TotalParameterCount;
5011 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5012 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5013 pSMB->DataCount = 0;
5014 pSMB->DataOffset = 0;
5015 pSMB->SetupCount = 1;
5016 pSMB->Reserved3 = 0;
5017 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5018 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5019 inc_rfc1001_len(pSMB, byte_count);
5020 pSMB->ByteCount = cpu_to_le16(byte_count);
5022 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5023 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5025 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5026 } else { /* decode response */
5027 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5029 if (rc || get_bcc(&pSMBr->hdr) < 24)
5030 rc = -EIO; /* bad smb */
5032 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5036 *) (((char *) &pSMBr->hdr.Protocol) +
5039 le32_to_cpu(response_data->BytesPerSector) *
5040 le32_to_cpu(response_data->
5041 SectorsPerAllocationUnit);
5043 le64_to_cpu(response_data->TotalAllocationUnits);
5044 FSData->f_bfree = FSData->f_bavail =
5045 le64_to_cpu(response_data->FreeAllocationUnits);
5046 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5047 (unsigned long long)FSData->f_blocks,
5048 (unsigned long long)FSData->f_bfree,
5052 cifs_buf_release(pSMB);
5061 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5063 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5064 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5065 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5066 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5068 int bytes_returned = 0;
5069 __u16 params, byte_count;
5071 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5073 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5078 params = 2; /* level */
5079 pSMB->TotalDataCount = 0;
5080 pSMB->MaxParameterCount = cpu_to_le16(2);
5081 /* BB find exact max SMB PDU from sess structure BB */
5082 pSMB->MaxDataCount = cpu_to_le16(1000);
5083 pSMB->MaxSetupCount = 0;
5087 pSMB->Reserved2 = 0;
5088 byte_count = params + 1 /* pad */ ;
5089 pSMB->TotalParameterCount = cpu_to_le16(params);
5090 pSMB->ParameterCount = pSMB->TotalParameterCount;
5091 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5092 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5093 pSMB->DataCount = 0;
5094 pSMB->DataOffset = 0;
5095 pSMB->SetupCount = 1;
5096 pSMB->Reserved3 = 0;
5097 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5098 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5099 inc_rfc1001_len(pSMB, byte_count);
5100 pSMB->ByteCount = cpu_to_le16(byte_count);
5102 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5103 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5105 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5106 } else { /* decode response */
5107 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5109 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5110 /* BB also check if enough bytes returned */
5111 rc = -EIO; /* bad smb */
5113 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5115 (FILE_SYSTEM_ATTRIBUTE_INFO
5116 *) (((char *) &pSMBr->hdr.Protocol) +
5118 memcpy(&tcon->fsAttrInfo, response_data,
5119 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5122 cifs_buf_release(pSMB);
5125 goto QFSAttributeRetry;
5131 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5133 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5134 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5135 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5136 FILE_SYSTEM_DEVICE_INFO *response_data;
5138 int bytes_returned = 0;
5139 __u16 params, byte_count;
5141 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5143 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5148 params = 2; /* level */
5149 pSMB->TotalDataCount = 0;
5150 pSMB->MaxParameterCount = cpu_to_le16(2);
5151 /* BB find exact max SMB PDU from sess structure BB */
5152 pSMB->MaxDataCount = cpu_to_le16(1000);
5153 pSMB->MaxSetupCount = 0;
5157 pSMB->Reserved2 = 0;
5158 byte_count = params + 1 /* pad */ ;
5159 pSMB->TotalParameterCount = cpu_to_le16(params);
5160 pSMB->ParameterCount = pSMB->TotalParameterCount;
5161 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5162 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5164 pSMB->DataCount = 0;
5165 pSMB->DataOffset = 0;
5166 pSMB->SetupCount = 1;
5167 pSMB->Reserved3 = 0;
5168 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5169 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5170 inc_rfc1001_len(pSMB, byte_count);
5171 pSMB->ByteCount = cpu_to_le16(byte_count);
5173 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5174 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5176 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5177 } else { /* decode response */
5178 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5180 if (rc || get_bcc(&pSMBr->hdr) <
5181 sizeof(FILE_SYSTEM_DEVICE_INFO))
5182 rc = -EIO; /* bad smb */
5184 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5186 (FILE_SYSTEM_DEVICE_INFO *)
5187 (((char *) &pSMBr->hdr.Protocol) +
5189 memcpy(&tcon->fsDevInfo, response_data,
5190 sizeof(FILE_SYSTEM_DEVICE_INFO));
5193 cifs_buf_release(pSMB);
5196 goto QFSDeviceRetry;
5202 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5204 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5205 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5206 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5207 FILE_SYSTEM_UNIX_INFO *response_data;
5209 int bytes_returned = 0;
5210 __u16 params, byte_count;
5212 cifs_dbg(FYI, "In QFSUnixInfo\n");
5214 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5215 (void **) &pSMB, (void **) &pSMBr);
5219 params = 2; /* level */
5220 pSMB->TotalDataCount = 0;
5221 pSMB->DataCount = 0;
5222 pSMB->DataOffset = 0;
5223 pSMB->MaxParameterCount = cpu_to_le16(2);
5224 /* BB find exact max SMB PDU from sess structure BB */
5225 pSMB->MaxDataCount = cpu_to_le16(100);
5226 pSMB->MaxSetupCount = 0;
5230 pSMB->Reserved2 = 0;
5231 byte_count = params + 1 /* pad */ ;
5232 pSMB->ParameterCount = cpu_to_le16(params);
5233 pSMB->TotalParameterCount = pSMB->ParameterCount;
5234 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5235 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5236 pSMB->SetupCount = 1;
5237 pSMB->Reserved3 = 0;
5238 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5239 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5240 inc_rfc1001_len(pSMB, byte_count);
5241 pSMB->ByteCount = cpu_to_le16(byte_count);
5243 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5244 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5246 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5247 } else { /* decode response */
5248 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5250 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5251 rc = -EIO; /* bad smb */
5253 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5255 (FILE_SYSTEM_UNIX_INFO
5256 *) (((char *) &pSMBr->hdr.Protocol) +
5258 memcpy(&tcon->fsUnixInfo, response_data,
5259 sizeof(FILE_SYSTEM_UNIX_INFO));
5262 cifs_buf_release(pSMB);
5272 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5274 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5275 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5276 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5278 int bytes_returned = 0;
5279 __u16 params, param_offset, offset, byte_count;
5281 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5283 /* BB switch to small buf init to save memory */
5284 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5285 (void **) &pSMB, (void **) &pSMBr);
5289 params = 4; /* 2 bytes zero followed by info level. */
5290 pSMB->MaxSetupCount = 0;
5294 pSMB->Reserved2 = 0;
5295 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5297 offset = param_offset + params;
5299 pSMB->MaxParameterCount = cpu_to_le16(4);
5300 /* BB find exact max SMB PDU from sess structure BB */
5301 pSMB->MaxDataCount = cpu_to_le16(100);
5302 pSMB->SetupCount = 1;
5303 pSMB->Reserved3 = 0;
5304 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5305 byte_count = 1 /* pad */ + params + 12;
5307 pSMB->DataCount = cpu_to_le16(12);
5308 pSMB->ParameterCount = cpu_to_le16(params);
5309 pSMB->TotalDataCount = pSMB->DataCount;
5310 pSMB->TotalParameterCount = pSMB->ParameterCount;
5311 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5312 pSMB->DataOffset = cpu_to_le16(offset);
5316 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5319 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5320 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5321 pSMB->ClientUnixCap = cpu_to_le64(cap);
5323 inc_rfc1001_len(pSMB, byte_count);
5324 pSMB->ByteCount = cpu_to_le16(byte_count);
5326 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5327 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5329 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5330 } else { /* decode response */
5331 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5333 rc = -EIO; /* bad smb */
5335 cifs_buf_release(pSMB);
5338 goto SETFSUnixRetry;
5346 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5347 struct kstatfs *FSData)
5349 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5350 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5351 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5352 FILE_SYSTEM_POSIX_INFO *response_data;
5354 int bytes_returned = 0;
5355 __u16 params, byte_count;
5357 cifs_dbg(FYI, "In QFSPosixInfo\n");
5359 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5364 params = 2; /* level */
5365 pSMB->TotalDataCount = 0;
5366 pSMB->DataCount = 0;
5367 pSMB->DataOffset = 0;
5368 pSMB->MaxParameterCount = cpu_to_le16(2);
5369 /* BB find exact max SMB PDU from sess structure BB */
5370 pSMB->MaxDataCount = cpu_to_le16(100);
5371 pSMB->MaxSetupCount = 0;
5375 pSMB->Reserved2 = 0;
5376 byte_count = params + 1 /* pad */ ;
5377 pSMB->ParameterCount = cpu_to_le16(params);
5378 pSMB->TotalParameterCount = pSMB->ParameterCount;
5379 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5380 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5381 pSMB->SetupCount = 1;
5382 pSMB->Reserved3 = 0;
5383 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5384 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5385 inc_rfc1001_len(pSMB, byte_count);
5386 pSMB->ByteCount = cpu_to_le16(byte_count);
5388 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5389 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5391 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5392 } else { /* decode response */
5393 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5395 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5396 rc = -EIO; /* bad smb */
5398 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5400 (FILE_SYSTEM_POSIX_INFO
5401 *) (((char *) &pSMBr->hdr.Protocol) +
5404 le32_to_cpu(response_data->BlockSize);
5406 le64_to_cpu(response_data->TotalBlocks);
5408 le64_to_cpu(response_data->BlocksAvail);
5409 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5410 FSData->f_bavail = FSData->f_bfree;
5413 le64_to_cpu(response_data->UserBlocksAvail);
5415 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5417 le64_to_cpu(response_data->TotalFileNodes);
5418 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5420 le64_to_cpu(response_data->FreeFileNodes);
5423 cifs_buf_release(pSMB);
5433 * We can not use write of zero bytes trick to set file size due to need for
5434 * large file support. Also note that this SetPathInfo is preferred to
5435 * SetFileInfo based method in next routine which is only needed to work around
5436 * a sharing violation bugin Samba which this routine can run into.
5439 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5440 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5441 bool set_allocation)
5443 struct smb_com_transaction2_spi_req *pSMB = NULL;
5444 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5445 struct file_end_of_file_info *parm_data;
5448 int bytes_returned = 0;
5449 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
5451 __u16 params, byte_count, data_count, param_offset, offset;
5453 cifs_dbg(FYI, "In SetEOF\n");
5455 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5460 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5462 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5463 PATH_MAX, cifs_sb->local_nls, remap);
5464 name_len++; /* trailing null */
5466 } else { /* BB improve the check for buffer overruns BB */
5467 name_len = strnlen(file_name, PATH_MAX);
5468 name_len++; /* trailing null */
5469 strncpy(pSMB->FileName, file_name, name_len);
5471 params = 6 + name_len;
5472 data_count = sizeof(struct file_end_of_file_info);
5473 pSMB->MaxParameterCount = cpu_to_le16(2);
5474 pSMB->MaxDataCount = cpu_to_le16(4100);
5475 pSMB->MaxSetupCount = 0;
5479 pSMB->Reserved2 = 0;
5480 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5481 InformationLevel) - 4;
5482 offset = param_offset + params;
5483 if (set_allocation) {
5484 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5485 pSMB->InformationLevel =
5486 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5488 pSMB->InformationLevel =
5489 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5490 } else /* Set File Size */ {
5491 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5492 pSMB->InformationLevel =
5493 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5495 pSMB->InformationLevel =
5496 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5500 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5502 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5503 pSMB->DataOffset = cpu_to_le16(offset);
5504 pSMB->SetupCount = 1;
5505 pSMB->Reserved3 = 0;
5506 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5507 byte_count = 3 /* pad */ + params + data_count;
5508 pSMB->DataCount = cpu_to_le16(data_count);
5509 pSMB->TotalDataCount = pSMB->DataCount;
5510 pSMB->ParameterCount = cpu_to_le16(params);
5511 pSMB->TotalParameterCount = pSMB->ParameterCount;
5512 pSMB->Reserved4 = 0;
5513 inc_rfc1001_len(pSMB, byte_count);
5514 parm_data->FileSize = cpu_to_le64(size);
5515 pSMB->ByteCount = cpu_to_le16(byte_count);
5516 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5517 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5519 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5521 cifs_buf_release(pSMB);
5530 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5531 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5533 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5534 struct file_end_of_file_info *parm_data;
5536 __u16 params, param_offset, offset, byte_count, count;
5538 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5540 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5545 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5546 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5549 pSMB->MaxSetupCount = 0;
5553 pSMB->Reserved2 = 0;
5554 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5555 offset = param_offset + params;
5557 count = sizeof(struct file_end_of_file_info);
5558 pSMB->MaxParameterCount = cpu_to_le16(2);
5559 /* BB find exact max SMB PDU from sess structure BB */
5560 pSMB->MaxDataCount = cpu_to_le16(1000);
5561 pSMB->SetupCount = 1;
5562 pSMB->Reserved3 = 0;
5563 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5564 byte_count = 3 /* pad */ + params + count;
5565 pSMB->DataCount = cpu_to_le16(count);
5566 pSMB->ParameterCount = cpu_to_le16(params);
5567 pSMB->TotalDataCount = pSMB->DataCount;
5568 pSMB->TotalParameterCount = pSMB->ParameterCount;
5569 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5571 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5573 pSMB->DataOffset = cpu_to_le16(offset);
5574 parm_data->FileSize = cpu_to_le64(size);
5575 pSMB->Fid = cfile->fid.netfid;
5576 if (set_allocation) {
5577 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5578 pSMB->InformationLevel =
5579 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5581 pSMB->InformationLevel =
5582 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5583 } else /* Set File Size */ {
5584 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5585 pSMB->InformationLevel =
5586 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5588 pSMB->InformationLevel =
5589 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5591 pSMB->Reserved4 = 0;
5592 inc_rfc1001_len(pSMB, byte_count);
5593 pSMB->ByteCount = cpu_to_le16(byte_count);
5594 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5596 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5600 /* Note: On -EAGAIN error only caller can retry on handle based calls
5601 since file handle passed in no longer valid */
5606 /* Some legacy servers such as NT4 require that the file times be set on
5607 an open handle, rather than by pathname - this is awkward due to
5608 potential access conflicts on the open, but it is unavoidable for these
5609 old servers since the only other choice is to go from 100 nanosecond DCE
5610 time and resort to the original setpathinfo level which takes the ancient
5611 DOS time format with 2 second granularity */
5613 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5614 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5616 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5619 __u16 params, param_offset, offset, byte_count, count;
5621 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5622 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5627 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5628 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5631 pSMB->MaxSetupCount = 0;
5635 pSMB->Reserved2 = 0;
5636 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5637 offset = param_offset + params;
5639 data_offset = (char *)pSMB +
5640 offsetof(struct smb_hdr, Protocol) + offset;
5642 count = sizeof(FILE_BASIC_INFO);
5643 pSMB->MaxParameterCount = cpu_to_le16(2);
5644 /* BB find max SMB PDU from sess */
5645 pSMB->MaxDataCount = cpu_to_le16(1000);
5646 pSMB->SetupCount = 1;
5647 pSMB->Reserved3 = 0;
5648 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5649 byte_count = 3 /* pad */ + params + count;
5650 pSMB->DataCount = cpu_to_le16(count);
5651 pSMB->ParameterCount = cpu_to_le16(params);
5652 pSMB->TotalDataCount = pSMB->DataCount;
5653 pSMB->TotalParameterCount = pSMB->ParameterCount;
5654 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5655 pSMB->DataOffset = cpu_to_le16(offset);
5657 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5658 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5660 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5661 pSMB->Reserved4 = 0;
5662 inc_rfc1001_len(pSMB, byte_count);
5663 pSMB->ByteCount = cpu_to_le16(byte_count);
5664 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5665 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5667 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5670 /* Note: On -EAGAIN error only caller can retry on handle based calls
5671 since file handle passed in no longer valid */
5677 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5678 bool delete_file, __u16 fid, __u32 pid_of_opener)
5680 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5683 __u16 params, param_offset, offset, byte_count, count;
5685 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5686 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5691 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5692 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5695 pSMB->MaxSetupCount = 0;
5699 pSMB->Reserved2 = 0;
5700 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5701 offset = param_offset + params;
5703 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5706 pSMB->MaxParameterCount = cpu_to_le16(2);
5707 /* BB find max SMB PDU from sess */
5708 pSMB->MaxDataCount = cpu_to_le16(1000);
5709 pSMB->SetupCount = 1;
5710 pSMB->Reserved3 = 0;
5711 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5712 byte_count = 3 /* pad */ + params + count;
5713 pSMB->DataCount = cpu_to_le16(count);
5714 pSMB->ParameterCount = cpu_to_le16(params);
5715 pSMB->TotalDataCount = pSMB->DataCount;
5716 pSMB->TotalParameterCount = pSMB->ParameterCount;
5717 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5718 pSMB->DataOffset = cpu_to_le16(offset);
5720 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5721 pSMB->Reserved4 = 0;
5722 inc_rfc1001_len(pSMB, byte_count);
5723 pSMB->ByteCount = cpu_to_le16(byte_count);
5724 *data_offset = delete_file ? 1 : 0;
5725 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5727 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5733 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5734 const char *fileName, const FILE_BASIC_INFO *data,
5735 const struct nls_table *nls_codepage, int remap)
5737 TRANSACTION2_SPI_REQ *pSMB = NULL;
5738 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5741 int bytes_returned = 0;
5743 __u16 params, param_offset, offset, byte_count, count;
5745 cifs_dbg(FYI, "In SetTimes\n");
5748 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5753 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5755 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5756 PATH_MAX, nls_codepage, remap);
5757 name_len++; /* trailing null */
5759 } else { /* BB improve the check for buffer overruns BB */
5760 name_len = strnlen(fileName, PATH_MAX);
5761 name_len++; /* trailing null */
5762 strncpy(pSMB->FileName, fileName, name_len);
5765 params = 6 + name_len;
5766 count = sizeof(FILE_BASIC_INFO);
5767 pSMB->MaxParameterCount = cpu_to_le16(2);
5768 /* BB find max SMB PDU from sess structure BB */
5769 pSMB->MaxDataCount = cpu_to_le16(1000);
5770 pSMB->MaxSetupCount = 0;
5774 pSMB->Reserved2 = 0;
5775 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5776 InformationLevel) - 4;
5777 offset = param_offset + params;
5778 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5779 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5780 pSMB->DataOffset = cpu_to_le16(offset);
5781 pSMB->SetupCount = 1;
5782 pSMB->Reserved3 = 0;
5783 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5784 byte_count = 3 /* pad */ + params + count;
5786 pSMB->DataCount = cpu_to_le16(count);
5787 pSMB->ParameterCount = cpu_to_le16(params);
5788 pSMB->TotalDataCount = pSMB->DataCount;
5789 pSMB->TotalParameterCount = pSMB->ParameterCount;
5790 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5791 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5793 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5794 pSMB->Reserved4 = 0;
5795 inc_rfc1001_len(pSMB, byte_count);
5796 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5797 pSMB->ByteCount = cpu_to_le16(byte_count);
5798 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5799 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5801 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5803 cifs_buf_release(pSMB);
5811 /* Can not be used to set time stamps yet (due to old DOS time format) */
5812 /* Can be used to set attributes */
5813 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5814 handling it anyway and NT4 was what we thought it would be needed for
5815 Do not delete it until we prove whether needed for Win9x though */
5817 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
5818 __u16 dos_attrs, const struct nls_table *nls_codepage)
5820 SETATTR_REQ *pSMB = NULL;
5821 SETATTR_RSP *pSMBr = NULL;
5826 cifs_dbg(FYI, "In SetAttrLegacy\n");
5829 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5834 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5836 ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5837 PATH_MAX, nls_codepage);
5838 name_len++; /* trailing null */
5840 } else { /* BB improve the check for buffer overruns BB */
5841 name_len = strnlen(fileName, PATH_MAX);
5842 name_len++; /* trailing null */
5843 strncpy(pSMB->fileName, fileName, name_len);
5845 pSMB->attr = cpu_to_le16(dos_attrs);
5846 pSMB->BufferFormat = 0x04;
5847 inc_rfc1001_len(pSMB, name_len + 1);
5848 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5849 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5850 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5852 cifs_dbg(FYI, "Error in LegacySetAttr = %d\n", rc);
5854 cifs_buf_release(pSMB);
5857 goto SetAttrLgcyRetry;
5861 #endif /* temporarily unneeded SetAttr legacy function */
5864 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5865 const struct cifs_unix_set_info_args *args)
5867 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5868 u64 mode = args->mode;
5870 if (uid_valid(args->uid))
5871 uid = from_kuid(&init_user_ns, args->uid);
5872 if (gid_valid(args->gid))
5873 gid = from_kgid(&init_user_ns, args->gid);
5876 * Samba server ignores set of file size to zero due to bugs in some
5877 * older clients, but we should be precise - we use SetFileSize to
5878 * set file size and do not want to truncate file size to zero
5879 * accidentally as happened on one Samba server beta by putting
5880 * zero instead of -1 here
5882 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5883 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5884 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5885 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5886 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5887 data_offset->Uid = cpu_to_le64(uid);
5888 data_offset->Gid = cpu_to_le64(gid);
5889 /* better to leave device as zero when it is */
5890 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5891 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5892 data_offset->Permissions = cpu_to_le64(mode);
5895 data_offset->Type = cpu_to_le32(UNIX_FILE);
5896 else if (S_ISDIR(mode))
5897 data_offset->Type = cpu_to_le32(UNIX_DIR);
5898 else if (S_ISLNK(mode))
5899 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5900 else if (S_ISCHR(mode))
5901 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5902 else if (S_ISBLK(mode))
5903 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5904 else if (S_ISFIFO(mode))
5905 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5906 else if (S_ISSOCK(mode))
5907 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5911 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5912 const struct cifs_unix_set_info_args *args,
5913 u16 fid, u32 pid_of_opener)
5915 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5918 u16 params, param_offset, offset, byte_count, count;
5920 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5921 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5926 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5927 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5930 pSMB->MaxSetupCount = 0;
5934 pSMB->Reserved2 = 0;
5935 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5936 offset = param_offset + params;
5938 data_offset = (char *)pSMB +
5939 offsetof(struct smb_hdr, Protocol) + offset;
5941 count = sizeof(FILE_UNIX_BASIC_INFO);
5943 pSMB->MaxParameterCount = cpu_to_le16(2);
5944 /* BB find max SMB PDU from sess */
5945 pSMB->MaxDataCount = cpu_to_le16(1000);
5946 pSMB->SetupCount = 1;
5947 pSMB->Reserved3 = 0;
5948 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5949 byte_count = 3 /* pad */ + params + count;
5950 pSMB->DataCount = cpu_to_le16(count);
5951 pSMB->ParameterCount = cpu_to_le16(params);
5952 pSMB->TotalDataCount = pSMB->DataCount;
5953 pSMB->TotalParameterCount = pSMB->ParameterCount;
5954 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5955 pSMB->DataOffset = cpu_to_le16(offset);
5957 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5958 pSMB->Reserved4 = 0;
5959 inc_rfc1001_len(pSMB, byte_count);
5960 pSMB->ByteCount = cpu_to_le16(byte_count);
5962 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5964 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5966 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5969 /* Note: On -EAGAIN error only caller can retry on handle based calls
5970 since file handle passed in no longer valid */
5976 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5977 const char *file_name,
5978 const struct cifs_unix_set_info_args *args,
5979 const struct nls_table *nls_codepage, int remap)
5981 TRANSACTION2_SPI_REQ *pSMB = NULL;
5982 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5985 int bytes_returned = 0;
5986 FILE_UNIX_BASIC_INFO *data_offset;
5987 __u16 params, param_offset, offset, count, byte_count;
5989 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5991 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5996 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5998 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5999 PATH_MAX, nls_codepage, remap);
6000 name_len++; /* trailing null */
6002 } else { /* BB improve the check for buffer overruns BB */
6003 name_len = strnlen(file_name, PATH_MAX);
6004 name_len++; /* trailing null */
6005 strncpy(pSMB->FileName, file_name, name_len);
6008 params = 6 + name_len;
6009 count = sizeof(FILE_UNIX_BASIC_INFO);
6010 pSMB->MaxParameterCount = cpu_to_le16(2);
6011 /* BB find max SMB PDU from sess structure BB */
6012 pSMB->MaxDataCount = cpu_to_le16(1000);
6013 pSMB->MaxSetupCount = 0;
6017 pSMB->Reserved2 = 0;
6018 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6019 InformationLevel) - 4;
6020 offset = param_offset + params;
6022 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6024 memset(data_offset, 0, count);
6025 pSMB->DataOffset = cpu_to_le16(offset);
6026 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6027 pSMB->SetupCount = 1;
6028 pSMB->Reserved3 = 0;
6029 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6030 byte_count = 3 /* pad */ + params + count;
6031 pSMB->ParameterCount = cpu_to_le16(params);
6032 pSMB->DataCount = cpu_to_le16(count);
6033 pSMB->TotalParameterCount = pSMB->ParameterCount;
6034 pSMB->TotalDataCount = pSMB->DataCount;
6035 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6036 pSMB->Reserved4 = 0;
6037 inc_rfc1001_len(pSMB, byte_count);
6039 cifs_fill_unix_set_info(data_offset, args);
6041 pSMB->ByteCount = cpu_to_le16(byte_count);
6042 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6043 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6045 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6047 cifs_buf_release(pSMB);
6053 #ifdef CONFIG_CIFS_XATTR
6055 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6056 * function used by listxattr and getxattr type calls. When ea_name is set,
6057 * it looks for that attribute name and stuffs that value into the EAData
6058 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6059 * buffer. In both cases, the return value is either the length of the
6060 * resulting data or a negative error code. If EAData is a NULL pointer then
6061 * the data isn't copied to it, but the length is returned.
6064 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6065 const unsigned char *searchName, const unsigned char *ea_name,
6066 char *EAData, size_t buf_size,
6067 const struct nls_table *nls_codepage, int remap)
6069 /* BB assumes one setup word */
6070 TRANSACTION2_QPI_REQ *pSMB = NULL;
6071 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6075 struct fealist *ea_response_data;
6076 struct fea *temp_fea;
6079 __u16 params, byte_count, data_offset;
6080 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6082 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6084 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6089 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6091 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6092 PATH_MAX, nls_codepage, remap);
6093 list_len++; /* trailing null */
6095 } else { /* BB improve the check for buffer overruns BB */
6096 list_len = strnlen(searchName, PATH_MAX);
6097 list_len++; /* trailing null */
6098 strncpy(pSMB->FileName, searchName, list_len);
6101 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6102 pSMB->TotalDataCount = 0;
6103 pSMB->MaxParameterCount = cpu_to_le16(2);
6104 /* BB find exact max SMB PDU from sess structure BB */
6105 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6106 pSMB->MaxSetupCount = 0;
6110 pSMB->Reserved2 = 0;
6111 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6112 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6113 pSMB->DataCount = 0;
6114 pSMB->DataOffset = 0;
6115 pSMB->SetupCount = 1;
6116 pSMB->Reserved3 = 0;
6117 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6118 byte_count = params + 1 /* pad */ ;
6119 pSMB->TotalParameterCount = cpu_to_le16(params);
6120 pSMB->ParameterCount = pSMB->TotalParameterCount;
6121 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6122 pSMB->Reserved4 = 0;
6123 inc_rfc1001_len(pSMB, byte_count);
6124 pSMB->ByteCount = cpu_to_le16(byte_count);
6126 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6127 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6129 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6134 /* BB also check enough total bytes returned */
6135 /* BB we need to improve the validity checking
6136 of these trans2 responses */
6138 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6139 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6140 rc = -EIO; /* bad smb */
6144 /* check that length of list is not more than bcc */
6145 /* check that each entry does not go beyond length
6147 /* check that each element of each entry does not
6148 go beyond end of list */
6149 /* validate_trans2_offsets() */
6150 /* BB check if start of smb + data_offset > &bcc+ bcc */
6152 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6153 ea_response_data = (struct fealist *)
6154 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6156 list_len = le32_to_cpu(ea_response_data->list_len);
6157 cifs_dbg(FYI, "ea length %d\n", list_len);
6158 if (list_len <= 8) {
6159 cifs_dbg(FYI, "empty EA list returned from server\n");
6163 /* make sure list_len doesn't go past end of SMB */
6164 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6165 if ((char *)ea_response_data + list_len > end_of_smb) {
6166 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6171 /* account for ea list len */
6173 temp_fea = ea_response_data->list;
6174 temp_ptr = (char *)temp_fea;
6175 while (list_len > 0) {
6176 unsigned int name_len;
6181 /* make sure we can read name_len and value_len */
6183 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6188 name_len = temp_fea->name_len;
6189 value_len = le16_to_cpu(temp_fea->value_len);
6190 list_len -= name_len + 1 + value_len;
6192 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6198 if (ea_name_len == name_len &&
6199 memcmp(ea_name, temp_ptr, name_len) == 0) {
6200 temp_ptr += name_len + 1;
6204 if ((size_t)value_len > buf_size) {
6208 memcpy(EAData, temp_ptr, value_len);
6212 /* account for prefix user. and trailing null */
6213 rc += (5 + 1 + name_len);
6214 if (rc < (int) buf_size) {
6215 memcpy(EAData, "user.", 5);
6217 memcpy(EAData, temp_ptr, name_len);
6219 /* null terminate name */
6222 } else if (buf_size == 0) {
6223 /* skip copy - calc size only */
6225 /* stop before overrun buffer */
6230 temp_ptr += name_len + 1 + value_len;
6231 temp_fea = (struct fea *)temp_ptr;
6234 /* didn't find the named attribute */
6239 cifs_buf_release(pSMB);
6247 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6248 const char *fileName, const char *ea_name, const void *ea_value,
6249 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6252 struct smb_com_transaction2_spi_req *pSMB = NULL;
6253 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6254 struct fealist *parm_data;
6257 int bytes_returned = 0;
6258 __u16 params, param_offset, byte_count, offset, count;
6260 cifs_dbg(FYI, "In SetEA\n");
6262 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6267 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6269 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6270 PATH_MAX, nls_codepage, remap);
6271 name_len++; /* trailing null */
6273 } else { /* BB improve the check for buffer overruns BB */
6274 name_len = strnlen(fileName, PATH_MAX);
6275 name_len++; /* trailing null */
6276 strncpy(pSMB->FileName, fileName, name_len);
6279 params = 6 + name_len;
6281 /* done calculating parms using name_len of file name,
6282 now use name_len to calculate length of ea name
6283 we are going to create in the inode xattrs */
6284 if (ea_name == NULL)
6287 name_len = strnlen(ea_name, 255);
6289 count = sizeof(*parm_data) + ea_value_len + name_len;
6290 pSMB->MaxParameterCount = cpu_to_le16(2);
6291 /* BB find max SMB PDU from sess */
6292 pSMB->MaxDataCount = cpu_to_le16(1000);
6293 pSMB->MaxSetupCount = 0;
6297 pSMB->Reserved2 = 0;
6298 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6299 InformationLevel) - 4;
6300 offset = param_offset + params;
6301 pSMB->InformationLevel =
6302 cpu_to_le16(SMB_SET_FILE_EA);
6305 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6307 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6308 pSMB->DataOffset = cpu_to_le16(offset);
6309 pSMB->SetupCount = 1;
6310 pSMB->Reserved3 = 0;
6311 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6312 byte_count = 3 /* pad */ + params + count;
6313 pSMB->DataCount = cpu_to_le16(count);
6314 parm_data->list_len = cpu_to_le32(count);
6315 parm_data->list[0].EA_flags = 0;
6316 /* we checked above that name len is less than 255 */
6317 parm_data->list[0].name_len = (__u8)name_len;
6318 /* EA names are always ASCII */
6320 strncpy(parm_data->list[0].name, ea_name, name_len);
6321 parm_data->list[0].name[name_len] = 0;
6322 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6323 /* caller ensures that ea_value_len is less than 64K but
6324 we need to ensure that it fits within the smb */
6326 /*BB add length check to see if it would fit in
6327 negotiated SMB buffer size BB */
6328 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6330 memcpy(parm_data->list[0].name+name_len+1,
6331 ea_value, ea_value_len);
6333 pSMB->TotalDataCount = pSMB->DataCount;
6334 pSMB->ParameterCount = cpu_to_le16(params);
6335 pSMB->TotalParameterCount = pSMB->ParameterCount;
6336 pSMB->Reserved4 = 0;
6337 inc_rfc1001_len(pSMB, byte_count);
6338 pSMB->ByteCount = cpu_to_le16(byte_count);
6339 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6340 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6342 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6344 cifs_buf_release(pSMB);
6353 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6355 * Years ago the kernel added a "dnotify" function for Samba server,
6356 * to allow network clients (such as Windows) to display updated
6357 * lists of files in directory listings automatically when
6358 * files are added by one user when another user has the
6359 * same directory open on their desktop. The Linux cifs kernel
6360 * client hooked into the kernel side of this interface for
6361 * the same reason, but ironically when the VFS moved from
6362 * "dnotify" to "inotify" it became harder to plug in Linux
6363 * network file system clients (the most obvious use case
6364 * for notify interfaces is when multiple users can update
6365 * the contents of the same directory - exactly what network
6366 * file systems can do) although the server (Samba) could
6367 * still use it. For the short term we leave the worker
6368 * function ifdeffed out (below) until inotify is fixed
6369 * in the VFS to make it easier to plug in network file
6370 * system clients. If inotify turns out to be permanently
6371 * incompatible for network fs clients, we could instead simply
6372 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6374 int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
6375 const int notify_subdirs, const __u16 netfid,
6376 __u32 filter, struct file *pfile, int multishot,
6377 const struct nls_table *nls_codepage)
6380 struct smb_com_transaction_change_notify_req *pSMB = NULL;
6381 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6382 struct dir_notify_req *dnotify_req;
6385 cifs_dbg(FYI, "In CIFSSMBNotify for file handle %d\n", (int)netfid);
6386 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6391 pSMB->TotalParameterCount = 0 ;
6392 pSMB->TotalDataCount = 0;
6393 pSMB->MaxParameterCount = cpu_to_le32(2);
6394 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6395 pSMB->MaxSetupCount = 4;
6397 pSMB->ParameterOffset = 0;
6398 pSMB->DataCount = 0;
6399 pSMB->DataOffset = 0;
6400 pSMB->SetupCount = 4; /* single byte does not need le conversion */
6401 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6402 pSMB->ParameterCount = pSMB->TotalParameterCount;
6404 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6405 pSMB->Reserved2 = 0;
6406 pSMB->CompletionFilter = cpu_to_le32(filter);
6407 pSMB->Fid = netfid; /* file handle always le */
6408 pSMB->ByteCount = 0;
6410 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6411 (struct smb_hdr *)pSMBr, &bytes_returned,
6414 cifs_dbg(FYI, "Error in Notify = %d\n", rc);
6416 /* Add file to outstanding requests */
6417 /* BB change to kmem cache alloc */
6418 dnotify_req = kmalloc(
6419 sizeof(struct dir_notify_req),
6422 dnotify_req->Pid = pSMB->hdr.Pid;
6423 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6424 dnotify_req->Mid = pSMB->hdr.Mid;
6425 dnotify_req->Tid = pSMB->hdr.Tid;
6426 dnotify_req->Uid = pSMB->hdr.Uid;
6427 dnotify_req->netfid = netfid;
6428 dnotify_req->pfile = pfile;
6429 dnotify_req->filter = filter;
6430 dnotify_req->multishot = multishot;
6431 spin_lock(&GlobalMid_Lock);
6432 list_add_tail(&dnotify_req->lhead,
6433 &GlobalDnotifyReqList);
6434 spin_unlock(&GlobalMid_Lock);
6438 cifs_buf_release(pSMB);
6441 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */