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 */
91 * On arches that have high memory, kmap address space is limited. By
92 * serializing the kmap operations on those arches, we ensure that we don't
93 * end up with a bunch of threads in writeback with partially mapped page
94 * arrays, stuck waiting for kmap to come back. That situation prevents
95 * progress and can deadlock.
97 static DEFINE_MUTEX(cifs_kmap_mutex);
102 mutex_lock(&cifs_kmap_mutex);
106 cifs_kmap_unlock(void)
108 mutex_unlock(&cifs_kmap_mutex);
110 #else /* !CONFIG_HIGHMEM */
111 #define cifs_kmap_lock() do { ; } while(0)
112 #define cifs_kmap_unlock() do { ; } while(0)
113 #endif /* CONFIG_HIGHMEM */
116 * Mark as invalid, all open files on tree connections since they
117 * were closed when session to server was lost.
120 cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
122 struct cifsFileInfo *open_file = NULL;
123 struct list_head *tmp;
124 struct list_head *tmp1;
126 /* list all files open on tree connection and mark them invalid */
127 spin_lock(&cifs_file_list_lock);
128 list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
129 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
130 open_file->invalidHandle = true;
131 open_file->oplock_break_cancelled = true;
133 spin_unlock(&cifs_file_list_lock);
135 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
140 /* reconnect the socket, tcon, and smb session if needed */
142 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
145 struct cifs_ses *ses;
146 struct TCP_Server_Info *server;
147 struct nls_table *nls_codepage;
150 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
151 * tcp and smb session status done differently for those three - in the
158 server = ses->server;
161 * only tree disconnect, open, and write, (and ulogoff which does not
162 * have tcon) are allowed as we start force umount
164 if (tcon->tidStatus == CifsExiting) {
165 if (smb_command != SMB_COM_WRITE_ANDX &&
166 smb_command != SMB_COM_OPEN_ANDX &&
167 smb_command != SMB_COM_TREE_DISCONNECT) {
168 cFYI(1, "can not send cmd %d while umounting",
175 * Give demultiplex thread up to 10 seconds to reconnect, should be
176 * greater than cifs socket timeout which is 7 seconds
178 while (server->tcpStatus == CifsNeedReconnect) {
179 wait_event_interruptible_timeout(server->response_q,
180 (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
182 /* are we still trying to reconnect? */
183 if (server->tcpStatus != CifsNeedReconnect)
187 * on "soft" mounts we wait once. Hard mounts keep
188 * retrying until process is killed or server comes
192 cFYI(1, "gave up waiting on reconnect in smb_init");
197 if (!ses->need_reconnect && !tcon->need_reconnect)
200 nls_codepage = load_nls_default();
203 * need to prevent multiple threads trying to simultaneously
204 * reconnect the same SMB session
206 mutex_lock(&ses->session_mutex);
207 rc = cifs_negotiate_protocol(0, ses);
208 if (rc == 0 && ses->need_reconnect)
209 rc = cifs_setup_session(0, ses, nls_codepage);
211 /* do we need to reconnect tcon? */
212 if (rc || !tcon->need_reconnect) {
213 mutex_unlock(&ses->session_mutex);
217 cifs_mark_open_files_invalid(tcon);
218 rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
219 mutex_unlock(&ses->session_mutex);
220 cFYI(1, "reconnect tcon rc = %d", rc);
226 * FIXME: check if wsize needs updated due to negotiated smb buffer
229 atomic_inc(&tconInfoReconnectCount);
231 /* tell server Unix caps we support */
232 if (ses->capabilities & CAP_UNIX)
233 reset_cifs_unix_caps(0, tcon, NULL, NULL);
236 * Removed call to reopen open files here. It is safer (and faster) to
237 * reopen files one at a time as needed in read and write.
239 * FIXME: what about file locks? don't we need to reclaim them ASAP?
244 * Check if handle based operation so we know whether we can continue
245 * or not without returning to caller to reset file handle
247 switch (smb_command) {
248 case SMB_COM_READ_ANDX:
249 case SMB_COM_WRITE_ANDX:
251 case SMB_COM_FIND_CLOSE2:
252 case SMB_COM_LOCKING_ANDX:
256 unload_nls(nls_codepage);
260 /* Allocate and return pointer to an SMB request buffer, and set basic
261 SMB information in the SMB header. If the return code is zero, this
262 function must have filled in request_buf pointer */
264 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
269 rc = cifs_reconnect_tcon(tcon, smb_command);
273 *request_buf = cifs_small_buf_get();
274 if (*request_buf == NULL) {
275 /* BB should we add a retry in here if not a writepage? */
279 header_assemble((struct smb_hdr *) *request_buf, smb_command,
283 cifs_stats_inc(&tcon->num_smbs_sent);
289 small_smb_init_no_tc(const int smb_command, const int wct,
290 struct cifs_ses *ses, void **request_buf)
293 struct smb_hdr *buffer;
295 rc = small_smb_init(smb_command, wct, NULL, request_buf);
299 buffer = (struct smb_hdr *)*request_buf;
300 buffer->Mid = get_next_mid(ses->server);
301 if (ses->capabilities & CAP_UNICODE)
302 buffer->Flags2 |= SMBFLG2_UNICODE;
303 if (ses->capabilities & CAP_STATUS32)
304 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
306 /* uid, tid can stay at zero as set in header assemble */
308 /* BB add support for turning on the signing when
309 this function is used after 1st of session setup requests */
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)
319 *request_buf = cifs_buf_get();
320 if (*request_buf == NULL) {
321 /* BB should we add a retry in here if not a writepage? */
324 /* Although the original thought was we needed the response buf for */
325 /* potential retries of smb operations it turns out we can determine */
326 /* from the mid flags when the request buffer can be resent without */
327 /* having to use a second distinct buffer for the response */
329 *response_buf = *request_buf;
331 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
335 cifs_stats_inc(&tcon->num_smbs_sent);
340 /* If the return code is zero, this function must fill in request_buf pointer */
342 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
343 void **request_buf, void **response_buf)
347 rc = cifs_reconnect_tcon(tcon, smb_command);
351 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
355 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
356 void **request_buf, void **response_buf)
358 if (tcon->ses->need_reconnect || tcon->need_reconnect)
361 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
364 static int validate_t2(struct smb_t2_rsp *pSMB)
366 unsigned int total_size;
368 /* check for plausible wct */
369 if (pSMB->hdr.WordCount < 10)
372 /* check for parm and data offset going beyond end of smb */
373 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
374 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
377 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
378 if (total_size >= 512)
381 /* check that bcc is at least as big as parms + data, and that it is
382 * less than negotiated smb buffer
384 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
385 if (total_size > get_bcc(&pSMB->hdr) ||
386 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
391 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
392 sizeof(struct smb_t2_rsp) + 16);
397 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
400 NEGOTIATE_RSP *pSMBr;
404 struct TCP_Server_Info *server;
406 unsigned int secFlags;
409 server = ses->server;
414 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
415 (void **) &pSMB, (void **) &pSMBr);
419 /* if any of auth flags (ie not sign or seal) are overriden use them */
420 if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
421 secFlags = ses->overrideSecFlg; /* BB FIXME fix sign flags? */
422 else /* if override flags set only sign/seal OR them with global auth */
423 secFlags = global_secflags | ses->overrideSecFlg;
425 cFYI(1, "secFlags 0x%x", secFlags);
427 pSMB->hdr.Mid = get_next_mid(server);
428 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
430 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
431 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
432 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
433 cFYI(1, "Kerberos only mechanism, enable extended security");
434 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
435 } else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
436 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
437 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
438 cFYI(1, "NTLMSSP only mechanism, enable extended security");
439 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
443 for (i = 0; i < CIFS_NUM_PROT; i++) {
444 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
445 count += strlen(protocols[i].name) + 1;
446 /* null at end of source and target buffers anyway */
448 inc_rfc1001_len(pSMB, count);
449 pSMB->ByteCount = cpu_to_le16(count);
451 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
452 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
456 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
457 cFYI(1, "Dialect: %d", server->dialect);
458 /* Check wct = 1 error case */
459 if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
460 /* core returns wct = 1, but we do not ask for core - otherwise
461 small wct just comes when dialect index is -1 indicating we
462 could not negotiate a common dialect */
465 #ifdef CONFIG_CIFS_WEAK_PW_HASH
466 } else if ((pSMBr->hdr.WordCount == 13)
467 && ((server->dialect == LANMAN_PROT)
468 || (server->dialect == LANMAN2_PROT))) {
470 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
472 if ((secFlags & CIFSSEC_MAY_LANMAN) ||
473 (secFlags & CIFSSEC_MAY_PLNTXT))
474 server->secType = LANMAN;
476 cERROR(1, "mount failed weak security disabled"
477 " in /proc/fs/cifs/SecurityFlags");
481 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
482 server->maxReq = min_t(unsigned int,
483 le16_to_cpu(rsp->MaxMpxCount),
485 set_credits(server, server->maxReq);
486 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
487 server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
488 /* even though we do not use raw we might as well set this
489 accurately, in case we ever find a need for it */
490 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
491 server->max_rw = 0xFF00;
492 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
494 server->max_rw = 0;/* do not need to use raw anyway */
495 server->capabilities = CAP_MPX_MODE;
497 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
499 /* OS/2 often does not set timezone therefore
500 * we must use server time to calc time zone.
501 * Could deviate slightly from the right zone.
502 * Smallest defined timezone difference is 15 minutes
503 * (i.e. Nepal). Rounding up/down is done to match
506 int val, seconds, remain, result;
507 struct timespec ts, utc;
509 ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
510 rsp->SrvTime.Time, 0);
511 cFYI(1, "SrvTime %d sec since 1970 (utc: %d) diff: %d",
512 (int)ts.tv_sec, (int)utc.tv_sec,
513 (int)(utc.tv_sec - ts.tv_sec));
514 val = (int)(utc.tv_sec - ts.tv_sec);
516 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
517 remain = seconds % MIN_TZ_ADJ;
518 if (remain >= (MIN_TZ_ADJ / 2))
519 result += MIN_TZ_ADJ;
522 server->timeAdj = result;
524 server->timeAdj = (int)tmp;
525 server->timeAdj *= 60; /* also in seconds */
527 cFYI(1, "server->timeAdj: %d seconds", server->timeAdj);
530 /* BB get server time for time conversions and add
531 code to use it and timezone since this is not UTC */
533 if (rsp->EncryptionKeyLength ==
534 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
535 memcpy(ses->server->cryptkey, rsp->EncryptionKey,
536 CIFS_CRYPTO_KEY_SIZE);
537 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
538 rc = -EIO; /* need cryptkey unless plain text */
542 cFYI(1, "LANMAN negotiated");
543 /* we will not end up setting signing flags - as no signing
544 was in LANMAN and server did not return the flags on */
546 #else /* weak security disabled */
547 } else if (pSMBr->hdr.WordCount == 13) {
548 cERROR(1, "mount failed, cifs module not built "
549 "with CIFS_WEAK_PW_HASH support");
551 #endif /* WEAK_PW_HASH */
553 } else if (pSMBr->hdr.WordCount != 17) {
558 /* else wct == 17 NTLM */
559 server->sec_mode = pSMBr->SecurityMode;
560 if ((server->sec_mode & SECMODE_USER) == 0)
561 cFYI(1, "share mode security");
563 if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
564 #ifdef CONFIG_CIFS_WEAK_PW_HASH
565 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
566 #endif /* CIFS_WEAK_PW_HASH */
567 cERROR(1, "Server requests plain text password"
568 " but client support disabled");
570 if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
571 server->secType = NTLMv2;
572 else if (secFlags & CIFSSEC_MAY_NTLM)
573 server->secType = NTLM;
574 else if (secFlags & CIFSSEC_MAY_NTLMV2)
575 server->secType = NTLMv2;
576 else if (secFlags & CIFSSEC_MAY_KRB5)
577 server->secType = Kerberos;
578 else if (secFlags & CIFSSEC_MAY_NTLMSSP)
579 server->secType = RawNTLMSSP;
580 else if (secFlags & CIFSSEC_MAY_LANMAN)
581 server->secType = LANMAN;
584 cERROR(1, "Invalid security type");
587 /* else ... any others ...? */
589 /* one byte, so no need to convert this or EncryptionKeyLen from
591 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
593 set_credits(server, server->maxReq);
594 /* probably no need to store and check maxvcs */
595 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
596 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
597 cFYI(DBG2, "Max buf = %d", ses->server->maxBuf);
598 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
599 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
600 server->timeAdj *= 60;
601 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
602 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
603 CIFS_CRYPTO_KEY_SIZE);
604 } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
605 server->capabilities & CAP_EXTENDED_SECURITY) &&
606 (pSMBr->EncryptionKeyLength == 0)) {
607 /* decode security blob */
608 count = get_bcc(&pSMBr->hdr);
613 spin_lock(&cifs_tcp_ses_lock);
614 if (server->srv_count > 1) {
615 spin_unlock(&cifs_tcp_ses_lock);
616 if (memcmp(server->server_GUID,
617 pSMBr->u.extended_response.
619 cFYI(1, "server UID changed");
620 memcpy(server->server_GUID,
621 pSMBr->u.extended_response.GUID,
625 spin_unlock(&cifs_tcp_ses_lock);
626 memcpy(server->server_GUID,
627 pSMBr->u.extended_response.GUID, 16);
631 server->secType = RawNTLMSSP;
633 rc = decode_negTokenInit(pSMBr->u.extended_response.
634 SecurityBlob, count - 16,
640 if (server->secType == Kerberos) {
641 if (!server->sec_kerberos &&
642 !server->sec_mskerberos)
644 } else if (server->secType == RawNTLMSSP) {
645 if (!server->sec_ntlmssp)
650 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
651 rc = -EIO; /* no crypt key only if plain text pwd */
654 server->capabilities &= ~CAP_EXTENDED_SECURITY;
656 #ifdef CONFIG_CIFS_WEAK_PW_HASH
659 if ((secFlags & CIFSSEC_MAY_SIGN) == 0) {
660 /* MUST_SIGN already includes the MAY_SIGN FLAG
661 so if this is zero it means that signing is disabled */
662 cFYI(1, "Signing disabled");
663 if (server->sec_mode & SECMODE_SIGN_REQUIRED) {
664 cERROR(1, "Server requires "
665 "packet signing to be enabled in "
666 "/proc/fs/cifs/SecurityFlags.");
670 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
671 } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
672 /* signing required */
673 cFYI(1, "Must sign - secFlags 0x%x", secFlags);
674 if ((server->sec_mode &
675 (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
676 cERROR(1, "signing required but server lacks support");
679 server->sec_mode |= SECMODE_SIGN_REQUIRED;
681 /* signing optional ie CIFSSEC_MAY_SIGN */
682 if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0)
684 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
688 cifs_buf_release(pSMB);
690 cFYI(1, "negprot rc %d", rc);
695 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
697 struct smb_hdr *smb_buffer;
700 cFYI(1, "In tree disconnect");
702 /* BB: do we need to check this? These should never be NULL. */
703 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
707 * No need to return error on this operation if tid invalidated and
708 * closed on server already e.g. due to tcp session crashing. Also,
709 * the tcon is no longer on the list, so no need to take lock before
712 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
715 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
716 (void **)&smb_buffer);
720 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
722 cFYI(1, "Tree disconnect failed %d", rc);
724 /* No need to return error on this operation if tid invalidated and
725 closed on server already e.g. due to tcp session crashing */
733 * This is a no-op for now. We're not really interested in the reply, but
734 * rather in the fact that the server sent one and that server->lstrp
737 * FIXME: maybe we should consider checking that the reply matches request?
740 cifs_echo_callback(struct mid_q_entry *mid)
742 struct TCP_Server_Info *server = mid->callback_data;
744 DeleteMidQEntry(mid);
745 add_credits(server, 1, CIFS_ECHO_OP);
749 CIFSSMBEcho(struct TCP_Server_Info *server)
755 cFYI(1, "In echo request");
757 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
761 /* set up echo request */
762 smb->hdr.Tid = 0xffff;
763 smb->hdr.WordCount = 1;
764 put_unaligned_le16(1, &smb->EchoCount);
765 put_bcc(1, &smb->hdr);
767 inc_rfc1001_len(smb, 3);
769 iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
771 rc = cifs_call_async(server, &iov, 1, NULL, cifs_echo_callback,
772 server, CIFS_ASYNC_OP | CIFS_ECHO_OP);
774 cFYI(1, "Echo request failed: %d", rc);
776 cifs_small_buf_release(smb);
782 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
784 LOGOFF_ANDX_REQ *pSMB;
787 cFYI(1, "In SMBLogoff for session disconnect");
790 * BB: do we need to check validity of ses and server? They should
791 * always be valid since we have an active reference. If not, that
792 * should probably be a BUG()
794 if (!ses || !ses->server)
797 mutex_lock(&ses->session_mutex);
798 if (ses->need_reconnect)
799 goto session_already_dead; /* no need to send SMBlogoff if uid
800 already closed due to reconnect */
801 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
803 mutex_unlock(&ses->session_mutex);
807 pSMB->hdr.Mid = get_next_mid(ses->server);
809 if (ses->server->sec_mode &
810 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
811 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
813 pSMB->hdr.Uid = ses->Suid;
815 pSMB->AndXCommand = 0xFF;
816 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
817 session_already_dead:
818 mutex_unlock(&ses->session_mutex);
820 /* if session dead then we do not need to do ulogoff,
821 since server closed smb session, no sense reporting
829 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
830 const char *fileName, __u16 type,
831 const struct nls_table *nls_codepage, int remap)
833 TRANSACTION2_SPI_REQ *pSMB = NULL;
834 TRANSACTION2_SPI_RSP *pSMBr = NULL;
835 struct unlink_psx_rq *pRqD;
838 int bytes_returned = 0;
839 __u16 params, param_offset, offset, byte_count;
841 cFYI(1, "In POSIX delete");
843 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
848 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
850 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
851 PATH_MAX, nls_codepage, remap);
852 name_len++; /* trailing null */
854 } else { /* BB add path length overrun check */
855 name_len = strnlen(fileName, PATH_MAX);
856 name_len++; /* trailing null */
857 strncpy(pSMB->FileName, fileName, name_len);
860 params = 6 + name_len;
861 pSMB->MaxParameterCount = cpu_to_le16(2);
862 pSMB->MaxDataCount = 0; /* BB double check this with jra */
863 pSMB->MaxSetupCount = 0;
868 param_offset = offsetof(struct smb_com_transaction2_spi_req,
869 InformationLevel) - 4;
870 offset = param_offset + params;
872 /* Setup pointer to Request Data (inode type) */
873 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
874 pRqD->type = cpu_to_le16(type);
875 pSMB->ParameterOffset = cpu_to_le16(param_offset);
876 pSMB->DataOffset = cpu_to_le16(offset);
877 pSMB->SetupCount = 1;
879 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
880 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
882 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
883 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
884 pSMB->ParameterCount = cpu_to_le16(params);
885 pSMB->TotalParameterCount = pSMB->ParameterCount;
886 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
888 inc_rfc1001_len(pSMB, byte_count);
889 pSMB->ByteCount = cpu_to_le16(byte_count);
890 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
891 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
893 cFYI(1, "Posix delete returned %d", rc);
894 cifs_buf_release(pSMB);
896 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
905 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon,
906 const char *fileName, const struct nls_table *nls_codepage,
909 DELETE_FILE_REQ *pSMB = NULL;
910 DELETE_FILE_RSP *pSMBr = NULL;
916 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
921 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
923 cifsConvertToUTF16((__le16 *) pSMB->fileName, fileName,
924 PATH_MAX, nls_codepage, remap);
925 name_len++; /* trailing null */
927 } else { /* BB improve check for buffer overruns BB */
928 name_len = strnlen(fileName, PATH_MAX);
929 name_len++; /* trailing null */
930 strncpy(pSMB->fileName, fileName, name_len);
932 pSMB->SearchAttributes =
933 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
934 pSMB->BufferFormat = 0x04;
935 inc_rfc1001_len(pSMB, name_len + 1);
936 pSMB->ByteCount = cpu_to_le16(name_len + 1);
937 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
938 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
939 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
941 cFYI(1, "Error in RMFile = %d", rc);
943 cifs_buf_release(pSMB);
951 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
952 struct cifs_sb_info *cifs_sb)
954 DELETE_DIRECTORY_REQ *pSMB = NULL;
955 DELETE_DIRECTORY_RSP *pSMBr = NULL;
959 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
961 cFYI(1, "In CIFSSMBRmDir");
963 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
968 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
969 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
970 PATH_MAX, cifs_sb->local_nls,
972 name_len++; /* trailing null */
974 } else { /* BB improve check for buffer overruns BB */
975 name_len = strnlen(name, PATH_MAX);
976 name_len++; /* trailing null */
977 strncpy(pSMB->DirName, name, name_len);
980 pSMB->BufferFormat = 0x04;
981 inc_rfc1001_len(pSMB, name_len + 1);
982 pSMB->ByteCount = cpu_to_le16(name_len + 1);
983 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
984 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
985 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
987 cFYI(1, "Error in RMDir = %d", rc);
989 cifs_buf_release(pSMB);
996 CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
997 struct cifs_sb_info *cifs_sb)
1000 CREATE_DIRECTORY_REQ *pSMB = NULL;
1001 CREATE_DIRECTORY_RSP *pSMBr = NULL;
1004 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
1006 cFYI(1, "In CIFSSMBMkDir");
1008 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
1013 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1014 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1015 PATH_MAX, cifs_sb->local_nls,
1017 name_len++; /* trailing null */
1019 } else { /* BB improve check for buffer overruns BB */
1020 name_len = strnlen(name, PATH_MAX);
1021 name_len++; /* trailing null */
1022 strncpy(pSMB->DirName, name, name_len);
1025 pSMB->BufferFormat = 0x04;
1026 inc_rfc1001_len(pSMB, name_len + 1);
1027 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1028 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1029 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1030 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1032 cFYI(1, "Error in Mkdir = %d", rc);
1034 cifs_buf_release(pSMB);
1041 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1042 __u32 posix_flags, __u64 mode, __u16 *netfid,
1043 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1044 const char *name, const struct nls_table *nls_codepage,
1047 TRANSACTION2_SPI_REQ *pSMB = NULL;
1048 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1051 int bytes_returned = 0;
1052 __u16 params, param_offset, offset, byte_count, count;
1053 OPEN_PSX_REQ *pdata;
1054 OPEN_PSX_RSP *psx_rsp;
1056 cFYI(1, "In POSIX Create");
1058 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1063 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1065 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1066 PATH_MAX, nls_codepage, remap);
1067 name_len++; /* trailing null */
1069 } else { /* BB improve the check for buffer overruns BB */
1070 name_len = strnlen(name, PATH_MAX);
1071 name_len++; /* trailing null */
1072 strncpy(pSMB->FileName, name, name_len);
1075 params = 6 + name_len;
1076 count = sizeof(OPEN_PSX_REQ);
1077 pSMB->MaxParameterCount = cpu_to_le16(2);
1078 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1079 pSMB->MaxSetupCount = 0;
1083 pSMB->Reserved2 = 0;
1084 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1085 InformationLevel) - 4;
1086 offset = param_offset + params;
1087 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1088 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1089 pdata->Permissions = cpu_to_le64(mode);
1090 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1091 pdata->OpenFlags = cpu_to_le32(*pOplock);
1092 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1093 pSMB->DataOffset = cpu_to_le16(offset);
1094 pSMB->SetupCount = 1;
1095 pSMB->Reserved3 = 0;
1096 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1097 byte_count = 3 /* pad */ + params + count;
1099 pSMB->DataCount = cpu_to_le16(count);
1100 pSMB->ParameterCount = cpu_to_le16(params);
1101 pSMB->TotalDataCount = pSMB->DataCount;
1102 pSMB->TotalParameterCount = pSMB->ParameterCount;
1103 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1104 pSMB->Reserved4 = 0;
1105 inc_rfc1001_len(pSMB, byte_count);
1106 pSMB->ByteCount = cpu_to_le16(byte_count);
1107 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1108 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1110 cFYI(1, "Posix create returned %d", rc);
1111 goto psx_create_err;
1114 cFYI(1, "copying inode info");
1115 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1117 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1118 rc = -EIO; /* bad smb */
1119 goto psx_create_err;
1122 /* copy return information to pRetData */
1123 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1124 + le16_to_cpu(pSMBr->t2.DataOffset));
1126 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1128 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1129 /* Let caller know file was created so we can set the mode. */
1130 /* Do we care about the CreateAction in any other cases? */
1131 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1132 *pOplock |= CIFS_CREATE_ACTION;
1133 /* check to make sure response data is there */
1134 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1135 pRetData->Type = cpu_to_le32(-1); /* unknown */
1136 cFYI(DBG2, "unknown type");
1138 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1139 + sizeof(FILE_UNIX_BASIC_INFO)) {
1140 cERROR(1, "Open response data too small");
1141 pRetData->Type = cpu_to_le32(-1);
1142 goto psx_create_err;
1144 memcpy((char *) pRetData,
1145 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1146 sizeof(FILE_UNIX_BASIC_INFO));
1150 cifs_buf_release(pSMB);
1152 if (posix_flags & SMB_O_DIRECTORY)
1153 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1155 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1163 static __u16 convert_disposition(int disposition)
1167 switch (disposition) {
1168 case FILE_SUPERSEDE:
1169 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1172 ofun = SMBOPEN_OAPPEND;
1175 ofun = SMBOPEN_OCREATE;
1178 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1180 case FILE_OVERWRITE:
1181 ofun = SMBOPEN_OTRUNC;
1183 case FILE_OVERWRITE_IF:
1184 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1187 cFYI(1, "unknown disposition %d", disposition);
1188 ofun = SMBOPEN_OAPPEND; /* regular open */
1194 access_flags_to_smbopen_mode(const int access_flags)
1196 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1198 if (masked_flags == GENERIC_READ)
1199 return SMBOPEN_READ;
1200 else if (masked_flags == GENERIC_WRITE)
1201 return SMBOPEN_WRITE;
1203 /* just go for read/write */
1204 return SMBOPEN_READWRITE;
1208 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1209 const char *fileName, const int openDisposition,
1210 const int access_flags, const int create_options, __u16 *netfid,
1211 int *pOplock, FILE_ALL_INFO *pfile_info,
1212 const struct nls_table *nls_codepage, int remap)
1215 OPENX_REQ *pSMB = NULL;
1216 OPENX_RSP *pSMBr = NULL;
1222 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1227 pSMB->AndXCommand = 0xFF; /* none */
1229 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1230 count = 1; /* account for one byte pad to word boundary */
1232 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1233 fileName, PATH_MAX, nls_codepage, remap);
1234 name_len++; /* trailing null */
1236 } else { /* BB improve check for buffer overruns BB */
1237 count = 0; /* no pad */
1238 name_len = strnlen(fileName, PATH_MAX);
1239 name_len++; /* trailing null */
1240 strncpy(pSMB->fileName, fileName, name_len);
1242 if (*pOplock & REQ_OPLOCK)
1243 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1244 else if (*pOplock & REQ_BATCHOPLOCK)
1245 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1247 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1248 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1249 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1250 /* set file as system file if special file such
1251 as fifo and server expecting SFU style and
1252 no Unix extensions */
1254 if (create_options & CREATE_OPTION_SPECIAL)
1255 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1256 else /* BB FIXME BB */
1257 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1259 if (create_options & CREATE_OPTION_READONLY)
1260 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1263 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1264 CREATE_OPTIONS_MASK); */
1265 /* BB FIXME END BB */
1267 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1268 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1270 inc_rfc1001_len(pSMB, count);
1272 pSMB->ByteCount = cpu_to_le16(count);
1273 /* long_op set to 1 to allow for oplock break timeouts */
1274 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1275 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1276 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1278 cFYI(1, "Error in Open = %d", rc);
1280 /* BB verify if wct == 15 */
1282 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1284 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1285 /* Let caller know file was created so we can set the mode. */
1286 /* Do we care about the CreateAction in any other cases? */
1288 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1289 *pOplock |= CIFS_CREATE_ACTION; */
1293 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1294 pfile_info->LastAccessTime = 0; /* BB fixme */
1295 pfile_info->LastWriteTime = 0; /* BB fixme */
1296 pfile_info->ChangeTime = 0; /* BB fixme */
1297 pfile_info->Attributes =
1298 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1299 /* the file_info buf is endian converted by caller */
1300 pfile_info->AllocationSize =
1301 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1302 pfile_info->EndOfFile = pfile_info->AllocationSize;
1303 pfile_info->NumberOfLinks = cpu_to_le32(1);
1304 pfile_info->DeletePending = 0;
1308 cifs_buf_release(pSMB);
1315 CIFSSMBOpen(const unsigned int xid, struct cifs_tcon *tcon,
1316 const char *fileName, const int openDisposition,
1317 const int access_flags, const int create_options, __u16 *netfid,
1318 int *pOplock, FILE_ALL_INFO *pfile_info,
1319 const struct nls_table *nls_codepage, int remap)
1322 OPEN_REQ *pSMB = NULL;
1323 OPEN_RSP *pSMBr = NULL;
1329 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **) &pSMB,
1334 pSMB->AndXCommand = 0xFF; /* none */
1336 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1337 count = 1; /* account for one byte pad to word boundary */
1339 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1340 fileName, PATH_MAX, nls_codepage, remap);
1341 name_len++; /* trailing null */
1343 pSMB->NameLength = cpu_to_le16(name_len);
1344 } else { /* BB improve check for buffer overruns BB */
1345 count = 0; /* no pad */
1346 name_len = strnlen(fileName, PATH_MAX);
1347 name_len++; /* trailing null */
1348 pSMB->NameLength = cpu_to_le16(name_len);
1349 strncpy(pSMB->fileName, fileName, name_len);
1351 if (*pOplock & REQ_OPLOCK)
1352 pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1353 else if (*pOplock & REQ_BATCHOPLOCK)
1354 pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1355 pSMB->DesiredAccess = cpu_to_le32(access_flags);
1356 pSMB->AllocationSize = 0;
1357 /* set file as system file if special file such
1358 as fifo and server expecting SFU style and
1359 no Unix extensions */
1360 if (create_options & CREATE_OPTION_SPECIAL)
1361 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1363 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1365 /* XP does not handle ATTR_POSIX_SEMANTICS */
1366 /* but it helps speed up case sensitive checks for other
1367 servers such as Samba */
1368 if (tcon->ses->capabilities & CAP_UNIX)
1369 pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1371 if (create_options & CREATE_OPTION_READONLY)
1372 pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1374 pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1375 pSMB->CreateDisposition = cpu_to_le32(openDisposition);
1376 pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1377 /* BB Expirement with various impersonation levels and verify */
1378 pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1379 pSMB->SecurityFlags =
1380 SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
1383 inc_rfc1001_len(pSMB, count);
1385 pSMB->ByteCount = cpu_to_le16(count);
1386 /* long_op set to 1 to allow for oplock break timeouts */
1387 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1388 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1389 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1391 cFYI(1, "Error in Open = %d", rc);
1393 *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
1394 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1395 /* Let caller know file was created so we can set the mode. */
1396 /* Do we care about the CreateAction in any other cases? */
1397 if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1398 *pOplock |= CIFS_CREATE_ACTION;
1400 memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
1401 36 /* CreationTime to Attributes */);
1402 /* the file_info buf is endian converted by caller */
1403 pfile_info->AllocationSize = pSMBr->AllocationSize;
1404 pfile_info->EndOfFile = pSMBr->EndOfFile;
1405 pfile_info->NumberOfLinks = cpu_to_le32(1);
1406 pfile_info->DeletePending = 0;
1410 cifs_buf_release(pSMB);
1417 * Discard any remaining data in the current SMB. To do this, we borrow the
1421 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1423 unsigned int rfclen = get_rfc1002_length(server->smallbuf);
1424 int remaining = rfclen + 4 - server->total_read;
1425 struct cifs_readdata *rdata = mid->callback_data;
1427 while (remaining > 0) {
1430 length = cifs_read_from_socket(server, server->bigbuf,
1431 min_t(unsigned int, remaining,
1432 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1435 server->total_read += length;
1436 remaining -= length;
1439 dequeue_mid(mid, rdata->result);
1444 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1447 unsigned int data_offset, data_len;
1448 struct cifs_readdata *rdata = mid->callback_data;
1449 char *buf = server->smallbuf;
1450 unsigned int buflen = get_rfc1002_length(buf) + 4;
1452 cFYI(1, "%s: mid=%llu offset=%llu bytes=%u", __func__,
1453 mid->mid, rdata->offset, rdata->bytes);
1456 * read the rest of READ_RSP header (sans Data array), or whatever we
1457 * can if there's not enough data. At this point, we've read down to
1460 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1461 HEADER_SIZE(server) + 1;
1463 rdata->iov[0].iov_base = buf + HEADER_SIZE(server) - 1;
1464 rdata->iov[0].iov_len = len;
1466 length = cifs_readv_from_socket(server, rdata->iov, 1, len);
1469 server->total_read += length;
1471 /* Was the SMB read successful? */
1472 rdata->result = server->ops->map_error(buf, false);
1473 if (rdata->result != 0) {
1474 cFYI(1, "%s: server returned error %d", __func__,
1476 return cifs_readv_discard(server, mid);
1479 /* Is there enough to get to the rest of the READ_RSP header? */
1480 if (server->total_read < server->vals->read_rsp_size) {
1481 cFYI(1, "%s: server returned short header. got=%u expected=%zu",
1482 __func__, server->total_read,
1483 server->vals->read_rsp_size);
1484 rdata->result = -EIO;
1485 return cifs_readv_discard(server, mid);
1488 data_offset = server->ops->read_data_offset(buf) + 4;
1489 if (data_offset < server->total_read) {
1491 * win2k8 sometimes sends an offset of 0 when the read
1492 * is beyond the EOF. Treat it as if the data starts just after
1495 cFYI(1, "%s: data offset (%u) inside read response header",
1496 __func__, data_offset);
1497 data_offset = server->total_read;
1498 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1499 /* data_offset is beyond the end of smallbuf */
1500 cFYI(1, "%s: data offset (%u) beyond end of smallbuf",
1501 __func__, data_offset);
1502 rdata->result = -EIO;
1503 return cifs_readv_discard(server, mid);
1506 cFYI(1, "%s: total_read=%u data_offset=%u", __func__,
1507 server->total_read, data_offset);
1509 len = data_offset - server->total_read;
1511 /* read any junk before data into the rest of smallbuf */
1512 rdata->iov[0].iov_base = buf + server->total_read;
1513 rdata->iov[0].iov_len = len;
1514 length = cifs_readv_from_socket(server, rdata->iov, 1, len);
1517 server->total_read += length;
1520 /* set up first iov for signature check */
1521 rdata->iov[0].iov_base = buf;
1522 rdata->iov[0].iov_len = server->total_read;
1523 cFYI(1, "0: iov_base=%p iov_len=%zu",
1524 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1526 /* how much data is in the response? */
1527 data_len = server->ops->read_data_length(buf);
1528 if (data_offset + data_len > buflen) {
1529 /* data_len is corrupt -- discard frame */
1530 rdata->result = -EIO;
1531 return cifs_readv_discard(server, mid);
1534 /* marshal up the page array */
1536 len = rdata->marshal_iov(rdata, data_len);
1540 /* issue the read if we have any iovecs left to fill */
1541 if (rdata->nr_iov > 1) {
1542 length = cifs_readv_from_socket(server, &rdata->iov[1],
1543 rdata->nr_iov - 1, len);
1546 server->total_read += length;
1551 rdata->bytes = length;
1553 cFYI(1, "total_read=%u buflen=%u remaining=%u", server->total_read,
1556 /* discard anything left over */
1557 if (server->total_read < buflen)
1558 return cifs_readv_discard(server, mid);
1560 dequeue_mid(mid, false);
1565 cifs_readv_callback(struct mid_q_entry *mid)
1567 struct cifs_readdata *rdata = mid->callback_data;
1568 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1569 struct TCP_Server_Info *server = tcon->ses->server;
1571 cFYI(1, "%s: mid=%llu state=%d result=%d bytes=%u", __func__,
1572 mid->mid, mid->mid_state, rdata->result, rdata->bytes);
1574 switch (mid->mid_state) {
1575 case MID_RESPONSE_RECEIVED:
1576 /* result already set, check signature */
1577 if (server->sec_mode &
1578 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
1581 rc = cifs_verify_signature(rdata->iov, rdata->nr_iov,
1583 mid->sequence_number + 1);
1585 cERROR(1, "SMB signature verification returned "
1588 /* FIXME: should this be counted toward the initiating task? */
1589 task_io_account_read(rdata->bytes);
1590 cifs_stats_bytes_read(tcon, rdata->bytes);
1592 case MID_REQUEST_SUBMITTED:
1593 case MID_RETRY_NEEDED:
1594 rdata->result = -EAGAIN;
1597 rdata->result = -EIO;
1600 queue_work(cifsiod_wq, &rdata->work);
1601 DeleteMidQEntry(mid);
1602 add_credits(server, 1, 0);
1605 /* cifs_async_readv - send an async write, and set up mid to handle result */
1607 cifs_async_readv(struct cifs_readdata *rdata)
1610 READ_REQ *smb = NULL;
1612 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1614 cFYI(1, "%s: offset=%llu bytes=%u", __func__,
1615 rdata->offset, rdata->bytes);
1617 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1620 wct = 10; /* old style read */
1621 if ((rdata->offset >> 32) > 0) {
1622 /* can not handle this big offset for old */
1627 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1631 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1632 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1634 smb->AndXCommand = 0xFF; /* none */
1635 smb->Fid = rdata->cfile->netfid;
1636 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1638 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1640 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1641 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1645 /* old style read */
1646 struct smb_com_readx_req *smbr =
1647 (struct smb_com_readx_req *)smb;
1648 smbr->ByteCount = 0;
1651 /* 4 for RFC1001 length + 1 for BCC */
1652 rdata->iov[0].iov_base = smb;
1653 rdata->iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
1655 kref_get(&rdata->refcount);
1656 rc = cifs_call_async(tcon->ses->server, rdata->iov, 1,
1657 cifs_readv_receive, cifs_readv_callback,
1661 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1663 kref_put(&rdata->refcount, cifs_readdata_release);
1665 cifs_small_buf_release(smb);
1670 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1671 unsigned int *nbytes, char **buf, int *pbuf_type)
1674 READ_REQ *pSMB = NULL;
1675 READ_RSP *pSMBr = NULL;
1676 char *pReadData = NULL;
1678 int resp_buf_type = 0;
1680 __u32 pid = io_parms->pid;
1681 __u16 netfid = io_parms->netfid;
1682 __u64 offset = io_parms->offset;
1683 struct cifs_tcon *tcon = io_parms->tcon;
1684 unsigned int count = io_parms->length;
1686 cFYI(1, "Reading %d bytes on fid %d", count, netfid);
1687 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1690 wct = 10; /* old style read */
1691 if ((offset >> 32) > 0) {
1692 /* can not handle this big offset for old */
1698 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1702 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1703 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1705 /* tcon and ses pointer are checked in smb_init */
1706 if (tcon->ses->server == NULL)
1707 return -ECONNABORTED;
1709 pSMB->AndXCommand = 0xFF; /* none */
1711 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1713 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1715 pSMB->Remaining = 0;
1716 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1717 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1719 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1721 /* old style read */
1722 struct smb_com_readx_req *pSMBW =
1723 (struct smb_com_readx_req *)pSMB;
1724 pSMBW->ByteCount = 0;
1727 iov[0].iov_base = (char *)pSMB;
1728 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1729 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1730 &resp_buf_type, CIFS_LOG_ERROR);
1731 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1732 pSMBr = (READ_RSP *)iov[0].iov_base;
1734 cERROR(1, "Send error in read = %d", rc);
1736 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1737 data_length = data_length << 16;
1738 data_length += le16_to_cpu(pSMBr->DataLength);
1739 *nbytes = data_length;
1741 /*check that DataLength would not go beyond end of SMB */
1742 if ((data_length > CIFSMaxBufSize)
1743 || (data_length > count)) {
1744 cFYI(1, "bad length %d for count %d",
1745 data_length, count);
1749 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1750 le16_to_cpu(pSMBr->DataOffset);
1751 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1752 cERROR(1, "Faulting on read rc = %d",rc);
1754 }*/ /* can not use copy_to_user when using page cache*/
1756 memcpy(*buf, pReadData, data_length);
1760 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1762 if (resp_buf_type == CIFS_SMALL_BUFFER)
1763 cifs_small_buf_release(iov[0].iov_base);
1764 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1765 cifs_buf_release(iov[0].iov_base);
1766 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1767 /* return buffer to caller to free */
1768 *buf = iov[0].iov_base;
1769 if (resp_buf_type == CIFS_SMALL_BUFFER)
1770 *pbuf_type = CIFS_SMALL_BUFFER;
1771 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1772 *pbuf_type = CIFS_LARGE_BUFFER;
1773 } /* else no valid buffer on return - leave as null */
1775 /* Note: On -EAGAIN error only caller can retry on handle based calls
1776 since file handle passed in no longer valid */
1782 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1783 unsigned int *nbytes, const char *buf,
1784 const char __user *ubuf, const int long_op)
1787 WRITE_REQ *pSMB = NULL;
1788 WRITE_RSP *pSMBr = NULL;
1789 int bytes_returned, wct;
1792 __u32 pid = io_parms->pid;
1793 __u16 netfid = io_parms->netfid;
1794 __u64 offset = io_parms->offset;
1795 struct cifs_tcon *tcon = io_parms->tcon;
1796 unsigned int count = io_parms->length;
1800 /* cFYI(1, "write at %lld %d bytes", offset, count);*/
1801 if (tcon->ses == NULL)
1802 return -ECONNABORTED;
1804 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1808 if ((offset >> 32) > 0) {
1809 /* can not handle big offset for old srv */
1814 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1819 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1820 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1822 /* tcon and ses pointer are checked in smb_init */
1823 if (tcon->ses->server == NULL)
1824 return -ECONNABORTED;
1826 pSMB->AndXCommand = 0xFF; /* none */
1828 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1830 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1832 pSMB->Reserved = 0xFFFFFFFF;
1833 pSMB->WriteMode = 0;
1834 pSMB->Remaining = 0;
1836 /* Can increase buffer size if buffer is big enough in some cases ie we
1837 can send more if LARGE_WRITE_X capability returned by the server and if
1838 our buffer is big enough or if we convert to iovecs on socket writes
1839 and eliminate the copy to the CIFS buffer */
1840 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1841 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1843 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1847 if (bytes_sent > count)
1850 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1852 memcpy(pSMB->Data, buf, bytes_sent);
1854 if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
1855 cifs_buf_release(pSMB);
1858 } else if (count != 0) {
1860 cifs_buf_release(pSMB);
1862 } /* else setting file size with write of zero bytes */
1864 byte_count = bytes_sent + 1; /* pad */
1865 else /* wct == 12 */
1866 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1868 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1869 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1870 inc_rfc1001_len(pSMB, byte_count);
1873 pSMB->ByteCount = cpu_to_le16(byte_count);
1874 else { /* old style write has byte count 4 bytes earlier
1876 struct smb_com_writex_req *pSMBW =
1877 (struct smb_com_writex_req *)pSMB;
1878 pSMBW->ByteCount = cpu_to_le16(byte_count);
1881 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1882 (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
1883 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1885 cFYI(1, "Send error in write = %d", rc);
1887 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1888 *nbytes = (*nbytes) << 16;
1889 *nbytes += le16_to_cpu(pSMBr->Count);
1892 * Mask off high 16 bits when bytes written as returned by the
1893 * server is greater than bytes requested by the client. Some
1894 * OS/2 servers are known to set incorrect CountHigh values.
1896 if (*nbytes > count)
1900 cifs_buf_release(pSMB);
1902 /* Note: On -EAGAIN error only caller can retry on handle based calls
1903 since file handle passed in no longer valid */
1909 cifs_writedata_release(struct kref *refcount)
1911 struct cifs_writedata *wdata = container_of(refcount,
1912 struct cifs_writedata, refcount);
1915 cifsFileInfo_put(wdata->cfile);
1921 * Write failed with a retryable error. Resend the write request. It's also
1922 * possible that the page was redirtied so re-clean the page.
1925 cifs_writev_requeue(struct cifs_writedata *wdata)
1928 struct inode *inode = wdata->cfile->dentry->d_inode;
1930 for (i = 0; i < wdata->nr_pages; i++) {
1931 lock_page(wdata->pages[i]);
1932 clear_page_dirty_for_io(wdata->pages[i]);
1936 rc = cifs_async_writev(wdata);
1937 } while (rc == -EAGAIN);
1939 for (i = 0; i < wdata->nr_pages; i++) {
1941 SetPageError(wdata->pages[i]);
1942 unlock_page(wdata->pages[i]);
1945 mapping_set_error(inode->i_mapping, rc);
1946 kref_put(&wdata->refcount, cifs_writedata_release);
1950 cifs_writev_complete(struct work_struct *work)
1952 struct cifs_writedata *wdata = container_of(work,
1953 struct cifs_writedata, work);
1954 struct inode *inode = wdata->cfile->dentry->d_inode;
1957 if (wdata->result == 0) {
1958 spin_lock(&inode->i_lock);
1959 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
1960 spin_unlock(&inode->i_lock);
1961 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
1963 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
1964 return cifs_writev_requeue(wdata);
1966 for (i = 0; i < wdata->nr_pages; i++) {
1967 struct page *page = wdata->pages[i];
1968 if (wdata->result == -EAGAIN)
1969 __set_page_dirty_nobuffers(page);
1970 else if (wdata->result < 0)
1972 end_page_writeback(page);
1973 page_cache_release(page);
1975 if (wdata->result != -EAGAIN)
1976 mapping_set_error(inode->i_mapping, wdata->result);
1977 kref_put(&wdata->refcount, cifs_writedata_release);
1980 struct cifs_writedata *
1981 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
1983 struct cifs_writedata *wdata;
1985 /* this would overflow */
1986 if (nr_pages == 0) {
1987 cERROR(1, "%s: called with nr_pages == 0!", __func__);
1991 /* writedata + number of page pointers */
1992 wdata = kzalloc(sizeof(*wdata) +
1993 sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
1994 if (wdata != NULL) {
1995 kref_init(&wdata->refcount);
1996 INIT_LIST_HEAD(&wdata->list);
1997 init_completion(&wdata->done);
1998 INIT_WORK(&wdata->work, complete);
2004 * Check the mid_state and signature on received buffer (if any), and queue the
2005 * workqueue completion task.
2008 cifs_writev_callback(struct mid_q_entry *mid)
2010 struct cifs_writedata *wdata = mid->callback_data;
2011 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2012 unsigned int written;
2013 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2015 switch (mid->mid_state) {
2016 case MID_RESPONSE_RECEIVED:
2017 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2018 if (wdata->result != 0)
2021 written = le16_to_cpu(smb->CountHigh);
2023 written += le16_to_cpu(smb->Count);
2025 * Mask off high 16 bits when bytes written as returned
2026 * by the server is greater than bytes requested by the
2027 * client. OS/2 servers are known to set incorrect
2030 if (written > wdata->bytes)
2033 if (written < wdata->bytes)
2034 wdata->result = -ENOSPC;
2036 wdata->bytes = written;
2038 case MID_REQUEST_SUBMITTED:
2039 case MID_RETRY_NEEDED:
2040 wdata->result = -EAGAIN;
2043 wdata->result = -EIO;
2047 queue_work(cifsiod_wq, &wdata->work);
2048 DeleteMidQEntry(mid);
2049 add_credits(tcon->ses->server, 1, 0);
2052 /* cifs_async_writev - send an async write, and set up mid to handle result */
2054 cifs_async_writev(struct cifs_writedata *wdata)
2056 int i, rc = -EACCES;
2057 WRITE_REQ *smb = NULL;
2059 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2060 struct kvec *iov = NULL;
2062 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2066 if (wdata->offset >> 32 > 0) {
2067 /* can not handle big offset for old srv */
2072 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2074 goto async_writev_out;
2076 /* 1 iov per page + 1 for header */
2077 iov = kzalloc((wdata->nr_pages + 1) * sizeof(*iov), GFP_NOFS);
2080 goto async_writev_out;
2083 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2084 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2086 smb->AndXCommand = 0xFF; /* none */
2087 smb->Fid = wdata->cfile->netfid;
2088 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2090 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2091 smb->Reserved = 0xFFFFFFFF;
2096 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2098 /* 4 for RFC1001 length + 1 for BCC */
2099 iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
2100 iov[0].iov_base = smb;
2103 * This function should marshal up the page array into the kvec
2104 * array, reserving [0] for the header. It should kmap the pages
2105 * and set the iov_len properly for each one. It may also set
2109 wdata->marshal_iov(iov, wdata);
2112 cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
2114 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2115 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2118 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2119 put_bcc(wdata->bytes + 1, &smb->hdr);
2122 struct smb_com_writex_req *smbw =
2123 (struct smb_com_writex_req *)smb;
2124 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2125 put_bcc(wdata->bytes + 5, &smbw->hdr);
2126 iov[0].iov_len += 4; /* pad bigger by four bytes */
2129 kref_get(&wdata->refcount);
2130 rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1,
2131 NULL, cifs_writev_callback, wdata, 0);
2134 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2136 kref_put(&wdata->refcount, cifs_writedata_release);
2138 /* send is done, unmap pages */
2139 for (i = 0; i < wdata->nr_pages; i++)
2140 kunmap(wdata->pages[i]);
2143 cifs_small_buf_release(smb);
2149 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2150 unsigned int *nbytes, struct kvec *iov, int n_vec,
2154 WRITE_REQ *pSMB = NULL;
2157 int resp_buf_type = 0;
2158 __u32 pid = io_parms->pid;
2159 __u16 netfid = io_parms->netfid;
2160 __u64 offset = io_parms->offset;
2161 struct cifs_tcon *tcon = io_parms->tcon;
2162 unsigned int count = io_parms->length;
2166 cFYI(1, "write2 at %lld %d bytes", (long long)offset, count);
2168 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2172 if ((offset >> 32) > 0) {
2173 /* can not handle big offset for old srv */
2177 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2181 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2182 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2184 /* tcon and ses pointer are checked in smb_init */
2185 if (tcon->ses->server == NULL)
2186 return -ECONNABORTED;
2188 pSMB->AndXCommand = 0xFF; /* none */
2190 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2192 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2193 pSMB->Reserved = 0xFFFFFFFF;
2194 pSMB->WriteMode = 0;
2195 pSMB->Remaining = 0;
2198 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2200 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2201 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2202 /* header + 1 byte pad */
2203 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2205 inc_rfc1001_len(pSMB, count + 1);
2206 else /* wct == 12 */
2207 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2209 pSMB->ByteCount = cpu_to_le16(count + 1);
2210 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2211 struct smb_com_writex_req *pSMBW =
2212 (struct smb_com_writex_req *)pSMB;
2213 pSMBW->ByteCount = cpu_to_le16(count + 5);
2215 iov[0].iov_base = pSMB;
2217 iov[0].iov_len = smb_hdr_len + 4;
2218 else /* wct == 12 pad bigger by four bytes */
2219 iov[0].iov_len = smb_hdr_len + 8;
2222 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
2224 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2226 cFYI(1, "Send error Write2 = %d", rc);
2227 } else if (resp_buf_type == 0) {
2228 /* presumably this can not happen, but best to be safe */
2231 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base;
2232 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2233 *nbytes = (*nbytes) << 16;
2234 *nbytes += le16_to_cpu(pSMBr->Count);
2237 * Mask off high 16 bits when bytes written as returned by the
2238 * server is greater than bytes requested by the client. OS/2
2239 * servers are known to set incorrect CountHigh values.
2241 if (*nbytes > count)
2245 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2246 if (resp_buf_type == CIFS_SMALL_BUFFER)
2247 cifs_small_buf_release(iov[0].iov_base);
2248 else if (resp_buf_type == CIFS_LARGE_BUFFER)
2249 cifs_buf_release(iov[0].iov_base);
2251 /* Note: On -EAGAIN error only caller can retry on handle based calls
2252 since file handle passed in no longer valid */
2257 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2258 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2259 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2262 LOCK_REQ *pSMB = NULL;
2267 cFYI(1, "cifs_lockv num lock %d num unlock %d", num_lock, num_unlock);
2269 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2274 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2275 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2276 pSMB->LockType = lock_type;
2277 pSMB->AndXCommand = 0xFF; /* none */
2278 pSMB->Fid = netfid; /* netfid stays le */
2280 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2281 inc_rfc1001_len(pSMB, count);
2282 pSMB->ByteCount = cpu_to_le16(count);
2284 iov[0].iov_base = (char *)pSMB;
2285 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2286 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2287 iov[1].iov_base = (char *)buf;
2288 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2290 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2291 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
2293 cFYI(1, "Send error in cifs_lockv = %d", rc);
2299 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2300 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2301 const __u64 offset, const __u32 numUnlock,
2302 const __u32 numLock, const __u8 lockType,
2303 const bool waitFlag, const __u8 oplock_level)
2306 LOCK_REQ *pSMB = NULL;
2307 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2312 cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock);
2313 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2318 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2319 /* no response expected */
2320 flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP;
2322 } else if (waitFlag) {
2323 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2324 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2329 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2330 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2331 pSMB->LockType = lockType;
2332 pSMB->OplockLevel = oplock_level;
2333 pSMB->AndXCommand = 0xFF; /* none */
2334 pSMB->Fid = smb_file_id; /* netfid stays le */
2336 if ((numLock != 0) || (numUnlock != 0)) {
2337 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2338 /* BB where to store pid high? */
2339 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2340 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2341 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2342 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2343 count = sizeof(LOCKING_ANDX_RANGE);
2348 inc_rfc1001_len(pSMB, count);
2349 pSMB->ByteCount = cpu_to_le16(count);
2352 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2353 (struct smb_hdr *) pSMB, &bytes_returned);
2354 cifs_small_buf_release(pSMB);
2356 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2357 /* SMB buffer freed by function above */
2359 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2361 cFYI(1, "Send error in Lock = %d", rc);
2363 /* Note: On -EAGAIN error only caller can retry on handle based calls
2364 since file handle passed in no longer valid */
2369 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2370 const __u16 smb_file_id, const __u32 netpid,
2371 const loff_t start_offset, const __u64 len,
2372 struct file_lock *pLockData, const __u16 lock_type,
2373 const bool waitFlag)
2375 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2376 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2377 struct cifs_posix_lock *parm_data;
2380 int bytes_returned = 0;
2381 int resp_buf_type = 0;
2382 __u16 params, param_offset, offset, byte_count, count;
2385 cFYI(1, "Posix Lock");
2387 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2392 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2395 pSMB->MaxSetupCount = 0;
2398 pSMB->Reserved2 = 0;
2399 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2400 offset = param_offset + params;
2402 count = sizeof(struct cifs_posix_lock);
2403 pSMB->MaxParameterCount = cpu_to_le16(2);
2404 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2405 pSMB->SetupCount = 1;
2406 pSMB->Reserved3 = 0;
2408 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2410 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2411 byte_count = 3 /* pad */ + params + count;
2412 pSMB->DataCount = cpu_to_le16(count);
2413 pSMB->ParameterCount = cpu_to_le16(params);
2414 pSMB->TotalDataCount = pSMB->DataCount;
2415 pSMB->TotalParameterCount = pSMB->ParameterCount;
2416 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2417 parm_data = (struct cifs_posix_lock *)
2418 (((char *) &pSMB->hdr.Protocol) + offset);
2420 parm_data->lock_type = cpu_to_le16(lock_type);
2422 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2423 parm_data->lock_flags = cpu_to_le16(1);
2424 pSMB->Timeout = cpu_to_le32(-1);
2428 parm_data->pid = cpu_to_le32(netpid);
2429 parm_data->start = cpu_to_le64(start_offset);
2430 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2432 pSMB->DataOffset = cpu_to_le16(offset);
2433 pSMB->Fid = smb_file_id;
2434 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2435 pSMB->Reserved4 = 0;
2436 inc_rfc1001_len(pSMB, byte_count);
2437 pSMB->ByteCount = cpu_to_le16(byte_count);
2439 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2440 (struct smb_hdr *) pSMBr, &bytes_returned);
2442 iov[0].iov_base = (char *)pSMB;
2443 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2444 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2445 &resp_buf_type, timeout);
2446 pSMB = NULL; /* request buf already freed by SendReceive2. Do
2447 not try to free it twice below on exit */
2448 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
2452 cFYI(1, "Send error in Posix Lock = %d", rc);
2453 } else if (pLockData) {
2454 /* lock structure can be returned on get */
2457 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2459 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2460 rc = -EIO; /* bad smb */
2463 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2464 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2465 if (data_count < sizeof(struct cifs_posix_lock)) {
2469 parm_data = (struct cifs_posix_lock *)
2470 ((char *)&pSMBr->hdr.Protocol + data_offset);
2471 if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
2472 pLockData->fl_type = F_UNLCK;
2474 if (parm_data->lock_type ==
2475 __constant_cpu_to_le16(CIFS_RDLCK))
2476 pLockData->fl_type = F_RDLCK;
2477 else if (parm_data->lock_type ==
2478 __constant_cpu_to_le16(CIFS_WRLCK))
2479 pLockData->fl_type = F_WRLCK;
2481 pLockData->fl_start = le64_to_cpu(parm_data->start);
2482 pLockData->fl_end = pLockData->fl_start +
2483 le64_to_cpu(parm_data->length) - 1;
2484 pLockData->fl_pid = le32_to_cpu(parm_data->pid);
2490 cifs_small_buf_release(pSMB);
2492 if (resp_buf_type == CIFS_SMALL_BUFFER)
2493 cifs_small_buf_release(iov[0].iov_base);
2494 else if (resp_buf_type == CIFS_LARGE_BUFFER)
2495 cifs_buf_release(iov[0].iov_base);
2497 /* Note: On -EAGAIN error only caller can retry on handle based calls
2498 since file handle passed in no longer valid */
2505 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2508 CLOSE_REQ *pSMB = NULL;
2509 cFYI(1, "In CIFSSMBClose");
2511 /* do not retry on dead session on close */
2512 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2518 pSMB->FileID = (__u16) smb_file_id;
2519 pSMB->LastWriteTime = 0xFFFFFFFF;
2520 pSMB->ByteCount = 0;
2521 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2522 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2525 /* EINTR is expected when user ctl-c to kill app */
2526 cERROR(1, "Send error in Close = %d", rc);
2530 /* Since session is dead, file will be closed on server already */
2538 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2541 FLUSH_REQ *pSMB = NULL;
2542 cFYI(1, "In CIFSSMBFlush");
2544 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2548 pSMB->FileID = (__u16) smb_file_id;
2549 pSMB->ByteCount = 0;
2550 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2551 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2553 cERROR(1, "Send error in Flush = %d", rc);
2559 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2560 const char *fromName, const char *toName,
2561 const struct nls_table *nls_codepage, int remap)
2564 RENAME_REQ *pSMB = NULL;
2565 RENAME_RSP *pSMBr = NULL;
2567 int name_len, name_len2;
2570 cFYI(1, "In CIFSSMBRename");
2572 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2577 pSMB->BufferFormat = 0x04;
2578 pSMB->SearchAttributes =
2579 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2582 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2584 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
2585 PATH_MAX, nls_codepage, remap);
2586 name_len++; /* trailing null */
2588 pSMB->OldFileName[name_len] = 0x04; /* pad */
2589 /* protocol requires ASCII signature byte on Unicode string */
2590 pSMB->OldFileName[name_len + 1] = 0x00;
2592 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2593 toName, PATH_MAX, nls_codepage, remap);
2594 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2595 name_len2 *= 2; /* convert to bytes */
2596 } else { /* BB improve the check for buffer overruns BB */
2597 name_len = strnlen(fromName, PATH_MAX);
2598 name_len++; /* trailing null */
2599 strncpy(pSMB->OldFileName, fromName, name_len);
2600 name_len2 = strnlen(toName, PATH_MAX);
2601 name_len2++; /* trailing null */
2602 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2603 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2604 name_len2++; /* trailing null */
2605 name_len2++; /* signature byte */
2608 count = 1 /* 1st signature byte */ + name_len + name_len2;
2609 inc_rfc1001_len(pSMB, count);
2610 pSMB->ByteCount = cpu_to_le16(count);
2612 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2613 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2614 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2616 cFYI(1, "Send error in rename = %d", rc);
2618 cifs_buf_release(pSMB);
2626 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2627 int netfid, const char *target_name,
2628 const struct nls_table *nls_codepage, int remap)
2630 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2631 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2632 struct set_file_rename *rename_info;
2634 char dummy_string[30];
2636 int bytes_returned = 0;
2638 __u16 params, param_offset, offset, count, byte_count;
2640 cFYI(1, "Rename to File by handle");
2641 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2647 pSMB->MaxSetupCount = 0;
2651 pSMB->Reserved2 = 0;
2652 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2653 offset = param_offset + params;
2655 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2656 rename_info = (struct set_file_rename *) data_offset;
2657 pSMB->MaxParameterCount = cpu_to_le16(2);
2658 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2659 pSMB->SetupCount = 1;
2660 pSMB->Reserved3 = 0;
2661 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2662 byte_count = 3 /* pad */ + params;
2663 pSMB->ParameterCount = cpu_to_le16(params);
2664 pSMB->TotalParameterCount = pSMB->ParameterCount;
2665 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2666 pSMB->DataOffset = cpu_to_le16(offset);
2667 /* construct random name ".cifs_tmp<inodenum><mid>" */
2668 rename_info->overwrite = cpu_to_le32(1);
2669 rename_info->root_fid = 0;
2670 /* unicode only call */
2671 if (target_name == NULL) {
2672 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2674 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2675 dummy_string, 24, nls_codepage, remap);
2678 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2679 target_name, PATH_MAX, nls_codepage,
2682 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2683 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2684 byte_count += count;
2685 pSMB->DataCount = cpu_to_le16(count);
2686 pSMB->TotalDataCount = pSMB->DataCount;
2688 pSMB->InformationLevel =
2689 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2690 pSMB->Reserved4 = 0;
2691 inc_rfc1001_len(pSMB, byte_count);
2692 pSMB->ByteCount = cpu_to_le16(byte_count);
2693 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2694 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2695 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2697 cFYI(1, "Send error in Rename (by file handle) = %d", rc);
2699 cifs_buf_release(pSMB);
2701 /* Note: On -EAGAIN error only caller can retry on handle based calls
2702 since file handle passed in no longer valid */
2708 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2709 const char *fromName, const __u16 target_tid, const char *toName,
2710 const int flags, const struct nls_table *nls_codepage, int remap)
2713 COPY_REQ *pSMB = NULL;
2714 COPY_RSP *pSMBr = NULL;
2716 int name_len, name_len2;
2719 cFYI(1, "In CIFSSMBCopy");
2721 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2726 pSMB->BufferFormat = 0x04;
2727 pSMB->Tid2 = target_tid;
2729 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2731 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2732 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2733 fromName, PATH_MAX, nls_codepage,
2735 name_len++; /* trailing null */
2737 pSMB->OldFileName[name_len] = 0x04; /* pad */
2738 /* protocol requires ASCII signature byte on Unicode string */
2739 pSMB->OldFileName[name_len + 1] = 0x00;
2741 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2742 toName, PATH_MAX, nls_codepage, remap);
2743 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2744 name_len2 *= 2; /* convert to bytes */
2745 } else { /* BB improve the check for buffer overruns BB */
2746 name_len = strnlen(fromName, PATH_MAX);
2747 name_len++; /* trailing null */
2748 strncpy(pSMB->OldFileName, fromName, name_len);
2749 name_len2 = strnlen(toName, PATH_MAX);
2750 name_len2++; /* trailing null */
2751 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2752 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2753 name_len2++; /* trailing null */
2754 name_len2++; /* signature byte */
2757 count = 1 /* 1st signature byte */ + name_len + name_len2;
2758 inc_rfc1001_len(pSMB, count);
2759 pSMB->ByteCount = cpu_to_le16(count);
2761 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2762 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2764 cFYI(1, "Send error in copy = %d with %d files copied",
2765 rc, le16_to_cpu(pSMBr->CopyCount));
2767 cifs_buf_release(pSMB);
2776 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2777 const char *fromName, const char *toName,
2778 const struct nls_table *nls_codepage)
2780 TRANSACTION2_SPI_REQ *pSMB = NULL;
2781 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2784 int name_len_target;
2786 int bytes_returned = 0;
2787 __u16 params, param_offset, offset, byte_count;
2789 cFYI(1, "In Symlink Unix style");
2791 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2796 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2798 cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName,
2799 /* find define for this maxpathcomponent */
2800 PATH_MAX, nls_codepage);
2801 name_len++; /* trailing null */
2804 } else { /* BB improve the check for buffer overruns BB */
2805 name_len = strnlen(fromName, PATH_MAX);
2806 name_len++; /* trailing null */
2807 strncpy(pSMB->FileName, fromName, name_len);
2809 params = 6 + name_len;
2810 pSMB->MaxSetupCount = 0;
2814 pSMB->Reserved2 = 0;
2815 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2816 InformationLevel) - 4;
2817 offset = param_offset + params;
2819 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2820 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2822 cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX
2823 /* find define for this maxpathcomponent */
2825 name_len_target++; /* trailing null */
2826 name_len_target *= 2;
2827 } else { /* BB improve the check for buffer overruns BB */
2828 name_len_target = strnlen(toName, PATH_MAX);
2829 name_len_target++; /* trailing null */
2830 strncpy(data_offset, toName, name_len_target);
2833 pSMB->MaxParameterCount = cpu_to_le16(2);
2834 /* BB find exact max on data count below from sess */
2835 pSMB->MaxDataCount = cpu_to_le16(1000);
2836 pSMB->SetupCount = 1;
2837 pSMB->Reserved3 = 0;
2838 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2839 byte_count = 3 /* pad */ + params + name_len_target;
2840 pSMB->DataCount = cpu_to_le16(name_len_target);
2841 pSMB->ParameterCount = cpu_to_le16(params);
2842 pSMB->TotalDataCount = pSMB->DataCount;
2843 pSMB->TotalParameterCount = pSMB->ParameterCount;
2844 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2845 pSMB->DataOffset = cpu_to_le16(offset);
2846 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2847 pSMB->Reserved4 = 0;
2848 inc_rfc1001_len(pSMB, byte_count);
2849 pSMB->ByteCount = cpu_to_le16(byte_count);
2850 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2851 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2852 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2854 cFYI(1, "Send error in SetPathInfo create symlink = %d", rc);
2856 cifs_buf_release(pSMB);
2859 goto createSymLinkRetry;
2865 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2866 const char *fromName, const char *toName,
2867 const struct nls_table *nls_codepage, int remap)
2869 TRANSACTION2_SPI_REQ *pSMB = NULL;
2870 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2873 int name_len_target;
2875 int bytes_returned = 0;
2876 __u16 params, param_offset, offset, byte_count;
2878 cFYI(1, "In Create Hard link Unix style");
2879 createHardLinkRetry:
2880 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2885 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2886 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2887 PATH_MAX, nls_codepage, remap);
2888 name_len++; /* trailing null */
2891 } else { /* BB improve the check for buffer overruns BB */
2892 name_len = strnlen(toName, PATH_MAX);
2893 name_len++; /* trailing null */
2894 strncpy(pSMB->FileName, toName, name_len);
2896 params = 6 + name_len;
2897 pSMB->MaxSetupCount = 0;
2901 pSMB->Reserved2 = 0;
2902 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2903 InformationLevel) - 4;
2904 offset = param_offset + params;
2906 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2907 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2909 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2910 PATH_MAX, nls_codepage, remap);
2911 name_len_target++; /* trailing null */
2912 name_len_target *= 2;
2913 } else { /* BB improve the check for buffer overruns BB */
2914 name_len_target = strnlen(fromName, PATH_MAX);
2915 name_len_target++; /* trailing null */
2916 strncpy(data_offset, fromName, name_len_target);
2919 pSMB->MaxParameterCount = cpu_to_le16(2);
2920 /* BB find exact max on data count below from sess*/
2921 pSMB->MaxDataCount = cpu_to_le16(1000);
2922 pSMB->SetupCount = 1;
2923 pSMB->Reserved3 = 0;
2924 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2925 byte_count = 3 /* pad */ + params + name_len_target;
2926 pSMB->ParameterCount = cpu_to_le16(params);
2927 pSMB->TotalParameterCount = pSMB->ParameterCount;
2928 pSMB->DataCount = cpu_to_le16(name_len_target);
2929 pSMB->TotalDataCount = pSMB->DataCount;
2930 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2931 pSMB->DataOffset = cpu_to_le16(offset);
2932 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2933 pSMB->Reserved4 = 0;
2934 inc_rfc1001_len(pSMB, byte_count);
2935 pSMB->ByteCount = cpu_to_le16(byte_count);
2936 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2937 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2938 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2940 cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc);
2942 cifs_buf_release(pSMB);
2944 goto createHardLinkRetry;
2950 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2951 const char *fromName, const char *toName,
2952 const struct nls_table *nls_codepage, int remap)
2955 NT_RENAME_REQ *pSMB = NULL;
2956 RENAME_RSP *pSMBr = NULL;
2958 int name_len, name_len2;
2961 cFYI(1, "In CIFSCreateHardLink");
2962 winCreateHardLinkRetry:
2964 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2969 pSMB->SearchAttributes =
2970 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2972 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2973 pSMB->ClusterCount = 0;
2975 pSMB->BufferFormat = 0x04;
2977 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2979 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
2980 PATH_MAX, nls_codepage, remap);
2981 name_len++; /* trailing null */
2984 /* protocol specifies ASCII buffer format (0x04) for unicode */
2985 pSMB->OldFileName[name_len] = 0x04;
2986 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2988 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2989 toName, PATH_MAX, nls_codepage, remap);
2990 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2991 name_len2 *= 2; /* convert to bytes */
2992 } else { /* BB improve the check for buffer overruns BB */
2993 name_len = strnlen(fromName, PATH_MAX);
2994 name_len++; /* trailing null */
2995 strncpy(pSMB->OldFileName, fromName, name_len);
2996 name_len2 = strnlen(toName, PATH_MAX);
2997 name_len2++; /* trailing null */
2998 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2999 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
3000 name_len2++; /* trailing null */
3001 name_len2++; /* signature byte */
3004 count = 1 /* string type byte */ + name_len + name_len2;
3005 inc_rfc1001_len(pSMB, count);
3006 pSMB->ByteCount = cpu_to_le16(count);
3008 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3009 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3010 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3012 cFYI(1, "Send error in hard link (NT rename) = %d", rc);
3014 cifs_buf_release(pSMB);
3016 goto winCreateHardLinkRetry;
3022 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3023 const unsigned char *searchName, char **symlinkinfo,
3024 const struct nls_table *nls_codepage)
3026 /* SMB_QUERY_FILE_UNIX_LINK */
3027 TRANSACTION2_QPI_REQ *pSMB = NULL;
3028 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3032 __u16 params, byte_count;
3035 cFYI(1, "In QPathSymLinkInfo (Unix) for path %s", searchName);
3038 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3043 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3045 cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName,
3046 PATH_MAX, nls_codepage);
3047 name_len++; /* trailing null */
3049 } else { /* BB improve the check for buffer overruns BB */
3050 name_len = strnlen(searchName, PATH_MAX);
3051 name_len++; /* trailing null */
3052 strncpy(pSMB->FileName, searchName, name_len);
3055 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3056 pSMB->TotalDataCount = 0;
3057 pSMB->MaxParameterCount = cpu_to_le16(2);
3058 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3059 pSMB->MaxSetupCount = 0;
3063 pSMB->Reserved2 = 0;
3064 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3065 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3066 pSMB->DataCount = 0;
3067 pSMB->DataOffset = 0;
3068 pSMB->SetupCount = 1;
3069 pSMB->Reserved3 = 0;
3070 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3071 byte_count = params + 1 /* pad */ ;
3072 pSMB->TotalParameterCount = cpu_to_le16(params);
3073 pSMB->ParameterCount = pSMB->TotalParameterCount;
3074 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3075 pSMB->Reserved4 = 0;
3076 inc_rfc1001_len(pSMB, byte_count);
3077 pSMB->ByteCount = cpu_to_le16(byte_count);
3079 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3080 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3082 cFYI(1, "Send error in QuerySymLinkInfo = %d", rc);
3084 /* decode response */
3086 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3087 /* BB also check enough total bytes returned */
3088 if (rc || get_bcc(&pSMBr->hdr) < 2)
3092 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3094 data_start = ((char *) &pSMBr->hdr.Protocol) +
3095 le16_to_cpu(pSMBr->t2.DataOffset);
3097 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3102 /* BB FIXME investigate remapping reserved chars here */
3103 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3104 count, is_unicode, nls_codepage);
3109 cifs_buf_release(pSMB);
3111 goto querySymLinkRetry;
3115 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3117 * Recent Windows versions now create symlinks more frequently
3118 * and they use the "reparse point" mechanism below. We can of course
3119 * do symlinks nicely to Samba and other servers which support the
3120 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3121 * "MF" symlinks optionally, but for recent Windows we really need to
3122 * reenable the code below and fix the cifs_symlink callers to handle this.
3123 * In the interim this code has been moved to its own config option so
3124 * it is not compiled in by default until callers fixed up and more tested.
3127 CIFSSMBQueryReparseLinkInfo(const unsigned int xid, struct cifs_tcon *tcon,
3128 const unsigned char *searchName,
3129 char *symlinkinfo, const int buflen, __u16 fid,
3130 const struct nls_table *nls_codepage)
3134 struct smb_com_transaction_ioctl_req *pSMB;
3135 struct smb_com_transaction_ioctl_rsp *pSMBr;
3137 cFYI(1, "In Windows reparse style QueryLink for path %s", searchName);
3138 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3143 pSMB->TotalParameterCount = 0 ;
3144 pSMB->TotalDataCount = 0;
3145 pSMB->MaxParameterCount = cpu_to_le32(2);
3146 /* BB find exact data count max from sess structure BB */
3147 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3148 pSMB->MaxSetupCount = 4;
3150 pSMB->ParameterOffset = 0;
3151 pSMB->DataCount = 0;
3152 pSMB->DataOffset = 0;
3153 pSMB->SetupCount = 4;
3154 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3155 pSMB->ParameterCount = pSMB->TotalParameterCount;
3156 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3157 pSMB->IsFsctl = 1; /* FSCTL */
3158 pSMB->IsRootFlag = 0;
3159 pSMB->Fid = fid; /* file handle always le */
3160 pSMB->ByteCount = 0;
3162 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3163 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3165 cFYI(1, "Send error in QueryReparseLinkInfo = %d", rc);
3166 } else { /* decode response */
3167 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
3168 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
3169 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3170 /* BB also check enough total bytes returned */
3171 rc = -EIO; /* bad smb */
3174 if (data_count && (data_count < 2048)) {
3175 char *end_of_smb = 2 /* sizeof byte count */ +
3176 get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3178 struct reparse_data *reparse_buf =
3179 (struct reparse_data *)
3180 ((char *)&pSMBr->hdr.Protocol
3182 if ((char *)reparse_buf >= end_of_smb) {
3186 if ((reparse_buf->LinkNamesBuf +
3187 reparse_buf->TargetNameOffset +
3188 reparse_buf->TargetNameLen) > end_of_smb) {
3189 cFYI(1, "reparse buf beyond SMB");
3194 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3195 cifs_from_ucs2(symlinkinfo, (__le16 *)
3196 (reparse_buf->LinkNamesBuf +
3197 reparse_buf->TargetNameOffset),
3199 reparse_buf->TargetNameLen,
3201 } else { /* ASCII names */
3202 strncpy(symlinkinfo,
3203 reparse_buf->LinkNamesBuf +
3204 reparse_buf->TargetNameOffset,
3205 min_t(const int, buflen,
3206 reparse_buf->TargetNameLen));
3210 cFYI(1, "Invalid return data count on "
3211 "get reparse info ioctl");
3213 symlinkinfo[buflen] = 0; /* just in case so the caller
3214 does not go off the end of the buffer */
3215 cFYI(1, "readlink result - %s", symlinkinfo);
3219 cifs_buf_release(pSMB);
3221 /* Note: On -EAGAIN error only caller can retry on handle based calls
3222 since file handle passed in no longer valid */
3226 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3228 #ifdef CONFIG_CIFS_POSIX
3230 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3231 static void cifs_convert_ace(posix_acl_xattr_entry *ace,
3232 struct cifs_posix_ace *cifs_ace)
3234 /* u8 cifs fields do not need le conversion */
3235 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3236 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3237 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3238 /* cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id); */
3243 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3244 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3245 const int acl_type, const int size_of_data_area)
3250 struct cifs_posix_ace *pACE;
3251 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3252 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
3254 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3257 if (acl_type & ACL_TYPE_ACCESS) {
3258 count = le16_to_cpu(cifs_acl->access_entry_count);
3259 pACE = &cifs_acl->ace_array[0];
3260 size = sizeof(struct cifs_posix_acl);
3261 size += sizeof(struct cifs_posix_ace) * count;
3262 /* check if we would go beyond end of SMB */
3263 if (size_of_data_area < size) {
3264 cFYI(1, "bad CIFS POSIX ACL size %d vs. %d",
3265 size_of_data_area, size);
3268 } else if (acl_type & ACL_TYPE_DEFAULT) {
3269 count = le16_to_cpu(cifs_acl->access_entry_count);
3270 size = sizeof(struct cifs_posix_acl);
3271 size += sizeof(struct cifs_posix_ace) * count;
3272 /* skip past access ACEs to get to default ACEs */
3273 pACE = &cifs_acl->ace_array[count];
3274 count = le16_to_cpu(cifs_acl->default_entry_count);
3275 size += sizeof(struct cifs_posix_ace) * count;
3276 /* check if we would go beyond end of SMB */
3277 if (size_of_data_area < size)
3284 size = posix_acl_xattr_size(count);
3285 if ((buflen == 0) || (local_acl == NULL)) {
3286 /* used to query ACL EA size */
3287 } else if (size > buflen) {
3289 } else /* buffer big enough */ {
3290 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3291 for (i = 0; i < count ; i++) {
3292 cifs_convert_ace(&local_acl->a_entries[i], pACE);
3299 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3300 const posix_acl_xattr_entry *local_ace)
3302 __u16 rc = 0; /* 0 = ACL converted ok */
3304 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3305 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3306 /* BB is there a better way to handle the large uid? */
3307 if (local_ace->e_id == cpu_to_le32(-1)) {
3308 /* Probably no need to le convert -1 on any arch but can not hurt */
3309 cifs_ace->cifs_uid = cpu_to_le64(-1);
3311 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3312 /*cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id);*/
3316 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3317 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3318 const int buflen, const int acl_type)
3321 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3322 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
3326 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3329 count = posix_acl_xattr_count((size_t)buflen);
3330 cFYI(1, "setting acl with %d entries from buf of length %d and "
3332 count, buflen, le32_to_cpu(local_acl->a_version));
3333 if (le32_to_cpu(local_acl->a_version) != 2) {
3334 cFYI(1, "unknown POSIX ACL version %d",
3335 le32_to_cpu(local_acl->a_version));
3338 cifs_acl->version = cpu_to_le16(1);
3339 if (acl_type == ACL_TYPE_ACCESS)
3340 cifs_acl->access_entry_count = cpu_to_le16(count);
3341 else if (acl_type == ACL_TYPE_DEFAULT)
3342 cifs_acl->default_entry_count = cpu_to_le16(count);
3344 cFYI(1, "unknown ACL type %d", acl_type);
3347 for (i = 0; i < count; i++) {
3348 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3349 &local_acl->a_entries[i]);
3351 /* ACE not converted */
3356 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3357 rc += sizeof(struct cifs_posix_acl);
3358 /* BB add check to make sure ACL does not overflow SMB */
3364 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3365 const unsigned char *searchName,
3366 char *acl_inf, const int buflen, const int acl_type,
3367 const struct nls_table *nls_codepage, int remap)
3369 /* SMB_QUERY_POSIX_ACL */
3370 TRANSACTION2_QPI_REQ *pSMB = NULL;
3371 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3375 __u16 params, byte_count;
3377 cFYI(1, "In GetPosixACL (Unix) for path %s", searchName);
3380 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3385 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3387 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3388 searchName, PATH_MAX, nls_codepage,
3390 name_len++; /* trailing null */
3392 pSMB->FileName[name_len] = 0;
3393 pSMB->FileName[name_len+1] = 0;
3394 } else { /* BB improve the check for buffer overruns BB */
3395 name_len = strnlen(searchName, PATH_MAX);
3396 name_len++; /* trailing null */
3397 strncpy(pSMB->FileName, searchName, name_len);
3400 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3401 pSMB->TotalDataCount = 0;
3402 pSMB->MaxParameterCount = cpu_to_le16(2);
3403 /* BB find exact max data count below from sess structure BB */
3404 pSMB->MaxDataCount = cpu_to_le16(4000);
3405 pSMB->MaxSetupCount = 0;
3409 pSMB->Reserved2 = 0;
3410 pSMB->ParameterOffset = cpu_to_le16(
3411 offsetof(struct smb_com_transaction2_qpi_req,
3412 InformationLevel) - 4);
3413 pSMB->DataCount = 0;
3414 pSMB->DataOffset = 0;
3415 pSMB->SetupCount = 1;
3416 pSMB->Reserved3 = 0;
3417 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3418 byte_count = params + 1 /* pad */ ;
3419 pSMB->TotalParameterCount = cpu_to_le16(params);
3420 pSMB->ParameterCount = pSMB->TotalParameterCount;
3421 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3422 pSMB->Reserved4 = 0;
3423 inc_rfc1001_len(pSMB, byte_count);
3424 pSMB->ByteCount = cpu_to_le16(byte_count);
3426 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3427 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3428 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3430 cFYI(1, "Send error in Query POSIX ACL = %d", rc);
3432 /* decode response */
3434 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3435 /* BB also check enough total bytes returned */
3436 if (rc || get_bcc(&pSMBr->hdr) < 2)
3437 rc = -EIO; /* bad smb */
3439 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3440 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3441 rc = cifs_copy_posix_acl(acl_inf,
3442 (char *)&pSMBr->hdr.Protocol+data_offset,
3443 buflen, acl_type, count);
3446 cifs_buf_release(pSMB);
3453 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3454 const unsigned char *fileName,
3455 const char *local_acl, const int buflen,
3457 const struct nls_table *nls_codepage, int remap)
3459 struct smb_com_transaction2_spi_req *pSMB = NULL;
3460 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3464 int bytes_returned = 0;
3465 __u16 params, byte_count, data_count, param_offset, offset;
3467 cFYI(1, "In SetPosixACL (Unix) for path %s", fileName);
3469 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3473 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3475 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3476 PATH_MAX, nls_codepage, remap);
3477 name_len++; /* trailing null */
3479 } else { /* BB improve the check for buffer overruns BB */
3480 name_len = strnlen(fileName, PATH_MAX);
3481 name_len++; /* trailing null */
3482 strncpy(pSMB->FileName, fileName, name_len);
3484 params = 6 + name_len;
3485 pSMB->MaxParameterCount = cpu_to_le16(2);
3486 /* BB find max SMB size from sess */
3487 pSMB->MaxDataCount = cpu_to_le16(1000);
3488 pSMB->MaxSetupCount = 0;
3492 pSMB->Reserved2 = 0;
3493 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3494 InformationLevel) - 4;
3495 offset = param_offset + params;
3496 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3497 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3499 /* convert to on the wire format for POSIX ACL */
3500 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3502 if (data_count == 0) {
3504 goto setACLerrorExit;
3506 pSMB->DataOffset = cpu_to_le16(offset);
3507 pSMB->SetupCount = 1;
3508 pSMB->Reserved3 = 0;
3509 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3510 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3511 byte_count = 3 /* pad */ + params + data_count;
3512 pSMB->DataCount = cpu_to_le16(data_count);
3513 pSMB->TotalDataCount = pSMB->DataCount;
3514 pSMB->ParameterCount = cpu_to_le16(params);
3515 pSMB->TotalParameterCount = pSMB->ParameterCount;
3516 pSMB->Reserved4 = 0;
3517 inc_rfc1001_len(pSMB, byte_count);
3518 pSMB->ByteCount = cpu_to_le16(byte_count);
3519 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3520 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3522 cFYI(1, "Set POSIX ACL returned %d", rc);
3525 cifs_buf_release(pSMB);
3531 /* BB fix tabs in this function FIXME BB */
3533 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3534 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3537 struct smb_t2_qfi_req *pSMB = NULL;
3538 struct smb_t2_qfi_rsp *pSMBr = NULL;
3540 __u16 params, byte_count;
3542 cFYI(1, "In GetExtAttr");
3547 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3552 params = 2 /* level */ + 2 /* fid */;
3553 pSMB->t2.TotalDataCount = 0;
3554 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3555 /* BB find exact max data count below from sess structure BB */
3556 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3557 pSMB->t2.MaxSetupCount = 0;
3558 pSMB->t2.Reserved = 0;
3560 pSMB->t2.Timeout = 0;
3561 pSMB->t2.Reserved2 = 0;
3562 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3564 pSMB->t2.DataCount = 0;
3565 pSMB->t2.DataOffset = 0;
3566 pSMB->t2.SetupCount = 1;
3567 pSMB->t2.Reserved3 = 0;
3568 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3569 byte_count = params + 1 /* pad */ ;
3570 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3571 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3572 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3575 inc_rfc1001_len(pSMB, byte_count);
3576 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3578 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3579 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3581 cFYI(1, "error %d in GetExtAttr", rc);
3583 /* decode response */
3584 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3585 /* BB also check enough total bytes returned */
3586 if (rc || get_bcc(&pSMBr->hdr) < 2)
3587 /* If rc should we check for EOPNOSUPP and
3588 disable the srvino flag? or in caller? */
3589 rc = -EIO; /* bad smb */
3591 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3592 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3593 struct file_chattr_info *pfinfo;
3594 /* BB Do we need a cast or hash here ? */
3596 cFYI(1, "Illegal size ret in GetExtAttr");
3600 pfinfo = (struct file_chattr_info *)
3601 (data_offset + (char *) &pSMBr->hdr.Protocol);
3602 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3603 *pMask = le64_to_cpu(pfinfo->mask);
3607 cifs_buf_release(pSMB);
3609 goto GetExtAttrRetry;
3613 #endif /* CONFIG_POSIX */
3615 #ifdef CONFIG_CIFS_ACL
3617 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3618 * all NT TRANSACTS that we init here have total parm and data under about 400
3619 * bytes (to fit in small cifs buffer size), which is the case so far, it
3620 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3621 * returned setup area) and MaxParameterCount (returned parms size) must be set
3625 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3626 const int parm_len, struct cifs_tcon *tcon,
3631 struct smb_com_ntransact_req *pSMB;
3633 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3637 *ret_buf = (void *)pSMB;
3639 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3640 pSMB->TotalDataCount = 0;
3641 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3642 pSMB->ParameterCount = pSMB->TotalParameterCount;
3643 pSMB->DataCount = pSMB->TotalDataCount;
3644 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3645 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3646 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3647 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3648 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3649 pSMB->SubCommand = cpu_to_le16(sub_command);
3654 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3655 __u32 *pparmlen, __u32 *pdatalen)
3658 __u32 data_count, data_offset, parm_count, parm_offset;
3659 struct smb_com_ntransact_rsp *pSMBr;
3668 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3670 bcc = get_bcc(&pSMBr->hdr);
3671 end_of_smb = 2 /* sizeof byte count */ + bcc +
3672 (char *)&pSMBr->ByteCount;
3674 data_offset = le32_to_cpu(pSMBr->DataOffset);
3675 data_count = le32_to_cpu(pSMBr->DataCount);
3676 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3677 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3679 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3680 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3682 /* should we also check that parm and data areas do not overlap? */
3683 if (*ppparm > end_of_smb) {
3684 cFYI(1, "parms start after end of smb");
3686 } else if (parm_count + *ppparm > end_of_smb) {
3687 cFYI(1, "parm end after end of smb");
3689 } else if (*ppdata > end_of_smb) {
3690 cFYI(1, "data starts after end of smb");
3692 } else if (data_count + *ppdata > end_of_smb) {
3693 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
3694 *ppdata, data_count, (data_count + *ppdata),
3697 } else if (parm_count + data_count > bcc) {
3698 cFYI(1, "parm count and data count larger than SMB");
3701 *pdatalen = data_count;
3702 *pparmlen = parm_count;
3706 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3708 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3709 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3713 QUERY_SEC_DESC_REQ *pSMB;
3716 cFYI(1, "GetCifsACL");
3721 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3722 8 /* parm len */, tcon, (void **) &pSMB);
3726 pSMB->MaxParameterCount = cpu_to_le32(4);
3727 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3728 pSMB->MaxSetupCount = 0;
3729 pSMB->Fid = fid; /* file handle always le */
3730 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3732 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3733 inc_rfc1001_len(pSMB, 11);
3734 iov[0].iov_base = (char *)pSMB;
3735 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3737 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3739 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3741 cFYI(1, "Send error in QuerySecDesc = %d", rc);
3742 } else { /* decode response */
3746 struct smb_com_ntransact_rsp *pSMBr;
3749 /* validate_nttransact */
3750 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3751 &pdata, &parm_len, pbuflen);
3754 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3756 cFYI(1, "smb %p parm %p data %p", pSMBr, parm, *acl_inf);
3758 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3759 rc = -EIO; /* bad smb */
3764 /* BB check that data area is minimum length and as big as acl_len */
3766 acl_len = le32_to_cpu(*parm);
3767 if (acl_len != *pbuflen) {
3768 cERROR(1, "acl length %d does not match %d",
3770 if (*pbuflen > acl_len)
3774 /* check if buffer is big enough for the acl
3775 header followed by the smallest SID */
3776 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3777 (*pbuflen >= 64 * 1024)) {
3778 cERROR(1, "bad acl length %d", *pbuflen);
3782 *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
3783 if (*acl_inf == NULL) {
3787 memcpy(*acl_inf, pdata, *pbuflen);
3791 if (buf_type == CIFS_SMALL_BUFFER)
3792 cifs_small_buf_release(iov[0].iov_base);
3793 else if (buf_type == CIFS_LARGE_BUFFER)
3794 cifs_buf_release(iov[0].iov_base);
3795 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3800 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3801 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3803 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3805 int bytes_returned = 0;
3806 SET_SEC_DESC_REQ *pSMB = NULL;
3810 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3814 pSMB->MaxSetupCount = 0;
3818 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3819 data_count = acllen;
3820 data_offset = param_offset + param_count;
3821 byte_count = 3 /* pad */ + param_count;
3823 pSMB->DataCount = cpu_to_le32(data_count);
3824 pSMB->TotalDataCount = pSMB->DataCount;
3825 pSMB->MaxParameterCount = cpu_to_le32(4);
3826 pSMB->MaxDataCount = cpu_to_le32(16384);
3827 pSMB->ParameterCount = cpu_to_le32(param_count);
3828 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3829 pSMB->TotalParameterCount = pSMB->ParameterCount;
3830 pSMB->DataOffset = cpu_to_le32(data_offset);
3831 pSMB->SetupCount = 0;
3832 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3833 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3835 pSMB->Fid = fid; /* file handle always le */
3836 pSMB->Reserved2 = 0;
3837 pSMB->AclFlags = cpu_to_le32(aclflag);
3839 if (pntsd && acllen) {
3840 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3841 data_offset, pntsd, acllen);
3842 inc_rfc1001_len(pSMB, byte_count + data_count);
3844 inc_rfc1001_len(pSMB, byte_count);
3846 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3847 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3849 cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
3851 cFYI(1, "Set CIFS ACL returned %d", rc);
3852 cifs_buf_release(pSMB);
3855 goto setCifsAclRetry;
3860 #endif /* CONFIG_CIFS_ACL */
3862 /* Legacy Query Path Information call for lookup to old servers such
3865 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3866 const char *search_name, FILE_ALL_INFO *data,
3867 const struct nls_table *nls_codepage, int remap)
3869 QUERY_INFORMATION_REQ *pSMB;
3870 QUERY_INFORMATION_RSP *pSMBr;
3875 cFYI(1, "In SMBQPath path %s", search_name);
3877 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3882 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3884 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3885 search_name, PATH_MAX, nls_codepage,
3887 name_len++; /* trailing null */
3890 name_len = strnlen(search_name, PATH_MAX);
3891 name_len++; /* trailing null */
3892 strncpy(pSMB->FileName, search_name, name_len);
3894 pSMB->BufferFormat = 0x04;
3895 name_len++; /* account for buffer type byte */
3896 inc_rfc1001_len(pSMB, (__u16)name_len);
3897 pSMB->ByteCount = cpu_to_le16(name_len);
3899 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3900 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3902 cFYI(1, "Send error in QueryInfo = %d", rc);
3905 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3907 /* decode response */
3908 /* BB FIXME - add time zone adjustment BB */
3909 memset(data, 0, sizeof(FILE_ALL_INFO));
3912 /* decode time fields */
3913 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3914 data->LastWriteTime = data->ChangeTime;
3915 data->LastAccessTime = 0;
3916 data->AllocationSize =
3917 cpu_to_le64(le32_to_cpu(pSMBr->size));
3918 data->EndOfFile = data->AllocationSize;
3920 cpu_to_le32(le16_to_cpu(pSMBr->attr));
3922 rc = -EIO; /* bad buffer passed in */
3924 cifs_buf_release(pSMB);
3933 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3934 u16 netfid, FILE_ALL_INFO *pFindData)
3936 struct smb_t2_qfi_req *pSMB = NULL;
3937 struct smb_t2_qfi_rsp *pSMBr = NULL;
3940 __u16 params, byte_count;
3943 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3948 params = 2 /* level */ + 2 /* fid */;
3949 pSMB->t2.TotalDataCount = 0;
3950 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3951 /* BB find exact max data count below from sess structure BB */
3952 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3953 pSMB->t2.MaxSetupCount = 0;
3954 pSMB->t2.Reserved = 0;
3956 pSMB->t2.Timeout = 0;
3957 pSMB->t2.Reserved2 = 0;
3958 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3960 pSMB->t2.DataCount = 0;
3961 pSMB->t2.DataOffset = 0;
3962 pSMB->t2.SetupCount = 1;
3963 pSMB->t2.Reserved3 = 0;
3964 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3965 byte_count = params + 1 /* pad */ ;
3966 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3967 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3968 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3971 inc_rfc1001_len(pSMB, byte_count);
3973 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3974 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3976 cFYI(1, "Send error in QPathInfo = %d", rc);
3977 } else { /* decode response */
3978 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3980 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3982 else if (get_bcc(&pSMBr->hdr) < 40)
3983 rc = -EIO; /* bad smb */
3984 else if (pFindData) {
3985 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3986 memcpy((char *) pFindData,
3987 (char *) &pSMBr->hdr.Protocol +
3988 data_offset, sizeof(FILE_ALL_INFO));
3992 cifs_buf_release(pSMB);
3994 goto QFileInfoRetry;
4000 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4001 const char *search_name, FILE_ALL_INFO *data,
4002 int legacy /* old style infolevel */,
4003 const struct nls_table *nls_codepage, int remap)
4005 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4006 TRANSACTION2_QPI_REQ *pSMB = NULL;
4007 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4011 __u16 params, byte_count;
4013 /* cFYI(1, "In QPathInfo path %s", search_name); */
4015 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4020 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4022 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4023 PATH_MAX, nls_codepage, remap);
4024 name_len++; /* trailing null */
4026 } else { /* BB improve the check for buffer overruns BB */
4027 name_len = strnlen(search_name, PATH_MAX);
4028 name_len++; /* trailing null */
4029 strncpy(pSMB->FileName, search_name, name_len);
4032 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4033 pSMB->TotalDataCount = 0;
4034 pSMB->MaxParameterCount = cpu_to_le16(2);
4035 /* BB find exact max SMB PDU from sess structure BB */
4036 pSMB->MaxDataCount = cpu_to_le16(4000);
4037 pSMB->MaxSetupCount = 0;
4041 pSMB->Reserved2 = 0;
4042 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4043 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4044 pSMB->DataCount = 0;
4045 pSMB->DataOffset = 0;
4046 pSMB->SetupCount = 1;
4047 pSMB->Reserved3 = 0;
4048 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4049 byte_count = params + 1 /* pad */ ;
4050 pSMB->TotalParameterCount = cpu_to_le16(params);
4051 pSMB->ParameterCount = pSMB->TotalParameterCount;
4053 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4055 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4056 pSMB->Reserved4 = 0;
4057 inc_rfc1001_len(pSMB, byte_count);
4058 pSMB->ByteCount = cpu_to_le16(byte_count);
4060 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4061 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4063 cFYI(1, "Send error in QPathInfo = %d", rc);
4064 } else { /* decode response */
4065 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4067 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4069 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4070 rc = -EIO; /* bad smb */
4071 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4072 rc = -EIO; /* 24 or 26 expected but we do not read
4076 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4079 * On legacy responses we do not read the last field,
4080 * EAsize, fortunately since it varies by subdialect and
4081 * also note it differs on Set vs Get, ie two bytes or 4
4082 * bytes depending but we don't care here.
4085 size = sizeof(FILE_INFO_STANDARD);
4087 size = sizeof(FILE_ALL_INFO);
4088 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4093 cifs_buf_release(pSMB);
4095 goto QPathInfoRetry;
4101 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4102 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4104 struct smb_t2_qfi_req *pSMB = NULL;
4105 struct smb_t2_qfi_rsp *pSMBr = NULL;
4108 __u16 params, byte_count;
4111 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4116 params = 2 /* level */ + 2 /* fid */;
4117 pSMB->t2.TotalDataCount = 0;
4118 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4119 /* BB find exact max data count below from sess structure BB */
4120 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4121 pSMB->t2.MaxSetupCount = 0;
4122 pSMB->t2.Reserved = 0;
4124 pSMB->t2.Timeout = 0;
4125 pSMB->t2.Reserved2 = 0;
4126 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4128 pSMB->t2.DataCount = 0;
4129 pSMB->t2.DataOffset = 0;
4130 pSMB->t2.SetupCount = 1;
4131 pSMB->t2.Reserved3 = 0;
4132 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4133 byte_count = params + 1 /* pad */ ;
4134 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4135 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4136 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4139 inc_rfc1001_len(pSMB, byte_count);
4141 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4142 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4144 cFYI(1, "Send error in QPathInfo = %d", rc);
4145 } else { /* decode response */
4146 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4148 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4149 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response. "
4150 "Unix Extensions can be disabled on mount "
4151 "by specifying the nosfu mount option.");
4152 rc = -EIO; /* bad smb */
4154 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4155 memcpy((char *) pFindData,
4156 (char *) &pSMBr->hdr.Protocol +
4158 sizeof(FILE_UNIX_BASIC_INFO));
4162 cifs_buf_release(pSMB);
4164 goto UnixQFileInfoRetry;
4170 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4171 const unsigned char *searchName,
4172 FILE_UNIX_BASIC_INFO *pFindData,
4173 const struct nls_table *nls_codepage, int remap)
4175 /* SMB_QUERY_FILE_UNIX_BASIC */
4176 TRANSACTION2_QPI_REQ *pSMB = NULL;
4177 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4179 int bytes_returned = 0;
4181 __u16 params, byte_count;
4183 cFYI(1, "In QPathInfo (Unix) the path %s", searchName);
4185 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4190 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4192 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4193 PATH_MAX, nls_codepage, remap);
4194 name_len++; /* trailing null */
4196 } else { /* BB improve the check for buffer overruns BB */
4197 name_len = strnlen(searchName, PATH_MAX);
4198 name_len++; /* trailing null */
4199 strncpy(pSMB->FileName, searchName, name_len);
4202 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4203 pSMB->TotalDataCount = 0;
4204 pSMB->MaxParameterCount = cpu_to_le16(2);
4205 /* BB find exact max SMB PDU from sess structure BB */
4206 pSMB->MaxDataCount = cpu_to_le16(4000);
4207 pSMB->MaxSetupCount = 0;
4211 pSMB->Reserved2 = 0;
4212 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4213 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4214 pSMB->DataCount = 0;
4215 pSMB->DataOffset = 0;
4216 pSMB->SetupCount = 1;
4217 pSMB->Reserved3 = 0;
4218 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4219 byte_count = params + 1 /* pad */ ;
4220 pSMB->TotalParameterCount = cpu_to_le16(params);
4221 pSMB->ParameterCount = pSMB->TotalParameterCount;
4222 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4223 pSMB->Reserved4 = 0;
4224 inc_rfc1001_len(pSMB, byte_count);
4225 pSMB->ByteCount = cpu_to_le16(byte_count);
4227 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4228 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4230 cFYI(1, "Send error in QPathInfo = %d", rc);
4231 } else { /* decode response */
4232 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4234 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4235 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response. "
4236 "Unix Extensions can be disabled on mount "
4237 "by specifying the nosfu mount option.");
4238 rc = -EIO; /* bad smb */
4240 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4241 memcpy((char *) pFindData,
4242 (char *) &pSMBr->hdr.Protocol +
4244 sizeof(FILE_UNIX_BASIC_INFO));
4247 cifs_buf_release(pSMB);
4249 goto UnixQPathInfoRetry;
4254 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4256 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4257 const char *searchName,
4258 const struct nls_table *nls_codepage,
4259 __u16 *pnetfid, __u16 search_flags,
4260 struct cifs_search_info *psrch_inf, int remap, const char dirsep)
4262 /* level 257 SMB_ */
4263 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4264 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4265 T2_FFIRST_RSP_PARMS *parms;
4267 int bytes_returned = 0;
4269 __u16 params, byte_count;
4271 cFYI(1, "In FindFirst for %s", searchName);
4274 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4279 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4281 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4282 PATH_MAX, nls_codepage, remap);
4283 /* We can not add the asterik earlier in case
4284 it got remapped to 0xF03A as if it were part of the
4285 directory name instead of a wildcard */
4287 pSMB->FileName[name_len] = dirsep;
4288 pSMB->FileName[name_len+1] = 0;
4289 pSMB->FileName[name_len+2] = '*';
4290 pSMB->FileName[name_len+3] = 0;
4291 name_len += 4; /* now the trailing null */
4292 pSMB->FileName[name_len] = 0; /* null terminate just in case */
4293 pSMB->FileName[name_len+1] = 0;
4295 } else { /* BB add check for overrun of SMB buf BB */
4296 name_len = strnlen(searchName, PATH_MAX);
4297 /* BB fix here and in unicode clause above ie
4298 if (name_len > buffersize-header)
4299 free buffer exit; BB */
4300 strncpy(pSMB->FileName, searchName, name_len);
4301 pSMB->FileName[name_len] = dirsep;
4302 pSMB->FileName[name_len+1] = '*';
4303 pSMB->FileName[name_len+2] = 0;
4307 params = 12 + name_len /* includes null */ ;
4308 pSMB->TotalDataCount = 0; /* no EAs */
4309 pSMB->MaxParameterCount = cpu_to_le16(10);
4310 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4311 pSMB->MaxSetupCount = 0;
4315 pSMB->Reserved2 = 0;
4316 byte_count = params + 1 /* pad */ ;
4317 pSMB->TotalParameterCount = cpu_to_le16(params);
4318 pSMB->ParameterCount = pSMB->TotalParameterCount;
4319 pSMB->ParameterOffset = cpu_to_le16(
4320 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4322 pSMB->DataCount = 0;
4323 pSMB->DataOffset = 0;
4324 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4325 pSMB->Reserved3 = 0;
4326 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4327 pSMB->SearchAttributes =
4328 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4330 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4331 pSMB->SearchFlags = cpu_to_le16(search_flags);
4332 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4334 /* BB what should we set StorageType to? Does it matter? BB */
4335 pSMB->SearchStorageType = 0;
4336 inc_rfc1001_len(pSMB, byte_count);
4337 pSMB->ByteCount = cpu_to_le16(byte_count);
4339 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4340 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4341 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4343 if (rc) {/* BB add logic to retry regular search if Unix search
4344 rejected unexpectedly by server */
4345 /* BB Add code to handle unsupported level rc */
4346 cFYI(1, "Error in FindFirst = %d", rc);
4348 cifs_buf_release(pSMB);
4350 /* BB eventually could optimize out free and realloc of buf */
4353 goto findFirstRetry;
4354 } else { /* decode response */
4355 /* BB remember to free buffer if error BB */
4356 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4360 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4361 psrch_inf->unicode = true;
4363 psrch_inf->unicode = false;
4365 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4366 psrch_inf->smallBuf = 0;
4367 psrch_inf->srch_entries_start =
4368 (char *) &pSMBr->hdr.Protocol +
4369 le16_to_cpu(pSMBr->t2.DataOffset);
4370 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4371 le16_to_cpu(pSMBr->t2.ParameterOffset));
4373 if (parms->EndofSearch)
4374 psrch_inf->endOfSearch = true;
4376 psrch_inf->endOfSearch = false;
4378 psrch_inf->entries_in_buffer =
4379 le16_to_cpu(parms->SearchCount);
4380 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4381 psrch_inf->entries_in_buffer;
4382 lnoff = le16_to_cpu(parms->LastNameOffset);
4383 if (CIFSMaxBufSize < lnoff) {
4384 cERROR(1, "ignoring corrupt resume name");
4385 psrch_inf->last_entry = NULL;
4389 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4392 *pnetfid = parms->SearchHandle;
4394 cifs_buf_release(pSMB);
4401 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4402 __u16 searchHandle, __u16 search_flags,
4403 struct cifs_search_info *psrch_inf)
4405 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4406 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4407 T2_FNEXT_RSP_PARMS *parms;
4408 char *response_data;
4411 unsigned int name_len;
4412 __u16 params, byte_count;
4414 cFYI(1, "In FindNext");
4416 if (psrch_inf->endOfSearch)
4419 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4424 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4426 pSMB->TotalDataCount = 0; /* no EAs */
4427 pSMB->MaxParameterCount = cpu_to_le16(8);
4428 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4429 pSMB->MaxSetupCount = 0;
4433 pSMB->Reserved2 = 0;
4434 pSMB->ParameterOffset = cpu_to_le16(
4435 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4436 pSMB->DataCount = 0;
4437 pSMB->DataOffset = 0;
4438 pSMB->SetupCount = 1;
4439 pSMB->Reserved3 = 0;
4440 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4441 pSMB->SearchHandle = searchHandle; /* always kept as le */
4443 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4444 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4445 pSMB->ResumeKey = psrch_inf->resume_key;
4446 pSMB->SearchFlags = cpu_to_le16(search_flags);
4448 name_len = psrch_inf->resume_name_len;
4450 if (name_len < PATH_MAX) {
4451 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4452 byte_count += name_len;
4453 /* 14 byte parm len above enough for 2 byte null terminator */
4454 pSMB->ResumeFileName[name_len] = 0;
4455 pSMB->ResumeFileName[name_len+1] = 0;
4458 goto FNext2_err_exit;
4460 byte_count = params + 1 /* pad */ ;
4461 pSMB->TotalParameterCount = cpu_to_le16(params);
4462 pSMB->ParameterCount = pSMB->TotalParameterCount;
4463 inc_rfc1001_len(pSMB, byte_count);
4464 pSMB->ByteCount = cpu_to_le16(byte_count);
4466 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4467 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4468 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4471 psrch_inf->endOfSearch = true;
4472 cifs_buf_release(pSMB);
4473 rc = 0; /* search probably was closed at end of search*/
4475 cFYI(1, "FindNext returned = %d", rc);
4476 } else { /* decode response */
4477 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4482 /* BB fixme add lock for file (srch_info) struct here */
4483 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4484 psrch_inf->unicode = true;
4486 psrch_inf->unicode = false;
4487 response_data = (char *) &pSMBr->hdr.Protocol +
4488 le16_to_cpu(pSMBr->t2.ParameterOffset);
4489 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4490 response_data = (char *)&pSMBr->hdr.Protocol +
4491 le16_to_cpu(pSMBr->t2.DataOffset);
4492 if (psrch_inf->smallBuf)
4493 cifs_small_buf_release(
4494 psrch_inf->ntwrk_buf_start);
4496 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4497 psrch_inf->srch_entries_start = response_data;
4498 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4499 psrch_inf->smallBuf = 0;
4500 if (parms->EndofSearch)
4501 psrch_inf->endOfSearch = true;
4503 psrch_inf->endOfSearch = false;
4504 psrch_inf->entries_in_buffer =
4505 le16_to_cpu(parms->SearchCount);
4506 psrch_inf->index_of_last_entry +=
4507 psrch_inf->entries_in_buffer;
4508 lnoff = le16_to_cpu(parms->LastNameOffset);
4509 if (CIFSMaxBufSize < lnoff) {
4510 cERROR(1, "ignoring corrupt resume name");
4511 psrch_inf->last_entry = NULL;
4514 psrch_inf->last_entry =
4515 psrch_inf->srch_entries_start + lnoff;
4517 /* cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
4518 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4520 /* BB fixme add unlock here */
4525 /* BB On error, should we leave previous search buf (and count and
4526 last entry fields) intact or free the previous one? */
4528 /* Note: On -EAGAIN error only caller can retry on handle based calls
4529 since file handle passed in no longer valid */
4532 cifs_buf_release(pSMB);
4537 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4538 const __u16 searchHandle)
4541 FINDCLOSE_REQ *pSMB = NULL;
4543 cFYI(1, "In CIFSSMBFindClose");
4544 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4546 /* no sense returning error if session restarted
4547 as file handle has been closed */
4553 pSMB->FileID = searchHandle;
4554 pSMB->ByteCount = 0;
4555 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4557 cERROR(1, "Send error in FindClose = %d", rc);
4559 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4561 /* Since session is dead, search handle closed on server already */
4569 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4570 const char *search_name, __u64 *inode_number,
4571 const struct nls_table *nls_codepage, int remap)
4574 TRANSACTION2_QPI_REQ *pSMB = NULL;
4575 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4576 int name_len, bytes_returned;
4577 __u16 params, byte_count;
4579 cFYI(1, "In GetSrvInodeNum for %s", search_name);
4583 GetInodeNumberRetry:
4584 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4589 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4591 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4592 search_name, PATH_MAX, nls_codepage,
4594 name_len++; /* trailing null */
4596 } else { /* BB improve the check for buffer overruns BB */
4597 name_len = strnlen(search_name, PATH_MAX);
4598 name_len++; /* trailing null */
4599 strncpy(pSMB->FileName, search_name, name_len);
4602 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4603 pSMB->TotalDataCount = 0;
4604 pSMB->MaxParameterCount = cpu_to_le16(2);
4605 /* BB find exact max data count below from sess structure BB */
4606 pSMB->MaxDataCount = cpu_to_le16(4000);
4607 pSMB->MaxSetupCount = 0;
4611 pSMB->Reserved2 = 0;
4612 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4613 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4614 pSMB->DataCount = 0;
4615 pSMB->DataOffset = 0;
4616 pSMB->SetupCount = 1;
4617 pSMB->Reserved3 = 0;
4618 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4619 byte_count = params + 1 /* pad */ ;
4620 pSMB->TotalParameterCount = cpu_to_le16(params);
4621 pSMB->ParameterCount = pSMB->TotalParameterCount;
4622 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4623 pSMB->Reserved4 = 0;
4624 inc_rfc1001_len(pSMB, byte_count);
4625 pSMB->ByteCount = cpu_to_le16(byte_count);
4627 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4628 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4630 cFYI(1, "error %d in QueryInternalInfo", rc);
4632 /* decode response */
4633 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4634 /* BB also check enough total bytes returned */
4635 if (rc || get_bcc(&pSMBr->hdr) < 2)
4636 /* If rc should we check for EOPNOSUPP and
4637 disable the srvino flag? or in caller? */
4638 rc = -EIO; /* bad smb */
4640 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4641 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4642 struct file_internal_info *pfinfo;
4643 /* BB Do we need a cast or hash here ? */
4645 cFYI(1, "Illegal size ret in QryIntrnlInf");
4647 goto GetInodeNumOut;
4649 pfinfo = (struct file_internal_info *)
4650 (data_offset + (char *) &pSMBr->hdr.Protocol);
4651 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4655 cifs_buf_release(pSMB);
4657 goto GetInodeNumberRetry;
4661 /* parses DFS refferal V3 structure
4662 * caller is responsible for freeing target_nodes
4665 * on failure - errno
4668 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4669 unsigned int *num_of_nodes,
4670 struct dfs_info3_param **target_nodes,
4671 const struct nls_table *nls_codepage, int remap,
4672 const char *searchName)
4677 struct dfs_referral_level_3 *ref;
4679 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4683 *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4685 if (*num_of_nodes < 1) {
4686 cERROR(1, "num_referrals: must be at least > 0,"
4687 "but we get num_referrals = %d", *num_of_nodes);
4689 goto parse_DFS_referrals_exit;
4692 ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4693 if (ref->VersionNumber != cpu_to_le16(3)) {
4694 cERROR(1, "Referrals of V%d version are not supported,"
4695 "should be V3", le16_to_cpu(ref->VersionNumber));
4697 goto parse_DFS_referrals_exit;
4700 /* get the upper boundary of the resp buffer */
4701 data_end = (char *)(&(pSMBr->PathConsumed)) +
4702 le16_to_cpu(pSMBr->t2.DataCount);
4704 cFYI(1, "num_referrals: %d dfs flags: 0x%x ...",
4706 le32_to_cpu(pSMBr->DFSFlags));
4708 *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
4709 *num_of_nodes, GFP_KERNEL);
4710 if (*target_nodes == NULL) {
4711 cERROR(1, "Failed to allocate buffer for target_nodes");
4713 goto parse_DFS_referrals_exit;
4716 /* collect necessary data from referrals */
4717 for (i = 0; i < *num_of_nodes; i++) {
4720 struct dfs_info3_param *node = (*target_nodes)+i;
4722 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4724 __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4728 goto parse_DFS_referrals_exit;
4730 cifsConvertToUTF16((__le16 *) tmp, searchName,
4731 PATH_MAX, nls_codepage, remap);
4732 node->path_consumed = cifs_utf16_bytes(tmp,
4733 le16_to_cpu(pSMBr->PathConsumed),
4737 node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4739 node->server_type = le16_to_cpu(ref->ServerType);
4740 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4743 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4744 max_len = data_end - temp;
4745 node->path_name = cifs_strndup_from_utf16(temp, max_len,
4746 is_unicode, nls_codepage);
4747 if (!node->path_name) {
4749 goto parse_DFS_referrals_exit;
4752 /* copy link target UNC */
4753 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4754 max_len = data_end - temp;
4755 node->node_name = cifs_strndup_from_utf16(temp, max_len,
4756 is_unicode, nls_codepage);
4757 if (!node->node_name) {
4759 goto parse_DFS_referrals_exit;
4765 parse_DFS_referrals_exit:
4767 free_dfs_info_array(*target_nodes, *num_of_nodes);
4768 *target_nodes = NULL;
4775 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4776 const char *search_name, struct dfs_info3_param **target_nodes,
4777 unsigned int *num_of_nodes,
4778 const struct nls_table *nls_codepage, int remap)
4780 /* TRANS2_GET_DFS_REFERRAL */
4781 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4782 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4786 __u16 params, byte_count;
4788 *target_nodes = NULL;
4790 cFYI(1, "In GetDFSRefer the path %s", search_name);
4794 rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4799 /* server pointer checked in called function,
4800 but should never be null here anyway */
4801 pSMB->hdr.Mid = get_next_mid(ses->server);
4802 pSMB->hdr.Tid = ses->ipc_tid;
4803 pSMB->hdr.Uid = ses->Suid;
4804 if (ses->capabilities & CAP_STATUS32)
4805 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4806 if (ses->capabilities & CAP_DFS)
4807 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4809 if (ses->capabilities & CAP_UNICODE) {
4810 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4812 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4813 search_name, PATH_MAX, nls_codepage,
4815 name_len++; /* trailing null */
4817 } else { /* BB improve the check for buffer overruns BB */
4818 name_len = strnlen(search_name, PATH_MAX);
4819 name_len++; /* trailing null */
4820 strncpy(pSMB->RequestFileName, search_name, name_len);
4824 if (ses->server->sec_mode &
4825 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4826 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4829 pSMB->hdr.Uid = ses->Suid;
4831 params = 2 /* level */ + name_len /*includes null */ ;
4832 pSMB->TotalDataCount = 0;
4833 pSMB->DataCount = 0;
4834 pSMB->DataOffset = 0;
4835 pSMB->MaxParameterCount = 0;
4836 /* BB find exact max SMB PDU from sess structure BB */
4837 pSMB->MaxDataCount = cpu_to_le16(4000);
4838 pSMB->MaxSetupCount = 0;
4842 pSMB->Reserved2 = 0;
4843 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4844 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4845 pSMB->SetupCount = 1;
4846 pSMB->Reserved3 = 0;
4847 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4848 byte_count = params + 3 /* pad */ ;
4849 pSMB->ParameterCount = cpu_to_le16(params);
4850 pSMB->TotalParameterCount = pSMB->ParameterCount;
4851 pSMB->MaxReferralLevel = cpu_to_le16(3);
4852 inc_rfc1001_len(pSMB, byte_count);
4853 pSMB->ByteCount = cpu_to_le16(byte_count);
4855 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4856 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4858 cFYI(1, "Send error in GetDFSRefer = %d", rc);
4861 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4863 /* BB Also check if enough total bytes returned? */
4864 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4865 rc = -EIO; /* bad smb */
4869 cFYI(1, "Decoding GetDFSRefer response BCC: %d Offset %d",
4870 get_bcc(&pSMBr->hdr),
4871 le16_to_cpu(pSMBr->t2.DataOffset));
4873 /* parse returned result into more usable form */
4874 rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4875 target_nodes, nls_codepage, remap,
4879 cifs_buf_release(pSMB);
4887 /* Query File System Info such as free space to old servers such as Win 9x */
4889 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4890 struct kstatfs *FSData)
4892 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4893 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4894 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4895 FILE_SYSTEM_ALLOC_INFO *response_data;
4897 int bytes_returned = 0;
4898 __u16 params, byte_count;
4900 cFYI(1, "OldQFSInfo");
4902 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4907 params = 2; /* level */
4908 pSMB->TotalDataCount = 0;
4909 pSMB->MaxParameterCount = cpu_to_le16(2);
4910 pSMB->MaxDataCount = cpu_to_le16(1000);
4911 pSMB->MaxSetupCount = 0;
4915 pSMB->Reserved2 = 0;
4916 byte_count = params + 1 /* pad */ ;
4917 pSMB->TotalParameterCount = cpu_to_le16(params);
4918 pSMB->ParameterCount = pSMB->TotalParameterCount;
4919 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4920 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4921 pSMB->DataCount = 0;
4922 pSMB->DataOffset = 0;
4923 pSMB->SetupCount = 1;
4924 pSMB->Reserved3 = 0;
4925 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4926 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4927 inc_rfc1001_len(pSMB, byte_count);
4928 pSMB->ByteCount = cpu_to_le16(byte_count);
4930 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4931 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4933 cFYI(1, "Send error in QFSInfo = %d", rc);
4934 } else { /* decode response */
4935 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4937 if (rc || get_bcc(&pSMBr->hdr) < 18)
4938 rc = -EIO; /* bad smb */
4940 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4941 cFYI(1, "qfsinf resp BCC: %d Offset %d",
4942 get_bcc(&pSMBr->hdr), data_offset);
4944 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4945 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4947 le16_to_cpu(response_data->BytesPerSector) *
4948 le32_to_cpu(response_data->
4949 SectorsPerAllocationUnit);
4951 le32_to_cpu(response_data->TotalAllocationUnits);
4952 FSData->f_bfree = FSData->f_bavail =
4953 le32_to_cpu(response_data->FreeAllocationUnits);
4954 cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
4955 (unsigned long long)FSData->f_blocks,
4956 (unsigned long long)FSData->f_bfree,
4960 cifs_buf_release(pSMB);
4963 goto oldQFSInfoRetry;
4969 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4970 struct kstatfs *FSData)
4972 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4973 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4974 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4975 FILE_SYSTEM_INFO *response_data;
4977 int bytes_returned = 0;
4978 __u16 params, byte_count;
4980 cFYI(1, "In QFSInfo");
4982 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4987 params = 2; /* level */
4988 pSMB->TotalDataCount = 0;
4989 pSMB->MaxParameterCount = cpu_to_le16(2);
4990 pSMB->MaxDataCount = cpu_to_le16(1000);
4991 pSMB->MaxSetupCount = 0;
4995 pSMB->Reserved2 = 0;
4996 byte_count = params + 1 /* pad */ ;
4997 pSMB->TotalParameterCount = cpu_to_le16(params);
4998 pSMB->ParameterCount = pSMB->TotalParameterCount;
4999 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5000 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5001 pSMB->DataCount = 0;
5002 pSMB->DataOffset = 0;
5003 pSMB->SetupCount = 1;
5004 pSMB->Reserved3 = 0;
5005 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5006 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5007 inc_rfc1001_len(pSMB, byte_count);
5008 pSMB->ByteCount = cpu_to_le16(byte_count);
5010 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5011 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5013 cFYI(1, "Send error in QFSInfo = %d", rc);
5014 } else { /* decode response */
5015 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5017 if (rc || get_bcc(&pSMBr->hdr) < 24)
5018 rc = -EIO; /* bad smb */
5020 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5024 *) (((char *) &pSMBr->hdr.Protocol) +
5027 le32_to_cpu(response_data->BytesPerSector) *
5028 le32_to_cpu(response_data->
5029 SectorsPerAllocationUnit);
5031 le64_to_cpu(response_data->TotalAllocationUnits);
5032 FSData->f_bfree = FSData->f_bavail =
5033 le64_to_cpu(response_data->FreeAllocationUnits);
5034 cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
5035 (unsigned long long)FSData->f_blocks,
5036 (unsigned long long)FSData->f_bfree,
5040 cifs_buf_release(pSMB);
5049 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5051 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5052 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5053 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5054 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5056 int bytes_returned = 0;
5057 __u16 params, byte_count;
5059 cFYI(1, "In QFSAttributeInfo");
5061 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5066 params = 2; /* level */
5067 pSMB->TotalDataCount = 0;
5068 pSMB->MaxParameterCount = cpu_to_le16(2);
5069 /* BB find exact max SMB PDU from sess structure BB */
5070 pSMB->MaxDataCount = cpu_to_le16(1000);
5071 pSMB->MaxSetupCount = 0;
5075 pSMB->Reserved2 = 0;
5076 byte_count = params + 1 /* pad */ ;
5077 pSMB->TotalParameterCount = cpu_to_le16(params);
5078 pSMB->ParameterCount = pSMB->TotalParameterCount;
5079 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5080 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5081 pSMB->DataCount = 0;
5082 pSMB->DataOffset = 0;
5083 pSMB->SetupCount = 1;
5084 pSMB->Reserved3 = 0;
5085 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5086 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5087 inc_rfc1001_len(pSMB, byte_count);
5088 pSMB->ByteCount = cpu_to_le16(byte_count);
5090 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5091 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5093 cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
5094 } else { /* decode response */
5095 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5097 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5098 /* BB also check if enough bytes returned */
5099 rc = -EIO; /* bad smb */
5101 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5103 (FILE_SYSTEM_ATTRIBUTE_INFO
5104 *) (((char *) &pSMBr->hdr.Protocol) +
5106 memcpy(&tcon->fsAttrInfo, response_data,
5107 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5110 cifs_buf_release(pSMB);
5113 goto QFSAttributeRetry;
5119 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5121 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5122 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5123 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5124 FILE_SYSTEM_DEVICE_INFO *response_data;
5126 int bytes_returned = 0;
5127 __u16 params, byte_count;
5129 cFYI(1, "In QFSDeviceInfo");
5131 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5136 params = 2; /* level */
5137 pSMB->TotalDataCount = 0;
5138 pSMB->MaxParameterCount = cpu_to_le16(2);
5139 /* BB find exact max SMB PDU from sess structure BB */
5140 pSMB->MaxDataCount = cpu_to_le16(1000);
5141 pSMB->MaxSetupCount = 0;
5145 pSMB->Reserved2 = 0;
5146 byte_count = params + 1 /* pad */ ;
5147 pSMB->TotalParameterCount = cpu_to_le16(params);
5148 pSMB->ParameterCount = pSMB->TotalParameterCount;
5149 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5150 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5152 pSMB->DataCount = 0;
5153 pSMB->DataOffset = 0;
5154 pSMB->SetupCount = 1;
5155 pSMB->Reserved3 = 0;
5156 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5157 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5158 inc_rfc1001_len(pSMB, byte_count);
5159 pSMB->ByteCount = cpu_to_le16(byte_count);
5161 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5162 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5164 cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
5165 } else { /* decode response */
5166 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5168 if (rc || get_bcc(&pSMBr->hdr) <
5169 sizeof(FILE_SYSTEM_DEVICE_INFO))
5170 rc = -EIO; /* bad smb */
5172 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5174 (FILE_SYSTEM_DEVICE_INFO *)
5175 (((char *) &pSMBr->hdr.Protocol) +
5177 memcpy(&tcon->fsDevInfo, response_data,
5178 sizeof(FILE_SYSTEM_DEVICE_INFO));
5181 cifs_buf_release(pSMB);
5184 goto QFSDeviceRetry;
5190 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5192 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5193 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5194 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5195 FILE_SYSTEM_UNIX_INFO *response_data;
5197 int bytes_returned = 0;
5198 __u16 params, byte_count;
5200 cFYI(1, "In QFSUnixInfo");
5202 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5203 (void **) &pSMB, (void **) &pSMBr);
5207 params = 2; /* level */
5208 pSMB->TotalDataCount = 0;
5209 pSMB->DataCount = 0;
5210 pSMB->DataOffset = 0;
5211 pSMB->MaxParameterCount = cpu_to_le16(2);
5212 /* BB find exact max SMB PDU from sess structure BB */
5213 pSMB->MaxDataCount = cpu_to_le16(100);
5214 pSMB->MaxSetupCount = 0;
5218 pSMB->Reserved2 = 0;
5219 byte_count = params + 1 /* pad */ ;
5220 pSMB->ParameterCount = cpu_to_le16(params);
5221 pSMB->TotalParameterCount = pSMB->ParameterCount;
5222 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5223 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5224 pSMB->SetupCount = 1;
5225 pSMB->Reserved3 = 0;
5226 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5227 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5228 inc_rfc1001_len(pSMB, byte_count);
5229 pSMB->ByteCount = cpu_to_le16(byte_count);
5231 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5232 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5234 cERROR(1, "Send error in QFSUnixInfo = %d", rc);
5235 } else { /* decode response */
5236 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5238 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5239 rc = -EIO; /* bad smb */
5241 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5243 (FILE_SYSTEM_UNIX_INFO
5244 *) (((char *) &pSMBr->hdr.Protocol) +
5246 memcpy(&tcon->fsUnixInfo, response_data,
5247 sizeof(FILE_SYSTEM_UNIX_INFO));
5250 cifs_buf_release(pSMB);
5260 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5262 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5263 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5264 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5266 int bytes_returned = 0;
5267 __u16 params, param_offset, offset, byte_count;
5269 cFYI(1, "In SETFSUnixInfo");
5271 /* BB switch to small buf init to save memory */
5272 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5273 (void **) &pSMB, (void **) &pSMBr);
5277 params = 4; /* 2 bytes zero followed by info level. */
5278 pSMB->MaxSetupCount = 0;
5282 pSMB->Reserved2 = 0;
5283 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5285 offset = param_offset + params;
5287 pSMB->MaxParameterCount = cpu_to_le16(4);
5288 /* BB find exact max SMB PDU from sess structure BB */
5289 pSMB->MaxDataCount = cpu_to_le16(100);
5290 pSMB->SetupCount = 1;
5291 pSMB->Reserved3 = 0;
5292 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5293 byte_count = 1 /* pad */ + params + 12;
5295 pSMB->DataCount = cpu_to_le16(12);
5296 pSMB->ParameterCount = cpu_to_le16(params);
5297 pSMB->TotalDataCount = pSMB->DataCount;
5298 pSMB->TotalParameterCount = pSMB->ParameterCount;
5299 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5300 pSMB->DataOffset = cpu_to_le16(offset);
5304 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5307 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5308 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5309 pSMB->ClientUnixCap = cpu_to_le64(cap);
5311 inc_rfc1001_len(pSMB, byte_count);
5312 pSMB->ByteCount = cpu_to_le16(byte_count);
5314 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5315 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5317 cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
5318 } else { /* decode response */
5319 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5321 rc = -EIO; /* bad smb */
5323 cifs_buf_release(pSMB);
5326 goto SETFSUnixRetry;
5334 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5335 struct kstatfs *FSData)
5337 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5338 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5339 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5340 FILE_SYSTEM_POSIX_INFO *response_data;
5342 int bytes_returned = 0;
5343 __u16 params, byte_count;
5345 cFYI(1, "In QFSPosixInfo");
5347 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5352 params = 2; /* level */
5353 pSMB->TotalDataCount = 0;
5354 pSMB->DataCount = 0;
5355 pSMB->DataOffset = 0;
5356 pSMB->MaxParameterCount = cpu_to_le16(2);
5357 /* BB find exact max SMB PDU from sess structure BB */
5358 pSMB->MaxDataCount = cpu_to_le16(100);
5359 pSMB->MaxSetupCount = 0;
5363 pSMB->Reserved2 = 0;
5364 byte_count = params + 1 /* pad */ ;
5365 pSMB->ParameterCount = cpu_to_le16(params);
5366 pSMB->TotalParameterCount = pSMB->ParameterCount;
5367 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5368 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5369 pSMB->SetupCount = 1;
5370 pSMB->Reserved3 = 0;
5371 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5372 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5373 inc_rfc1001_len(pSMB, byte_count);
5374 pSMB->ByteCount = cpu_to_le16(byte_count);
5376 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5377 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5379 cFYI(1, "Send error in QFSUnixInfo = %d", rc);
5380 } else { /* decode response */
5381 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5383 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5384 rc = -EIO; /* bad smb */
5386 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5388 (FILE_SYSTEM_POSIX_INFO
5389 *) (((char *) &pSMBr->hdr.Protocol) +
5392 le32_to_cpu(response_data->BlockSize);
5394 le64_to_cpu(response_data->TotalBlocks);
5396 le64_to_cpu(response_data->BlocksAvail);
5397 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5398 FSData->f_bavail = FSData->f_bfree;
5401 le64_to_cpu(response_data->UserBlocksAvail);
5403 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5405 le64_to_cpu(response_data->TotalFileNodes);
5406 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5408 le64_to_cpu(response_data->FreeFileNodes);
5411 cifs_buf_release(pSMB);
5420 /* We can not use write of zero bytes trick to
5421 set file size due to need for large file support. Also note that
5422 this SetPathInfo is preferred to SetFileInfo based method in next
5423 routine which is only needed to work around a sharing violation bug
5424 in Samba which this routine can run into */
5427 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5428 const char *fileName, __u64 size, bool SetAllocation,
5429 const struct nls_table *nls_codepage, int remap)
5431 struct smb_com_transaction2_spi_req *pSMB = NULL;
5432 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5433 struct file_end_of_file_info *parm_data;
5436 int bytes_returned = 0;
5437 __u16 params, byte_count, data_count, param_offset, offset;
5439 cFYI(1, "In SetEOF");
5441 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5446 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5448 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5449 PATH_MAX, nls_codepage, remap);
5450 name_len++; /* trailing null */
5452 } else { /* BB improve the check for buffer overruns BB */
5453 name_len = strnlen(fileName, PATH_MAX);
5454 name_len++; /* trailing null */
5455 strncpy(pSMB->FileName, fileName, name_len);
5457 params = 6 + name_len;
5458 data_count = sizeof(struct file_end_of_file_info);
5459 pSMB->MaxParameterCount = cpu_to_le16(2);
5460 pSMB->MaxDataCount = cpu_to_le16(4100);
5461 pSMB->MaxSetupCount = 0;
5465 pSMB->Reserved2 = 0;
5466 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5467 InformationLevel) - 4;
5468 offset = param_offset + params;
5469 if (SetAllocation) {
5470 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5471 pSMB->InformationLevel =
5472 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5474 pSMB->InformationLevel =
5475 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5476 } else /* Set File Size */ {
5477 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5478 pSMB->InformationLevel =
5479 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5481 pSMB->InformationLevel =
5482 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5486 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5488 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5489 pSMB->DataOffset = cpu_to_le16(offset);
5490 pSMB->SetupCount = 1;
5491 pSMB->Reserved3 = 0;
5492 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5493 byte_count = 3 /* pad */ + params + data_count;
5494 pSMB->DataCount = cpu_to_le16(data_count);
5495 pSMB->TotalDataCount = pSMB->DataCount;
5496 pSMB->ParameterCount = cpu_to_le16(params);
5497 pSMB->TotalParameterCount = pSMB->ParameterCount;
5498 pSMB->Reserved4 = 0;
5499 inc_rfc1001_len(pSMB, byte_count);
5500 parm_data->FileSize = cpu_to_le64(size);
5501 pSMB->ByteCount = cpu_to_le16(byte_count);
5502 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5503 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5505 cFYI(1, "SetPathInfo (file size) returned %d", rc);
5507 cifs_buf_release(pSMB);
5516 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, __u64 size,
5517 __u16 fid, __u32 pid_of_opener, bool SetAllocation)
5519 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5520 struct file_end_of_file_info *parm_data;
5522 __u16 params, param_offset, offset, byte_count, count;
5524 cFYI(1, "SetFileSize (via SetFileInfo) %lld",
5526 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5531 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5532 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5535 pSMB->MaxSetupCount = 0;
5539 pSMB->Reserved2 = 0;
5540 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5541 offset = param_offset + params;
5543 count = sizeof(struct file_end_of_file_info);
5544 pSMB->MaxParameterCount = cpu_to_le16(2);
5545 /* BB find exact max SMB PDU from sess structure BB */
5546 pSMB->MaxDataCount = cpu_to_le16(1000);
5547 pSMB->SetupCount = 1;
5548 pSMB->Reserved3 = 0;
5549 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5550 byte_count = 3 /* pad */ + params + count;
5551 pSMB->DataCount = cpu_to_le16(count);
5552 pSMB->ParameterCount = cpu_to_le16(params);
5553 pSMB->TotalDataCount = pSMB->DataCount;
5554 pSMB->TotalParameterCount = pSMB->ParameterCount;
5555 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5557 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5559 pSMB->DataOffset = cpu_to_le16(offset);
5560 parm_data->FileSize = cpu_to_le64(size);
5562 if (SetAllocation) {
5563 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5564 pSMB->InformationLevel =
5565 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5567 pSMB->InformationLevel =
5568 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5569 } else /* Set File Size */ {
5570 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5571 pSMB->InformationLevel =
5572 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5574 pSMB->InformationLevel =
5575 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5577 pSMB->Reserved4 = 0;
5578 inc_rfc1001_len(pSMB, byte_count);
5579 pSMB->ByteCount = cpu_to_le16(byte_count);
5580 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5582 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
5585 /* Note: On -EAGAIN error only caller can retry on handle based calls
5586 since file handle passed in no longer valid */
5591 /* Some legacy servers such as NT4 require that the file times be set on
5592 an open handle, rather than by pathname - this is awkward due to
5593 potential access conflicts on the open, but it is unavoidable for these
5594 old servers since the only other choice is to go from 100 nanosecond DCE
5595 time and resort to the original setpathinfo level which takes the ancient
5596 DOS time format with 2 second granularity */
5598 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5599 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5601 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5604 __u16 params, param_offset, offset, byte_count, count;
5606 cFYI(1, "Set Times (via SetFileInfo)");
5607 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5612 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5613 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5616 pSMB->MaxSetupCount = 0;
5620 pSMB->Reserved2 = 0;
5621 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5622 offset = param_offset + params;
5624 data_offset = (char *)pSMB +
5625 offsetof(struct smb_hdr, Protocol) + offset;
5627 count = sizeof(FILE_BASIC_INFO);
5628 pSMB->MaxParameterCount = cpu_to_le16(2);
5629 /* BB find max SMB PDU from sess */
5630 pSMB->MaxDataCount = cpu_to_le16(1000);
5631 pSMB->SetupCount = 1;
5632 pSMB->Reserved3 = 0;
5633 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5634 byte_count = 3 /* pad */ + params + count;
5635 pSMB->DataCount = cpu_to_le16(count);
5636 pSMB->ParameterCount = cpu_to_le16(params);
5637 pSMB->TotalDataCount = pSMB->DataCount;
5638 pSMB->TotalParameterCount = pSMB->ParameterCount;
5639 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5640 pSMB->DataOffset = cpu_to_le16(offset);
5642 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5643 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5645 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5646 pSMB->Reserved4 = 0;
5647 inc_rfc1001_len(pSMB, byte_count);
5648 pSMB->ByteCount = cpu_to_le16(byte_count);
5649 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5650 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5652 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5654 /* Note: On -EAGAIN error only caller can retry on handle based calls
5655 since file handle passed in no longer valid */
5661 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5662 bool delete_file, __u16 fid, __u32 pid_of_opener)
5664 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5667 __u16 params, param_offset, offset, byte_count, count;
5669 cFYI(1, "Set File Disposition (via SetFileInfo)");
5670 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5675 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5676 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5679 pSMB->MaxSetupCount = 0;
5683 pSMB->Reserved2 = 0;
5684 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5685 offset = param_offset + params;
5687 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5690 pSMB->MaxParameterCount = cpu_to_le16(2);
5691 /* BB find max SMB PDU from sess */
5692 pSMB->MaxDataCount = cpu_to_le16(1000);
5693 pSMB->SetupCount = 1;
5694 pSMB->Reserved3 = 0;
5695 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5696 byte_count = 3 /* pad */ + params + count;
5697 pSMB->DataCount = cpu_to_le16(count);
5698 pSMB->ParameterCount = cpu_to_le16(params);
5699 pSMB->TotalDataCount = pSMB->DataCount;
5700 pSMB->TotalParameterCount = pSMB->ParameterCount;
5701 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5702 pSMB->DataOffset = cpu_to_le16(offset);
5704 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5705 pSMB->Reserved4 = 0;
5706 inc_rfc1001_len(pSMB, byte_count);
5707 pSMB->ByteCount = cpu_to_le16(byte_count);
5708 *data_offset = delete_file ? 1 : 0;
5709 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5711 cFYI(1, "Send error in SetFileDisposition = %d", rc);
5717 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5718 const char *fileName, const FILE_BASIC_INFO *data,
5719 const struct nls_table *nls_codepage, int remap)
5721 TRANSACTION2_SPI_REQ *pSMB = NULL;
5722 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5725 int bytes_returned = 0;
5727 __u16 params, param_offset, offset, byte_count, count;
5729 cFYI(1, "In SetTimes");
5732 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5737 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5739 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5740 PATH_MAX, nls_codepage, remap);
5741 name_len++; /* trailing null */
5743 } else { /* BB improve the check for buffer overruns BB */
5744 name_len = strnlen(fileName, PATH_MAX);
5745 name_len++; /* trailing null */
5746 strncpy(pSMB->FileName, fileName, name_len);
5749 params = 6 + name_len;
5750 count = sizeof(FILE_BASIC_INFO);
5751 pSMB->MaxParameterCount = cpu_to_le16(2);
5752 /* BB find max SMB PDU from sess structure BB */
5753 pSMB->MaxDataCount = cpu_to_le16(1000);
5754 pSMB->MaxSetupCount = 0;
5758 pSMB->Reserved2 = 0;
5759 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5760 InformationLevel) - 4;
5761 offset = param_offset + params;
5762 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5763 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5764 pSMB->DataOffset = cpu_to_le16(offset);
5765 pSMB->SetupCount = 1;
5766 pSMB->Reserved3 = 0;
5767 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5768 byte_count = 3 /* pad */ + params + count;
5770 pSMB->DataCount = cpu_to_le16(count);
5771 pSMB->ParameterCount = cpu_to_le16(params);
5772 pSMB->TotalDataCount = pSMB->DataCount;
5773 pSMB->TotalParameterCount = pSMB->ParameterCount;
5774 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5775 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5777 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5778 pSMB->Reserved4 = 0;
5779 inc_rfc1001_len(pSMB, byte_count);
5780 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5781 pSMB->ByteCount = cpu_to_le16(byte_count);
5782 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5783 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5785 cFYI(1, "SetPathInfo (times) returned %d", rc);
5787 cifs_buf_release(pSMB);
5795 /* Can not be used to set time stamps yet (due to old DOS time format) */
5796 /* Can be used to set attributes */
5797 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5798 handling it anyway and NT4 was what we thought it would be needed for
5799 Do not delete it until we prove whether needed for Win9x though */
5801 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
5802 __u16 dos_attrs, const struct nls_table *nls_codepage)
5804 SETATTR_REQ *pSMB = NULL;
5805 SETATTR_RSP *pSMBr = NULL;
5810 cFYI(1, "In SetAttrLegacy");
5813 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5818 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5820 ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5821 PATH_MAX, nls_codepage);
5822 name_len++; /* trailing null */
5824 } else { /* BB improve the check for buffer overruns BB */
5825 name_len = strnlen(fileName, PATH_MAX);
5826 name_len++; /* trailing null */
5827 strncpy(pSMB->fileName, fileName, name_len);
5829 pSMB->attr = cpu_to_le16(dos_attrs);
5830 pSMB->BufferFormat = 0x04;
5831 inc_rfc1001_len(pSMB, name_len + 1);
5832 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5833 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5834 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5836 cFYI(1, "Error in LegacySetAttr = %d", rc);
5838 cifs_buf_release(pSMB);
5841 goto SetAttrLgcyRetry;
5845 #endif /* temporarily unneeded SetAttr legacy function */
5848 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5849 const struct cifs_unix_set_info_args *args)
5851 u64 mode = args->mode;
5854 * Samba server ignores set of file size to zero due to bugs in some
5855 * older clients, but we should be precise - we use SetFileSize to
5856 * set file size and do not want to truncate file size to zero
5857 * accidentally as happened on one Samba server beta by putting
5858 * zero instead of -1 here
5860 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5861 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5862 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5863 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5864 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5865 data_offset->Uid = cpu_to_le64(args->uid);
5866 data_offset->Gid = cpu_to_le64(args->gid);
5867 /* better to leave device as zero when it is */
5868 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5869 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5870 data_offset->Permissions = cpu_to_le64(mode);
5873 data_offset->Type = cpu_to_le32(UNIX_FILE);
5874 else if (S_ISDIR(mode))
5875 data_offset->Type = cpu_to_le32(UNIX_DIR);
5876 else if (S_ISLNK(mode))
5877 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5878 else if (S_ISCHR(mode))
5879 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5880 else if (S_ISBLK(mode))
5881 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5882 else if (S_ISFIFO(mode))
5883 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5884 else if (S_ISSOCK(mode))
5885 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5889 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5890 const struct cifs_unix_set_info_args *args,
5891 u16 fid, u32 pid_of_opener)
5893 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5896 u16 params, param_offset, offset, byte_count, count;
5898 cFYI(1, "Set Unix Info (via SetFileInfo)");
5899 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5904 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5905 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5908 pSMB->MaxSetupCount = 0;
5912 pSMB->Reserved2 = 0;
5913 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5914 offset = param_offset + params;
5916 data_offset = (char *)pSMB +
5917 offsetof(struct smb_hdr, Protocol) + offset;
5919 count = sizeof(FILE_UNIX_BASIC_INFO);
5921 pSMB->MaxParameterCount = cpu_to_le16(2);
5922 /* BB find max SMB PDU from sess */
5923 pSMB->MaxDataCount = cpu_to_le16(1000);
5924 pSMB->SetupCount = 1;
5925 pSMB->Reserved3 = 0;
5926 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5927 byte_count = 3 /* pad */ + params + count;
5928 pSMB->DataCount = cpu_to_le16(count);
5929 pSMB->ParameterCount = cpu_to_le16(params);
5930 pSMB->TotalDataCount = pSMB->DataCount;
5931 pSMB->TotalParameterCount = pSMB->ParameterCount;
5932 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5933 pSMB->DataOffset = cpu_to_le16(offset);
5935 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5936 pSMB->Reserved4 = 0;
5937 inc_rfc1001_len(pSMB, byte_count);
5938 pSMB->ByteCount = cpu_to_le16(byte_count);
5940 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5942 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5944 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5946 /* Note: On -EAGAIN error only caller can retry on handle based calls
5947 since file handle passed in no longer valid */
5953 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5954 const char *file_name,
5955 const struct cifs_unix_set_info_args *args,
5956 const struct nls_table *nls_codepage, int remap)
5958 TRANSACTION2_SPI_REQ *pSMB = NULL;
5959 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5962 int bytes_returned = 0;
5963 FILE_UNIX_BASIC_INFO *data_offset;
5964 __u16 params, param_offset, offset, count, byte_count;
5966 cFYI(1, "In SetUID/GID/Mode");
5968 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5973 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5975 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5976 PATH_MAX, nls_codepage, remap);
5977 name_len++; /* trailing null */
5979 } else { /* BB improve the check for buffer overruns BB */
5980 name_len = strnlen(file_name, PATH_MAX);
5981 name_len++; /* trailing null */
5982 strncpy(pSMB->FileName, file_name, name_len);
5985 params = 6 + name_len;
5986 count = sizeof(FILE_UNIX_BASIC_INFO);
5987 pSMB->MaxParameterCount = cpu_to_le16(2);
5988 /* BB find max SMB PDU from sess structure BB */
5989 pSMB->MaxDataCount = cpu_to_le16(1000);
5990 pSMB->MaxSetupCount = 0;
5994 pSMB->Reserved2 = 0;
5995 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5996 InformationLevel) - 4;
5997 offset = param_offset + params;
5999 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6001 memset(data_offset, 0, count);
6002 pSMB->DataOffset = cpu_to_le16(offset);
6003 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6004 pSMB->SetupCount = 1;
6005 pSMB->Reserved3 = 0;
6006 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6007 byte_count = 3 /* pad */ + params + count;
6008 pSMB->ParameterCount = cpu_to_le16(params);
6009 pSMB->DataCount = cpu_to_le16(count);
6010 pSMB->TotalParameterCount = pSMB->ParameterCount;
6011 pSMB->TotalDataCount = pSMB->DataCount;
6012 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6013 pSMB->Reserved4 = 0;
6014 inc_rfc1001_len(pSMB, byte_count);
6016 cifs_fill_unix_set_info(data_offset, args);
6018 pSMB->ByteCount = cpu_to_le16(byte_count);
6019 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6020 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6022 cFYI(1, "SetPathInfo (perms) returned %d", rc);
6024 cifs_buf_release(pSMB);
6030 #ifdef CONFIG_CIFS_XATTR
6032 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6033 * function used by listxattr and getxattr type calls. When ea_name is set,
6034 * it looks for that attribute name and stuffs that value into the EAData
6035 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6036 * buffer. In both cases, the return value is either the length of the
6037 * resulting data or a negative error code. If EAData is a NULL pointer then
6038 * the data isn't copied to it, but the length is returned.
6041 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6042 const unsigned char *searchName, const unsigned char *ea_name,
6043 char *EAData, size_t buf_size,
6044 const struct nls_table *nls_codepage, int remap)
6046 /* BB assumes one setup word */
6047 TRANSACTION2_QPI_REQ *pSMB = NULL;
6048 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6052 struct fealist *ea_response_data;
6053 struct fea *temp_fea;
6056 __u16 params, byte_count, data_offset;
6057 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6059 cFYI(1, "In Query All EAs path %s", searchName);
6061 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6066 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6068 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6069 PATH_MAX, nls_codepage, remap);
6070 list_len++; /* trailing null */
6072 } else { /* BB improve the check for buffer overruns BB */
6073 list_len = strnlen(searchName, PATH_MAX);
6074 list_len++; /* trailing null */
6075 strncpy(pSMB->FileName, searchName, list_len);
6078 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6079 pSMB->TotalDataCount = 0;
6080 pSMB->MaxParameterCount = cpu_to_le16(2);
6081 /* BB find exact max SMB PDU from sess structure BB */
6082 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6083 pSMB->MaxSetupCount = 0;
6087 pSMB->Reserved2 = 0;
6088 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6089 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6090 pSMB->DataCount = 0;
6091 pSMB->DataOffset = 0;
6092 pSMB->SetupCount = 1;
6093 pSMB->Reserved3 = 0;
6094 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6095 byte_count = params + 1 /* pad */ ;
6096 pSMB->TotalParameterCount = cpu_to_le16(params);
6097 pSMB->ParameterCount = pSMB->TotalParameterCount;
6098 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6099 pSMB->Reserved4 = 0;
6100 inc_rfc1001_len(pSMB, byte_count);
6101 pSMB->ByteCount = cpu_to_le16(byte_count);
6103 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6104 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6106 cFYI(1, "Send error in QueryAllEAs = %d", rc);
6111 /* BB also check enough total bytes returned */
6112 /* BB we need to improve the validity checking
6113 of these trans2 responses */
6115 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6116 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6117 rc = -EIO; /* bad smb */
6121 /* check that length of list is not more than bcc */
6122 /* check that each entry does not go beyond length
6124 /* check that each element of each entry does not
6125 go beyond end of list */
6126 /* validate_trans2_offsets() */
6127 /* BB check if start of smb + data_offset > &bcc+ bcc */
6129 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6130 ea_response_data = (struct fealist *)
6131 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6133 list_len = le32_to_cpu(ea_response_data->list_len);
6134 cFYI(1, "ea length %d", list_len);
6135 if (list_len <= 8) {
6136 cFYI(1, "empty EA list returned from server");
6140 /* make sure list_len doesn't go past end of SMB */
6141 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6142 if ((char *)ea_response_data + list_len > end_of_smb) {
6143 cFYI(1, "EA list appears to go beyond SMB");
6148 /* account for ea list len */
6150 temp_fea = ea_response_data->list;
6151 temp_ptr = (char *)temp_fea;
6152 while (list_len > 0) {
6153 unsigned int name_len;
6158 /* make sure we can read name_len and value_len */
6160 cFYI(1, "EA entry goes beyond length of list");
6165 name_len = temp_fea->name_len;
6166 value_len = le16_to_cpu(temp_fea->value_len);
6167 list_len -= name_len + 1 + value_len;
6169 cFYI(1, "EA entry goes beyond length of list");
6175 if (ea_name_len == name_len &&
6176 memcmp(ea_name, temp_ptr, name_len) == 0) {
6177 temp_ptr += name_len + 1;
6181 if ((size_t)value_len > buf_size) {
6185 memcpy(EAData, temp_ptr, value_len);
6189 /* account for prefix user. and trailing null */
6190 rc += (5 + 1 + name_len);
6191 if (rc < (int) buf_size) {
6192 memcpy(EAData, "user.", 5);
6194 memcpy(EAData, temp_ptr, name_len);
6196 /* null terminate name */
6199 } else if (buf_size == 0) {
6200 /* skip copy - calc size only */
6202 /* stop before overrun buffer */
6207 temp_ptr += name_len + 1 + value_len;
6208 temp_fea = (struct fea *)temp_ptr;
6211 /* didn't find the named attribute */
6216 cifs_buf_release(pSMB);
6224 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6225 const char *fileName, const char *ea_name, const void *ea_value,
6226 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6229 struct smb_com_transaction2_spi_req *pSMB = NULL;
6230 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6231 struct fealist *parm_data;
6234 int bytes_returned = 0;
6235 __u16 params, param_offset, byte_count, offset, count;
6237 cFYI(1, "In SetEA");
6239 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6244 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6246 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6247 PATH_MAX, nls_codepage, remap);
6248 name_len++; /* trailing null */
6250 } else { /* BB improve the check for buffer overruns BB */
6251 name_len = strnlen(fileName, PATH_MAX);
6252 name_len++; /* trailing null */
6253 strncpy(pSMB->FileName, fileName, name_len);
6256 params = 6 + name_len;
6258 /* done calculating parms using name_len of file name,
6259 now use name_len to calculate length of ea name
6260 we are going to create in the inode xattrs */
6261 if (ea_name == NULL)
6264 name_len = strnlen(ea_name, 255);
6266 count = sizeof(*parm_data) + ea_value_len + name_len;
6267 pSMB->MaxParameterCount = cpu_to_le16(2);
6268 /* BB find max SMB PDU from sess */
6269 pSMB->MaxDataCount = cpu_to_le16(1000);
6270 pSMB->MaxSetupCount = 0;
6274 pSMB->Reserved2 = 0;
6275 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6276 InformationLevel) - 4;
6277 offset = param_offset + params;
6278 pSMB->InformationLevel =
6279 cpu_to_le16(SMB_SET_FILE_EA);
6282 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6284 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6285 pSMB->DataOffset = cpu_to_le16(offset);
6286 pSMB->SetupCount = 1;
6287 pSMB->Reserved3 = 0;
6288 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6289 byte_count = 3 /* pad */ + params + count;
6290 pSMB->DataCount = cpu_to_le16(count);
6291 parm_data->list_len = cpu_to_le32(count);
6292 parm_data->list[0].EA_flags = 0;
6293 /* we checked above that name len is less than 255 */
6294 parm_data->list[0].name_len = (__u8)name_len;
6295 /* EA names are always ASCII */
6297 strncpy(parm_data->list[0].name, ea_name, name_len);
6298 parm_data->list[0].name[name_len] = 0;
6299 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6300 /* caller ensures that ea_value_len is less than 64K but
6301 we need to ensure that it fits within the smb */
6303 /*BB add length check to see if it would fit in
6304 negotiated SMB buffer size BB */
6305 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6307 memcpy(parm_data->list[0].name+name_len+1,
6308 ea_value, ea_value_len);
6310 pSMB->TotalDataCount = pSMB->DataCount;
6311 pSMB->ParameterCount = cpu_to_le16(params);
6312 pSMB->TotalParameterCount = pSMB->ParameterCount;
6313 pSMB->Reserved4 = 0;
6314 inc_rfc1001_len(pSMB, byte_count);
6315 pSMB->ByteCount = cpu_to_le16(byte_count);
6316 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6317 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6319 cFYI(1, "SetPathInfo (EA) returned %d", rc);
6321 cifs_buf_release(pSMB);
6330 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6332 * Years ago the kernel added a "dnotify" function for Samba server,
6333 * to allow network clients (such as Windows) to display updated
6334 * lists of files in directory listings automatically when
6335 * files are added by one user when another user has the
6336 * same directory open on their desktop. The Linux cifs kernel
6337 * client hooked into the kernel side of this interface for
6338 * the same reason, but ironically when the VFS moved from
6339 * "dnotify" to "inotify" it became harder to plug in Linux
6340 * network file system clients (the most obvious use case
6341 * for notify interfaces is when multiple users can update
6342 * the contents of the same directory - exactly what network
6343 * file systems can do) although the server (Samba) could
6344 * still use it. For the short term we leave the worker
6345 * function ifdeffed out (below) until inotify is fixed
6346 * in the VFS to make it easier to plug in network file
6347 * system clients. If inotify turns out to be permanently
6348 * incompatible for network fs clients, we could instead simply
6349 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6351 int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
6352 const int notify_subdirs, const __u16 netfid,
6353 __u32 filter, struct file *pfile, int multishot,
6354 const struct nls_table *nls_codepage)
6357 struct smb_com_transaction_change_notify_req *pSMB = NULL;
6358 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6359 struct dir_notify_req *dnotify_req;
6362 cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
6363 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6368 pSMB->TotalParameterCount = 0 ;
6369 pSMB->TotalDataCount = 0;
6370 pSMB->MaxParameterCount = cpu_to_le32(2);
6371 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6372 pSMB->MaxSetupCount = 4;
6374 pSMB->ParameterOffset = 0;
6375 pSMB->DataCount = 0;
6376 pSMB->DataOffset = 0;
6377 pSMB->SetupCount = 4; /* single byte does not need le conversion */
6378 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6379 pSMB->ParameterCount = pSMB->TotalParameterCount;
6381 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6382 pSMB->Reserved2 = 0;
6383 pSMB->CompletionFilter = cpu_to_le32(filter);
6384 pSMB->Fid = netfid; /* file handle always le */
6385 pSMB->ByteCount = 0;
6387 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6388 (struct smb_hdr *)pSMBr, &bytes_returned,
6391 cFYI(1, "Error in Notify = %d", rc);
6393 /* Add file to outstanding requests */
6394 /* BB change to kmem cache alloc */
6395 dnotify_req = kmalloc(
6396 sizeof(struct dir_notify_req),
6399 dnotify_req->Pid = pSMB->hdr.Pid;
6400 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6401 dnotify_req->Mid = pSMB->hdr.Mid;
6402 dnotify_req->Tid = pSMB->hdr.Tid;
6403 dnotify_req->Uid = pSMB->hdr.Uid;
6404 dnotify_req->netfid = netfid;
6405 dnotify_req->pfile = pfile;
6406 dnotify_req->filter = filter;
6407 dnotify_req->multishot = multishot;
6408 spin_lock(&GlobalMid_Lock);
6409 list_add_tail(&dnotify_req->lhead,
6410 &GlobalDnotifyReqList);
6411 spin_unlock(&GlobalMid_Lock);
6415 cifs_buf_release(pSMB);
6418 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */