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 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
424 NEGOTIATE_RSP *pSMBr;
428 struct TCP_Server_Info *server = ses->server;
430 unsigned int secFlags;
433 WARN(1, "%s: server is NULL!\n", __func__);
437 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
438 (void **) &pSMB, (void **) &pSMBr);
442 /* if any of auth flags (ie not sign or seal) are overriden use them */
443 if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
444 secFlags = ses->overrideSecFlg; /* BB FIXME fix sign flags? */
445 else /* if override flags set only sign/seal OR them with global auth */
446 secFlags = global_secflags | ses->overrideSecFlg;
448 cifs_dbg(FYI, "secFlags 0x%x\n", secFlags);
450 pSMB->hdr.Mid = get_next_mid(server);
451 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
453 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
454 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
455 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
456 cifs_dbg(FYI, "Kerberos only mechanism, enable extended security\n");
457 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
458 } else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
459 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
460 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
461 cifs_dbg(FYI, "NTLMSSP only mechanism, enable extended security\n");
462 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
466 for (i = 0; i < CIFS_NUM_PROT; i++) {
467 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
468 count += strlen(protocols[i].name) + 1;
469 /* null at end of source and target buffers anyway */
471 inc_rfc1001_len(pSMB, count);
472 pSMB->ByteCount = cpu_to_le16(count);
474 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
475 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
479 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
480 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
481 /* Check wct = 1 error case */
482 if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
483 /* core returns wct = 1, but we do not ask for core - otherwise
484 small wct just comes when dialect index is -1 indicating we
485 could not negotiate a common dialect */
488 #ifdef CONFIG_CIFS_WEAK_PW_HASH
489 } else if ((pSMBr->hdr.WordCount == 13)
490 && ((server->dialect == LANMAN_PROT)
491 || (server->dialect == LANMAN2_PROT))) {
493 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
495 if ((secFlags & CIFSSEC_MAY_LANMAN) ||
496 (secFlags & CIFSSEC_MAY_PLNTXT))
497 server->secType = LANMAN;
499 cifs_dbg(VFS, "mount failed weak security disabled in /proc/fs/cifs/SecurityFlags\n");
503 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
504 server->maxReq = min_t(unsigned int,
505 le16_to_cpu(rsp->MaxMpxCount),
507 set_credits(server, server->maxReq);
508 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
509 server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
510 /* even though we do not use raw we might as well set this
511 accurately, in case we ever find a need for it */
512 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
513 server->max_rw = 0xFF00;
514 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
516 server->max_rw = 0;/* do not need to use raw anyway */
517 server->capabilities = CAP_MPX_MODE;
519 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
521 /* OS/2 often does not set timezone therefore
522 * we must use server time to calc time zone.
523 * Could deviate slightly from the right zone.
524 * Smallest defined timezone difference is 15 minutes
525 * (i.e. Nepal). Rounding up/down is done to match
528 int val, seconds, remain, result;
529 struct timespec ts, utc;
531 ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
532 rsp->SrvTime.Time, 0);
533 cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
534 (int)ts.tv_sec, (int)utc.tv_sec,
535 (int)(utc.tv_sec - ts.tv_sec));
536 val = (int)(utc.tv_sec - ts.tv_sec);
538 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
539 remain = seconds % MIN_TZ_ADJ;
540 if (remain >= (MIN_TZ_ADJ / 2))
541 result += MIN_TZ_ADJ;
544 server->timeAdj = result;
546 server->timeAdj = (int)tmp;
547 server->timeAdj *= 60; /* also in seconds */
549 cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
552 /* BB get server time for time conversions and add
553 code to use it and timezone since this is not UTC */
555 if (rsp->EncryptionKeyLength ==
556 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
557 memcpy(ses->server->cryptkey, rsp->EncryptionKey,
558 CIFS_CRYPTO_KEY_SIZE);
559 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
560 rc = -EIO; /* need cryptkey unless plain text */
564 cifs_dbg(FYI, "LANMAN negotiated\n");
565 /* we will not end up setting signing flags - as no signing
566 was in LANMAN and server did not return the flags on */
568 #else /* weak security disabled */
569 } else if (pSMBr->hdr.WordCount == 13) {
570 cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
572 #endif /* WEAK_PW_HASH */
574 } else if (pSMBr->hdr.WordCount != 17) {
579 /* else wct == 17 NTLM */
580 server->sec_mode = pSMBr->SecurityMode;
581 if ((server->sec_mode & SECMODE_USER) == 0)
582 cifs_dbg(FYI, "share mode security\n");
584 if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
585 #ifdef CONFIG_CIFS_WEAK_PW_HASH
586 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
587 #endif /* CIFS_WEAK_PW_HASH */
588 cifs_dbg(VFS, "Server requests plain text password but client support disabled\n");
590 if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
591 server->secType = NTLMv2;
592 else if (secFlags & CIFSSEC_MAY_NTLM)
593 server->secType = NTLM;
594 else if (secFlags & CIFSSEC_MAY_NTLMV2)
595 server->secType = NTLMv2;
596 else if (secFlags & CIFSSEC_MAY_KRB5)
597 server->secType = Kerberos;
598 else if (secFlags & CIFSSEC_MAY_NTLMSSP)
599 server->secType = RawNTLMSSP;
600 else if (secFlags & CIFSSEC_MAY_LANMAN)
601 server->secType = LANMAN;
604 cifs_dbg(VFS, "Invalid security type\n");
607 /* else ... any others ...? */
609 /* one byte, so no need to convert this or EncryptionKeyLen from
611 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
613 set_credits(server, server->maxReq);
614 /* probably no need to store and check maxvcs */
615 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
616 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
617 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
618 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
619 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
620 server->timeAdj *= 60;
622 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE)
623 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
624 CIFS_CRYPTO_KEY_SIZE);
625 else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
626 server->capabilities & CAP_EXTENDED_SECURITY) &&
627 (pSMBr->EncryptionKeyLength == 0))
628 rc = decode_ext_sec_blob(server, pSMBr);
629 else if (server->sec_mode & SECMODE_PW_ENCRYPT)
630 rc = -EIO; /* no crypt key only if plain text pwd */
632 server->capabilities &= ~CAP_EXTENDED_SECURITY;
637 #ifdef CONFIG_CIFS_WEAK_PW_HASH
640 if ((secFlags & CIFSSEC_MAY_SIGN) == 0) {
641 /* MUST_SIGN already includes the MAY_SIGN FLAG
642 so if this is zero it means that signing is disabled */
643 cifs_dbg(FYI, "Signing disabled\n");
644 if (server->sec_mode & SECMODE_SIGN_REQUIRED) {
645 cifs_dbg(VFS, "Server requires packet signing to be enabled in /proc/fs/cifs/SecurityFlags\n");
649 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
650 } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
651 /* signing required */
652 cifs_dbg(FYI, "Must sign - secFlags 0x%x\n", secFlags);
653 if ((server->sec_mode &
654 (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
655 cifs_dbg(VFS, "signing required but server lacks support\n");
658 server->sec_mode |= SECMODE_SIGN_REQUIRED;
660 /* signing optional ie CIFSSEC_MAY_SIGN */
661 if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0)
663 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
667 cifs_buf_release(pSMB);
669 cifs_dbg(FYI, "negprot rc %d\n", rc);
674 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
676 struct smb_hdr *smb_buffer;
679 cifs_dbg(FYI, "In tree disconnect\n");
681 /* BB: do we need to check this? These should never be NULL. */
682 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
686 * No need to return error on this operation if tid invalidated and
687 * closed on server already e.g. due to tcp session crashing. Also,
688 * the tcon is no longer on the list, so no need to take lock before
691 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
694 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
695 (void **)&smb_buffer);
699 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
701 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
703 /* No need to return error on this operation if tid invalidated and
704 closed on server already e.g. due to tcp session crashing */
712 * This is a no-op for now. We're not really interested in the reply, but
713 * rather in the fact that the server sent one and that server->lstrp
716 * FIXME: maybe we should consider checking that the reply matches request?
719 cifs_echo_callback(struct mid_q_entry *mid)
721 struct TCP_Server_Info *server = mid->callback_data;
723 DeleteMidQEntry(mid);
724 add_credits(server, 1, CIFS_ECHO_OP);
728 CIFSSMBEcho(struct TCP_Server_Info *server)
733 struct smb_rqst rqst = { .rq_iov = &iov,
736 cifs_dbg(FYI, "In echo request\n");
738 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
742 /* set up echo request */
743 smb->hdr.Tid = 0xffff;
744 smb->hdr.WordCount = 1;
745 put_unaligned_le16(1, &smb->EchoCount);
746 put_bcc(1, &smb->hdr);
748 inc_rfc1001_len(smb, 3);
750 iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
752 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback,
753 server, CIFS_ASYNC_OP | CIFS_ECHO_OP);
755 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
757 cifs_small_buf_release(smb);
763 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
765 LOGOFF_ANDX_REQ *pSMB;
768 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
771 * BB: do we need to check validity of ses and server? They should
772 * always be valid since we have an active reference. If not, that
773 * should probably be a BUG()
775 if (!ses || !ses->server)
778 mutex_lock(&ses->session_mutex);
779 if (ses->need_reconnect)
780 goto session_already_dead; /* no need to send SMBlogoff if uid
781 already closed due to reconnect */
782 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
784 mutex_unlock(&ses->session_mutex);
788 pSMB->hdr.Mid = get_next_mid(ses->server);
790 if (ses->server->sec_mode &
791 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
792 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
794 pSMB->hdr.Uid = ses->Suid;
796 pSMB->AndXCommand = 0xFF;
797 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
798 session_already_dead:
799 mutex_unlock(&ses->session_mutex);
801 /* if session dead then we do not need to do ulogoff,
802 since server closed smb session, no sense reporting
810 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
811 const char *fileName, __u16 type,
812 const struct nls_table *nls_codepage, int remap)
814 TRANSACTION2_SPI_REQ *pSMB = NULL;
815 TRANSACTION2_SPI_RSP *pSMBr = NULL;
816 struct unlink_psx_rq *pRqD;
819 int bytes_returned = 0;
820 __u16 params, param_offset, offset, byte_count;
822 cifs_dbg(FYI, "In POSIX delete\n");
824 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
829 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
831 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
832 PATH_MAX, nls_codepage, remap);
833 name_len++; /* trailing null */
835 } else { /* BB add path length overrun check */
836 name_len = strnlen(fileName, PATH_MAX);
837 name_len++; /* trailing null */
838 strncpy(pSMB->FileName, fileName, name_len);
841 params = 6 + name_len;
842 pSMB->MaxParameterCount = cpu_to_le16(2);
843 pSMB->MaxDataCount = 0; /* BB double check this with jra */
844 pSMB->MaxSetupCount = 0;
849 param_offset = offsetof(struct smb_com_transaction2_spi_req,
850 InformationLevel) - 4;
851 offset = param_offset + params;
853 /* Setup pointer to Request Data (inode type) */
854 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
855 pRqD->type = cpu_to_le16(type);
856 pSMB->ParameterOffset = cpu_to_le16(param_offset);
857 pSMB->DataOffset = cpu_to_le16(offset);
858 pSMB->SetupCount = 1;
860 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
861 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
863 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
864 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
865 pSMB->ParameterCount = cpu_to_le16(params);
866 pSMB->TotalParameterCount = pSMB->ParameterCount;
867 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
869 inc_rfc1001_len(pSMB, byte_count);
870 pSMB->ByteCount = cpu_to_le16(byte_count);
871 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
872 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
874 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
875 cifs_buf_release(pSMB);
877 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
886 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
887 struct cifs_sb_info *cifs_sb)
889 DELETE_FILE_REQ *pSMB = NULL;
890 DELETE_FILE_RSP *pSMBr = NULL;
894 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
897 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
902 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
903 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
904 PATH_MAX, cifs_sb->local_nls,
906 name_len++; /* trailing null */
908 } else { /* BB improve check for buffer overruns BB */
909 name_len = strnlen(name, PATH_MAX);
910 name_len++; /* trailing null */
911 strncpy(pSMB->fileName, name, name_len);
913 pSMB->SearchAttributes =
914 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
915 pSMB->BufferFormat = 0x04;
916 inc_rfc1001_len(pSMB, name_len + 1);
917 pSMB->ByteCount = cpu_to_le16(name_len + 1);
918 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
919 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
920 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
922 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
924 cifs_buf_release(pSMB);
932 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
933 struct cifs_sb_info *cifs_sb)
935 DELETE_DIRECTORY_REQ *pSMB = NULL;
936 DELETE_DIRECTORY_RSP *pSMBr = NULL;
940 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
942 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
944 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
949 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
950 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
951 PATH_MAX, cifs_sb->local_nls,
953 name_len++; /* trailing null */
955 } else { /* BB improve check for buffer overruns BB */
956 name_len = strnlen(name, PATH_MAX);
957 name_len++; /* trailing null */
958 strncpy(pSMB->DirName, name, name_len);
961 pSMB->BufferFormat = 0x04;
962 inc_rfc1001_len(pSMB, name_len + 1);
963 pSMB->ByteCount = cpu_to_le16(name_len + 1);
964 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
965 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
966 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
968 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
970 cifs_buf_release(pSMB);
977 CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
978 struct cifs_sb_info *cifs_sb)
981 CREATE_DIRECTORY_REQ *pSMB = NULL;
982 CREATE_DIRECTORY_RSP *pSMBr = NULL;
985 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
987 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
989 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
994 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
995 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
996 PATH_MAX, cifs_sb->local_nls,
998 name_len++; /* trailing null */
1000 } else { /* BB improve check for buffer overruns BB */
1001 name_len = strnlen(name, PATH_MAX);
1002 name_len++; /* trailing null */
1003 strncpy(pSMB->DirName, name, name_len);
1006 pSMB->BufferFormat = 0x04;
1007 inc_rfc1001_len(pSMB, name_len + 1);
1008 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1009 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1010 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1011 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1013 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
1015 cifs_buf_release(pSMB);
1022 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1023 __u32 posix_flags, __u64 mode, __u16 *netfid,
1024 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1025 const char *name, const struct nls_table *nls_codepage,
1028 TRANSACTION2_SPI_REQ *pSMB = NULL;
1029 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1032 int bytes_returned = 0;
1033 __u16 params, param_offset, offset, byte_count, count;
1034 OPEN_PSX_REQ *pdata;
1035 OPEN_PSX_RSP *psx_rsp;
1037 cifs_dbg(FYI, "In POSIX Create\n");
1039 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1044 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1046 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1047 PATH_MAX, nls_codepage, remap);
1048 name_len++; /* trailing null */
1050 } else { /* BB improve the check for buffer overruns BB */
1051 name_len = strnlen(name, PATH_MAX);
1052 name_len++; /* trailing null */
1053 strncpy(pSMB->FileName, name, name_len);
1056 params = 6 + name_len;
1057 count = sizeof(OPEN_PSX_REQ);
1058 pSMB->MaxParameterCount = cpu_to_le16(2);
1059 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1060 pSMB->MaxSetupCount = 0;
1064 pSMB->Reserved2 = 0;
1065 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1066 InformationLevel) - 4;
1067 offset = param_offset + params;
1068 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1069 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1070 pdata->Permissions = cpu_to_le64(mode);
1071 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1072 pdata->OpenFlags = cpu_to_le32(*pOplock);
1073 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1074 pSMB->DataOffset = cpu_to_le16(offset);
1075 pSMB->SetupCount = 1;
1076 pSMB->Reserved3 = 0;
1077 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1078 byte_count = 3 /* pad */ + params + count;
1080 pSMB->DataCount = cpu_to_le16(count);
1081 pSMB->ParameterCount = cpu_to_le16(params);
1082 pSMB->TotalDataCount = pSMB->DataCount;
1083 pSMB->TotalParameterCount = pSMB->ParameterCount;
1084 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1085 pSMB->Reserved4 = 0;
1086 inc_rfc1001_len(pSMB, byte_count);
1087 pSMB->ByteCount = cpu_to_le16(byte_count);
1088 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1089 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1091 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1092 goto psx_create_err;
1095 cifs_dbg(FYI, "copying inode info\n");
1096 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1098 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1099 rc = -EIO; /* bad smb */
1100 goto psx_create_err;
1103 /* copy return information to pRetData */
1104 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1105 + le16_to_cpu(pSMBr->t2.DataOffset));
1107 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1109 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1110 /* Let caller know file was created so we can set the mode. */
1111 /* Do we care about the CreateAction in any other cases? */
1112 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1113 *pOplock |= CIFS_CREATE_ACTION;
1114 /* check to make sure response data is there */
1115 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1116 pRetData->Type = cpu_to_le32(-1); /* unknown */
1117 cifs_dbg(NOISY, "unknown type\n");
1119 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1120 + sizeof(FILE_UNIX_BASIC_INFO)) {
1121 cifs_dbg(VFS, "Open response data too small\n");
1122 pRetData->Type = cpu_to_le32(-1);
1123 goto psx_create_err;
1125 memcpy((char *) pRetData,
1126 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1127 sizeof(FILE_UNIX_BASIC_INFO));
1131 cifs_buf_release(pSMB);
1133 if (posix_flags & SMB_O_DIRECTORY)
1134 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1136 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1144 static __u16 convert_disposition(int disposition)
1148 switch (disposition) {
1149 case FILE_SUPERSEDE:
1150 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1153 ofun = SMBOPEN_OAPPEND;
1156 ofun = SMBOPEN_OCREATE;
1159 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1161 case FILE_OVERWRITE:
1162 ofun = SMBOPEN_OTRUNC;
1164 case FILE_OVERWRITE_IF:
1165 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1168 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1169 ofun = SMBOPEN_OAPPEND; /* regular open */
1175 access_flags_to_smbopen_mode(const int access_flags)
1177 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1179 if (masked_flags == GENERIC_READ)
1180 return SMBOPEN_READ;
1181 else if (masked_flags == GENERIC_WRITE)
1182 return SMBOPEN_WRITE;
1184 /* just go for read/write */
1185 return SMBOPEN_READWRITE;
1189 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1190 const char *fileName, const int openDisposition,
1191 const int access_flags, const int create_options, __u16 *netfid,
1192 int *pOplock, FILE_ALL_INFO *pfile_info,
1193 const struct nls_table *nls_codepage, int remap)
1196 OPENX_REQ *pSMB = NULL;
1197 OPENX_RSP *pSMBr = NULL;
1203 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1208 pSMB->AndXCommand = 0xFF; /* none */
1210 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1211 count = 1; /* account for one byte pad to word boundary */
1213 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1214 fileName, PATH_MAX, nls_codepage, remap);
1215 name_len++; /* trailing null */
1217 } else { /* BB improve check for buffer overruns BB */
1218 count = 0; /* no pad */
1219 name_len = strnlen(fileName, PATH_MAX);
1220 name_len++; /* trailing null */
1221 strncpy(pSMB->fileName, fileName, name_len);
1223 if (*pOplock & REQ_OPLOCK)
1224 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1225 else if (*pOplock & REQ_BATCHOPLOCK)
1226 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1228 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1229 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1230 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1231 /* set file as system file if special file such
1232 as fifo and server expecting SFU style and
1233 no Unix extensions */
1235 if (create_options & CREATE_OPTION_SPECIAL)
1236 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1237 else /* BB FIXME BB */
1238 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1240 if (create_options & CREATE_OPTION_READONLY)
1241 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1244 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1245 CREATE_OPTIONS_MASK); */
1246 /* BB FIXME END BB */
1248 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1249 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1251 inc_rfc1001_len(pSMB, count);
1253 pSMB->ByteCount = cpu_to_le16(count);
1254 /* long_op set to 1 to allow for oplock break timeouts */
1255 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1256 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1257 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1259 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1261 /* BB verify if wct == 15 */
1263 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1265 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1266 /* Let caller know file was created so we can set the mode. */
1267 /* Do we care about the CreateAction in any other cases? */
1269 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1270 *pOplock |= CIFS_CREATE_ACTION; */
1274 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1275 pfile_info->LastAccessTime = 0; /* BB fixme */
1276 pfile_info->LastWriteTime = 0; /* BB fixme */
1277 pfile_info->ChangeTime = 0; /* BB fixme */
1278 pfile_info->Attributes =
1279 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1280 /* the file_info buf is endian converted by caller */
1281 pfile_info->AllocationSize =
1282 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1283 pfile_info->EndOfFile = pfile_info->AllocationSize;
1284 pfile_info->NumberOfLinks = cpu_to_le32(1);
1285 pfile_info->DeletePending = 0;
1289 cifs_buf_release(pSMB);
1296 CIFSSMBOpen(const unsigned int xid, struct cifs_tcon *tcon,
1297 const char *fileName, const int openDisposition,
1298 const int access_flags, const int create_options, __u16 *netfid,
1299 int *pOplock, FILE_ALL_INFO *pfile_info,
1300 const struct nls_table *nls_codepage, int remap)
1303 OPEN_REQ *pSMB = NULL;
1304 OPEN_RSP *pSMBr = NULL;
1310 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **) &pSMB,
1315 pSMB->AndXCommand = 0xFF; /* none */
1317 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1318 count = 1; /* account for one byte pad to word boundary */
1320 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1321 fileName, PATH_MAX, nls_codepage, remap);
1322 name_len++; /* trailing null */
1324 pSMB->NameLength = cpu_to_le16(name_len);
1325 } else { /* BB improve check for buffer overruns BB */
1326 count = 0; /* no pad */
1327 name_len = strnlen(fileName, PATH_MAX);
1328 name_len++; /* trailing null */
1329 pSMB->NameLength = cpu_to_le16(name_len);
1330 strncpy(pSMB->fileName, fileName, name_len);
1332 if (*pOplock & REQ_OPLOCK)
1333 pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1334 else if (*pOplock & REQ_BATCHOPLOCK)
1335 pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1336 pSMB->DesiredAccess = cpu_to_le32(access_flags);
1337 pSMB->AllocationSize = 0;
1338 /* set file as system file if special file such
1339 as fifo and server expecting SFU style and
1340 no Unix extensions */
1341 if (create_options & CREATE_OPTION_SPECIAL)
1342 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1344 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1346 /* XP does not handle ATTR_POSIX_SEMANTICS */
1347 /* but it helps speed up case sensitive checks for other
1348 servers such as Samba */
1349 if (tcon->ses->capabilities & CAP_UNIX)
1350 pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1352 if (create_options & CREATE_OPTION_READONLY)
1353 pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1355 pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1356 pSMB->CreateDisposition = cpu_to_le32(openDisposition);
1357 pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1358 /* BB Expirement with various impersonation levels and verify */
1359 pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1360 pSMB->SecurityFlags =
1361 SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
1364 inc_rfc1001_len(pSMB, count);
1366 pSMB->ByteCount = cpu_to_le16(count);
1367 /* long_op set to 1 to allow for oplock break timeouts */
1368 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1369 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1370 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1372 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1374 *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
1375 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1376 /* Let caller know file was created so we can set the mode. */
1377 /* Do we care about the CreateAction in any other cases? */
1378 if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1379 *pOplock |= CIFS_CREATE_ACTION;
1381 memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
1382 36 /* CreationTime to Attributes */);
1383 /* the file_info buf is endian converted by caller */
1384 pfile_info->AllocationSize = pSMBr->AllocationSize;
1385 pfile_info->EndOfFile = pSMBr->EndOfFile;
1386 pfile_info->NumberOfLinks = cpu_to_le32(1);
1387 pfile_info->DeletePending = 0;
1391 cifs_buf_release(pSMB);
1398 * Discard any remaining data in the current SMB. To do this, we borrow the
1402 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1404 unsigned int rfclen = get_rfc1002_length(server->smallbuf);
1405 int remaining = rfclen + 4 - server->total_read;
1406 struct cifs_readdata *rdata = mid->callback_data;
1408 while (remaining > 0) {
1411 length = cifs_read_from_socket(server, server->bigbuf,
1412 min_t(unsigned int, remaining,
1413 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1416 server->total_read += length;
1417 remaining -= length;
1420 dequeue_mid(mid, rdata->result);
1425 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1428 unsigned int data_offset, data_len;
1429 struct cifs_readdata *rdata = mid->callback_data;
1430 char *buf = server->smallbuf;
1431 unsigned int buflen = get_rfc1002_length(buf) + 4;
1433 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1434 __func__, mid->mid, rdata->offset, rdata->bytes);
1437 * read the rest of READ_RSP header (sans Data array), or whatever we
1438 * can if there's not enough data. At this point, we've read down to
1441 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1442 HEADER_SIZE(server) + 1;
1444 rdata->iov.iov_base = buf + HEADER_SIZE(server) - 1;
1445 rdata->iov.iov_len = len;
1447 length = cifs_readv_from_socket(server, &rdata->iov, 1, len);
1450 server->total_read += length;
1452 /* Was the SMB read successful? */
1453 rdata->result = server->ops->map_error(buf, false);
1454 if (rdata->result != 0) {
1455 cifs_dbg(FYI, "%s: server returned error %d\n",
1456 __func__, rdata->result);
1457 return cifs_readv_discard(server, mid);
1460 /* Is there enough to get to the rest of the READ_RSP header? */
1461 if (server->total_read < server->vals->read_rsp_size) {
1462 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1463 __func__, server->total_read,
1464 server->vals->read_rsp_size);
1465 rdata->result = -EIO;
1466 return cifs_readv_discard(server, mid);
1469 data_offset = server->ops->read_data_offset(buf) + 4;
1470 if (data_offset < server->total_read) {
1472 * win2k8 sometimes sends an offset of 0 when the read
1473 * is beyond the EOF. Treat it as if the data starts just after
1476 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1477 __func__, data_offset);
1478 data_offset = server->total_read;
1479 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1480 /* data_offset is beyond the end of smallbuf */
1481 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1482 __func__, data_offset);
1483 rdata->result = -EIO;
1484 return cifs_readv_discard(server, mid);
1487 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1488 __func__, server->total_read, data_offset);
1490 len = data_offset - server->total_read;
1492 /* read any junk before data into the rest of smallbuf */
1493 rdata->iov.iov_base = buf + server->total_read;
1494 rdata->iov.iov_len = len;
1495 length = cifs_readv_from_socket(server, &rdata->iov, 1, len);
1498 server->total_read += length;
1501 /* set up first iov for signature check */
1502 rdata->iov.iov_base = buf;
1503 rdata->iov.iov_len = server->total_read;
1504 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1505 rdata->iov.iov_base, rdata->iov.iov_len);
1507 /* how much data is in the response? */
1508 data_len = server->ops->read_data_length(buf);
1509 if (data_offset + data_len > buflen) {
1510 /* data_len is corrupt -- discard frame */
1511 rdata->result = -EIO;
1512 return cifs_readv_discard(server, mid);
1515 length = rdata->read_into_pages(server, rdata, data_len);
1519 server->total_read += length;
1520 rdata->bytes = length;
1522 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1523 server->total_read, buflen, data_len);
1525 /* discard anything left over */
1526 if (server->total_read < buflen)
1527 return cifs_readv_discard(server, mid);
1529 dequeue_mid(mid, false);
1534 cifs_readv_callback(struct mid_q_entry *mid)
1536 struct cifs_readdata *rdata = mid->callback_data;
1537 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1538 struct TCP_Server_Info *server = tcon->ses->server;
1539 struct smb_rqst rqst = { .rq_iov = &rdata->iov,
1541 .rq_pages = rdata->pages,
1542 .rq_npages = rdata->nr_pages,
1543 .rq_pagesz = rdata->pagesz,
1544 .rq_tailsz = rdata->tailsz };
1546 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1547 __func__, mid->mid, mid->mid_state, rdata->result,
1550 switch (mid->mid_state) {
1551 case MID_RESPONSE_RECEIVED:
1552 /* result already set, check signature */
1553 if (server->sec_mode &
1554 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
1557 rc = cifs_verify_signature(&rqst, server,
1558 mid->sequence_number);
1560 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1563 /* FIXME: should this be counted toward the initiating task? */
1564 task_io_account_read(rdata->bytes);
1565 cifs_stats_bytes_read(tcon, rdata->bytes);
1567 case MID_REQUEST_SUBMITTED:
1568 case MID_RETRY_NEEDED:
1569 rdata->result = -EAGAIN;
1572 rdata->result = -EIO;
1575 queue_work(cifsiod_wq, &rdata->work);
1576 DeleteMidQEntry(mid);
1577 add_credits(server, 1, 0);
1580 /* cifs_async_readv - send an async write, and set up mid to handle result */
1582 cifs_async_readv(struct cifs_readdata *rdata)
1585 READ_REQ *smb = NULL;
1587 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1588 struct smb_rqst rqst = { .rq_iov = &rdata->iov,
1591 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1592 __func__, rdata->offset, rdata->bytes);
1594 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1597 wct = 10; /* old style read */
1598 if ((rdata->offset >> 32) > 0) {
1599 /* can not handle this big offset for old */
1604 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1608 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1609 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1611 smb->AndXCommand = 0xFF; /* none */
1612 smb->Fid = rdata->cfile->fid.netfid;
1613 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1615 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1617 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1618 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1622 /* old style read */
1623 struct smb_com_readx_req *smbr =
1624 (struct smb_com_readx_req *)smb;
1625 smbr->ByteCount = 0;
1628 /* 4 for RFC1001 length + 1 for BCC */
1629 rdata->iov.iov_base = smb;
1630 rdata->iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
1632 kref_get(&rdata->refcount);
1633 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1634 cifs_readv_callback, rdata, 0);
1637 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1639 kref_put(&rdata->refcount, cifs_readdata_release);
1641 cifs_small_buf_release(smb);
1646 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1647 unsigned int *nbytes, char **buf, int *pbuf_type)
1650 READ_REQ *pSMB = NULL;
1651 READ_RSP *pSMBr = NULL;
1652 char *pReadData = NULL;
1654 int resp_buf_type = 0;
1656 __u32 pid = io_parms->pid;
1657 __u16 netfid = io_parms->netfid;
1658 __u64 offset = io_parms->offset;
1659 struct cifs_tcon *tcon = io_parms->tcon;
1660 unsigned int count = io_parms->length;
1662 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1663 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1666 wct = 10; /* old style read */
1667 if ((offset >> 32) > 0) {
1668 /* can not handle this big offset for old */
1674 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1678 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1679 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1681 /* tcon and ses pointer are checked in smb_init */
1682 if (tcon->ses->server == NULL)
1683 return -ECONNABORTED;
1685 pSMB->AndXCommand = 0xFF; /* none */
1687 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1689 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1691 pSMB->Remaining = 0;
1692 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1693 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1695 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1697 /* old style read */
1698 struct smb_com_readx_req *pSMBW =
1699 (struct smb_com_readx_req *)pSMB;
1700 pSMBW->ByteCount = 0;
1703 iov[0].iov_base = (char *)pSMB;
1704 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1705 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1706 &resp_buf_type, CIFS_LOG_ERROR);
1707 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1708 pSMBr = (READ_RSP *)iov[0].iov_base;
1710 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1712 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1713 data_length = data_length << 16;
1714 data_length += le16_to_cpu(pSMBr->DataLength);
1715 *nbytes = data_length;
1717 /*check that DataLength would not go beyond end of SMB */
1718 if ((data_length > CIFSMaxBufSize)
1719 || (data_length > count)) {
1720 cifs_dbg(FYI, "bad length %d for count %d\n",
1721 data_length, count);
1725 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1726 le16_to_cpu(pSMBr->DataOffset);
1727 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1728 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1730 }*/ /* can not use copy_to_user when using page cache*/
1732 memcpy(*buf, pReadData, data_length);
1736 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1738 if (resp_buf_type == CIFS_SMALL_BUFFER)
1739 cifs_small_buf_release(iov[0].iov_base);
1740 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1741 cifs_buf_release(iov[0].iov_base);
1742 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1743 /* return buffer to caller to free */
1744 *buf = iov[0].iov_base;
1745 if (resp_buf_type == CIFS_SMALL_BUFFER)
1746 *pbuf_type = CIFS_SMALL_BUFFER;
1747 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1748 *pbuf_type = CIFS_LARGE_BUFFER;
1749 } /* else no valid buffer on return - leave as null */
1751 /* Note: On -EAGAIN error only caller can retry on handle based calls
1752 since file handle passed in no longer valid */
1758 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1759 unsigned int *nbytes, const char *buf,
1760 const char __user *ubuf, const int long_op)
1763 WRITE_REQ *pSMB = NULL;
1764 WRITE_RSP *pSMBr = NULL;
1765 int bytes_returned, wct;
1768 __u32 pid = io_parms->pid;
1769 __u16 netfid = io_parms->netfid;
1770 __u64 offset = io_parms->offset;
1771 struct cifs_tcon *tcon = io_parms->tcon;
1772 unsigned int count = io_parms->length;
1776 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1777 if (tcon->ses == NULL)
1778 return -ECONNABORTED;
1780 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1784 if ((offset >> 32) > 0) {
1785 /* can not handle big offset for old srv */
1790 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1795 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1796 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1798 /* tcon and ses pointer are checked in smb_init */
1799 if (tcon->ses->server == NULL)
1800 return -ECONNABORTED;
1802 pSMB->AndXCommand = 0xFF; /* none */
1804 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1806 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1808 pSMB->Reserved = 0xFFFFFFFF;
1809 pSMB->WriteMode = 0;
1810 pSMB->Remaining = 0;
1812 /* Can increase buffer size if buffer is big enough in some cases ie we
1813 can send more if LARGE_WRITE_X capability returned by the server and if
1814 our buffer is big enough or if we convert to iovecs on socket writes
1815 and eliminate the copy to the CIFS buffer */
1816 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1817 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1819 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1823 if (bytes_sent > count)
1826 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1828 memcpy(pSMB->Data, buf, bytes_sent);
1830 if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
1831 cifs_buf_release(pSMB);
1834 } else if (count != 0) {
1836 cifs_buf_release(pSMB);
1838 } /* else setting file size with write of zero bytes */
1840 byte_count = bytes_sent + 1; /* pad */
1841 else /* wct == 12 */
1842 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1844 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1845 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1846 inc_rfc1001_len(pSMB, byte_count);
1849 pSMB->ByteCount = cpu_to_le16(byte_count);
1850 else { /* old style write has byte count 4 bytes earlier
1852 struct smb_com_writex_req *pSMBW =
1853 (struct smb_com_writex_req *)pSMB;
1854 pSMBW->ByteCount = cpu_to_le16(byte_count);
1857 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1858 (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
1859 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1861 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1863 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1864 *nbytes = (*nbytes) << 16;
1865 *nbytes += le16_to_cpu(pSMBr->Count);
1868 * Mask off high 16 bits when bytes written as returned by the
1869 * server is greater than bytes requested by the client. Some
1870 * OS/2 servers are known to set incorrect CountHigh values.
1872 if (*nbytes > count)
1876 cifs_buf_release(pSMB);
1878 /* Note: On -EAGAIN error only caller can retry on handle based calls
1879 since file handle passed in no longer valid */
1885 cifs_writedata_release(struct kref *refcount)
1887 struct cifs_writedata *wdata = container_of(refcount,
1888 struct cifs_writedata, refcount);
1891 cifsFileInfo_put(wdata->cfile);
1897 * Write failed with a retryable error. Resend the write request. It's also
1898 * possible that the page was redirtied so re-clean the page.
1901 cifs_writev_requeue(struct cifs_writedata *wdata)
1904 struct inode *inode = wdata->cfile->dentry->d_inode;
1905 struct TCP_Server_Info *server;
1907 for (i = 0; i < wdata->nr_pages; i++) {
1908 lock_page(wdata->pages[i]);
1909 clear_page_dirty_for_io(wdata->pages[i]);
1913 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1914 rc = server->ops->async_writev(wdata);
1915 } while (rc == -EAGAIN);
1917 for (i = 0; i < wdata->nr_pages; i++) {
1918 unlock_page(wdata->pages[i]);
1920 SetPageError(wdata->pages[i]);
1921 end_page_writeback(wdata->pages[i]);
1922 page_cache_release(wdata->pages[i]);
1926 mapping_set_error(inode->i_mapping, rc);
1927 kref_put(&wdata->refcount, cifs_writedata_release);
1931 cifs_writev_complete(struct work_struct *work)
1933 struct cifs_writedata *wdata = container_of(work,
1934 struct cifs_writedata, work);
1935 struct inode *inode = wdata->cfile->dentry->d_inode;
1938 if (wdata->result == 0) {
1939 spin_lock(&inode->i_lock);
1940 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
1941 spin_unlock(&inode->i_lock);
1942 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
1944 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
1945 return cifs_writev_requeue(wdata);
1947 for (i = 0; i < wdata->nr_pages; i++) {
1948 struct page *page = wdata->pages[i];
1949 if (wdata->result == -EAGAIN)
1950 __set_page_dirty_nobuffers(page);
1951 else if (wdata->result < 0)
1953 end_page_writeback(page);
1954 page_cache_release(page);
1956 if (wdata->result != -EAGAIN)
1957 mapping_set_error(inode->i_mapping, wdata->result);
1958 kref_put(&wdata->refcount, cifs_writedata_release);
1961 struct cifs_writedata *
1962 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
1964 struct cifs_writedata *wdata;
1966 /* this would overflow */
1967 if (nr_pages == 0) {
1968 cifs_dbg(VFS, "%s: called with nr_pages == 0!\n", __func__);
1972 /* writedata + number of page pointers */
1973 wdata = kzalloc(sizeof(*wdata) +
1974 sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
1975 if (wdata != NULL) {
1976 kref_init(&wdata->refcount);
1977 INIT_LIST_HEAD(&wdata->list);
1978 init_completion(&wdata->done);
1979 INIT_WORK(&wdata->work, complete);
1985 * Check the mid_state and signature on received buffer (if any), and queue the
1986 * workqueue completion task.
1989 cifs_writev_callback(struct mid_q_entry *mid)
1991 struct cifs_writedata *wdata = mid->callback_data;
1992 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1993 unsigned int written;
1994 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1996 switch (mid->mid_state) {
1997 case MID_RESPONSE_RECEIVED:
1998 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
1999 if (wdata->result != 0)
2002 written = le16_to_cpu(smb->CountHigh);
2004 written += le16_to_cpu(smb->Count);
2006 * Mask off high 16 bits when bytes written as returned
2007 * by the server is greater than bytes requested by the
2008 * client. OS/2 servers are known to set incorrect
2011 if (written > wdata->bytes)
2014 if (written < wdata->bytes)
2015 wdata->result = -ENOSPC;
2017 wdata->bytes = written;
2019 case MID_REQUEST_SUBMITTED:
2020 case MID_RETRY_NEEDED:
2021 wdata->result = -EAGAIN;
2024 wdata->result = -EIO;
2028 queue_work(cifsiod_wq, &wdata->work);
2029 DeleteMidQEntry(mid);
2030 add_credits(tcon->ses->server, 1, 0);
2033 /* cifs_async_writev - send an async write, and set up mid to handle result */
2035 cifs_async_writev(struct cifs_writedata *wdata)
2038 WRITE_REQ *smb = NULL;
2040 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2042 struct smb_rqst rqst = { };
2044 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2048 if (wdata->offset >> 32 > 0) {
2049 /* can not handle big offset for old srv */
2054 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2056 goto async_writev_out;
2058 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2059 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2061 smb->AndXCommand = 0xFF; /* none */
2062 smb->Fid = wdata->cfile->fid.netfid;
2063 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2065 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2066 smb->Reserved = 0xFFFFFFFF;
2071 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2073 /* 4 for RFC1001 length + 1 for BCC */
2074 iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
2079 rqst.rq_pages = wdata->pages;
2080 rqst.rq_npages = wdata->nr_pages;
2081 rqst.rq_pagesz = wdata->pagesz;
2082 rqst.rq_tailsz = wdata->tailsz;
2084 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2085 wdata->offset, wdata->bytes);
2087 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2088 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2091 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2092 put_bcc(wdata->bytes + 1, &smb->hdr);
2095 struct smb_com_writex_req *smbw =
2096 (struct smb_com_writex_req *)smb;
2097 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2098 put_bcc(wdata->bytes + 5, &smbw->hdr);
2099 iov.iov_len += 4; /* pad bigger by four bytes */
2102 kref_get(&wdata->refcount);
2103 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2104 cifs_writev_callback, wdata, 0);
2107 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2109 kref_put(&wdata->refcount, cifs_writedata_release);
2112 cifs_small_buf_release(smb);
2117 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2118 unsigned int *nbytes, struct kvec *iov, int n_vec)
2121 WRITE_REQ *pSMB = NULL;
2124 int resp_buf_type = 0;
2125 __u32 pid = io_parms->pid;
2126 __u16 netfid = io_parms->netfid;
2127 __u64 offset = io_parms->offset;
2128 struct cifs_tcon *tcon = io_parms->tcon;
2129 unsigned int count = io_parms->length;
2133 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2135 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2139 if ((offset >> 32) > 0) {
2140 /* can not handle big offset for old srv */
2144 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2148 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2149 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2151 /* tcon and ses pointer are checked in smb_init */
2152 if (tcon->ses->server == NULL)
2153 return -ECONNABORTED;
2155 pSMB->AndXCommand = 0xFF; /* none */
2157 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2159 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2160 pSMB->Reserved = 0xFFFFFFFF;
2161 pSMB->WriteMode = 0;
2162 pSMB->Remaining = 0;
2165 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2167 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2168 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2169 /* header + 1 byte pad */
2170 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2172 inc_rfc1001_len(pSMB, count + 1);
2173 else /* wct == 12 */
2174 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2176 pSMB->ByteCount = cpu_to_le16(count + 1);
2177 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2178 struct smb_com_writex_req *pSMBW =
2179 (struct smb_com_writex_req *)pSMB;
2180 pSMBW->ByteCount = cpu_to_le16(count + 5);
2182 iov[0].iov_base = pSMB;
2184 iov[0].iov_len = smb_hdr_len + 4;
2185 else /* wct == 12 pad bigger by four bytes */
2186 iov[0].iov_len = smb_hdr_len + 8;
2189 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0);
2190 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2192 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2193 } else if (resp_buf_type == 0) {
2194 /* presumably this can not happen, but best to be safe */
2197 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base;
2198 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2199 *nbytes = (*nbytes) << 16;
2200 *nbytes += le16_to_cpu(pSMBr->Count);
2203 * Mask off high 16 bits when bytes written as returned by the
2204 * server is greater than bytes requested by the client. OS/2
2205 * servers are known to set incorrect CountHigh values.
2207 if (*nbytes > count)
2211 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2212 if (resp_buf_type == CIFS_SMALL_BUFFER)
2213 cifs_small_buf_release(iov[0].iov_base);
2214 else if (resp_buf_type == CIFS_LARGE_BUFFER)
2215 cifs_buf_release(iov[0].iov_base);
2217 /* Note: On -EAGAIN error only caller can retry on handle based calls
2218 since file handle passed in no longer valid */
2223 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2224 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2225 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2228 LOCK_REQ *pSMB = NULL;
2233 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2234 num_lock, num_unlock);
2236 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2241 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2242 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2243 pSMB->LockType = lock_type;
2244 pSMB->AndXCommand = 0xFF; /* none */
2245 pSMB->Fid = netfid; /* netfid stays le */
2247 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2248 inc_rfc1001_len(pSMB, count);
2249 pSMB->ByteCount = cpu_to_le16(count);
2251 iov[0].iov_base = (char *)pSMB;
2252 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2253 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2254 iov[1].iov_base = (char *)buf;
2255 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2257 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2258 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
2260 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2266 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2267 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2268 const __u64 offset, const __u32 numUnlock,
2269 const __u32 numLock, const __u8 lockType,
2270 const bool waitFlag, const __u8 oplock_level)
2273 LOCK_REQ *pSMB = NULL;
2274 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2279 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2280 (int)waitFlag, numLock);
2281 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2286 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2287 /* no response expected */
2288 flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP;
2290 } else if (waitFlag) {
2291 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2292 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2297 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2298 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2299 pSMB->LockType = lockType;
2300 pSMB->OplockLevel = oplock_level;
2301 pSMB->AndXCommand = 0xFF; /* none */
2302 pSMB->Fid = smb_file_id; /* netfid stays le */
2304 if ((numLock != 0) || (numUnlock != 0)) {
2305 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2306 /* BB where to store pid high? */
2307 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2308 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2309 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2310 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2311 count = sizeof(LOCKING_ANDX_RANGE);
2316 inc_rfc1001_len(pSMB, count);
2317 pSMB->ByteCount = cpu_to_le16(count);
2320 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2321 (struct smb_hdr *) pSMB, &bytes_returned);
2322 cifs_small_buf_release(pSMB);
2324 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2325 /* SMB buffer freed by function above */
2327 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2329 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2331 /* Note: On -EAGAIN error only caller can retry on handle based calls
2332 since file handle passed in no longer valid */
2337 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2338 const __u16 smb_file_id, const __u32 netpid,
2339 const loff_t start_offset, const __u64 len,
2340 struct file_lock *pLockData, const __u16 lock_type,
2341 const bool waitFlag)
2343 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2344 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2345 struct cifs_posix_lock *parm_data;
2348 int bytes_returned = 0;
2349 int resp_buf_type = 0;
2350 __u16 params, param_offset, offset, byte_count, count;
2353 cifs_dbg(FYI, "Posix Lock\n");
2355 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2360 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2363 pSMB->MaxSetupCount = 0;
2366 pSMB->Reserved2 = 0;
2367 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2368 offset = param_offset + params;
2370 count = sizeof(struct cifs_posix_lock);
2371 pSMB->MaxParameterCount = cpu_to_le16(2);
2372 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2373 pSMB->SetupCount = 1;
2374 pSMB->Reserved3 = 0;
2376 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2378 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2379 byte_count = 3 /* pad */ + params + count;
2380 pSMB->DataCount = cpu_to_le16(count);
2381 pSMB->ParameterCount = cpu_to_le16(params);
2382 pSMB->TotalDataCount = pSMB->DataCount;
2383 pSMB->TotalParameterCount = pSMB->ParameterCount;
2384 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2385 parm_data = (struct cifs_posix_lock *)
2386 (((char *) &pSMB->hdr.Protocol) + offset);
2388 parm_data->lock_type = cpu_to_le16(lock_type);
2390 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2391 parm_data->lock_flags = cpu_to_le16(1);
2392 pSMB->Timeout = cpu_to_le32(-1);
2396 parm_data->pid = cpu_to_le32(netpid);
2397 parm_data->start = cpu_to_le64(start_offset);
2398 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2400 pSMB->DataOffset = cpu_to_le16(offset);
2401 pSMB->Fid = smb_file_id;
2402 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2403 pSMB->Reserved4 = 0;
2404 inc_rfc1001_len(pSMB, byte_count);
2405 pSMB->ByteCount = cpu_to_le16(byte_count);
2407 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2408 (struct smb_hdr *) pSMBr, &bytes_returned);
2410 iov[0].iov_base = (char *)pSMB;
2411 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2412 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2413 &resp_buf_type, timeout);
2414 pSMB = NULL; /* request buf already freed by SendReceive2. Do
2415 not try to free it twice below on exit */
2416 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
2420 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2421 } else if (pLockData) {
2422 /* lock structure can be returned on get */
2425 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2427 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2428 rc = -EIO; /* bad smb */
2431 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2432 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2433 if (data_count < sizeof(struct cifs_posix_lock)) {
2437 parm_data = (struct cifs_posix_lock *)
2438 ((char *)&pSMBr->hdr.Protocol + data_offset);
2439 if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
2440 pLockData->fl_type = F_UNLCK;
2442 if (parm_data->lock_type ==
2443 __constant_cpu_to_le16(CIFS_RDLCK))
2444 pLockData->fl_type = F_RDLCK;
2445 else if (parm_data->lock_type ==
2446 __constant_cpu_to_le16(CIFS_WRLCK))
2447 pLockData->fl_type = F_WRLCK;
2449 pLockData->fl_start = le64_to_cpu(parm_data->start);
2450 pLockData->fl_end = pLockData->fl_start +
2451 le64_to_cpu(parm_data->length) - 1;
2452 pLockData->fl_pid = le32_to_cpu(parm_data->pid);
2458 cifs_small_buf_release(pSMB);
2460 if (resp_buf_type == CIFS_SMALL_BUFFER)
2461 cifs_small_buf_release(iov[0].iov_base);
2462 else if (resp_buf_type == CIFS_LARGE_BUFFER)
2463 cifs_buf_release(iov[0].iov_base);
2465 /* Note: On -EAGAIN error only caller can retry on handle based calls
2466 since file handle passed in no longer valid */
2473 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2476 CLOSE_REQ *pSMB = NULL;
2477 cifs_dbg(FYI, "In CIFSSMBClose\n");
2479 /* do not retry on dead session on close */
2480 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2486 pSMB->FileID = (__u16) smb_file_id;
2487 pSMB->LastWriteTime = 0xFFFFFFFF;
2488 pSMB->ByteCount = 0;
2489 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2490 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2493 /* EINTR is expected when user ctl-c to kill app */
2494 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2498 /* Since session is dead, file will be closed on server already */
2506 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2509 FLUSH_REQ *pSMB = NULL;
2510 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2512 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2516 pSMB->FileID = (__u16) smb_file_id;
2517 pSMB->ByteCount = 0;
2518 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2519 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2521 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2527 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2528 const char *from_name, const char *to_name,
2529 struct cifs_sb_info *cifs_sb)
2532 RENAME_REQ *pSMB = NULL;
2533 RENAME_RSP *pSMBr = NULL;
2535 int name_len, name_len2;
2537 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
2539 cifs_dbg(FYI, "In CIFSSMBRename\n");
2541 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2546 pSMB->BufferFormat = 0x04;
2547 pSMB->SearchAttributes =
2548 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2551 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2552 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2553 from_name, PATH_MAX,
2554 cifs_sb->local_nls, remap);
2555 name_len++; /* trailing null */
2557 pSMB->OldFileName[name_len] = 0x04; /* pad */
2558 /* protocol requires ASCII signature byte on Unicode string */
2559 pSMB->OldFileName[name_len + 1] = 0x00;
2561 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2562 to_name, PATH_MAX, cifs_sb->local_nls,
2564 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2565 name_len2 *= 2; /* convert to bytes */
2566 } else { /* BB improve the check for buffer overruns BB */
2567 name_len = strnlen(from_name, PATH_MAX);
2568 name_len++; /* trailing null */
2569 strncpy(pSMB->OldFileName, from_name, name_len);
2570 name_len2 = strnlen(to_name, PATH_MAX);
2571 name_len2++; /* trailing null */
2572 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2573 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
2574 name_len2++; /* trailing null */
2575 name_len2++; /* signature byte */
2578 count = 1 /* 1st signature byte */ + name_len + name_len2;
2579 inc_rfc1001_len(pSMB, count);
2580 pSMB->ByteCount = cpu_to_le16(count);
2582 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2583 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2584 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2586 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2588 cifs_buf_release(pSMB);
2596 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2597 int netfid, const char *target_name,
2598 const struct nls_table *nls_codepage, int remap)
2600 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2601 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2602 struct set_file_rename *rename_info;
2604 char dummy_string[30];
2606 int bytes_returned = 0;
2608 __u16 params, param_offset, offset, count, byte_count;
2610 cifs_dbg(FYI, "Rename to File by handle\n");
2611 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2617 pSMB->MaxSetupCount = 0;
2621 pSMB->Reserved2 = 0;
2622 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2623 offset = param_offset + params;
2625 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2626 rename_info = (struct set_file_rename *) data_offset;
2627 pSMB->MaxParameterCount = cpu_to_le16(2);
2628 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2629 pSMB->SetupCount = 1;
2630 pSMB->Reserved3 = 0;
2631 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2632 byte_count = 3 /* pad */ + params;
2633 pSMB->ParameterCount = cpu_to_le16(params);
2634 pSMB->TotalParameterCount = pSMB->ParameterCount;
2635 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2636 pSMB->DataOffset = cpu_to_le16(offset);
2637 /* construct random name ".cifs_tmp<inodenum><mid>" */
2638 rename_info->overwrite = cpu_to_le32(1);
2639 rename_info->root_fid = 0;
2640 /* unicode only call */
2641 if (target_name == NULL) {
2642 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2644 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2645 dummy_string, 24, nls_codepage, remap);
2648 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2649 target_name, PATH_MAX, nls_codepage,
2652 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2653 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2654 byte_count += count;
2655 pSMB->DataCount = cpu_to_le16(count);
2656 pSMB->TotalDataCount = pSMB->DataCount;
2658 pSMB->InformationLevel =
2659 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2660 pSMB->Reserved4 = 0;
2661 inc_rfc1001_len(pSMB, byte_count);
2662 pSMB->ByteCount = cpu_to_le16(byte_count);
2663 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2664 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2665 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2667 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2670 cifs_buf_release(pSMB);
2672 /* Note: On -EAGAIN error only caller can retry on handle based calls
2673 since file handle passed in no longer valid */
2679 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2680 const char *fromName, const __u16 target_tid, const char *toName,
2681 const int flags, const struct nls_table *nls_codepage, int remap)
2684 COPY_REQ *pSMB = NULL;
2685 COPY_RSP *pSMBr = NULL;
2687 int name_len, name_len2;
2690 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2692 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2697 pSMB->BufferFormat = 0x04;
2698 pSMB->Tid2 = target_tid;
2700 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2702 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2703 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2704 fromName, PATH_MAX, nls_codepage,
2706 name_len++; /* trailing null */
2708 pSMB->OldFileName[name_len] = 0x04; /* pad */
2709 /* protocol requires ASCII signature byte on Unicode string */
2710 pSMB->OldFileName[name_len + 1] = 0x00;
2712 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2713 toName, PATH_MAX, nls_codepage, remap);
2714 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2715 name_len2 *= 2; /* convert to bytes */
2716 } else { /* BB improve the check for buffer overruns BB */
2717 name_len = strnlen(fromName, PATH_MAX);
2718 name_len++; /* trailing null */
2719 strncpy(pSMB->OldFileName, fromName, name_len);
2720 name_len2 = strnlen(toName, PATH_MAX);
2721 name_len2++; /* trailing null */
2722 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2723 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2724 name_len2++; /* trailing null */
2725 name_len2++; /* signature byte */
2728 count = 1 /* 1st signature byte */ + name_len + name_len2;
2729 inc_rfc1001_len(pSMB, count);
2730 pSMB->ByteCount = cpu_to_le16(count);
2732 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2733 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2735 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2736 rc, le16_to_cpu(pSMBr->CopyCount));
2738 cifs_buf_release(pSMB);
2747 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2748 const char *fromName, const char *toName,
2749 const struct nls_table *nls_codepage)
2751 TRANSACTION2_SPI_REQ *pSMB = NULL;
2752 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2755 int name_len_target;
2757 int bytes_returned = 0;
2758 __u16 params, param_offset, offset, byte_count;
2760 cifs_dbg(FYI, "In Symlink Unix style\n");
2762 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2767 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2769 cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName,
2770 /* find define for this maxpathcomponent */
2771 PATH_MAX, nls_codepage);
2772 name_len++; /* trailing null */
2775 } else { /* BB improve the check for buffer overruns BB */
2776 name_len = strnlen(fromName, PATH_MAX);
2777 name_len++; /* trailing null */
2778 strncpy(pSMB->FileName, fromName, name_len);
2780 params = 6 + name_len;
2781 pSMB->MaxSetupCount = 0;
2785 pSMB->Reserved2 = 0;
2786 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2787 InformationLevel) - 4;
2788 offset = param_offset + params;
2790 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2791 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2793 cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX
2794 /* find define for this maxpathcomponent */
2796 name_len_target++; /* trailing null */
2797 name_len_target *= 2;
2798 } else { /* BB improve the check for buffer overruns BB */
2799 name_len_target = strnlen(toName, PATH_MAX);
2800 name_len_target++; /* trailing null */
2801 strncpy(data_offset, toName, name_len_target);
2804 pSMB->MaxParameterCount = cpu_to_le16(2);
2805 /* BB find exact max on data count below from sess */
2806 pSMB->MaxDataCount = cpu_to_le16(1000);
2807 pSMB->SetupCount = 1;
2808 pSMB->Reserved3 = 0;
2809 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2810 byte_count = 3 /* pad */ + params + name_len_target;
2811 pSMB->DataCount = cpu_to_le16(name_len_target);
2812 pSMB->ParameterCount = cpu_to_le16(params);
2813 pSMB->TotalDataCount = pSMB->DataCount;
2814 pSMB->TotalParameterCount = pSMB->ParameterCount;
2815 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2816 pSMB->DataOffset = cpu_to_le16(offset);
2817 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2818 pSMB->Reserved4 = 0;
2819 inc_rfc1001_len(pSMB, byte_count);
2820 pSMB->ByteCount = cpu_to_le16(byte_count);
2821 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2822 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2823 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2825 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2828 cifs_buf_release(pSMB);
2831 goto createSymLinkRetry;
2837 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2838 const char *fromName, const char *toName,
2839 const struct nls_table *nls_codepage, int remap)
2841 TRANSACTION2_SPI_REQ *pSMB = NULL;
2842 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2845 int name_len_target;
2847 int bytes_returned = 0;
2848 __u16 params, param_offset, offset, byte_count;
2850 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2851 createHardLinkRetry:
2852 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2857 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2858 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2859 PATH_MAX, nls_codepage, remap);
2860 name_len++; /* trailing null */
2863 } else { /* BB improve the check for buffer overruns BB */
2864 name_len = strnlen(toName, PATH_MAX);
2865 name_len++; /* trailing null */
2866 strncpy(pSMB->FileName, toName, name_len);
2868 params = 6 + name_len;
2869 pSMB->MaxSetupCount = 0;
2873 pSMB->Reserved2 = 0;
2874 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2875 InformationLevel) - 4;
2876 offset = param_offset + params;
2878 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2879 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2881 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2882 PATH_MAX, nls_codepage, remap);
2883 name_len_target++; /* trailing null */
2884 name_len_target *= 2;
2885 } else { /* BB improve the check for buffer overruns BB */
2886 name_len_target = strnlen(fromName, PATH_MAX);
2887 name_len_target++; /* trailing null */
2888 strncpy(data_offset, fromName, name_len_target);
2891 pSMB->MaxParameterCount = cpu_to_le16(2);
2892 /* BB find exact max on data count below from sess*/
2893 pSMB->MaxDataCount = cpu_to_le16(1000);
2894 pSMB->SetupCount = 1;
2895 pSMB->Reserved3 = 0;
2896 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2897 byte_count = 3 /* pad */ + params + name_len_target;
2898 pSMB->ParameterCount = cpu_to_le16(params);
2899 pSMB->TotalParameterCount = pSMB->ParameterCount;
2900 pSMB->DataCount = cpu_to_le16(name_len_target);
2901 pSMB->TotalDataCount = pSMB->DataCount;
2902 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2903 pSMB->DataOffset = cpu_to_le16(offset);
2904 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2905 pSMB->Reserved4 = 0;
2906 inc_rfc1001_len(pSMB, byte_count);
2907 pSMB->ByteCount = cpu_to_le16(byte_count);
2908 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2909 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2910 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2912 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2915 cifs_buf_release(pSMB);
2917 goto createHardLinkRetry;
2923 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2924 const char *from_name, const char *to_name,
2925 struct cifs_sb_info *cifs_sb)
2928 NT_RENAME_REQ *pSMB = NULL;
2929 RENAME_RSP *pSMBr = NULL;
2931 int name_len, name_len2;
2933 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
2935 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2936 winCreateHardLinkRetry:
2938 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2943 pSMB->SearchAttributes =
2944 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2946 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2947 pSMB->ClusterCount = 0;
2949 pSMB->BufferFormat = 0x04;
2951 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2953 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2954 PATH_MAX, cifs_sb->local_nls, remap);
2955 name_len++; /* trailing null */
2958 /* protocol specifies ASCII buffer format (0x04) for unicode */
2959 pSMB->OldFileName[name_len] = 0x04;
2960 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2962 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2963 to_name, PATH_MAX, cifs_sb->local_nls,
2965 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2966 name_len2 *= 2; /* convert to bytes */
2967 } else { /* BB improve the check for buffer overruns BB */
2968 name_len = strnlen(from_name, PATH_MAX);
2969 name_len++; /* trailing null */
2970 strncpy(pSMB->OldFileName, from_name, name_len);
2971 name_len2 = strnlen(to_name, PATH_MAX);
2972 name_len2++; /* trailing null */
2973 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2974 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
2975 name_len2++; /* trailing null */
2976 name_len2++; /* signature byte */
2979 count = 1 /* string type byte */ + name_len + name_len2;
2980 inc_rfc1001_len(pSMB, count);
2981 pSMB->ByteCount = cpu_to_le16(count);
2983 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2984 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2985 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2987 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2989 cifs_buf_release(pSMB);
2991 goto winCreateHardLinkRetry;
2997 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2998 const unsigned char *searchName, char **symlinkinfo,
2999 const struct nls_table *nls_codepage)
3001 /* SMB_QUERY_FILE_UNIX_LINK */
3002 TRANSACTION2_QPI_REQ *pSMB = NULL;
3003 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3007 __u16 params, byte_count;
3010 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3013 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3018 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3020 cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName,
3021 PATH_MAX, nls_codepage);
3022 name_len++; /* trailing null */
3024 } else { /* BB improve the check for buffer overruns BB */
3025 name_len = strnlen(searchName, PATH_MAX);
3026 name_len++; /* trailing null */
3027 strncpy(pSMB->FileName, searchName, name_len);
3030 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3031 pSMB->TotalDataCount = 0;
3032 pSMB->MaxParameterCount = cpu_to_le16(2);
3033 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3034 pSMB->MaxSetupCount = 0;
3038 pSMB->Reserved2 = 0;
3039 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3040 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3041 pSMB->DataCount = 0;
3042 pSMB->DataOffset = 0;
3043 pSMB->SetupCount = 1;
3044 pSMB->Reserved3 = 0;
3045 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3046 byte_count = params + 1 /* pad */ ;
3047 pSMB->TotalParameterCount = cpu_to_le16(params);
3048 pSMB->ParameterCount = pSMB->TotalParameterCount;
3049 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3050 pSMB->Reserved4 = 0;
3051 inc_rfc1001_len(pSMB, byte_count);
3052 pSMB->ByteCount = cpu_to_le16(byte_count);
3054 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3055 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3057 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3059 /* decode response */
3061 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3062 /* BB also check enough total bytes returned */
3063 if (rc || get_bcc(&pSMBr->hdr) < 2)
3067 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3069 data_start = ((char *) &pSMBr->hdr.Protocol) +
3070 le16_to_cpu(pSMBr->t2.DataOffset);
3072 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3077 /* BB FIXME investigate remapping reserved chars here */
3078 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3079 count, is_unicode, nls_codepage);
3084 cifs_buf_release(pSMB);
3086 goto querySymLinkRetry;
3090 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3092 * Recent Windows versions now create symlinks more frequently
3093 * and they use the "reparse point" mechanism below. We can of course
3094 * do symlinks nicely to Samba and other servers which support the
3095 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3096 * "MF" symlinks optionally, but for recent Windows we really need to
3097 * reenable the code below and fix the cifs_symlink callers to handle this.
3098 * In the interim this code has been moved to its own config option so
3099 * it is not compiled in by default until callers fixed up and more tested.
3102 CIFSSMBQueryReparseLinkInfo(const unsigned int xid, struct cifs_tcon *tcon,
3103 const unsigned char *searchName,
3104 char *symlinkinfo, const int buflen, __u16 fid,
3105 const struct nls_table *nls_codepage)
3109 struct smb_com_transaction_ioctl_req *pSMB;
3110 struct smb_com_transaction_ioctl_rsp *pSMBr;
3112 cifs_dbg(FYI, "In Windows reparse style QueryLink for path %s\n",
3114 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3119 pSMB->TotalParameterCount = 0 ;
3120 pSMB->TotalDataCount = 0;
3121 pSMB->MaxParameterCount = cpu_to_le32(2);
3122 /* BB find exact data count max from sess structure BB */
3123 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3124 pSMB->MaxSetupCount = 4;
3126 pSMB->ParameterOffset = 0;
3127 pSMB->DataCount = 0;
3128 pSMB->DataOffset = 0;
3129 pSMB->SetupCount = 4;
3130 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3131 pSMB->ParameterCount = pSMB->TotalParameterCount;
3132 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3133 pSMB->IsFsctl = 1; /* FSCTL */
3134 pSMB->IsRootFlag = 0;
3135 pSMB->Fid = fid; /* file handle always le */
3136 pSMB->ByteCount = 0;
3138 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3139 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3141 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3142 } else { /* decode response */
3143 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
3144 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
3145 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3146 /* BB also check enough total bytes returned */
3147 rc = -EIO; /* bad smb */
3150 if (data_count && (data_count < 2048)) {
3151 char *end_of_smb = 2 /* sizeof byte count */ +
3152 get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3154 struct reparse_data *reparse_buf =
3155 (struct reparse_data *)
3156 ((char *)&pSMBr->hdr.Protocol
3158 if ((char *)reparse_buf >= end_of_smb) {
3162 if ((reparse_buf->LinkNamesBuf +
3163 reparse_buf->TargetNameOffset +
3164 reparse_buf->TargetNameLen) > end_of_smb) {
3165 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3170 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3171 cifs_from_ucs2(symlinkinfo, (__le16 *)
3172 (reparse_buf->LinkNamesBuf +
3173 reparse_buf->TargetNameOffset),
3175 reparse_buf->TargetNameLen,
3177 } else { /* ASCII names */
3178 strncpy(symlinkinfo,
3179 reparse_buf->LinkNamesBuf +
3180 reparse_buf->TargetNameOffset,
3181 min_t(const int, buflen,
3182 reparse_buf->TargetNameLen));
3186 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3188 symlinkinfo[buflen] = 0; /* just in case so the caller
3189 does not go off the end of the buffer */
3190 cifs_dbg(FYI, "readlink result - %s\n", symlinkinfo);
3194 cifs_buf_release(pSMB);
3196 /* Note: On -EAGAIN error only caller can retry on handle based calls
3197 since file handle passed in no longer valid */
3201 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3203 #ifdef CONFIG_CIFS_POSIX
3205 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3206 static void cifs_convert_ace(posix_acl_xattr_entry *ace,
3207 struct cifs_posix_ace *cifs_ace)
3209 /* u8 cifs fields do not need le conversion */
3210 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3211 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3212 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3214 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3215 ace->e_perm, ace->e_tag, ace->e_id);
3221 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3222 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3223 const int acl_type, const int size_of_data_area)
3228 struct cifs_posix_ace *pACE;
3229 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3230 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
3232 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3235 if (acl_type & ACL_TYPE_ACCESS) {
3236 count = le16_to_cpu(cifs_acl->access_entry_count);
3237 pACE = &cifs_acl->ace_array[0];
3238 size = sizeof(struct cifs_posix_acl);
3239 size += sizeof(struct cifs_posix_ace) * count;
3240 /* check if we would go beyond end of SMB */
3241 if (size_of_data_area < size) {
3242 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3243 size_of_data_area, size);
3246 } else if (acl_type & ACL_TYPE_DEFAULT) {
3247 count = le16_to_cpu(cifs_acl->access_entry_count);
3248 size = sizeof(struct cifs_posix_acl);
3249 size += sizeof(struct cifs_posix_ace) * count;
3250 /* skip past access ACEs to get to default ACEs */
3251 pACE = &cifs_acl->ace_array[count];
3252 count = le16_to_cpu(cifs_acl->default_entry_count);
3253 size += sizeof(struct cifs_posix_ace) * count;
3254 /* check if we would go beyond end of SMB */
3255 if (size_of_data_area < size)
3262 size = posix_acl_xattr_size(count);
3263 if ((buflen == 0) || (local_acl == NULL)) {
3264 /* used to query ACL EA size */
3265 } else if (size > buflen) {
3267 } else /* buffer big enough */ {
3268 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3269 for (i = 0; i < count ; i++) {
3270 cifs_convert_ace(&local_acl->a_entries[i], pACE);
3277 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3278 const posix_acl_xattr_entry *local_ace)
3280 __u16 rc = 0; /* 0 = ACL converted ok */
3282 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3283 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3284 /* BB is there a better way to handle the large uid? */
3285 if (local_ace->e_id == cpu_to_le32(-1)) {
3286 /* Probably no need to le convert -1 on any arch but can not hurt */
3287 cifs_ace->cifs_uid = cpu_to_le64(-1);
3289 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3291 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3292 ace->e_perm, ace->e_tag, ace->e_id);
3297 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3298 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3299 const int buflen, const int acl_type)
3302 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3303 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
3307 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3310 count = posix_acl_xattr_count((size_t)buflen);
3311 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3312 count, buflen, le32_to_cpu(local_acl->a_version));
3313 if (le32_to_cpu(local_acl->a_version) != 2) {
3314 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3315 le32_to_cpu(local_acl->a_version));
3318 cifs_acl->version = cpu_to_le16(1);
3319 if (acl_type == ACL_TYPE_ACCESS)
3320 cifs_acl->access_entry_count = cpu_to_le16(count);
3321 else if (acl_type == ACL_TYPE_DEFAULT)
3322 cifs_acl->default_entry_count = cpu_to_le16(count);
3324 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3327 for (i = 0; i < count; i++) {
3328 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3329 &local_acl->a_entries[i]);
3331 /* ACE not converted */
3336 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3337 rc += sizeof(struct cifs_posix_acl);
3338 /* BB add check to make sure ACL does not overflow SMB */
3344 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3345 const unsigned char *searchName,
3346 char *acl_inf, const int buflen, const int acl_type,
3347 const struct nls_table *nls_codepage, int remap)
3349 /* SMB_QUERY_POSIX_ACL */
3350 TRANSACTION2_QPI_REQ *pSMB = NULL;
3351 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3355 __u16 params, byte_count;
3357 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3360 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3365 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3367 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3368 searchName, PATH_MAX, nls_codepage,
3370 name_len++; /* trailing null */
3372 pSMB->FileName[name_len] = 0;
3373 pSMB->FileName[name_len+1] = 0;
3374 } else { /* BB improve the check for buffer overruns BB */
3375 name_len = strnlen(searchName, PATH_MAX);
3376 name_len++; /* trailing null */
3377 strncpy(pSMB->FileName, searchName, name_len);
3380 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3381 pSMB->TotalDataCount = 0;
3382 pSMB->MaxParameterCount = cpu_to_le16(2);
3383 /* BB find exact max data count below from sess structure BB */
3384 pSMB->MaxDataCount = cpu_to_le16(4000);
3385 pSMB->MaxSetupCount = 0;
3389 pSMB->Reserved2 = 0;
3390 pSMB->ParameterOffset = cpu_to_le16(
3391 offsetof(struct smb_com_transaction2_qpi_req,
3392 InformationLevel) - 4);
3393 pSMB->DataCount = 0;
3394 pSMB->DataOffset = 0;
3395 pSMB->SetupCount = 1;
3396 pSMB->Reserved3 = 0;
3397 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3398 byte_count = params + 1 /* pad */ ;
3399 pSMB->TotalParameterCount = cpu_to_le16(params);
3400 pSMB->ParameterCount = pSMB->TotalParameterCount;
3401 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3402 pSMB->Reserved4 = 0;
3403 inc_rfc1001_len(pSMB, byte_count);
3404 pSMB->ByteCount = cpu_to_le16(byte_count);
3406 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3407 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3408 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3410 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3412 /* decode response */
3414 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3415 /* BB also check enough total bytes returned */
3416 if (rc || get_bcc(&pSMBr->hdr) < 2)
3417 rc = -EIO; /* bad smb */
3419 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3420 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3421 rc = cifs_copy_posix_acl(acl_inf,
3422 (char *)&pSMBr->hdr.Protocol+data_offset,
3423 buflen, acl_type, count);
3426 cifs_buf_release(pSMB);
3433 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3434 const unsigned char *fileName,
3435 const char *local_acl, const int buflen,
3437 const struct nls_table *nls_codepage, int remap)
3439 struct smb_com_transaction2_spi_req *pSMB = NULL;
3440 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3444 int bytes_returned = 0;
3445 __u16 params, byte_count, data_count, param_offset, offset;
3447 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3449 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3453 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3455 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3456 PATH_MAX, nls_codepage, remap);
3457 name_len++; /* trailing null */
3459 } else { /* BB improve the check for buffer overruns BB */
3460 name_len = strnlen(fileName, PATH_MAX);
3461 name_len++; /* trailing null */
3462 strncpy(pSMB->FileName, fileName, name_len);
3464 params = 6 + name_len;
3465 pSMB->MaxParameterCount = cpu_to_le16(2);
3466 /* BB find max SMB size from sess */
3467 pSMB->MaxDataCount = cpu_to_le16(1000);
3468 pSMB->MaxSetupCount = 0;
3472 pSMB->Reserved2 = 0;
3473 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3474 InformationLevel) - 4;
3475 offset = param_offset + params;
3476 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3477 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3479 /* convert to on the wire format for POSIX ACL */
3480 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3482 if (data_count == 0) {
3484 goto setACLerrorExit;
3486 pSMB->DataOffset = cpu_to_le16(offset);
3487 pSMB->SetupCount = 1;
3488 pSMB->Reserved3 = 0;
3489 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3490 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3491 byte_count = 3 /* pad */ + params + data_count;
3492 pSMB->DataCount = cpu_to_le16(data_count);
3493 pSMB->TotalDataCount = pSMB->DataCount;
3494 pSMB->ParameterCount = cpu_to_le16(params);
3495 pSMB->TotalParameterCount = pSMB->ParameterCount;
3496 pSMB->Reserved4 = 0;
3497 inc_rfc1001_len(pSMB, byte_count);
3498 pSMB->ByteCount = cpu_to_le16(byte_count);
3499 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3500 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3502 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3505 cifs_buf_release(pSMB);
3511 /* BB fix tabs in this function FIXME BB */
3513 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3514 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3517 struct smb_t2_qfi_req *pSMB = NULL;
3518 struct smb_t2_qfi_rsp *pSMBr = NULL;
3520 __u16 params, byte_count;
3522 cifs_dbg(FYI, "In GetExtAttr\n");
3527 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3532 params = 2 /* level */ + 2 /* fid */;
3533 pSMB->t2.TotalDataCount = 0;
3534 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3535 /* BB find exact max data count below from sess structure BB */
3536 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3537 pSMB->t2.MaxSetupCount = 0;
3538 pSMB->t2.Reserved = 0;
3540 pSMB->t2.Timeout = 0;
3541 pSMB->t2.Reserved2 = 0;
3542 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3544 pSMB->t2.DataCount = 0;
3545 pSMB->t2.DataOffset = 0;
3546 pSMB->t2.SetupCount = 1;
3547 pSMB->t2.Reserved3 = 0;
3548 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3549 byte_count = params + 1 /* pad */ ;
3550 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3551 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3552 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3555 inc_rfc1001_len(pSMB, byte_count);
3556 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3558 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3559 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3561 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3563 /* decode response */
3564 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3565 /* BB also check enough total bytes returned */
3566 if (rc || get_bcc(&pSMBr->hdr) < 2)
3567 /* If rc should we check for EOPNOSUPP and
3568 disable the srvino flag? or in caller? */
3569 rc = -EIO; /* bad smb */
3571 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3572 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3573 struct file_chattr_info *pfinfo;
3574 /* BB Do we need a cast or hash here ? */
3576 cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n");
3580 pfinfo = (struct file_chattr_info *)
3581 (data_offset + (char *) &pSMBr->hdr.Protocol);
3582 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3583 *pMask = le64_to_cpu(pfinfo->mask);
3587 cifs_buf_release(pSMB);
3589 goto GetExtAttrRetry;
3593 #endif /* CONFIG_POSIX */
3595 #ifdef CONFIG_CIFS_ACL
3597 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3598 * all NT TRANSACTS that we init here have total parm and data under about 400
3599 * bytes (to fit in small cifs buffer size), which is the case so far, it
3600 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3601 * returned setup area) and MaxParameterCount (returned parms size) must be set
3605 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3606 const int parm_len, struct cifs_tcon *tcon,
3611 struct smb_com_ntransact_req *pSMB;
3613 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3617 *ret_buf = (void *)pSMB;
3619 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3620 pSMB->TotalDataCount = 0;
3621 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3622 pSMB->ParameterCount = pSMB->TotalParameterCount;
3623 pSMB->DataCount = pSMB->TotalDataCount;
3624 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3625 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3626 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3627 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3628 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3629 pSMB->SubCommand = cpu_to_le16(sub_command);
3634 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3635 __u32 *pparmlen, __u32 *pdatalen)
3638 __u32 data_count, data_offset, parm_count, parm_offset;
3639 struct smb_com_ntransact_rsp *pSMBr;
3648 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3650 bcc = get_bcc(&pSMBr->hdr);
3651 end_of_smb = 2 /* sizeof byte count */ + bcc +
3652 (char *)&pSMBr->ByteCount;
3654 data_offset = le32_to_cpu(pSMBr->DataOffset);
3655 data_count = le32_to_cpu(pSMBr->DataCount);
3656 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3657 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3659 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3660 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3662 /* should we also check that parm and data areas do not overlap? */
3663 if (*ppparm > end_of_smb) {
3664 cifs_dbg(FYI, "parms start after end of smb\n");
3666 } else if (parm_count + *ppparm > end_of_smb) {
3667 cifs_dbg(FYI, "parm end after end of smb\n");
3669 } else if (*ppdata > end_of_smb) {
3670 cifs_dbg(FYI, "data starts after end of smb\n");
3672 } else if (data_count + *ppdata > end_of_smb) {
3673 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3674 *ppdata, data_count, (data_count + *ppdata),
3677 } else if (parm_count + data_count > bcc) {
3678 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3681 *pdatalen = data_count;
3682 *pparmlen = parm_count;
3686 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3688 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3689 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3693 QUERY_SEC_DESC_REQ *pSMB;
3696 cifs_dbg(FYI, "GetCifsACL\n");
3701 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3702 8 /* parm len */, tcon, (void **) &pSMB);
3706 pSMB->MaxParameterCount = cpu_to_le32(4);
3707 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3708 pSMB->MaxSetupCount = 0;
3709 pSMB->Fid = fid; /* file handle always le */
3710 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3712 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3713 inc_rfc1001_len(pSMB, 11);
3714 iov[0].iov_base = (char *)pSMB;
3715 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3717 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3719 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3721 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3722 } else { /* decode response */
3726 struct smb_com_ntransact_rsp *pSMBr;
3729 /* validate_nttransact */
3730 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3731 &pdata, &parm_len, pbuflen);
3734 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3736 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3737 pSMBr, parm, *acl_inf);
3739 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3740 rc = -EIO; /* bad smb */
3745 /* BB check that data area is minimum length and as big as acl_len */
3747 acl_len = le32_to_cpu(*parm);
3748 if (acl_len != *pbuflen) {
3749 cifs_dbg(VFS, "acl length %d does not match %d\n",
3751 if (*pbuflen > acl_len)
3755 /* check if buffer is big enough for the acl
3756 header followed by the smallest SID */
3757 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3758 (*pbuflen >= 64 * 1024)) {
3759 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3763 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3764 if (*acl_inf == NULL) {
3771 if (buf_type == CIFS_SMALL_BUFFER)
3772 cifs_small_buf_release(iov[0].iov_base);
3773 else if (buf_type == CIFS_LARGE_BUFFER)
3774 cifs_buf_release(iov[0].iov_base);
3775 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3780 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3781 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3783 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3785 int bytes_returned = 0;
3786 SET_SEC_DESC_REQ *pSMB = NULL;
3790 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3794 pSMB->MaxSetupCount = 0;
3798 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3799 data_count = acllen;
3800 data_offset = param_offset + param_count;
3801 byte_count = 3 /* pad */ + param_count;
3803 pSMB->DataCount = cpu_to_le32(data_count);
3804 pSMB->TotalDataCount = pSMB->DataCount;
3805 pSMB->MaxParameterCount = cpu_to_le32(4);
3806 pSMB->MaxDataCount = cpu_to_le32(16384);
3807 pSMB->ParameterCount = cpu_to_le32(param_count);
3808 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3809 pSMB->TotalParameterCount = pSMB->ParameterCount;
3810 pSMB->DataOffset = cpu_to_le32(data_offset);
3811 pSMB->SetupCount = 0;
3812 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3813 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3815 pSMB->Fid = fid; /* file handle always le */
3816 pSMB->Reserved2 = 0;
3817 pSMB->AclFlags = cpu_to_le32(aclflag);
3819 if (pntsd && acllen) {
3820 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3821 data_offset, pntsd, acllen);
3822 inc_rfc1001_len(pSMB, byte_count + data_count);
3824 inc_rfc1001_len(pSMB, byte_count);
3826 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3827 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3829 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3830 bytes_returned, rc);
3832 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3833 cifs_buf_release(pSMB);
3836 goto setCifsAclRetry;
3841 #endif /* CONFIG_CIFS_ACL */
3843 /* Legacy Query Path Information call for lookup to old servers such
3846 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3847 const char *search_name, FILE_ALL_INFO *data,
3848 const struct nls_table *nls_codepage, int remap)
3850 QUERY_INFORMATION_REQ *pSMB;
3851 QUERY_INFORMATION_RSP *pSMBr;
3856 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3858 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3863 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3865 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3866 search_name, PATH_MAX, nls_codepage,
3868 name_len++; /* trailing null */
3871 name_len = strnlen(search_name, PATH_MAX);
3872 name_len++; /* trailing null */
3873 strncpy(pSMB->FileName, search_name, name_len);
3875 pSMB->BufferFormat = 0x04;
3876 name_len++; /* account for buffer type byte */
3877 inc_rfc1001_len(pSMB, (__u16)name_len);
3878 pSMB->ByteCount = cpu_to_le16(name_len);
3880 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3881 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3883 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3886 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3888 /* decode response */
3889 /* BB FIXME - add time zone adjustment BB */
3890 memset(data, 0, sizeof(FILE_ALL_INFO));
3893 /* decode time fields */
3894 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3895 data->LastWriteTime = data->ChangeTime;
3896 data->LastAccessTime = 0;
3897 data->AllocationSize =
3898 cpu_to_le64(le32_to_cpu(pSMBr->size));
3899 data->EndOfFile = data->AllocationSize;
3901 cpu_to_le32(le16_to_cpu(pSMBr->attr));
3903 rc = -EIO; /* bad buffer passed in */
3905 cifs_buf_release(pSMB);
3914 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3915 u16 netfid, FILE_ALL_INFO *pFindData)
3917 struct smb_t2_qfi_req *pSMB = NULL;
3918 struct smb_t2_qfi_rsp *pSMBr = NULL;
3921 __u16 params, byte_count;
3924 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3929 params = 2 /* level */ + 2 /* fid */;
3930 pSMB->t2.TotalDataCount = 0;
3931 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3932 /* BB find exact max data count below from sess structure BB */
3933 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3934 pSMB->t2.MaxSetupCount = 0;
3935 pSMB->t2.Reserved = 0;
3937 pSMB->t2.Timeout = 0;
3938 pSMB->t2.Reserved2 = 0;
3939 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3941 pSMB->t2.DataCount = 0;
3942 pSMB->t2.DataOffset = 0;
3943 pSMB->t2.SetupCount = 1;
3944 pSMB->t2.Reserved3 = 0;
3945 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3946 byte_count = params + 1 /* pad */ ;
3947 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3948 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3949 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3952 inc_rfc1001_len(pSMB, byte_count);
3954 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3955 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3957 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3958 } else { /* decode response */
3959 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3961 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3963 else if (get_bcc(&pSMBr->hdr) < 40)
3964 rc = -EIO; /* bad smb */
3965 else if (pFindData) {
3966 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3967 memcpy((char *) pFindData,
3968 (char *) &pSMBr->hdr.Protocol +
3969 data_offset, sizeof(FILE_ALL_INFO));
3973 cifs_buf_release(pSMB);
3975 goto QFileInfoRetry;
3981 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3982 const char *search_name, FILE_ALL_INFO *data,
3983 int legacy /* old style infolevel */,
3984 const struct nls_table *nls_codepage, int remap)
3986 /* level 263 SMB_QUERY_FILE_ALL_INFO */
3987 TRANSACTION2_QPI_REQ *pSMB = NULL;
3988 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3992 __u16 params, byte_count;
3994 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3996 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4001 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4003 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4004 PATH_MAX, nls_codepage, remap);
4005 name_len++; /* trailing null */
4007 } else { /* BB improve the check for buffer overruns BB */
4008 name_len = strnlen(search_name, PATH_MAX);
4009 name_len++; /* trailing null */
4010 strncpy(pSMB->FileName, search_name, name_len);
4013 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4014 pSMB->TotalDataCount = 0;
4015 pSMB->MaxParameterCount = cpu_to_le16(2);
4016 /* BB find exact max SMB PDU from sess structure BB */
4017 pSMB->MaxDataCount = cpu_to_le16(4000);
4018 pSMB->MaxSetupCount = 0;
4022 pSMB->Reserved2 = 0;
4023 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4024 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4025 pSMB->DataCount = 0;
4026 pSMB->DataOffset = 0;
4027 pSMB->SetupCount = 1;
4028 pSMB->Reserved3 = 0;
4029 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4030 byte_count = params + 1 /* pad */ ;
4031 pSMB->TotalParameterCount = cpu_to_le16(params);
4032 pSMB->ParameterCount = pSMB->TotalParameterCount;
4034 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4036 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4037 pSMB->Reserved4 = 0;
4038 inc_rfc1001_len(pSMB, byte_count);
4039 pSMB->ByteCount = cpu_to_le16(byte_count);
4041 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4042 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4044 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4045 } else { /* decode response */
4046 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4048 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4050 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4051 rc = -EIO; /* bad smb */
4052 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4053 rc = -EIO; /* 24 or 26 expected but we do not read
4057 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4060 * On legacy responses we do not read the last field,
4061 * EAsize, fortunately since it varies by subdialect and
4062 * also note it differs on Set vs Get, ie two bytes or 4
4063 * bytes depending but we don't care here.
4066 size = sizeof(FILE_INFO_STANDARD);
4068 size = sizeof(FILE_ALL_INFO);
4069 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4074 cifs_buf_release(pSMB);
4076 goto QPathInfoRetry;
4082 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4083 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4085 struct smb_t2_qfi_req *pSMB = NULL;
4086 struct smb_t2_qfi_rsp *pSMBr = NULL;
4089 __u16 params, byte_count;
4092 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4097 params = 2 /* level */ + 2 /* fid */;
4098 pSMB->t2.TotalDataCount = 0;
4099 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4100 /* BB find exact max data count below from sess structure BB */
4101 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4102 pSMB->t2.MaxSetupCount = 0;
4103 pSMB->t2.Reserved = 0;
4105 pSMB->t2.Timeout = 0;
4106 pSMB->t2.Reserved2 = 0;
4107 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4109 pSMB->t2.DataCount = 0;
4110 pSMB->t2.DataOffset = 0;
4111 pSMB->t2.SetupCount = 1;
4112 pSMB->t2.Reserved3 = 0;
4113 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4114 byte_count = params + 1 /* pad */ ;
4115 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4116 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4117 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4120 inc_rfc1001_len(pSMB, byte_count);
4122 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4123 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4125 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4126 } else { /* decode response */
4127 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4129 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4130 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4131 rc = -EIO; /* bad smb */
4133 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4134 memcpy((char *) pFindData,
4135 (char *) &pSMBr->hdr.Protocol +
4137 sizeof(FILE_UNIX_BASIC_INFO));
4141 cifs_buf_release(pSMB);
4143 goto UnixQFileInfoRetry;
4149 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4150 const unsigned char *searchName,
4151 FILE_UNIX_BASIC_INFO *pFindData,
4152 const struct nls_table *nls_codepage, int remap)
4154 /* SMB_QUERY_FILE_UNIX_BASIC */
4155 TRANSACTION2_QPI_REQ *pSMB = NULL;
4156 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4158 int bytes_returned = 0;
4160 __u16 params, byte_count;
4162 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4164 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4169 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4171 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4172 PATH_MAX, nls_codepage, remap);
4173 name_len++; /* trailing null */
4175 } else { /* BB improve the check for buffer overruns BB */
4176 name_len = strnlen(searchName, PATH_MAX);
4177 name_len++; /* trailing null */
4178 strncpy(pSMB->FileName, searchName, name_len);
4181 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4182 pSMB->TotalDataCount = 0;
4183 pSMB->MaxParameterCount = cpu_to_le16(2);
4184 /* BB find exact max SMB PDU from sess structure BB */
4185 pSMB->MaxDataCount = cpu_to_le16(4000);
4186 pSMB->MaxSetupCount = 0;
4190 pSMB->Reserved2 = 0;
4191 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4192 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4193 pSMB->DataCount = 0;
4194 pSMB->DataOffset = 0;
4195 pSMB->SetupCount = 1;
4196 pSMB->Reserved3 = 0;
4197 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4198 byte_count = params + 1 /* pad */ ;
4199 pSMB->TotalParameterCount = cpu_to_le16(params);
4200 pSMB->ParameterCount = pSMB->TotalParameterCount;
4201 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4202 pSMB->Reserved4 = 0;
4203 inc_rfc1001_len(pSMB, byte_count);
4204 pSMB->ByteCount = cpu_to_le16(byte_count);
4206 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4207 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4209 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4210 } else { /* decode response */
4211 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4213 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4214 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4215 rc = -EIO; /* bad smb */
4217 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4218 memcpy((char *) pFindData,
4219 (char *) &pSMBr->hdr.Protocol +
4221 sizeof(FILE_UNIX_BASIC_INFO));
4224 cifs_buf_release(pSMB);
4226 goto UnixQPathInfoRetry;
4231 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4233 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4234 const char *searchName, struct cifs_sb_info *cifs_sb,
4235 __u16 *pnetfid, __u16 search_flags,
4236 struct cifs_search_info *psrch_inf, bool msearch)
4238 /* level 257 SMB_ */
4239 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4240 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4241 T2_FFIRST_RSP_PARMS *parms;
4243 int bytes_returned = 0;
4244 int name_len, remap;
4245 __u16 params, byte_count;
4246 struct nls_table *nls_codepage;
4248 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4251 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4256 nls_codepage = cifs_sb->local_nls;
4257 remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
4259 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4261 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4262 PATH_MAX, nls_codepage, remap);
4263 /* We can not add the asterik earlier in case
4264 it got remapped to 0xF03A as if it were part of the
4265 directory name instead of a wildcard */
4268 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4269 pSMB->FileName[name_len+1] = 0;
4270 pSMB->FileName[name_len+2] = '*';
4271 pSMB->FileName[name_len+3] = 0;
4272 name_len += 4; /* now the trailing null */
4273 /* null terminate just in case */
4274 pSMB->FileName[name_len] = 0;
4275 pSMB->FileName[name_len+1] = 0;
4278 } else { /* BB add check for overrun of SMB buf BB */
4279 name_len = strnlen(searchName, PATH_MAX);
4280 /* BB fix here and in unicode clause above ie
4281 if (name_len > buffersize-header)
4282 free buffer exit; BB */
4283 strncpy(pSMB->FileName, searchName, name_len);
4285 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4286 pSMB->FileName[name_len+1] = '*';
4287 pSMB->FileName[name_len+2] = 0;
4292 params = 12 + name_len /* includes null */ ;
4293 pSMB->TotalDataCount = 0; /* no EAs */
4294 pSMB->MaxParameterCount = cpu_to_le16(10);
4295 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4296 pSMB->MaxSetupCount = 0;
4300 pSMB->Reserved2 = 0;
4301 byte_count = params + 1 /* pad */ ;
4302 pSMB->TotalParameterCount = cpu_to_le16(params);
4303 pSMB->ParameterCount = pSMB->TotalParameterCount;
4304 pSMB->ParameterOffset = cpu_to_le16(
4305 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4307 pSMB->DataCount = 0;
4308 pSMB->DataOffset = 0;
4309 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4310 pSMB->Reserved3 = 0;
4311 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4312 pSMB->SearchAttributes =
4313 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4315 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4316 pSMB->SearchFlags = cpu_to_le16(search_flags);
4317 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4319 /* BB what should we set StorageType to? Does it matter? BB */
4320 pSMB->SearchStorageType = 0;
4321 inc_rfc1001_len(pSMB, byte_count);
4322 pSMB->ByteCount = cpu_to_le16(byte_count);
4324 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4325 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4326 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4328 if (rc) {/* BB add logic to retry regular search if Unix search
4329 rejected unexpectedly by server */
4330 /* BB Add code to handle unsupported level rc */
4331 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4333 cifs_buf_release(pSMB);
4335 /* BB eventually could optimize out free and realloc of buf */
4338 goto findFirstRetry;
4339 } else { /* decode response */
4340 /* BB remember to free buffer if error BB */
4341 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4345 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4346 psrch_inf->unicode = true;
4348 psrch_inf->unicode = false;
4350 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4351 psrch_inf->smallBuf = 0;
4352 psrch_inf->srch_entries_start =
4353 (char *) &pSMBr->hdr.Protocol +
4354 le16_to_cpu(pSMBr->t2.DataOffset);
4355 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4356 le16_to_cpu(pSMBr->t2.ParameterOffset));
4358 if (parms->EndofSearch)
4359 psrch_inf->endOfSearch = true;
4361 psrch_inf->endOfSearch = false;
4363 psrch_inf->entries_in_buffer =
4364 le16_to_cpu(parms->SearchCount);
4365 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4366 psrch_inf->entries_in_buffer;
4367 lnoff = le16_to_cpu(parms->LastNameOffset);
4368 if (CIFSMaxBufSize < lnoff) {
4369 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4370 psrch_inf->last_entry = NULL;
4374 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4378 *pnetfid = parms->SearchHandle;
4380 cifs_buf_release(pSMB);
4387 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4388 __u16 searchHandle, __u16 search_flags,
4389 struct cifs_search_info *psrch_inf)
4391 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4392 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4393 T2_FNEXT_RSP_PARMS *parms;
4394 char *response_data;
4397 unsigned int name_len;
4398 __u16 params, byte_count;
4400 cifs_dbg(FYI, "In FindNext\n");
4402 if (psrch_inf->endOfSearch)
4405 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4410 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4412 pSMB->TotalDataCount = 0; /* no EAs */
4413 pSMB->MaxParameterCount = cpu_to_le16(8);
4414 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4415 pSMB->MaxSetupCount = 0;
4419 pSMB->Reserved2 = 0;
4420 pSMB->ParameterOffset = cpu_to_le16(
4421 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4422 pSMB->DataCount = 0;
4423 pSMB->DataOffset = 0;
4424 pSMB->SetupCount = 1;
4425 pSMB->Reserved3 = 0;
4426 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4427 pSMB->SearchHandle = searchHandle; /* always kept as le */
4429 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4430 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4431 pSMB->ResumeKey = psrch_inf->resume_key;
4432 pSMB->SearchFlags = cpu_to_le16(search_flags);
4434 name_len = psrch_inf->resume_name_len;
4436 if (name_len < PATH_MAX) {
4437 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4438 byte_count += name_len;
4439 /* 14 byte parm len above enough for 2 byte null terminator */
4440 pSMB->ResumeFileName[name_len] = 0;
4441 pSMB->ResumeFileName[name_len+1] = 0;
4444 goto FNext2_err_exit;
4446 byte_count = params + 1 /* pad */ ;
4447 pSMB->TotalParameterCount = cpu_to_le16(params);
4448 pSMB->ParameterCount = pSMB->TotalParameterCount;
4449 inc_rfc1001_len(pSMB, byte_count);
4450 pSMB->ByteCount = cpu_to_le16(byte_count);
4452 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4453 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4454 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4457 psrch_inf->endOfSearch = true;
4458 cifs_buf_release(pSMB);
4459 rc = 0; /* search probably was closed at end of search*/
4461 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4462 } else { /* decode response */
4463 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4468 /* BB fixme add lock for file (srch_info) struct here */
4469 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4470 psrch_inf->unicode = true;
4472 psrch_inf->unicode = false;
4473 response_data = (char *) &pSMBr->hdr.Protocol +
4474 le16_to_cpu(pSMBr->t2.ParameterOffset);
4475 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4476 response_data = (char *)&pSMBr->hdr.Protocol +
4477 le16_to_cpu(pSMBr->t2.DataOffset);
4478 if (psrch_inf->smallBuf)
4479 cifs_small_buf_release(
4480 psrch_inf->ntwrk_buf_start);
4482 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4483 psrch_inf->srch_entries_start = response_data;
4484 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4485 psrch_inf->smallBuf = 0;
4486 if (parms->EndofSearch)
4487 psrch_inf->endOfSearch = true;
4489 psrch_inf->endOfSearch = false;
4490 psrch_inf->entries_in_buffer =
4491 le16_to_cpu(parms->SearchCount);
4492 psrch_inf->index_of_last_entry +=
4493 psrch_inf->entries_in_buffer;
4494 lnoff = le16_to_cpu(parms->LastNameOffset);
4495 if (CIFSMaxBufSize < lnoff) {
4496 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4497 psrch_inf->last_entry = NULL;
4500 psrch_inf->last_entry =
4501 psrch_inf->srch_entries_start + lnoff;
4503 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4504 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4506 /* BB fixme add unlock here */
4511 /* BB On error, should we leave previous search buf (and count and
4512 last entry fields) intact or free the previous one? */
4514 /* Note: On -EAGAIN error only caller can retry on handle based calls
4515 since file handle passed in no longer valid */
4518 cifs_buf_release(pSMB);
4523 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4524 const __u16 searchHandle)
4527 FINDCLOSE_REQ *pSMB = NULL;
4529 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4530 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4532 /* no sense returning error if session restarted
4533 as file handle has been closed */
4539 pSMB->FileID = searchHandle;
4540 pSMB->ByteCount = 0;
4541 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4543 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4545 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4547 /* Since session is dead, search handle closed on server already */
4555 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4556 const char *search_name, __u64 *inode_number,
4557 const struct nls_table *nls_codepage, int remap)
4560 TRANSACTION2_QPI_REQ *pSMB = NULL;
4561 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4562 int name_len, bytes_returned;
4563 __u16 params, byte_count;
4565 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4569 GetInodeNumberRetry:
4570 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4575 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4577 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4578 search_name, PATH_MAX, nls_codepage,
4580 name_len++; /* trailing null */
4582 } else { /* BB improve the check for buffer overruns BB */
4583 name_len = strnlen(search_name, PATH_MAX);
4584 name_len++; /* trailing null */
4585 strncpy(pSMB->FileName, search_name, name_len);
4588 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4589 pSMB->TotalDataCount = 0;
4590 pSMB->MaxParameterCount = cpu_to_le16(2);
4591 /* BB find exact max data count below from sess structure BB */
4592 pSMB->MaxDataCount = cpu_to_le16(4000);
4593 pSMB->MaxSetupCount = 0;
4597 pSMB->Reserved2 = 0;
4598 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4599 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4600 pSMB->DataCount = 0;
4601 pSMB->DataOffset = 0;
4602 pSMB->SetupCount = 1;
4603 pSMB->Reserved3 = 0;
4604 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4605 byte_count = params + 1 /* pad */ ;
4606 pSMB->TotalParameterCount = cpu_to_le16(params);
4607 pSMB->ParameterCount = pSMB->TotalParameterCount;
4608 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4609 pSMB->Reserved4 = 0;
4610 inc_rfc1001_len(pSMB, byte_count);
4611 pSMB->ByteCount = cpu_to_le16(byte_count);
4613 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4614 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4616 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4618 /* decode response */
4619 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4620 /* BB also check enough total bytes returned */
4621 if (rc || get_bcc(&pSMBr->hdr) < 2)
4622 /* If rc should we check for EOPNOSUPP and
4623 disable the srvino flag? or in caller? */
4624 rc = -EIO; /* bad smb */
4626 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4627 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4628 struct file_internal_info *pfinfo;
4629 /* BB Do we need a cast or hash here ? */
4631 cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n");
4633 goto GetInodeNumOut;
4635 pfinfo = (struct file_internal_info *)
4636 (data_offset + (char *) &pSMBr->hdr.Protocol);
4637 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4641 cifs_buf_release(pSMB);
4643 goto GetInodeNumberRetry;
4647 /* parses DFS refferal V3 structure
4648 * caller is responsible for freeing target_nodes
4651 * on failure - errno
4654 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4655 unsigned int *num_of_nodes,
4656 struct dfs_info3_param **target_nodes,
4657 const struct nls_table *nls_codepage, int remap,
4658 const char *searchName)
4663 struct dfs_referral_level_3 *ref;
4665 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4669 *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4671 if (*num_of_nodes < 1) {
4672 cifs_dbg(VFS, "num_referrals: must be at least > 0, but we get num_referrals = %d\n",
4675 goto parse_DFS_referrals_exit;
4678 ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4679 if (ref->VersionNumber != cpu_to_le16(3)) {
4680 cifs_dbg(VFS, "Referrals of V%d version are not supported, should be V3\n",
4681 le16_to_cpu(ref->VersionNumber));
4683 goto parse_DFS_referrals_exit;
4686 /* get the upper boundary of the resp buffer */
4687 data_end = (char *)(&(pSMBr->PathConsumed)) +
4688 le16_to_cpu(pSMBr->t2.DataCount);
4690 cifs_dbg(FYI, "num_referrals: %d dfs flags: 0x%x ...\n",
4691 *num_of_nodes, le32_to_cpu(pSMBr->DFSFlags));
4693 *target_nodes = kcalloc(*num_of_nodes, sizeof(struct dfs_info3_param),
4695 if (*target_nodes == NULL) {
4697 goto parse_DFS_referrals_exit;
4700 /* collect necessary data from referrals */
4701 for (i = 0; i < *num_of_nodes; i++) {
4704 struct dfs_info3_param *node = (*target_nodes)+i;
4706 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4708 __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4712 goto parse_DFS_referrals_exit;
4714 cifsConvertToUTF16((__le16 *) tmp, searchName,
4715 PATH_MAX, nls_codepage, remap);
4716 node->path_consumed = cifs_utf16_bytes(tmp,
4717 le16_to_cpu(pSMBr->PathConsumed),
4721 node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4723 node->server_type = le16_to_cpu(ref->ServerType);
4724 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4727 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4728 max_len = data_end - temp;
4729 node->path_name = cifs_strndup_from_utf16(temp, max_len,
4730 is_unicode, nls_codepage);
4731 if (!node->path_name) {
4733 goto parse_DFS_referrals_exit;
4736 /* copy link target UNC */
4737 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4738 max_len = data_end - temp;
4739 node->node_name = cifs_strndup_from_utf16(temp, max_len,
4740 is_unicode, nls_codepage);
4741 if (!node->node_name) {
4743 goto parse_DFS_referrals_exit;
4749 parse_DFS_referrals_exit:
4751 free_dfs_info_array(*target_nodes, *num_of_nodes);
4752 *target_nodes = NULL;
4759 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4760 const char *search_name, struct dfs_info3_param **target_nodes,
4761 unsigned int *num_of_nodes,
4762 const struct nls_table *nls_codepage, int remap)
4764 /* TRANS2_GET_DFS_REFERRAL */
4765 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4766 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4770 __u16 params, byte_count;
4772 *target_nodes = NULL;
4774 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4778 rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4783 /* server pointer checked in called function,
4784 but should never be null here anyway */
4785 pSMB->hdr.Mid = get_next_mid(ses->server);
4786 pSMB->hdr.Tid = ses->ipc_tid;
4787 pSMB->hdr.Uid = ses->Suid;
4788 if (ses->capabilities & CAP_STATUS32)
4789 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4790 if (ses->capabilities & CAP_DFS)
4791 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4793 if (ses->capabilities & CAP_UNICODE) {
4794 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4796 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4797 search_name, PATH_MAX, nls_codepage,
4799 name_len++; /* trailing null */
4801 } else { /* BB improve the check for buffer overruns BB */
4802 name_len = strnlen(search_name, PATH_MAX);
4803 name_len++; /* trailing null */
4804 strncpy(pSMB->RequestFileName, search_name, name_len);
4808 if (ses->server->sec_mode &
4809 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4810 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4813 pSMB->hdr.Uid = ses->Suid;
4815 params = 2 /* level */ + name_len /*includes null */ ;
4816 pSMB->TotalDataCount = 0;
4817 pSMB->DataCount = 0;
4818 pSMB->DataOffset = 0;
4819 pSMB->MaxParameterCount = 0;
4820 /* BB find exact max SMB PDU from sess structure BB */
4821 pSMB->MaxDataCount = cpu_to_le16(4000);
4822 pSMB->MaxSetupCount = 0;
4826 pSMB->Reserved2 = 0;
4827 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4828 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4829 pSMB->SetupCount = 1;
4830 pSMB->Reserved3 = 0;
4831 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4832 byte_count = params + 3 /* pad */ ;
4833 pSMB->ParameterCount = cpu_to_le16(params);
4834 pSMB->TotalParameterCount = pSMB->ParameterCount;
4835 pSMB->MaxReferralLevel = cpu_to_le16(3);
4836 inc_rfc1001_len(pSMB, byte_count);
4837 pSMB->ByteCount = cpu_to_le16(byte_count);
4839 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4840 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4842 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4845 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4847 /* BB Also check if enough total bytes returned? */
4848 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4849 rc = -EIO; /* bad smb */
4853 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4854 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4856 /* parse returned result into more usable form */
4857 rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4858 target_nodes, nls_codepage, remap,
4862 cifs_buf_release(pSMB);
4870 /* Query File System Info such as free space to old servers such as Win 9x */
4872 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4873 struct kstatfs *FSData)
4875 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4876 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4877 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4878 FILE_SYSTEM_ALLOC_INFO *response_data;
4880 int bytes_returned = 0;
4881 __u16 params, byte_count;
4883 cifs_dbg(FYI, "OldQFSInfo\n");
4885 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4890 params = 2; /* level */
4891 pSMB->TotalDataCount = 0;
4892 pSMB->MaxParameterCount = cpu_to_le16(2);
4893 pSMB->MaxDataCount = cpu_to_le16(1000);
4894 pSMB->MaxSetupCount = 0;
4898 pSMB->Reserved2 = 0;
4899 byte_count = params + 1 /* pad */ ;
4900 pSMB->TotalParameterCount = cpu_to_le16(params);
4901 pSMB->ParameterCount = pSMB->TotalParameterCount;
4902 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4903 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4904 pSMB->DataCount = 0;
4905 pSMB->DataOffset = 0;
4906 pSMB->SetupCount = 1;
4907 pSMB->Reserved3 = 0;
4908 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4909 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4910 inc_rfc1001_len(pSMB, byte_count);
4911 pSMB->ByteCount = cpu_to_le16(byte_count);
4913 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4914 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4916 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4917 } else { /* decode response */
4918 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4920 if (rc || get_bcc(&pSMBr->hdr) < 18)
4921 rc = -EIO; /* bad smb */
4923 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4924 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4925 get_bcc(&pSMBr->hdr), data_offset);
4927 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4928 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4930 le16_to_cpu(response_data->BytesPerSector) *
4931 le32_to_cpu(response_data->
4932 SectorsPerAllocationUnit);
4934 le32_to_cpu(response_data->TotalAllocationUnits);
4935 FSData->f_bfree = FSData->f_bavail =
4936 le32_to_cpu(response_data->FreeAllocationUnits);
4937 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4938 (unsigned long long)FSData->f_blocks,
4939 (unsigned long long)FSData->f_bfree,
4943 cifs_buf_release(pSMB);
4946 goto oldQFSInfoRetry;
4952 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4953 struct kstatfs *FSData)
4955 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4956 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4957 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4958 FILE_SYSTEM_INFO *response_data;
4960 int bytes_returned = 0;
4961 __u16 params, byte_count;
4963 cifs_dbg(FYI, "In QFSInfo\n");
4965 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4970 params = 2; /* level */
4971 pSMB->TotalDataCount = 0;
4972 pSMB->MaxParameterCount = cpu_to_le16(2);
4973 pSMB->MaxDataCount = cpu_to_le16(1000);
4974 pSMB->MaxSetupCount = 0;
4978 pSMB->Reserved2 = 0;
4979 byte_count = params + 1 /* pad */ ;
4980 pSMB->TotalParameterCount = cpu_to_le16(params);
4981 pSMB->ParameterCount = pSMB->TotalParameterCount;
4982 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4983 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4984 pSMB->DataCount = 0;
4985 pSMB->DataOffset = 0;
4986 pSMB->SetupCount = 1;
4987 pSMB->Reserved3 = 0;
4988 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4989 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4990 inc_rfc1001_len(pSMB, byte_count);
4991 pSMB->ByteCount = cpu_to_le16(byte_count);
4993 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4994 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4996 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4997 } else { /* decode response */
4998 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5000 if (rc || get_bcc(&pSMBr->hdr) < 24)
5001 rc = -EIO; /* bad smb */
5003 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5007 *) (((char *) &pSMBr->hdr.Protocol) +
5010 le32_to_cpu(response_data->BytesPerSector) *
5011 le32_to_cpu(response_data->
5012 SectorsPerAllocationUnit);
5014 le64_to_cpu(response_data->TotalAllocationUnits);
5015 FSData->f_bfree = FSData->f_bavail =
5016 le64_to_cpu(response_data->FreeAllocationUnits);
5017 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5018 (unsigned long long)FSData->f_blocks,
5019 (unsigned long long)FSData->f_bfree,
5023 cifs_buf_release(pSMB);
5032 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5034 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5035 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5036 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5037 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5039 int bytes_returned = 0;
5040 __u16 params, byte_count;
5042 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5044 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5049 params = 2; /* level */
5050 pSMB->TotalDataCount = 0;
5051 pSMB->MaxParameterCount = cpu_to_le16(2);
5052 /* BB find exact max SMB PDU from sess structure BB */
5053 pSMB->MaxDataCount = cpu_to_le16(1000);
5054 pSMB->MaxSetupCount = 0;
5058 pSMB->Reserved2 = 0;
5059 byte_count = params + 1 /* pad */ ;
5060 pSMB->TotalParameterCount = cpu_to_le16(params);
5061 pSMB->ParameterCount = pSMB->TotalParameterCount;
5062 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5063 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5064 pSMB->DataCount = 0;
5065 pSMB->DataOffset = 0;
5066 pSMB->SetupCount = 1;
5067 pSMB->Reserved3 = 0;
5068 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5069 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5070 inc_rfc1001_len(pSMB, byte_count);
5071 pSMB->ByteCount = cpu_to_le16(byte_count);
5073 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5074 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5076 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5077 } else { /* decode response */
5078 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5080 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5081 /* BB also check if enough bytes returned */
5082 rc = -EIO; /* bad smb */
5084 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5086 (FILE_SYSTEM_ATTRIBUTE_INFO
5087 *) (((char *) &pSMBr->hdr.Protocol) +
5089 memcpy(&tcon->fsAttrInfo, response_data,
5090 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5093 cifs_buf_release(pSMB);
5096 goto QFSAttributeRetry;
5102 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5104 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5105 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5106 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5107 FILE_SYSTEM_DEVICE_INFO *response_data;
5109 int bytes_returned = 0;
5110 __u16 params, byte_count;
5112 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5114 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5119 params = 2; /* level */
5120 pSMB->TotalDataCount = 0;
5121 pSMB->MaxParameterCount = cpu_to_le16(2);
5122 /* BB find exact max SMB PDU from sess structure BB */
5123 pSMB->MaxDataCount = cpu_to_le16(1000);
5124 pSMB->MaxSetupCount = 0;
5128 pSMB->Reserved2 = 0;
5129 byte_count = params + 1 /* pad */ ;
5130 pSMB->TotalParameterCount = cpu_to_le16(params);
5131 pSMB->ParameterCount = pSMB->TotalParameterCount;
5132 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5133 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5135 pSMB->DataCount = 0;
5136 pSMB->DataOffset = 0;
5137 pSMB->SetupCount = 1;
5138 pSMB->Reserved3 = 0;
5139 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5140 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5141 inc_rfc1001_len(pSMB, byte_count);
5142 pSMB->ByteCount = cpu_to_le16(byte_count);
5144 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5145 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5147 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5148 } else { /* decode response */
5149 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5151 if (rc || get_bcc(&pSMBr->hdr) <
5152 sizeof(FILE_SYSTEM_DEVICE_INFO))
5153 rc = -EIO; /* bad smb */
5155 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5157 (FILE_SYSTEM_DEVICE_INFO *)
5158 (((char *) &pSMBr->hdr.Protocol) +
5160 memcpy(&tcon->fsDevInfo, response_data,
5161 sizeof(FILE_SYSTEM_DEVICE_INFO));
5164 cifs_buf_release(pSMB);
5167 goto QFSDeviceRetry;
5173 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5175 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5176 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5177 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5178 FILE_SYSTEM_UNIX_INFO *response_data;
5180 int bytes_returned = 0;
5181 __u16 params, byte_count;
5183 cifs_dbg(FYI, "In QFSUnixInfo\n");
5185 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5186 (void **) &pSMB, (void **) &pSMBr);
5190 params = 2; /* level */
5191 pSMB->TotalDataCount = 0;
5192 pSMB->DataCount = 0;
5193 pSMB->DataOffset = 0;
5194 pSMB->MaxParameterCount = cpu_to_le16(2);
5195 /* BB find exact max SMB PDU from sess structure BB */
5196 pSMB->MaxDataCount = cpu_to_le16(100);
5197 pSMB->MaxSetupCount = 0;
5201 pSMB->Reserved2 = 0;
5202 byte_count = params + 1 /* pad */ ;
5203 pSMB->ParameterCount = cpu_to_le16(params);
5204 pSMB->TotalParameterCount = pSMB->ParameterCount;
5205 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5206 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5207 pSMB->SetupCount = 1;
5208 pSMB->Reserved3 = 0;
5209 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5210 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5211 inc_rfc1001_len(pSMB, byte_count);
5212 pSMB->ByteCount = cpu_to_le16(byte_count);
5214 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5215 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5217 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5218 } else { /* decode response */
5219 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5221 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5222 rc = -EIO; /* bad smb */
5224 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5226 (FILE_SYSTEM_UNIX_INFO
5227 *) (((char *) &pSMBr->hdr.Protocol) +
5229 memcpy(&tcon->fsUnixInfo, response_data,
5230 sizeof(FILE_SYSTEM_UNIX_INFO));
5233 cifs_buf_release(pSMB);
5243 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5245 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5246 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5247 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5249 int bytes_returned = 0;
5250 __u16 params, param_offset, offset, byte_count;
5252 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5254 /* BB switch to small buf init to save memory */
5255 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5256 (void **) &pSMB, (void **) &pSMBr);
5260 params = 4; /* 2 bytes zero followed by info level. */
5261 pSMB->MaxSetupCount = 0;
5265 pSMB->Reserved2 = 0;
5266 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5268 offset = param_offset + params;
5270 pSMB->MaxParameterCount = cpu_to_le16(4);
5271 /* BB find exact max SMB PDU from sess structure BB */
5272 pSMB->MaxDataCount = cpu_to_le16(100);
5273 pSMB->SetupCount = 1;
5274 pSMB->Reserved3 = 0;
5275 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5276 byte_count = 1 /* pad */ + params + 12;
5278 pSMB->DataCount = cpu_to_le16(12);
5279 pSMB->ParameterCount = cpu_to_le16(params);
5280 pSMB->TotalDataCount = pSMB->DataCount;
5281 pSMB->TotalParameterCount = pSMB->ParameterCount;
5282 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5283 pSMB->DataOffset = cpu_to_le16(offset);
5287 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5290 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5291 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5292 pSMB->ClientUnixCap = cpu_to_le64(cap);
5294 inc_rfc1001_len(pSMB, byte_count);
5295 pSMB->ByteCount = cpu_to_le16(byte_count);
5297 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5298 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5300 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5301 } else { /* decode response */
5302 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5304 rc = -EIO; /* bad smb */
5306 cifs_buf_release(pSMB);
5309 goto SETFSUnixRetry;
5317 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5318 struct kstatfs *FSData)
5320 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5321 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5322 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5323 FILE_SYSTEM_POSIX_INFO *response_data;
5325 int bytes_returned = 0;
5326 __u16 params, byte_count;
5328 cifs_dbg(FYI, "In QFSPosixInfo\n");
5330 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5335 params = 2; /* level */
5336 pSMB->TotalDataCount = 0;
5337 pSMB->DataCount = 0;
5338 pSMB->DataOffset = 0;
5339 pSMB->MaxParameterCount = cpu_to_le16(2);
5340 /* BB find exact max SMB PDU from sess structure BB */
5341 pSMB->MaxDataCount = cpu_to_le16(100);
5342 pSMB->MaxSetupCount = 0;
5346 pSMB->Reserved2 = 0;
5347 byte_count = params + 1 /* pad */ ;
5348 pSMB->ParameterCount = cpu_to_le16(params);
5349 pSMB->TotalParameterCount = pSMB->ParameterCount;
5350 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5351 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5352 pSMB->SetupCount = 1;
5353 pSMB->Reserved3 = 0;
5354 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5355 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5356 inc_rfc1001_len(pSMB, byte_count);
5357 pSMB->ByteCount = cpu_to_le16(byte_count);
5359 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5360 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5362 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5363 } else { /* decode response */
5364 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5366 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5367 rc = -EIO; /* bad smb */
5369 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5371 (FILE_SYSTEM_POSIX_INFO
5372 *) (((char *) &pSMBr->hdr.Protocol) +
5375 le32_to_cpu(response_data->BlockSize);
5377 le64_to_cpu(response_data->TotalBlocks);
5379 le64_to_cpu(response_data->BlocksAvail);
5380 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5381 FSData->f_bavail = FSData->f_bfree;
5384 le64_to_cpu(response_data->UserBlocksAvail);
5386 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5388 le64_to_cpu(response_data->TotalFileNodes);
5389 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5391 le64_to_cpu(response_data->FreeFileNodes);
5394 cifs_buf_release(pSMB);
5404 * We can not use write of zero bytes trick to set file size due to need for
5405 * large file support. Also note that this SetPathInfo is preferred to
5406 * SetFileInfo based method in next routine which is only needed to work around
5407 * a sharing violation bugin Samba which this routine can run into.
5410 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5411 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5412 bool set_allocation)
5414 struct smb_com_transaction2_spi_req *pSMB = NULL;
5415 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5416 struct file_end_of_file_info *parm_data;
5419 int bytes_returned = 0;
5420 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
5422 __u16 params, byte_count, data_count, param_offset, offset;
5424 cifs_dbg(FYI, "In SetEOF\n");
5426 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5431 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5433 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5434 PATH_MAX, cifs_sb->local_nls, remap);
5435 name_len++; /* trailing null */
5437 } else { /* BB improve the check for buffer overruns BB */
5438 name_len = strnlen(file_name, PATH_MAX);
5439 name_len++; /* trailing null */
5440 strncpy(pSMB->FileName, file_name, name_len);
5442 params = 6 + name_len;
5443 data_count = sizeof(struct file_end_of_file_info);
5444 pSMB->MaxParameterCount = cpu_to_le16(2);
5445 pSMB->MaxDataCount = cpu_to_le16(4100);
5446 pSMB->MaxSetupCount = 0;
5450 pSMB->Reserved2 = 0;
5451 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5452 InformationLevel) - 4;
5453 offset = param_offset + params;
5454 if (set_allocation) {
5455 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5456 pSMB->InformationLevel =
5457 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5459 pSMB->InformationLevel =
5460 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5461 } else /* Set File Size */ {
5462 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5463 pSMB->InformationLevel =
5464 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5466 pSMB->InformationLevel =
5467 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5471 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5473 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5474 pSMB->DataOffset = cpu_to_le16(offset);
5475 pSMB->SetupCount = 1;
5476 pSMB->Reserved3 = 0;
5477 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5478 byte_count = 3 /* pad */ + params + data_count;
5479 pSMB->DataCount = cpu_to_le16(data_count);
5480 pSMB->TotalDataCount = pSMB->DataCount;
5481 pSMB->ParameterCount = cpu_to_le16(params);
5482 pSMB->TotalParameterCount = pSMB->ParameterCount;
5483 pSMB->Reserved4 = 0;
5484 inc_rfc1001_len(pSMB, byte_count);
5485 parm_data->FileSize = cpu_to_le64(size);
5486 pSMB->ByteCount = cpu_to_le16(byte_count);
5487 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5488 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5490 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5492 cifs_buf_release(pSMB);
5501 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5502 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5504 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5505 struct file_end_of_file_info *parm_data;
5507 __u16 params, param_offset, offset, byte_count, count;
5509 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5511 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5516 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5517 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5520 pSMB->MaxSetupCount = 0;
5524 pSMB->Reserved2 = 0;
5525 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5526 offset = param_offset + params;
5528 count = sizeof(struct file_end_of_file_info);
5529 pSMB->MaxParameterCount = cpu_to_le16(2);
5530 /* BB find exact max SMB PDU from sess structure BB */
5531 pSMB->MaxDataCount = cpu_to_le16(1000);
5532 pSMB->SetupCount = 1;
5533 pSMB->Reserved3 = 0;
5534 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5535 byte_count = 3 /* pad */ + params + count;
5536 pSMB->DataCount = cpu_to_le16(count);
5537 pSMB->ParameterCount = cpu_to_le16(params);
5538 pSMB->TotalDataCount = pSMB->DataCount;
5539 pSMB->TotalParameterCount = pSMB->ParameterCount;
5540 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5542 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5544 pSMB->DataOffset = cpu_to_le16(offset);
5545 parm_data->FileSize = cpu_to_le64(size);
5546 pSMB->Fid = cfile->fid.netfid;
5547 if (set_allocation) {
5548 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5549 pSMB->InformationLevel =
5550 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5552 pSMB->InformationLevel =
5553 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5554 } else /* Set File Size */ {
5555 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5556 pSMB->InformationLevel =
5557 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5559 pSMB->InformationLevel =
5560 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5562 pSMB->Reserved4 = 0;
5563 inc_rfc1001_len(pSMB, byte_count);
5564 pSMB->ByteCount = cpu_to_le16(byte_count);
5565 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5567 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5571 /* Note: On -EAGAIN error only caller can retry on handle based calls
5572 since file handle passed in no longer valid */
5577 /* Some legacy servers such as NT4 require that the file times be set on
5578 an open handle, rather than by pathname - this is awkward due to
5579 potential access conflicts on the open, but it is unavoidable for these
5580 old servers since the only other choice is to go from 100 nanosecond DCE
5581 time and resort to the original setpathinfo level which takes the ancient
5582 DOS time format with 2 second granularity */
5584 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5585 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5587 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5590 __u16 params, param_offset, offset, byte_count, count;
5592 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5593 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5598 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5599 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5602 pSMB->MaxSetupCount = 0;
5606 pSMB->Reserved2 = 0;
5607 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5608 offset = param_offset + params;
5610 data_offset = (char *)pSMB +
5611 offsetof(struct smb_hdr, Protocol) + offset;
5613 count = sizeof(FILE_BASIC_INFO);
5614 pSMB->MaxParameterCount = cpu_to_le16(2);
5615 /* BB find max SMB PDU from sess */
5616 pSMB->MaxDataCount = cpu_to_le16(1000);
5617 pSMB->SetupCount = 1;
5618 pSMB->Reserved3 = 0;
5619 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5620 byte_count = 3 /* pad */ + params + count;
5621 pSMB->DataCount = cpu_to_le16(count);
5622 pSMB->ParameterCount = cpu_to_le16(params);
5623 pSMB->TotalDataCount = pSMB->DataCount;
5624 pSMB->TotalParameterCount = pSMB->ParameterCount;
5625 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5626 pSMB->DataOffset = cpu_to_le16(offset);
5628 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5629 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5631 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5632 pSMB->Reserved4 = 0;
5633 inc_rfc1001_len(pSMB, byte_count);
5634 pSMB->ByteCount = cpu_to_le16(byte_count);
5635 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5636 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5638 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5641 /* Note: On -EAGAIN error only caller can retry on handle based calls
5642 since file handle passed in no longer valid */
5648 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5649 bool delete_file, __u16 fid, __u32 pid_of_opener)
5651 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5654 __u16 params, param_offset, offset, byte_count, count;
5656 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5657 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5662 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5663 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5666 pSMB->MaxSetupCount = 0;
5670 pSMB->Reserved2 = 0;
5671 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5672 offset = param_offset + params;
5674 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5677 pSMB->MaxParameterCount = cpu_to_le16(2);
5678 /* BB find max SMB PDU from sess */
5679 pSMB->MaxDataCount = cpu_to_le16(1000);
5680 pSMB->SetupCount = 1;
5681 pSMB->Reserved3 = 0;
5682 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5683 byte_count = 3 /* pad */ + params + count;
5684 pSMB->DataCount = cpu_to_le16(count);
5685 pSMB->ParameterCount = cpu_to_le16(params);
5686 pSMB->TotalDataCount = pSMB->DataCount;
5687 pSMB->TotalParameterCount = pSMB->ParameterCount;
5688 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5689 pSMB->DataOffset = cpu_to_le16(offset);
5691 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5692 pSMB->Reserved4 = 0;
5693 inc_rfc1001_len(pSMB, byte_count);
5694 pSMB->ByteCount = cpu_to_le16(byte_count);
5695 *data_offset = delete_file ? 1 : 0;
5696 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5698 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5704 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5705 const char *fileName, const FILE_BASIC_INFO *data,
5706 const struct nls_table *nls_codepage, int remap)
5708 TRANSACTION2_SPI_REQ *pSMB = NULL;
5709 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5712 int bytes_returned = 0;
5714 __u16 params, param_offset, offset, byte_count, count;
5716 cifs_dbg(FYI, "In SetTimes\n");
5719 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5724 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5726 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5727 PATH_MAX, nls_codepage, remap);
5728 name_len++; /* trailing null */
5730 } else { /* BB improve the check for buffer overruns BB */
5731 name_len = strnlen(fileName, PATH_MAX);
5732 name_len++; /* trailing null */
5733 strncpy(pSMB->FileName, fileName, name_len);
5736 params = 6 + name_len;
5737 count = sizeof(FILE_BASIC_INFO);
5738 pSMB->MaxParameterCount = cpu_to_le16(2);
5739 /* BB find max SMB PDU from sess structure BB */
5740 pSMB->MaxDataCount = cpu_to_le16(1000);
5741 pSMB->MaxSetupCount = 0;
5745 pSMB->Reserved2 = 0;
5746 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5747 InformationLevel) - 4;
5748 offset = param_offset + params;
5749 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5750 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5751 pSMB->DataOffset = cpu_to_le16(offset);
5752 pSMB->SetupCount = 1;
5753 pSMB->Reserved3 = 0;
5754 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5755 byte_count = 3 /* pad */ + params + count;
5757 pSMB->DataCount = cpu_to_le16(count);
5758 pSMB->ParameterCount = cpu_to_le16(params);
5759 pSMB->TotalDataCount = pSMB->DataCount;
5760 pSMB->TotalParameterCount = pSMB->ParameterCount;
5761 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5762 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5764 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5765 pSMB->Reserved4 = 0;
5766 inc_rfc1001_len(pSMB, byte_count);
5767 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5768 pSMB->ByteCount = cpu_to_le16(byte_count);
5769 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5770 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5772 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5774 cifs_buf_release(pSMB);
5782 /* Can not be used to set time stamps yet (due to old DOS time format) */
5783 /* Can be used to set attributes */
5784 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5785 handling it anyway and NT4 was what we thought it would be needed for
5786 Do not delete it until we prove whether needed for Win9x though */
5788 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
5789 __u16 dos_attrs, const struct nls_table *nls_codepage)
5791 SETATTR_REQ *pSMB = NULL;
5792 SETATTR_RSP *pSMBr = NULL;
5797 cifs_dbg(FYI, "In SetAttrLegacy\n");
5800 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5805 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5807 ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5808 PATH_MAX, nls_codepage);
5809 name_len++; /* trailing null */
5811 } else { /* BB improve the check for buffer overruns BB */
5812 name_len = strnlen(fileName, PATH_MAX);
5813 name_len++; /* trailing null */
5814 strncpy(pSMB->fileName, fileName, name_len);
5816 pSMB->attr = cpu_to_le16(dos_attrs);
5817 pSMB->BufferFormat = 0x04;
5818 inc_rfc1001_len(pSMB, name_len + 1);
5819 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5820 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5821 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5823 cifs_dbg(FYI, "Error in LegacySetAttr = %d\n", rc);
5825 cifs_buf_release(pSMB);
5828 goto SetAttrLgcyRetry;
5832 #endif /* temporarily unneeded SetAttr legacy function */
5835 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5836 const struct cifs_unix_set_info_args *args)
5838 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5839 u64 mode = args->mode;
5841 if (uid_valid(args->uid))
5842 uid = from_kuid(&init_user_ns, args->uid);
5843 if (gid_valid(args->gid))
5844 gid = from_kgid(&init_user_ns, args->gid);
5847 * Samba server ignores set of file size to zero due to bugs in some
5848 * older clients, but we should be precise - we use SetFileSize to
5849 * set file size and do not want to truncate file size to zero
5850 * accidentally as happened on one Samba server beta by putting
5851 * zero instead of -1 here
5853 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5854 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5855 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5856 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5857 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5858 data_offset->Uid = cpu_to_le64(uid);
5859 data_offset->Gid = cpu_to_le64(gid);
5860 /* better to leave device as zero when it is */
5861 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5862 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5863 data_offset->Permissions = cpu_to_le64(mode);
5866 data_offset->Type = cpu_to_le32(UNIX_FILE);
5867 else if (S_ISDIR(mode))
5868 data_offset->Type = cpu_to_le32(UNIX_DIR);
5869 else if (S_ISLNK(mode))
5870 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5871 else if (S_ISCHR(mode))
5872 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5873 else if (S_ISBLK(mode))
5874 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5875 else if (S_ISFIFO(mode))
5876 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5877 else if (S_ISSOCK(mode))
5878 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5882 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5883 const struct cifs_unix_set_info_args *args,
5884 u16 fid, u32 pid_of_opener)
5886 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5889 u16 params, param_offset, offset, byte_count, count;
5891 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5892 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5897 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5898 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5901 pSMB->MaxSetupCount = 0;
5905 pSMB->Reserved2 = 0;
5906 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5907 offset = param_offset + params;
5909 data_offset = (char *)pSMB +
5910 offsetof(struct smb_hdr, Protocol) + offset;
5912 count = sizeof(FILE_UNIX_BASIC_INFO);
5914 pSMB->MaxParameterCount = cpu_to_le16(2);
5915 /* BB find max SMB PDU from sess */
5916 pSMB->MaxDataCount = cpu_to_le16(1000);
5917 pSMB->SetupCount = 1;
5918 pSMB->Reserved3 = 0;
5919 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5920 byte_count = 3 /* pad */ + params + count;
5921 pSMB->DataCount = cpu_to_le16(count);
5922 pSMB->ParameterCount = cpu_to_le16(params);
5923 pSMB->TotalDataCount = pSMB->DataCount;
5924 pSMB->TotalParameterCount = pSMB->ParameterCount;
5925 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5926 pSMB->DataOffset = cpu_to_le16(offset);
5928 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5929 pSMB->Reserved4 = 0;
5930 inc_rfc1001_len(pSMB, byte_count);
5931 pSMB->ByteCount = cpu_to_le16(byte_count);
5933 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5935 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5937 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5940 /* Note: On -EAGAIN error only caller can retry on handle based calls
5941 since file handle passed in no longer valid */
5947 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5948 const char *file_name,
5949 const struct cifs_unix_set_info_args *args,
5950 const struct nls_table *nls_codepage, int remap)
5952 TRANSACTION2_SPI_REQ *pSMB = NULL;
5953 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5956 int bytes_returned = 0;
5957 FILE_UNIX_BASIC_INFO *data_offset;
5958 __u16 params, param_offset, offset, count, byte_count;
5960 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5962 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5967 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5969 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5970 PATH_MAX, nls_codepage, remap);
5971 name_len++; /* trailing null */
5973 } else { /* BB improve the check for buffer overruns BB */
5974 name_len = strnlen(file_name, PATH_MAX);
5975 name_len++; /* trailing null */
5976 strncpy(pSMB->FileName, file_name, name_len);
5979 params = 6 + name_len;
5980 count = sizeof(FILE_UNIX_BASIC_INFO);
5981 pSMB->MaxParameterCount = cpu_to_le16(2);
5982 /* BB find max SMB PDU from sess structure BB */
5983 pSMB->MaxDataCount = cpu_to_le16(1000);
5984 pSMB->MaxSetupCount = 0;
5988 pSMB->Reserved2 = 0;
5989 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5990 InformationLevel) - 4;
5991 offset = param_offset + params;
5993 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
5995 memset(data_offset, 0, count);
5996 pSMB->DataOffset = cpu_to_le16(offset);
5997 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5998 pSMB->SetupCount = 1;
5999 pSMB->Reserved3 = 0;
6000 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6001 byte_count = 3 /* pad */ + params + count;
6002 pSMB->ParameterCount = cpu_to_le16(params);
6003 pSMB->DataCount = cpu_to_le16(count);
6004 pSMB->TotalParameterCount = pSMB->ParameterCount;
6005 pSMB->TotalDataCount = pSMB->DataCount;
6006 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6007 pSMB->Reserved4 = 0;
6008 inc_rfc1001_len(pSMB, byte_count);
6010 cifs_fill_unix_set_info(data_offset, args);
6012 pSMB->ByteCount = cpu_to_le16(byte_count);
6013 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6014 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6016 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6018 cifs_buf_release(pSMB);
6024 #ifdef CONFIG_CIFS_XATTR
6026 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6027 * function used by listxattr and getxattr type calls. When ea_name is set,
6028 * it looks for that attribute name and stuffs that value into the EAData
6029 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6030 * buffer. In both cases, the return value is either the length of the
6031 * resulting data or a negative error code. If EAData is a NULL pointer then
6032 * the data isn't copied to it, but the length is returned.
6035 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6036 const unsigned char *searchName, const unsigned char *ea_name,
6037 char *EAData, size_t buf_size,
6038 const struct nls_table *nls_codepage, int remap)
6040 /* BB assumes one setup word */
6041 TRANSACTION2_QPI_REQ *pSMB = NULL;
6042 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6046 struct fealist *ea_response_data;
6047 struct fea *temp_fea;
6050 __u16 params, byte_count, data_offset;
6051 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6053 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6055 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6060 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6062 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6063 PATH_MAX, nls_codepage, remap);
6064 list_len++; /* trailing null */
6066 } else { /* BB improve the check for buffer overruns BB */
6067 list_len = strnlen(searchName, PATH_MAX);
6068 list_len++; /* trailing null */
6069 strncpy(pSMB->FileName, searchName, list_len);
6072 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6073 pSMB->TotalDataCount = 0;
6074 pSMB->MaxParameterCount = cpu_to_le16(2);
6075 /* BB find exact max SMB PDU from sess structure BB */
6076 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6077 pSMB->MaxSetupCount = 0;
6081 pSMB->Reserved2 = 0;
6082 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6083 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6084 pSMB->DataCount = 0;
6085 pSMB->DataOffset = 0;
6086 pSMB->SetupCount = 1;
6087 pSMB->Reserved3 = 0;
6088 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6089 byte_count = params + 1 /* pad */ ;
6090 pSMB->TotalParameterCount = cpu_to_le16(params);
6091 pSMB->ParameterCount = pSMB->TotalParameterCount;
6092 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6093 pSMB->Reserved4 = 0;
6094 inc_rfc1001_len(pSMB, byte_count);
6095 pSMB->ByteCount = cpu_to_le16(byte_count);
6097 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6098 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6100 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6105 /* BB also check enough total bytes returned */
6106 /* BB we need to improve the validity checking
6107 of these trans2 responses */
6109 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6110 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6111 rc = -EIO; /* bad smb */
6115 /* check that length of list is not more than bcc */
6116 /* check that each entry does not go beyond length
6118 /* check that each element of each entry does not
6119 go beyond end of list */
6120 /* validate_trans2_offsets() */
6121 /* BB check if start of smb + data_offset > &bcc+ bcc */
6123 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6124 ea_response_data = (struct fealist *)
6125 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6127 list_len = le32_to_cpu(ea_response_data->list_len);
6128 cifs_dbg(FYI, "ea length %d\n", list_len);
6129 if (list_len <= 8) {
6130 cifs_dbg(FYI, "empty EA list returned from server\n");
6134 /* make sure list_len doesn't go past end of SMB */
6135 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6136 if ((char *)ea_response_data + list_len > end_of_smb) {
6137 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6142 /* account for ea list len */
6144 temp_fea = ea_response_data->list;
6145 temp_ptr = (char *)temp_fea;
6146 while (list_len > 0) {
6147 unsigned int name_len;
6152 /* make sure we can read name_len and value_len */
6154 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6159 name_len = temp_fea->name_len;
6160 value_len = le16_to_cpu(temp_fea->value_len);
6161 list_len -= name_len + 1 + value_len;
6163 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6169 if (ea_name_len == name_len &&
6170 memcmp(ea_name, temp_ptr, name_len) == 0) {
6171 temp_ptr += name_len + 1;
6175 if ((size_t)value_len > buf_size) {
6179 memcpy(EAData, temp_ptr, value_len);
6183 /* account for prefix user. and trailing null */
6184 rc += (5 + 1 + name_len);
6185 if (rc < (int) buf_size) {
6186 memcpy(EAData, "user.", 5);
6188 memcpy(EAData, temp_ptr, name_len);
6190 /* null terminate name */
6193 } else if (buf_size == 0) {
6194 /* skip copy - calc size only */
6196 /* stop before overrun buffer */
6201 temp_ptr += name_len + 1 + value_len;
6202 temp_fea = (struct fea *)temp_ptr;
6205 /* didn't find the named attribute */
6210 cifs_buf_release(pSMB);
6218 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6219 const char *fileName, const char *ea_name, const void *ea_value,
6220 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6223 struct smb_com_transaction2_spi_req *pSMB = NULL;
6224 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6225 struct fealist *parm_data;
6228 int bytes_returned = 0;
6229 __u16 params, param_offset, byte_count, offset, count;
6231 cifs_dbg(FYI, "In SetEA\n");
6233 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6238 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6240 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6241 PATH_MAX, nls_codepage, remap);
6242 name_len++; /* trailing null */
6244 } else { /* BB improve the check for buffer overruns BB */
6245 name_len = strnlen(fileName, PATH_MAX);
6246 name_len++; /* trailing null */
6247 strncpy(pSMB->FileName, fileName, name_len);
6250 params = 6 + name_len;
6252 /* done calculating parms using name_len of file name,
6253 now use name_len to calculate length of ea name
6254 we are going to create in the inode xattrs */
6255 if (ea_name == NULL)
6258 name_len = strnlen(ea_name, 255);
6260 count = sizeof(*parm_data) + ea_value_len + name_len;
6261 pSMB->MaxParameterCount = cpu_to_le16(2);
6262 /* BB find max SMB PDU from sess */
6263 pSMB->MaxDataCount = cpu_to_le16(1000);
6264 pSMB->MaxSetupCount = 0;
6268 pSMB->Reserved2 = 0;
6269 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6270 InformationLevel) - 4;
6271 offset = param_offset + params;
6272 pSMB->InformationLevel =
6273 cpu_to_le16(SMB_SET_FILE_EA);
6276 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6278 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6279 pSMB->DataOffset = cpu_to_le16(offset);
6280 pSMB->SetupCount = 1;
6281 pSMB->Reserved3 = 0;
6282 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6283 byte_count = 3 /* pad */ + params + count;
6284 pSMB->DataCount = cpu_to_le16(count);
6285 parm_data->list_len = cpu_to_le32(count);
6286 parm_data->list[0].EA_flags = 0;
6287 /* we checked above that name len is less than 255 */
6288 parm_data->list[0].name_len = (__u8)name_len;
6289 /* EA names are always ASCII */
6291 strncpy(parm_data->list[0].name, ea_name, name_len);
6292 parm_data->list[0].name[name_len] = 0;
6293 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6294 /* caller ensures that ea_value_len is less than 64K but
6295 we need to ensure that it fits within the smb */
6297 /*BB add length check to see if it would fit in
6298 negotiated SMB buffer size BB */
6299 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6301 memcpy(parm_data->list[0].name+name_len+1,
6302 ea_value, ea_value_len);
6304 pSMB->TotalDataCount = pSMB->DataCount;
6305 pSMB->ParameterCount = cpu_to_le16(params);
6306 pSMB->TotalParameterCount = pSMB->ParameterCount;
6307 pSMB->Reserved4 = 0;
6308 inc_rfc1001_len(pSMB, byte_count);
6309 pSMB->ByteCount = cpu_to_le16(byte_count);
6310 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6311 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6313 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6315 cifs_buf_release(pSMB);
6324 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6326 * Years ago the kernel added a "dnotify" function for Samba server,
6327 * to allow network clients (such as Windows) to display updated
6328 * lists of files in directory listings automatically when
6329 * files are added by one user when another user has the
6330 * same directory open on their desktop. The Linux cifs kernel
6331 * client hooked into the kernel side of this interface for
6332 * the same reason, but ironically when the VFS moved from
6333 * "dnotify" to "inotify" it became harder to plug in Linux
6334 * network file system clients (the most obvious use case
6335 * for notify interfaces is when multiple users can update
6336 * the contents of the same directory - exactly what network
6337 * file systems can do) although the server (Samba) could
6338 * still use it. For the short term we leave the worker
6339 * function ifdeffed out (below) until inotify is fixed
6340 * in the VFS to make it easier to plug in network file
6341 * system clients. If inotify turns out to be permanently
6342 * incompatible for network fs clients, we could instead simply
6343 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6345 int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
6346 const int notify_subdirs, const __u16 netfid,
6347 __u32 filter, struct file *pfile, int multishot,
6348 const struct nls_table *nls_codepage)
6351 struct smb_com_transaction_change_notify_req *pSMB = NULL;
6352 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6353 struct dir_notify_req *dnotify_req;
6356 cifs_dbg(FYI, "In CIFSSMBNotify for file handle %d\n", (int)netfid);
6357 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6362 pSMB->TotalParameterCount = 0 ;
6363 pSMB->TotalDataCount = 0;
6364 pSMB->MaxParameterCount = cpu_to_le32(2);
6365 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6366 pSMB->MaxSetupCount = 4;
6368 pSMB->ParameterOffset = 0;
6369 pSMB->DataCount = 0;
6370 pSMB->DataOffset = 0;
6371 pSMB->SetupCount = 4; /* single byte does not need le conversion */
6372 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6373 pSMB->ParameterCount = pSMB->TotalParameterCount;
6375 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6376 pSMB->Reserved2 = 0;
6377 pSMB->CompletionFilter = cpu_to_le32(filter);
6378 pSMB->Fid = netfid; /* file handle always le */
6379 pSMB->ByteCount = 0;
6381 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6382 (struct smb_hdr *)pSMBr, &bytes_returned,
6385 cifs_dbg(FYI, "Error in Notify = %d\n", rc);
6387 /* Add file to outstanding requests */
6388 /* BB change to kmem cache alloc */
6389 dnotify_req = kmalloc(
6390 sizeof(struct dir_notify_req),
6393 dnotify_req->Pid = pSMB->hdr.Pid;
6394 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6395 dnotify_req->Mid = pSMB->hdr.Mid;
6396 dnotify_req->Tid = pSMB->hdr.Tid;
6397 dnotify_req->Uid = pSMB->hdr.Uid;
6398 dnotify_req->netfid = netfid;
6399 dnotify_req->pfile = pfile;
6400 dnotify_req->filter = filter;
6401 dnotify_req->multishot = multishot;
6402 spin_lock(&GlobalMid_Lock);
6403 list_add_tail(&dnotify_req->lhead,
6404 &GlobalDnotifyReqList);
6405 spin_unlock(&GlobalMid_Lock);
6409 cifs_buf_release(pSMB);
6412 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */