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)) {
1579 if (cifs_verify_signature(rdata->iov, rdata->nr_iov,
1580 server, mid->sequence_number + 1))
1581 cERROR(1, "Unexpected SMB signature");
1583 /* FIXME: should this be counted toward the initiating task? */
1584 task_io_account_read(rdata->bytes);
1585 cifs_stats_bytes_read(tcon, rdata->bytes);
1587 case MID_REQUEST_SUBMITTED:
1588 case MID_RETRY_NEEDED:
1589 rdata->result = -EAGAIN;
1592 rdata->result = -EIO;
1595 queue_work(cifsiod_wq, &rdata->work);
1596 DeleteMidQEntry(mid);
1597 add_credits(server, 1, 0);
1600 /* cifs_async_readv - send an async write, and set up mid to handle result */
1602 cifs_async_readv(struct cifs_readdata *rdata)
1605 READ_REQ *smb = NULL;
1607 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1609 cFYI(1, "%s: offset=%llu bytes=%u", __func__,
1610 rdata->offset, rdata->bytes);
1612 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1615 wct = 10; /* old style read */
1616 if ((rdata->offset >> 32) > 0) {
1617 /* can not handle this big offset for old */
1622 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1626 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1627 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1629 smb->AndXCommand = 0xFF; /* none */
1630 smb->Fid = rdata->cfile->netfid;
1631 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1633 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1635 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1636 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1640 /* old style read */
1641 struct smb_com_readx_req *smbr =
1642 (struct smb_com_readx_req *)smb;
1643 smbr->ByteCount = 0;
1646 /* 4 for RFC1001 length + 1 for BCC */
1647 rdata->iov[0].iov_base = smb;
1648 rdata->iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
1650 kref_get(&rdata->refcount);
1651 rc = cifs_call_async(tcon->ses->server, rdata->iov, 1,
1652 cifs_readv_receive, cifs_readv_callback,
1656 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1658 kref_put(&rdata->refcount, cifs_readdata_release);
1660 cifs_small_buf_release(smb);
1665 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1666 unsigned int *nbytes, char **buf, int *pbuf_type)
1669 READ_REQ *pSMB = NULL;
1670 READ_RSP *pSMBr = NULL;
1671 char *pReadData = NULL;
1673 int resp_buf_type = 0;
1675 __u32 pid = io_parms->pid;
1676 __u16 netfid = io_parms->netfid;
1677 __u64 offset = io_parms->offset;
1678 struct cifs_tcon *tcon = io_parms->tcon;
1679 unsigned int count = io_parms->length;
1681 cFYI(1, "Reading %d bytes on fid %d", count, netfid);
1682 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1685 wct = 10; /* old style read */
1686 if ((offset >> 32) > 0) {
1687 /* can not handle this big offset for old */
1693 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1697 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1698 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1700 /* tcon and ses pointer are checked in smb_init */
1701 if (tcon->ses->server == NULL)
1702 return -ECONNABORTED;
1704 pSMB->AndXCommand = 0xFF; /* none */
1706 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1708 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1710 pSMB->Remaining = 0;
1711 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1712 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1714 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1716 /* old style read */
1717 struct smb_com_readx_req *pSMBW =
1718 (struct smb_com_readx_req *)pSMB;
1719 pSMBW->ByteCount = 0;
1722 iov[0].iov_base = (char *)pSMB;
1723 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1724 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1725 &resp_buf_type, CIFS_LOG_ERROR);
1726 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1727 pSMBr = (READ_RSP *)iov[0].iov_base;
1729 cERROR(1, "Send error in read = %d", rc);
1731 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1732 data_length = data_length << 16;
1733 data_length += le16_to_cpu(pSMBr->DataLength);
1734 *nbytes = data_length;
1736 /*check that DataLength would not go beyond end of SMB */
1737 if ((data_length > CIFSMaxBufSize)
1738 || (data_length > count)) {
1739 cFYI(1, "bad length %d for count %d",
1740 data_length, count);
1744 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1745 le16_to_cpu(pSMBr->DataOffset);
1746 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1747 cERROR(1, "Faulting on read rc = %d",rc);
1749 }*/ /* can not use copy_to_user when using page cache*/
1751 memcpy(*buf, pReadData, data_length);
1755 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1757 if (resp_buf_type == CIFS_SMALL_BUFFER)
1758 cifs_small_buf_release(iov[0].iov_base);
1759 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1760 cifs_buf_release(iov[0].iov_base);
1761 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1762 /* return buffer to caller to free */
1763 *buf = iov[0].iov_base;
1764 if (resp_buf_type == CIFS_SMALL_BUFFER)
1765 *pbuf_type = CIFS_SMALL_BUFFER;
1766 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1767 *pbuf_type = CIFS_LARGE_BUFFER;
1768 } /* else no valid buffer on return - leave as null */
1770 /* Note: On -EAGAIN error only caller can retry on handle based calls
1771 since file handle passed in no longer valid */
1777 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1778 unsigned int *nbytes, const char *buf,
1779 const char __user *ubuf, const int long_op)
1782 WRITE_REQ *pSMB = NULL;
1783 WRITE_RSP *pSMBr = NULL;
1784 int bytes_returned, wct;
1787 __u32 pid = io_parms->pid;
1788 __u16 netfid = io_parms->netfid;
1789 __u64 offset = io_parms->offset;
1790 struct cifs_tcon *tcon = io_parms->tcon;
1791 unsigned int count = io_parms->length;
1795 /* cFYI(1, "write at %lld %d bytes", offset, count);*/
1796 if (tcon->ses == NULL)
1797 return -ECONNABORTED;
1799 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1803 if ((offset >> 32) > 0) {
1804 /* can not handle big offset for old srv */
1809 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1814 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1815 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1817 /* tcon and ses pointer are checked in smb_init */
1818 if (tcon->ses->server == NULL)
1819 return -ECONNABORTED;
1821 pSMB->AndXCommand = 0xFF; /* none */
1823 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1825 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1827 pSMB->Reserved = 0xFFFFFFFF;
1828 pSMB->WriteMode = 0;
1829 pSMB->Remaining = 0;
1831 /* Can increase buffer size if buffer is big enough in some cases ie we
1832 can send more if LARGE_WRITE_X capability returned by the server and if
1833 our buffer is big enough or if we convert to iovecs on socket writes
1834 and eliminate the copy to the CIFS buffer */
1835 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1836 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1838 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1842 if (bytes_sent > count)
1845 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1847 memcpy(pSMB->Data, buf, bytes_sent);
1849 if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
1850 cifs_buf_release(pSMB);
1853 } else if (count != 0) {
1855 cifs_buf_release(pSMB);
1857 } /* else setting file size with write of zero bytes */
1859 byte_count = bytes_sent + 1; /* pad */
1860 else /* wct == 12 */
1861 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1863 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1864 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1865 inc_rfc1001_len(pSMB, byte_count);
1868 pSMB->ByteCount = cpu_to_le16(byte_count);
1869 else { /* old style write has byte count 4 bytes earlier
1871 struct smb_com_writex_req *pSMBW =
1872 (struct smb_com_writex_req *)pSMB;
1873 pSMBW->ByteCount = cpu_to_le16(byte_count);
1876 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1877 (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
1878 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1880 cFYI(1, "Send error in write = %d", rc);
1882 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1883 *nbytes = (*nbytes) << 16;
1884 *nbytes += le16_to_cpu(pSMBr->Count);
1887 * Mask off high 16 bits when bytes written as returned by the
1888 * server is greater than bytes requested by the client. Some
1889 * OS/2 servers are known to set incorrect CountHigh values.
1891 if (*nbytes > count)
1895 cifs_buf_release(pSMB);
1897 /* Note: On -EAGAIN error only caller can retry on handle based calls
1898 since file handle passed in no longer valid */
1904 cifs_writedata_release(struct kref *refcount)
1906 struct cifs_writedata *wdata = container_of(refcount,
1907 struct cifs_writedata, refcount);
1910 cifsFileInfo_put(wdata->cfile);
1916 * Write failed with a retryable error. Resend the write request. It's also
1917 * possible that the page was redirtied so re-clean the page.
1920 cifs_writev_requeue(struct cifs_writedata *wdata)
1923 struct inode *inode = wdata->cfile->dentry->d_inode;
1925 for (i = 0; i < wdata->nr_pages; i++) {
1926 lock_page(wdata->pages[i]);
1927 clear_page_dirty_for_io(wdata->pages[i]);
1931 rc = cifs_async_writev(wdata);
1932 } while (rc == -EAGAIN);
1934 for (i = 0; i < wdata->nr_pages; i++) {
1936 SetPageError(wdata->pages[i]);
1937 unlock_page(wdata->pages[i]);
1940 mapping_set_error(inode->i_mapping, rc);
1941 kref_put(&wdata->refcount, cifs_writedata_release);
1945 cifs_writev_complete(struct work_struct *work)
1947 struct cifs_writedata *wdata = container_of(work,
1948 struct cifs_writedata, work);
1949 struct inode *inode = wdata->cfile->dentry->d_inode;
1952 if (wdata->result == 0) {
1953 spin_lock(&inode->i_lock);
1954 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
1955 spin_unlock(&inode->i_lock);
1956 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
1958 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
1959 return cifs_writev_requeue(wdata);
1961 for (i = 0; i < wdata->nr_pages; i++) {
1962 struct page *page = wdata->pages[i];
1963 if (wdata->result == -EAGAIN)
1964 __set_page_dirty_nobuffers(page);
1965 else if (wdata->result < 0)
1967 end_page_writeback(page);
1968 page_cache_release(page);
1970 if (wdata->result != -EAGAIN)
1971 mapping_set_error(inode->i_mapping, wdata->result);
1972 kref_put(&wdata->refcount, cifs_writedata_release);
1975 struct cifs_writedata *
1976 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
1978 struct cifs_writedata *wdata;
1980 /* this would overflow */
1981 if (nr_pages == 0) {
1982 cERROR(1, "%s: called with nr_pages == 0!", __func__);
1986 /* writedata + number of page pointers */
1987 wdata = kzalloc(sizeof(*wdata) +
1988 sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
1989 if (wdata != NULL) {
1990 kref_init(&wdata->refcount);
1991 INIT_LIST_HEAD(&wdata->list);
1992 init_completion(&wdata->done);
1993 INIT_WORK(&wdata->work, complete);
1999 * Check the mid_state and signature on received buffer (if any), and queue the
2000 * workqueue completion task.
2003 cifs_writev_callback(struct mid_q_entry *mid)
2005 struct cifs_writedata *wdata = mid->callback_data;
2006 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2007 unsigned int written;
2008 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2010 switch (mid->mid_state) {
2011 case MID_RESPONSE_RECEIVED:
2012 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2013 if (wdata->result != 0)
2016 written = le16_to_cpu(smb->CountHigh);
2018 written += le16_to_cpu(smb->Count);
2020 * Mask off high 16 bits when bytes written as returned
2021 * by the server is greater than bytes requested by the
2022 * client. OS/2 servers are known to set incorrect
2025 if (written > wdata->bytes)
2028 if (written < wdata->bytes)
2029 wdata->result = -ENOSPC;
2031 wdata->bytes = written;
2033 case MID_REQUEST_SUBMITTED:
2034 case MID_RETRY_NEEDED:
2035 wdata->result = -EAGAIN;
2038 wdata->result = -EIO;
2042 queue_work(cifsiod_wq, &wdata->work);
2043 DeleteMidQEntry(mid);
2044 add_credits(tcon->ses->server, 1, 0);
2047 /* cifs_async_writev - send an async write, and set up mid to handle result */
2049 cifs_async_writev(struct cifs_writedata *wdata)
2051 int i, rc = -EACCES;
2052 WRITE_REQ *smb = NULL;
2054 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2055 struct kvec *iov = NULL;
2057 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2061 if (wdata->offset >> 32 > 0) {
2062 /* can not handle big offset for old srv */
2067 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2069 goto async_writev_out;
2071 /* 1 iov per page + 1 for header */
2072 iov = kzalloc((wdata->nr_pages + 1) * sizeof(*iov), GFP_NOFS);
2075 goto async_writev_out;
2078 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2079 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2081 smb->AndXCommand = 0xFF; /* none */
2082 smb->Fid = wdata->cfile->netfid;
2083 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2085 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2086 smb->Reserved = 0xFFFFFFFF;
2091 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2093 /* 4 for RFC1001 length + 1 for BCC */
2094 iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
2095 iov[0].iov_base = smb;
2098 * This function should marshal up the page array into the kvec
2099 * array, reserving [0] for the header. It should kmap the pages
2100 * and set the iov_len properly for each one. It may also set
2104 wdata->marshal_iov(iov, wdata);
2107 cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
2109 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2110 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2113 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2114 put_bcc(wdata->bytes + 1, &smb->hdr);
2117 struct smb_com_writex_req *smbw =
2118 (struct smb_com_writex_req *)smb;
2119 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2120 put_bcc(wdata->bytes + 5, &smbw->hdr);
2121 iov[0].iov_len += 4; /* pad bigger by four bytes */
2124 kref_get(&wdata->refcount);
2125 rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1,
2126 NULL, cifs_writev_callback, wdata, 0);
2129 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2131 kref_put(&wdata->refcount, cifs_writedata_release);
2133 /* send is done, unmap pages */
2134 for (i = 0; i < wdata->nr_pages; i++)
2135 kunmap(wdata->pages[i]);
2138 cifs_small_buf_release(smb);
2144 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2145 unsigned int *nbytes, struct kvec *iov, int n_vec,
2149 WRITE_REQ *pSMB = NULL;
2152 int resp_buf_type = 0;
2153 __u32 pid = io_parms->pid;
2154 __u16 netfid = io_parms->netfid;
2155 __u64 offset = io_parms->offset;
2156 struct cifs_tcon *tcon = io_parms->tcon;
2157 unsigned int count = io_parms->length;
2161 cFYI(1, "write2 at %lld %d bytes", (long long)offset, count);
2163 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2167 if ((offset >> 32) > 0) {
2168 /* can not handle big offset for old srv */
2172 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2176 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2177 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2179 /* tcon and ses pointer are checked in smb_init */
2180 if (tcon->ses->server == NULL)
2181 return -ECONNABORTED;
2183 pSMB->AndXCommand = 0xFF; /* none */
2185 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2187 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2188 pSMB->Reserved = 0xFFFFFFFF;
2189 pSMB->WriteMode = 0;
2190 pSMB->Remaining = 0;
2193 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2195 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2196 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2197 /* header + 1 byte pad */
2198 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2200 inc_rfc1001_len(pSMB, count + 1);
2201 else /* wct == 12 */
2202 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2204 pSMB->ByteCount = cpu_to_le16(count + 1);
2205 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2206 struct smb_com_writex_req *pSMBW =
2207 (struct smb_com_writex_req *)pSMB;
2208 pSMBW->ByteCount = cpu_to_le16(count + 5);
2210 iov[0].iov_base = pSMB;
2212 iov[0].iov_len = smb_hdr_len + 4;
2213 else /* wct == 12 pad bigger by four bytes */
2214 iov[0].iov_len = smb_hdr_len + 8;
2217 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
2219 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2221 cFYI(1, "Send error Write2 = %d", rc);
2222 } else if (resp_buf_type == 0) {
2223 /* presumably this can not happen, but best to be safe */
2226 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base;
2227 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2228 *nbytes = (*nbytes) << 16;
2229 *nbytes += le16_to_cpu(pSMBr->Count);
2232 * Mask off high 16 bits when bytes written as returned by the
2233 * server is greater than bytes requested by the client. OS/2
2234 * servers are known to set incorrect CountHigh values.
2236 if (*nbytes > count)
2240 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2241 if (resp_buf_type == CIFS_SMALL_BUFFER)
2242 cifs_small_buf_release(iov[0].iov_base);
2243 else if (resp_buf_type == CIFS_LARGE_BUFFER)
2244 cifs_buf_release(iov[0].iov_base);
2246 /* Note: On -EAGAIN error only caller can retry on handle based calls
2247 since file handle passed in no longer valid */
2252 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2253 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2254 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2257 LOCK_REQ *pSMB = NULL;
2262 cFYI(1, "cifs_lockv num lock %d num unlock %d", num_lock, num_unlock);
2264 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2269 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2270 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2271 pSMB->LockType = lock_type;
2272 pSMB->AndXCommand = 0xFF; /* none */
2273 pSMB->Fid = netfid; /* netfid stays le */
2275 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2276 inc_rfc1001_len(pSMB, count);
2277 pSMB->ByteCount = cpu_to_le16(count);
2279 iov[0].iov_base = (char *)pSMB;
2280 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2281 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2282 iov[1].iov_base = (char *)buf;
2283 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2285 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2286 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
2288 cFYI(1, "Send error in cifs_lockv = %d", rc);
2294 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2295 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2296 const __u64 offset, const __u32 numUnlock,
2297 const __u32 numLock, const __u8 lockType,
2298 const bool waitFlag, const __u8 oplock_level)
2301 LOCK_REQ *pSMB = NULL;
2302 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2307 cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock);
2308 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2313 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2314 /* no response expected */
2315 flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP;
2317 } else if (waitFlag) {
2318 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2319 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2324 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2325 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2326 pSMB->LockType = lockType;
2327 pSMB->OplockLevel = oplock_level;
2328 pSMB->AndXCommand = 0xFF; /* none */
2329 pSMB->Fid = smb_file_id; /* netfid stays le */
2331 if ((numLock != 0) || (numUnlock != 0)) {
2332 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2333 /* BB where to store pid high? */
2334 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2335 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2336 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2337 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2338 count = sizeof(LOCKING_ANDX_RANGE);
2343 inc_rfc1001_len(pSMB, count);
2344 pSMB->ByteCount = cpu_to_le16(count);
2347 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2348 (struct smb_hdr *) pSMB, &bytes_returned);
2349 cifs_small_buf_release(pSMB);
2351 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2352 /* SMB buffer freed by function above */
2354 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2356 cFYI(1, "Send error in Lock = %d", rc);
2358 /* Note: On -EAGAIN error only caller can retry on handle based calls
2359 since file handle passed in no longer valid */
2364 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2365 const __u16 smb_file_id, const __u32 netpid,
2366 const loff_t start_offset, const __u64 len,
2367 struct file_lock *pLockData, const __u16 lock_type,
2368 const bool waitFlag)
2370 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2371 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2372 struct cifs_posix_lock *parm_data;
2375 int bytes_returned = 0;
2376 int resp_buf_type = 0;
2377 __u16 params, param_offset, offset, byte_count, count;
2380 cFYI(1, "Posix Lock");
2382 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2387 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2390 pSMB->MaxSetupCount = 0;
2393 pSMB->Reserved2 = 0;
2394 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2395 offset = param_offset + params;
2397 count = sizeof(struct cifs_posix_lock);
2398 pSMB->MaxParameterCount = cpu_to_le16(2);
2399 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2400 pSMB->SetupCount = 1;
2401 pSMB->Reserved3 = 0;
2403 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2405 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2406 byte_count = 3 /* pad */ + params + count;
2407 pSMB->DataCount = cpu_to_le16(count);
2408 pSMB->ParameterCount = cpu_to_le16(params);
2409 pSMB->TotalDataCount = pSMB->DataCount;
2410 pSMB->TotalParameterCount = pSMB->ParameterCount;
2411 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2412 parm_data = (struct cifs_posix_lock *)
2413 (((char *) &pSMB->hdr.Protocol) + offset);
2415 parm_data->lock_type = cpu_to_le16(lock_type);
2417 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2418 parm_data->lock_flags = cpu_to_le16(1);
2419 pSMB->Timeout = cpu_to_le32(-1);
2423 parm_data->pid = cpu_to_le32(netpid);
2424 parm_data->start = cpu_to_le64(start_offset);
2425 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2427 pSMB->DataOffset = cpu_to_le16(offset);
2428 pSMB->Fid = smb_file_id;
2429 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2430 pSMB->Reserved4 = 0;
2431 inc_rfc1001_len(pSMB, byte_count);
2432 pSMB->ByteCount = cpu_to_le16(byte_count);
2434 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2435 (struct smb_hdr *) pSMBr, &bytes_returned);
2437 iov[0].iov_base = (char *)pSMB;
2438 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2439 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2440 &resp_buf_type, timeout);
2441 pSMB = NULL; /* request buf already freed by SendReceive2. Do
2442 not try to free it twice below on exit */
2443 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
2447 cFYI(1, "Send error in Posix Lock = %d", rc);
2448 } else if (pLockData) {
2449 /* lock structure can be returned on get */
2452 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2454 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2455 rc = -EIO; /* bad smb */
2458 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2459 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2460 if (data_count < sizeof(struct cifs_posix_lock)) {
2464 parm_data = (struct cifs_posix_lock *)
2465 ((char *)&pSMBr->hdr.Protocol + data_offset);
2466 if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
2467 pLockData->fl_type = F_UNLCK;
2469 if (parm_data->lock_type ==
2470 __constant_cpu_to_le16(CIFS_RDLCK))
2471 pLockData->fl_type = F_RDLCK;
2472 else if (parm_data->lock_type ==
2473 __constant_cpu_to_le16(CIFS_WRLCK))
2474 pLockData->fl_type = F_WRLCK;
2476 pLockData->fl_start = le64_to_cpu(parm_data->start);
2477 pLockData->fl_end = pLockData->fl_start +
2478 le64_to_cpu(parm_data->length) - 1;
2479 pLockData->fl_pid = le32_to_cpu(parm_data->pid);
2485 cifs_small_buf_release(pSMB);
2487 if (resp_buf_type == CIFS_SMALL_BUFFER)
2488 cifs_small_buf_release(iov[0].iov_base);
2489 else if (resp_buf_type == CIFS_LARGE_BUFFER)
2490 cifs_buf_release(iov[0].iov_base);
2492 /* Note: On -EAGAIN error only caller can retry on handle based calls
2493 since file handle passed in no longer valid */
2500 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2503 CLOSE_REQ *pSMB = NULL;
2504 cFYI(1, "In CIFSSMBClose");
2506 /* do not retry on dead session on close */
2507 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2513 pSMB->FileID = (__u16) smb_file_id;
2514 pSMB->LastWriteTime = 0xFFFFFFFF;
2515 pSMB->ByteCount = 0;
2516 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2517 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2520 /* EINTR is expected when user ctl-c to kill app */
2521 cERROR(1, "Send error in Close = %d", rc);
2525 /* Since session is dead, file will be closed on server already */
2533 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2536 FLUSH_REQ *pSMB = NULL;
2537 cFYI(1, "In CIFSSMBFlush");
2539 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2543 pSMB->FileID = (__u16) smb_file_id;
2544 pSMB->ByteCount = 0;
2545 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2546 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2548 cERROR(1, "Send error in Flush = %d", rc);
2554 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2555 const char *fromName, const char *toName,
2556 const struct nls_table *nls_codepage, int remap)
2559 RENAME_REQ *pSMB = NULL;
2560 RENAME_RSP *pSMBr = NULL;
2562 int name_len, name_len2;
2565 cFYI(1, "In CIFSSMBRename");
2567 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2572 pSMB->BufferFormat = 0x04;
2573 pSMB->SearchAttributes =
2574 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2577 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2579 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
2580 PATH_MAX, nls_codepage, remap);
2581 name_len++; /* trailing null */
2583 pSMB->OldFileName[name_len] = 0x04; /* pad */
2584 /* protocol requires ASCII signature byte on Unicode string */
2585 pSMB->OldFileName[name_len + 1] = 0x00;
2587 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2588 toName, PATH_MAX, nls_codepage, remap);
2589 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2590 name_len2 *= 2; /* convert to bytes */
2591 } else { /* BB improve the check for buffer overruns BB */
2592 name_len = strnlen(fromName, PATH_MAX);
2593 name_len++; /* trailing null */
2594 strncpy(pSMB->OldFileName, fromName, name_len);
2595 name_len2 = strnlen(toName, PATH_MAX);
2596 name_len2++; /* trailing null */
2597 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2598 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2599 name_len2++; /* trailing null */
2600 name_len2++; /* signature byte */
2603 count = 1 /* 1st signature byte */ + name_len + name_len2;
2604 inc_rfc1001_len(pSMB, count);
2605 pSMB->ByteCount = cpu_to_le16(count);
2607 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2608 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2609 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2611 cFYI(1, "Send error in rename = %d", rc);
2613 cifs_buf_release(pSMB);
2621 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2622 int netfid, const char *target_name,
2623 const struct nls_table *nls_codepage, int remap)
2625 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2626 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2627 struct set_file_rename *rename_info;
2629 char dummy_string[30];
2631 int bytes_returned = 0;
2633 __u16 params, param_offset, offset, count, byte_count;
2635 cFYI(1, "Rename to File by handle");
2636 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2642 pSMB->MaxSetupCount = 0;
2646 pSMB->Reserved2 = 0;
2647 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2648 offset = param_offset + params;
2650 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2651 rename_info = (struct set_file_rename *) data_offset;
2652 pSMB->MaxParameterCount = cpu_to_le16(2);
2653 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2654 pSMB->SetupCount = 1;
2655 pSMB->Reserved3 = 0;
2656 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2657 byte_count = 3 /* pad */ + params;
2658 pSMB->ParameterCount = cpu_to_le16(params);
2659 pSMB->TotalParameterCount = pSMB->ParameterCount;
2660 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2661 pSMB->DataOffset = cpu_to_le16(offset);
2662 /* construct random name ".cifs_tmp<inodenum><mid>" */
2663 rename_info->overwrite = cpu_to_le32(1);
2664 rename_info->root_fid = 0;
2665 /* unicode only call */
2666 if (target_name == NULL) {
2667 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2669 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2670 dummy_string, 24, nls_codepage, remap);
2673 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2674 target_name, PATH_MAX, nls_codepage,
2677 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2678 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2679 byte_count += count;
2680 pSMB->DataCount = cpu_to_le16(count);
2681 pSMB->TotalDataCount = pSMB->DataCount;
2683 pSMB->InformationLevel =
2684 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2685 pSMB->Reserved4 = 0;
2686 inc_rfc1001_len(pSMB, byte_count);
2687 pSMB->ByteCount = cpu_to_le16(byte_count);
2688 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2689 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2690 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2692 cFYI(1, "Send error in Rename (by file handle) = %d", rc);
2694 cifs_buf_release(pSMB);
2696 /* Note: On -EAGAIN error only caller can retry on handle based calls
2697 since file handle passed in no longer valid */
2703 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2704 const char *fromName, const __u16 target_tid, const char *toName,
2705 const int flags, const struct nls_table *nls_codepage, int remap)
2708 COPY_REQ *pSMB = NULL;
2709 COPY_RSP *pSMBr = NULL;
2711 int name_len, name_len2;
2714 cFYI(1, "In CIFSSMBCopy");
2716 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2721 pSMB->BufferFormat = 0x04;
2722 pSMB->Tid2 = target_tid;
2724 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2726 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2727 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2728 fromName, PATH_MAX, nls_codepage,
2730 name_len++; /* trailing null */
2732 pSMB->OldFileName[name_len] = 0x04; /* pad */
2733 /* protocol requires ASCII signature byte on Unicode string */
2734 pSMB->OldFileName[name_len + 1] = 0x00;
2736 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2737 toName, PATH_MAX, nls_codepage, remap);
2738 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2739 name_len2 *= 2; /* convert to bytes */
2740 } else { /* BB improve the check for buffer overruns BB */
2741 name_len = strnlen(fromName, PATH_MAX);
2742 name_len++; /* trailing null */
2743 strncpy(pSMB->OldFileName, fromName, name_len);
2744 name_len2 = strnlen(toName, PATH_MAX);
2745 name_len2++; /* trailing null */
2746 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2747 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2748 name_len2++; /* trailing null */
2749 name_len2++; /* signature byte */
2752 count = 1 /* 1st signature byte */ + name_len + name_len2;
2753 inc_rfc1001_len(pSMB, count);
2754 pSMB->ByteCount = cpu_to_le16(count);
2756 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2757 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2759 cFYI(1, "Send error in copy = %d with %d files copied",
2760 rc, le16_to_cpu(pSMBr->CopyCount));
2762 cifs_buf_release(pSMB);
2771 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2772 const char *fromName, const char *toName,
2773 const struct nls_table *nls_codepage)
2775 TRANSACTION2_SPI_REQ *pSMB = NULL;
2776 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2779 int name_len_target;
2781 int bytes_returned = 0;
2782 __u16 params, param_offset, offset, byte_count;
2784 cFYI(1, "In Symlink Unix style");
2786 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2791 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2793 cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName,
2794 /* find define for this maxpathcomponent */
2795 PATH_MAX, nls_codepage);
2796 name_len++; /* trailing null */
2799 } else { /* BB improve the check for buffer overruns BB */
2800 name_len = strnlen(fromName, PATH_MAX);
2801 name_len++; /* trailing null */
2802 strncpy(pSMB->FileName, fromName, name_len);
2804 params = 6 + name_len;
2805 pSMB->MaxSetupCount = 0;
2809 pSMB->Reserved2 = 0;
2810 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2811 InformationLevel) - 4;
2812 offset = param_offset + params;
2814 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2815 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2817 cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX
2818 /* find define for this maxpathcomponent */
2820 name_len_target++; /* trailing null */
2821 name_len_target *= 2;
2822 } else { /* BB improve the check for buffer overruns BB */
2823 name_len_target = strnlen(toName, PATH_MAX);
2824 name_len_target++; /* trailing null */
2825 strncpy(data_offset, toName, name_len_target);
2828 pSMB->MaxParameterCount = cpu_to_le16(2);
2829 /* BB find exact max on data count below from sess */
2830 pSMB->MaxDataCount = cpu_to_le16(1000);
2831 pSMB->SetupCount = 1;
2832 pSMB->Reserved3 = 0;
2833 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2834 byte_count = 3 /* pad */ + params + name_len_target;
2835 pSMB->DataCount = cpu_to_le16(name_len_target);
2836 pSMB->ParameterCount = cpu_to_le16(params);
2837 pSMB->TotalDataCount = pSMB->DataCount;
2838 pSMB->TotalParameterCount = pSMB->ParameterCount;
2839 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2840 pSMB->DataOffset = cpu_to_le16(offset);
2841 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2842 pSMB->Reserved4 = 0;
2843 inc_rfc1001_len(pSMB, byte_count);
2844 pSMB->ByteCount = cpu_to_le16(byte_count);
2845 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2846 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2847 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2849 cFYI(1, "Send error in SetPathInfo create symlink = %d", rc);
2851 cifs_buf_release(pSMB);
2854 goto createSymLinkRetry;
2860 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2861 const char *fromName, const char *toName,
2862 const struct nls_table *nls_codepage, int remap)
2864 TRANSACTION2_SPI_REQ *pSMB = NULL;
2865 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2868 int name_len_target;
2870 int bytes_returned = 0;
2871 __u16 params, param_offset, offset, byte_count;
2873 cFYI(1, "In Create Hard link Unix style");
2874 createHardLinkRetry:
2875 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2880 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2881 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2882 PATH_MAX, nls_codepage, remap);
2883 name_len++; /* trailing null */
2886 } else { /* BB improve the check for buffer overruns BB */
2887 name_len = strnlen(toName, PATH_MAX);
2888 name_len++; /* trailing null */
2889 strncpy(pSMB->FileName, toName, name_len);
2891 params = 6 + name_len;
2892 pSMB->MaxSetupCount = 0;
2896 pSMB->Reserved2 = 0;
2897 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2898 InformationLevel) - 4;
2899 offset = param_offset + params;
2901 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2902 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2904 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2905 PATH_MAX, nls_codepage, remap);
2906 name_len_target++; /* trailing null */
2907 name_len_target *= 2;
2908 } else { /* BB improve the check for buffer overruns BB */
2909 name_len_target = strnlen(fromName, PATH_MAX);
2910 name_len_target++; /* trailing null */
2911 strncpy(data_offset, fromName, name_len_target);
2914 pSMB->MaxParameterCount = cpu_to_le16(2);
2915 /* BB find exact max on data count below from sess*/
2916 pSMB->MaxDataCount = cpu_to_le16(1000);
2917 pSMB->SetupCount = 1;
2918 pSMB->Reserved3 = 0;
2919 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2920 byte_count = 3 /* pad */ + params + name_len_target;
2921 pSMB->ParameterCount = cpu_to_le16(params);
2922 pSMB->TotalParameterCount = pSMB->ParameterCount;
2923 pSMB->DataCount = cpu_to_le16(name_len_target);
2924 pSMB->TotalDataCount = pSMB->DataCount;
2925 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2926 pSMB->DataOffset = cpu_to_le16(offset);
2927 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2928 pSMB->Reserved4 = 0;
2929 inc_rfc1001_len(pSMB, byte_count);
2930 pSMB->ByteCount = cpu_to_le16(byte_count);
2931 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2932 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2933 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2935 cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc);
2937 cifs_buf_release(pSMB);
2939 goto createHardLinkRetry;
2945 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2946 const char *fromName, const char *toName,
2947 const struct nls_table *nls_codepage, int remap)
2950 NT_RENAME_REQ *pSMB = NULL;
2951 RENAME_RSP *pSMBr = NULL;
2953 int name_len, name_len2;
2956 cFYI(1, "In CIFSCreateHardLink");
2957 winCreateHardLinkRetry:
2959 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2964 pSMB->SearchAttributes =
2965 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2967 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2968 pSMB->ClusterCount = 0;
2970 pSMB->BufferFormat = 0x04;
2972 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2974 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
2975 PATH_MAX, nls_codepage, remap);
2976 name_len++; /* trailing null */
2979 /* protocol specifies ASCII buffer format (0x04) for unicode */
2980 pSMB->OldFileName[name_len] = 0x04;
2981 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2983 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2984 toName, PATH_MAX, nls_codepage, remap);
2985 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2986 name_len2 *= 2; /* convert to bytes */
2987 } else { /* BB improve the check for buffer overruns BB */
2988 name_len = strnlen(fromName, PATH_MAX);
2989 name_len++; /* trailing null */
2990 strncpy(pSMB->OldFileName, fromName, name_len);
2991 name_len2 = strnlen(toName, PATH_MAX);
2992 name_len2++; /* trailing null */
2993 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2994 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2995 name_len2++; /* trailing null */
2996 name_len2++; /* signature byte */
2999 count = 1 /* string type byte */ + name_len + name_len2;
3000 inc_rfc1001_len(pSMB, count);
3001 pSMB->ByteCount = cpu_to_le16(count);
3003 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3004 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3005 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3007 cFYI(1, "Send error in hard link (NT rename) = %d", rc);
3009 cifs_buf_release(pSMB);
3011 goto winCreateHardLinkRetry;
3017 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3018 const unsigned char *searchName, char **symlinkinfo,
3019 const struct nls_table *nls_codepage)
3021 /* SMB_QUERY_FILE_UNIX_LINK */
3022 TRANSACTION2_QPI_REQ *pSMB = NULL;
3023 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3027 __u16 params, byte_count;
3030 cFYI(1, "In QPathSymLinkInfo (Unix) for path %s", searchName);
3033 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3038 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3040 cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName,
3041 PATH_MAX, nls_codepage);
3042 name_len++; /* trailing null */
3044 } else { /* BB improve the check for buffer overruns BB */
3045 name_len = strnlen(searchName, PATH_MAX);
3046 name_len++; /* trailing null */
3047 strncpy(pSMB->FileName, searchName, name_len);
3050 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3051 pSMB->TotalDataCount = 0;
3052 pSMB->MaxParameterCount = cpu_to_le16(2);
3053 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3054 pSMB->MaxSetupCount = 0;
3058 pSMB->Reserved2 = 0;
3059 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3060 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3061 pSMB->DataCount = 0;
3062 pSMB->DataOffset = 0;
3063 pSMB->SetupCount = 1;
3064 pSMB->Reserved3 = 0;
3065 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3066 byte_count = params + 1 /* pad */ ;
3067 pSMB->TotalParameterCount = cpu_to_le16(params);
3068 pSMB->ParameterCount = pSMB->TotalParameterCount;
3069 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3070 pSMB->Reserved4 = 0;
3071 inc_rfc1001_len(pSMB, byte_count);
3072 pSMB->ByteCount = cpu_to_le16(byte_count);
3074 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3075 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3077 cFYI(1, "Send error in QuerySymLinkInfo = %d", rc);
3079 /* decode response */
3081 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3082 /* BB also check enough total bytes returned */
3083 if (rc || get_bcc(&pSMBr->hdr) < 2)
3087 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3089 data_start = ((char *) &pSMBr->hdr.Protocol) +
3090 le16_to_cpu(pSMBr->t2.DataOffset);
3092 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3097 /* BB FIXME investigate remapping reserved chars here */
3098 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3099 count, is_unicode, nls_codepage);
3104 cifs_buf_release(pSMB);
3106 goto querySymLinkRetry;
3110 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3112 * Recent Windows versions now create symlinks more frequently
3113 * and they use the "reparse point" mechanism below. We can of course
3114 * do symlinks nicely to Samba and other servers which support the
3115 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3116 * "MF" symlinks optionally, but for recent Windows we really need to
3117 * reenable the code below and fix the cifs_symlink callers to handle this.
3118 * In the interim this code has been moved to its own config option so
3119 * it is not compiled in by default until callers fixed up and more tested.
3122 CIFSSMBQueryReparseLinkInfo(const unsigned int xid, struct cifs_tcon *tcon,
3123 const unsigned char *searchName,
3124 char *symlinkinfo, const int buflen, __u16 fid,
3125 const struct nls_table *nls_codepage)
3129 struct smb_com_transaction_ioctl_req *pSMB;
3130 struct smb_com_transaction_ioctl_rsp *pSMBr;
3132 cFYI(1, "In Windows reparse style QueryLink for path %s", searchName);
3133 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3138 pSMB->TotalParameterCount = 0 ;
3139 pSMB->TotalDataCount = 0;
3140 pSMB->MaxParameterCount = cpu_to_le32(2);
3141 /* BB find exact data count max from sess structure BB */
3142 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3143 pSMB->MaxSetupCount = 4;
3145 pSMB->ParameterOffset = 0;
3146 pSMB->DataCount = 0;
3147 pSMB->DataOffset = 0;
3148 pSMB->SetupCount = 4;
3149 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3150 pSMB->ParameterCount = pSMB->TotalParameterCount;
3151 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3152 pSMB->IsFsctl = 1; /* FSCTL */
3153 pSMB->IsRootFlag = 0;
3154 pSMB->Fid = fid; /* file handle always le */
3155 pSMB->ByteCount = 0;
3157 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3158 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3160 cFYI(1, "Send error in QueryReparseLinkInfo = %d", rc);
3161 } else { /* decode response */
3162 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
3163 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
3164 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3165 /* BB also check enough total bytes returned */
3166 rc = -EIO; /* bad smb */
3169 if (data_count && (data_count < 2048)) {
3170 char *end_of_smb = 2 /* sizeof byte count */ +
3171 get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3173 struct reparse_data *reparse_buf =
3174 (struct reparse_data *)
3175 ((char *)&pSMBr->hdr.Protocol
3177 if ((char *)reparse_buf >= end_of_smb) {
3181 if ((reparse_buf->LinkNamesBuf +
3182 reparse_buf->TargetNameOffset +
3183 reparse_buf->TargetNameLen) > end_of_smb) {
3184 cFYI(1, "reparse buf beyond SMB");
3189 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3190 cifs_from_ucs2(symlinkinfo, (__le16 *)
3191 (reparse_buf->LinkNamesBuf +
3192 reparse_buf->TargetNameOffset),
3194 reparse_buf->TargetNameLen,
3196 } else { /* ASCII names */
3197 strncpy(symlinkinfo,
3198 reparse_buf->LinkNamesBuf +
3199 reparse_buf->TargetNameOffset,
3200 min_t(const int, buflen,
3201 reparse_buf->TargetNameLen));
3205 cFYI(1, "Invalid return data count on "
3206 "get reparse info ioctl");
3208 symlinkinfo[buflen] = 0; /* just in case so the caller
3209 does not go off the end of the buffer */
3210 cFYI(1, "readlink result - %s", symlinkinfo);
3214 cifs_buf_release(pSMB);
3216 /* Note: On -EAGAIN error only caller can retry on handle based calls
3217 since file handle passed in no longer valid */
3221 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3223 #ifdef CONFIG_CIFS_POSIX
3225 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3226 static void cifs_convert_ace(posix_acl_xattr_entry *ace,
3227 struct cifs_posix_ace *cifs_ace)
3229 /* u8 cifs fields do not need le conversion */
3230 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3231 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3232 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3233 /* cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id); */
3238 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3239 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3240 const int acl_type, const int size_of_data_area)
3245 struct cifs_posix_ace *pACE;
3246 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3247 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
3249 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3252 if (acl_type & ACL_TYPE_ACCESS) {
3253 count = le16_to_cpu(cifs_acl->access_entry_count);
3254 pACE = &cifs_acl->ace_array[0];
3255 size = sizeof(struct cifs_posix_acl);
3256 size += sizeof(struct cifs_posix_ace) * count;
3257 /* check if we would go beyond end of SMB */
3258 if (size_of_data_area < size) {
3259 cFYI(1, "bad CIFS POSIX ACL size %d vs. %d",
3260 size_of_data_area, size);
3263 } else if (acl_type & ACL_TYPE_DEFAULT) {
3264 count = le16_to_cpu(cifs_acl->access_entry_count);
3265 size = sizeof(struct cifs_posix_acl);
3266 size += sizeof(struct cifs_posix_ace) * count;
3267 /* skip past access ACEs to get to default ACEs */
3268 pACE = &cifs_acl->ace_array[count];
3269 count = le16_to_cpu(cifs_acl->default_entry_count);
3270 size += sizeof(struct cifs_posix_ace) * count;
3271 /* check if we would go beyond end of SMB */
3272 if (size_of_data_area < size)
3279 size = posix_acl_xattr_size(count);
3280 if ((buflen == 0) || (local_acl == NULL)) {
3281 /* used to query ACL EA size */
3282 } else if (size > buflen) {
3284 } else /* buffer big enough */ {
3285 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3286 for (i = 0; i < count ; i++) {
3287 cifs_convert_ace(&local_acl->a_entries[i], pACE);
3294 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3295 const posix_acl_xattr_entry *local_ace)
3297 __u16 rc = 0; /* 0 = ACL converted ok */
3299 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3300 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3301 /* BB is there a better way to handle the large uid? */
3302 if (local_ace->e_id == cpu_to_le32(-1)) {
3303 /* Probably no need to le convert -1 on any arch but can not hurt */
3304 cifs_ace->cifs_uid = cpu_to_le64(-1);
3306 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3307 /*cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id);*/
3311 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3312 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3313 const int buflen, const int acl_type)
3316 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3317 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
3321 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3324 count = posix_acl_xattr_count((size_t)buflen);
3325 cFYI(1, "setting acl with %d entries from buf of length %d and "
3327 count, buflen, le32_to_cpu(local_acl->a_version));
3328 if (le32_to_cpu(local_acl->a_version) != 2) {
3329 cFYI(1, "unknown POSIX ACL version %d",
3330 le32_to_cpu(local_acl->a_version));
3333 cifs_acl->version = cpu_to_le16(1);
3334 if (acl_type == ACL_TYPE_ACCESS)
3335 cifs_acl->access_entry_count = cpu_to_le16(count);
3336 else if (acl_type == ACL_TYPE_DEFAULT)
3337 cifs_acl->default_entry_count = cpu_to_le16(count);
3339 cFYI(1, "unknown ACL type %d", acl_type);
3342 for (i = 0; i < count; i++) {
3343 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3344 &local_acl->a_entries[i]);
3346 /* ACE not converted */
3351 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3352 rc += sizeof(struct cifs_posix_acl);
3353 /* BB add check to make sure ACL does not overflow SMB */
3359 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3360 const unsigned char *searchName,
3361 char *acl_inf, const int buflen, const int acl_type,
3362 const struct nls_table *nls_codepage, int remap)
3364 /* SMB_QUERY_POSIX_ACL */
3365 TRANSACTION2_QPI_REQ *pSMB = NULL;
3366 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3370 __u16 params, byte_count;
3372 cFYI(1, "In GetPosixACL (Unix) for path %s", searchName);
3375 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3380 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3382 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3383 searchName, PATH_MAX, nls_codepage,
3385 name_len++; /* trailing null */
3387 pSMB->FileName[name_len] = 0;
3388 pSMB->FileName[name_len+1] = 0;
3389 } else { /* BB improve the check for buffer overruns BB */
3390 name_len = strnlen(searchName, PATH_MAX);
3391 name_len++; /* trailing null */
3392 strncpy(pSMB->FileName, searchName, name_len);
3395 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3396 pSMB->TotalDataCount = 0;
3397 pSMB->MaxParameterCount = cpu_to_le16(2);
3398 /* BB find exact max data count below from sess structure BB */
3399 pSMB->MaxDataCount = cpu_to_le16(4000);
3400 pSMB->MaxSetupCount = 0;
3404 pSMB->Reserved2 = 0;
3405 pSMB->ParameterOffset = cpu_to_le16(
3406 offsetof(struct smb_com_transaction2_qpi_req,
3407 InformationLevel) - 4);
3408 pSMB->DataCount = 0;
3409 pSMB->DataOffset = 0;
3410 pSMB->SetupCount = 1;
3411 pSMB->Reserved3 = 0;
3412 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3413 byte_count = params + 1 /* pad */ ;
3414 pSMB->TotalParameterCount = cpu_to_le16(params);
3415 pSMB->ParameterCount = pSMB->TotalParameterCount;
3416 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3417 pSMB->Reserved4 = 0;
3418 inc_rfc1001_len(pSMB, byte_count);
3419 pSMB->ByteCount = cpu_to_le16(byte_count);
3421 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3422 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3423 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3425 cFYI(1, "Send error in Query POSIX ACL = %d", rc);
3427 /* decode response */
3429 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3430 /* BB also check enough total bytes returned */
3431 if (rc || get_bcc(&pSMBr->hdr) < 2)
3432 rc = -EIO; /* bad smb */
3434 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3435 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3436 rc = cifs_copy_posix_acl(acl_inf,
3437 (char *)&pSMBr->hdr.Protocol+data_offset,
3438 buflen, acl_type, count);
3441 cifs_buf_release(pSMB);
3448 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3449 const unsigned char *fileName,
3450 const char *local_acl, const int buflen,
3452 const struct nls_table *nls_codepage, int remap)
3454 struct smb_com_transaction2_spi_req *pSMB = NULL;
3455 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3459 int bytes_returned = 0;
3460 __u16 params, byte_count, data_count, param_offset, offset;
3462 cFYI(1, "In SetPosixACL (Unix) for path %s", fileName);
3464 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3468 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3470 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3471 PATH_MAX, nls_codepage, remap);
3472 name_len++; /* trailing null */
3474 } else { /* BB improve the check for buffer overruns BB */
3475 name_len = strnlen(fileName, PATH_MAX);
3476 name_len++; /* trailing null */
3477 strncpy(pSMB->FileName, fileName, name_len);
3479 params = 6 + name_len;
3480 pSMB->MaxParameterCount = cpu_to_le16(2);
3481 /* BB find max SMB size from sess */
3482 pSMB->MaxDataCount = cpu_to_le16(1000);
3483 pSMB->MaxSetupCount = 0;
3487 pSMB->Reserved2 = 0;
3488 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3489 InformationLevel) - 4;
3490 offset = param_offset + params;
3491 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3492 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3494 /* convert to on the wire format for POSIX ACL */
3495 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3497 if (data_count == 0) {
3499 goto setACLerrorExit;
3501 pSMB->DataOffset = cpu_to_le16(offset);
3502 pSMB->SetupCount = 1;
3503 pSMB->Reserved3 = 0;
3504 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3505 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3506 byte_count = 3 /* pad */ + params + data_count;
3507 pSMB->DataCount = cpu_to_le16(data_count);
3508 pSMB->TotalDataCount = pSMB->DataCount;
3509 pSMB->ParameterCount = cpu_to_le16(params);
3510 pSMB->TotalParameterCount = pSMB->ParameterCount;
3511 pSMB->Reserved4 = 0;
3512 inc_rfc1001_len(pSMB, byte_count);
3513 pSMB->ByteCount = cpu_to_le16(byte_count);
3514 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3515 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3517 cFYI(1, "Set POSIX ACL returned %d", rc);
3520 cifs_buf_release(pSMB);
3526 /* BB fix tabs in this function FIXME BB */
3528 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3529 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3532 struct smb_t2_qfi_req *pSMB = NULL;
3533 struct smb_t2_qfi_rsp *pSMBr = NULL;
3535 __u16 params, byte_count;
3537 cFYI(1, "In GetExtAttr");
3542 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3547 params = 2 /* level */ + 2 /* fid */;
3548 pSMB->t2.TotalDataCount = 0;
3549 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3550 /* BB find exact max data count below from sess structure BB */
3551 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3552 pSMB->t2.MaxSetupCount = 0;
3553 pSMB->t2.Reserved = 0;
3555 pSMB->t2.Timeout = 0;
3556 pSMB->t2.Reserved2 = 0;
3557 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3559 pSMB->t2.DataCount = 0;
3560 pSMB->t2.DataOffset = 0;
3561 pSMB->t2.SetupCount = 1;
3562 pSMB->t2.Reserved3 = 0;
3563 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3564 byte_count = params + 1 /* pad */ ;
3565 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3566 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3567 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3570 inc_rfc1001_len(pSMB, byte_count);
3571 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3573 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3574 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3576 cFYI(1, "error %d in GetExtAttr", rc);
3578 /* decode response */
3579 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3580 /* BB also check enough total bytes returned */
3581 if (rc || get_bcc(&pSMBr->hdr) < 2)
3582 /* If rc should we check for EOPNOSUPP and
3583 disable the srvino flag? or in caller? */
3584 rc = -EIO; /* bad smb */
3586 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3587 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3588 struct file_chattr_info *pfinfo;
3589 /* BB Do we need a cast or hash here ? */
3591 cFYI(1, "Illegal size ret in GetExtAttr");
3595 pfinfo = (struct file_chattr_info *)
3596 (data_offset + (char *) &pSMBr->hdr.Protocol);
3597 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3598 *pMask = le64_to_cpu(pfinfo->mask);
3602 cifs_buf_release(pSMB);
3604 goto GetExtAttrRetry;
3608 #endif /* CONFIG_POSIX */
3610 #ifdef CONFIG_CIFS_ACL
3612 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3613 * all NT TRANSACTS that we init here have total parm and data under about 400
3614 * bytes (to fit in small cifs buffer size), which is the case so far, it
3615 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3616 * returned setup area) and MaxParameterCount (returned parms size) must be set
3620 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3621 const int parm_len, struct cifs_tcon *tcon,
3626 struct smb_com_ntransact_req *pSMB;
3628 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3632 *ret_buf = (void *)pSMB;
3634 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3635 pSMB->TotalDataCount = 0;
3636 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3637 pSMB->ParameterCount = pSMB->TotalParameterCount;
3638 pSMB->DataCount = pSMB->TotalDataCount;
3639 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3640 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3641 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3642 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3643 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3644 pSMB->SubCommand = cpu_to_le16(sub_command);
3649 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3650 __u32 *pparmlen, __u32 *pdatalen)
3653 __u32 data_count, data_offset, parm_count, parm_offset;
3654 struct smb_com_ntransact_rsp *pSMBr;
3663 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3665 bcc = get_bcc(&pSMBr->hdr);
3666 end_of_smb = 2 /* sizeof byte count */ + bcc +
3667 (char *)&pSMBr->ByteCount;
3669 data_offset = le32_to_cpu(pSMBr->DataOffset);
3670 data_count = le32_to_cpu(pSMBr->DataCount);
3671 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3672 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3674 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3675 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3677 /* should we also check that parm and data areas do not overlap? */
3678 if (*ppparm > end_of_smb) {
3679 cFYI(1, "parms start after end of smb");
3681 } else if (parm_count + *ppparm > end_of_smb) {
3682 cFYI(1, "parm end after end of smb");
3684 } else if (*ppdata > end_of_smb) {
3685 cFYI(1, "data starts after end of smb");
3687 } else if (data_count + *ppdata > end_of_smb) {
3688 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
3689 *ppdata, data_count, (data_count + *ppdata),
3692 } else if (parm_count + data_count > bcc) {
3693 cFYI(1, "parm count and data count larger than SMB");
3696 *pdatalen = data_count;
3697 *pparmlen = parm_count;
3701 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3703 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3704 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3708 QUERY_SEC_DESC_REQ *pSMB;
3711 cFYI(1, "GetCifsACL");
3716 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3717 8 /* parm len */, tcon, (void **) &pSMB);
3721 pSMB->MaxParameterCount = cpu_to_le32(4);
3722 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3723 pSMB->MaxSetupCount = 0;
3724 pSMB->Fid = fid; /* file handle always le */
3725 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3727 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3728 inc_rfc1001_len(pSMB, 11);
3729 iov[0].iov_base = (char *)pSMB;
3730 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3732 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3734 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3736 cFYI(1, "Send error in QuerySecDesc = %d", rc);
3737 } else { /* decode response */
3741 struct smb_com_ntransact_rsp *pSMBr;
3744 /* validate_nttransact */
3745 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3746 &pdata, &parm_len, pbuflen);
3749 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3751 cFYI(1, "smb %p parm %p data %p", pSMBr, parm, *acl_inf);
3753 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3754 rc = -EIO; /* bad smb */
3759 /* BB check that data area is minimum length and as big as acl_len */
3761 acl_len = le32_to_cpu(*parm);
3762 if (acl_len != *pbuflen) {
3763 cERROR(1, "acl length %d does not match %d",
3765 if (*pbuflen > acl_len)
3769 /* check if buffer is big enough for the acl
3770 header followed by the smallest SID */
3771 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3772 (*pbuflen >= 64 * 1024)) {
3773 cERROR(1, "bad acl length %d", *pbuflen);
3777 *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
3778 if (*acl_inf == NULL) {
3782 memcpy(*acl_inf, pdata, *pbuflen);
3786 if (buf_type == CIFS_SMALL_BUFFER)
3787 cifs_small_buf_release(iov[0].iov_base);
3788 else if (buf_type == CIFS_LARGE_BUFFER)
3789 cifs_buf_release(iov[0].iov_base);
3790 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3795 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3796 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3798 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3800 int bytes_returned = 0;
3801 SET_SEC_DESC_REQ *pSMB = NULL;
3805 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3809 pSMB->MaxSetupCount = 0;
3813 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3814 data_count = acllen;
3815 data_offset = param_offset + param_count;
3816 byte_count = 3 /* pad */ + param_count;
3818 pSMB->DataCount = cpu_to_le32(data_count);
3819 pSMB->TotalDataCount = pSMB->DataCount;
3820 pSMB->MaxParameterCount = cpu_to_le32(4);
3821 pSMB->MaxDataCount = cpu_to_le32(16384);
3822 pSMB->ParameterCount = cpu_to_le32(param_count);
3823 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3824 pSMB->TotalParameterCount = pSMB->ParameterCount;
3825 pSMB->DataOffset = cpu_to_le32(data_offset);
3826 pSMB->SetupCount = 0;
3827 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3828 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3830 pSMB->Fid = fid; /* file handle always le */
3831 pSMB->Reserved2 = 0;
3832 pSMB->AclFlags = cpu_to_le32(aclflag);
3834 if (pntsd && acllen) {
3835 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3836 data_offset, pntsd, acllen);
3837 inc_rfc1001_len(pSMB, byte_count + data_count);
3839 inc_rfc1001_len(pSMB, byte_count);
3841 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3842 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3844 cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
3846 cFYI(1, "Set CIFS ACL returned %d", rc);
3847 cifs_buf_release(pSMB);
3850 goto setCifsAclRetry;
3855 #endif /* CONFIG_CIFS_ACL */
3857 /* Legacy Query Path Information call for lookup to old servers such
3860 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3861 const char *search_name, FILE_ALL_INFO *data,
3862 const struct nls_table *nls_codepage, int remap)
3864 QUERY_INFORMATION_REQ *pSMB;
3865 QUERY_INFORMATION_RSP *pSMBr;
3870 cFYI(1, "In SMBQPath path %s", search_name);
3872 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3877 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3879 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3880 search_name, PATH_MAX, nls_codepage,
3882 name_len++; /* trailing null */
3885 name_len = strnlen(search_name, PATH_MAX);
3886 name_len++; /* trailing null */
3887 strncpy(pSMB->FileName, search_name, name_len);
3889 pSMB->BufferFormat = 0x04;
3890 name_len++; /* account for buffer type byte */
3891 inc_rfc1001_len(pSMB, (__u16)name_len);
3892 pSMB->ByteCount = cpu_to_le16(name_len);
3894 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3895 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3897 cFYI(1, "Send error in QueryInfo = %d", rc);
3900 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3902 /* decode response */
3903 /* BB FIXME - add time zone adjustment BB */
3904 memset(data, 0, sizeof(FILE_ALL_INFO));
3907 /* decode time fields */
3908 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3909 data->LastWriteTime = data->ChangeTime;
3910 data->LastAccessTime = 0;
3911 data->AllocationSize =
3912 cpu_to_le64(le32_to_cpu(pSMBr->size));
3913 data->EndOfFile = data->AllocationSize;
3915 cpu_to_le32(le16_to_cpu(pSMBr->attr));
3917 rc = -EIO; /* bad buffer passed in */
3919 cifs_buf_release(pSMB);
3928 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3929 u16 netfid, FILE_ALL_INFO *pFindData)
3931 struct smb_t2_qfi_req *pSMB = NULL;
3932 struct smb_t2_qfi_rsp *pSMBr = NULL;
3935 __u16 params, byte_count;
3938 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3943 params = 2 /* level */ + 2 /* fid */;
3944 pSMB->t2.TotalDataCount = 0;
3945 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3946 /* BB find exact max data count below from sess structure BB */
3947 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3948 pSMB->t2.MaxSetupCount = 0;
3949 pSMB->t2.Reserved = 0;
3951 pSMB->t2.Timeout = 0;
3952 pSMB->t2.Reserved2 = 0;
3953 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3955 pSMB->t2.DataCount = 0;
3956 pSMB->t2.DataOffset = 0;
3957 pSMB->t2.SetupCount = 1;
3958 pSMB->t2.Reserved3 = 0;
3959 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3960 byte_count = params + 1 /* pad */ ;
3961 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3962 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3963 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3966 inc_rfc1001_len(pSMB, byte_count);
3968 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3969 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3971 cFYI(1, "Send error in QPathInfo = %d", rc);
3972 } else { /* decode response */
3973 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3975 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3977 else if (get_bcc(&pSMBr->hdr) < 40)
3978 rc = -EIO; /* bad smb */
3979 else if (pFindData) {
3980 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3981 memcpy((char *) pFindData,
3982 (char *) &pSMBr->hdr.Protocol +
3983 data_offset, sizeof(FILE_ALL_INFO));
3987 cifs_buf_release(pSMB);
3989 goto QFileInfoRetry;
3995 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3996 const char *search_name, FILE_ALL_INFO *data,
3997 int legacy /* old style infolevel */,
3998 const struct nls_table *nls_codepage, int remap)
4000 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4001 TRANSACTION2_QPI_REQ *pSMB = NULL;
4002 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4006 __u16 params, byte_count;
4008 /* cFYI(1, "In QPathInfo path %s", search_name); */
4010 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4015 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4017 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4018 PATH_MAX, nls_codepage, remap);
4019 name_len++; /* trailing null */
4021 } else { /* BB improve the check for buffer overruns BB */
4022 name_len = strnlen(search_name, PATH_MAX);
4023 name_len++; /* trailing null */
4024 strncpy(pSMB->FileName, search_name, name_len);
4027 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4028 pSMB->TotalDataCount = 0;
4029 pSMB->MaxParameterCount = cpu_to_le16(2);
4030 /* BB find exact max SMB PDU from sess structure BB */
4031 pSMB->MaxDataCount = cpu_to_le16(4000);
4032 pSMB->MaxSetupCount = 0;
4036 pSMB->Reserved2 = 0;
4037 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4038 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4039 pSMB->DataCount = 0;
4040 pSMB->DataOffset = 0;
4041 pSMB->SetupCount = 1;
4042 pSMB->Reserved3 = 0;
4043 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4044 byte_count = params + 1 /* pad */ ;
4045 pSMB->TotalParameterCount = cpu_to_le16(params);
4046 pSMB->ParameterCount = pSMB->TotalParameterCount;
4048 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4050 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4051 pSMB->Reserved4 = 0;
4052 inc_rfc1001_len(pSMB, byte_count);
4053 pSMB->ByteCount = cpu_to_le16(byte_count);
4055 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4056 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4058 cFYI(1, "Send error in QPathInfo = %d", rc);
4059 } else { /* decode response */
4060 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4062 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4064 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4065 rc = -EIO; /* bad smb */
4066 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4067 rc = -EIO; /* 24 or 26 expected but we do not read
4071 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4074 * On legacy responses we do not read the last field,
4075 * EAsize, fortunately since it varies by subdialect and
4076 * also note it differs on Set vs Get, ie two bytes or 4
4077 * bytes depending but we don't care here.
4080 size = sizeof(FILE_INFO_STANDARD);
4082 size = sizeof(FILE_ALL_INFO);
4083 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4088 cifs_buf_release(pSMB);
4090 goto QPathInfoRetry;
4096 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4097 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4099 struct smb_t2_qfi_req *pSMB = NULL;
4100 struct smb_t2_qfi_rsp *pSMBr = NULL;
4103 __u16 params, byte_count;
4106 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4111 params = 2 /* level */ + 2 /* fid */;
4112 pSMB->t2.TotalDataCount = 0;
4113 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4114 /* BB find exact max data count below from sess structure BB */
4115 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4116 pSMB->t2.MaxSetupCount = 0;
4117 pSMB->t2.Reserved = 0;
4119 pSMB->t2.Timeout = 0;
4120 pSMB->t2.Reserved2 = 0;
4121 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4123 pSMB->t2.DataCount = 0;
4124 pSMB->t2.DataOffset = 0;
4125 pSMB->t2.SetupCount = 1;
4126 pSMB->t2.Reserved3 = 0;
4127 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4128 byte_count = params + 1 /* pad */ ;
4129 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4130 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4131 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4134 inc_rfc1001_len(pSMB, byte_count);
4136 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4137 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4139 cFYI(1, "Send error in QPathInfo = %d", rc);
4140 } else { /* decode response */
4141 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4143 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4144 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response. "
4145 "Unix Extensions can be disabled on mount "
4146 "by specifying the nosfu mount option.");
4147 rc = -EIO; /* bad smb */
4149 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4150 memcpy((char *) pFindData,
4151 (char *) &pSMBr->hdr.Protocol +
4153 sizeof(FILE_UNIX_BASIC_INFO));
4157 cifs_buf_release(pSMB);
4159 goto UnixQFileInfoRetry;
4165 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4166 const unsigned char *searchName,
4167 FILE_UNIX_BASIC_INFO *pFindData,
4168 const struct nls_table *nls_codepage, int remap)
4170 /* SMB_QUERY_FILE_UNIX_BASIC */
4171 TRANSACTION2_QPI_REQ *pSMB = NULL;
4172 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4174 int bytes_returned = 0;
4176 __u16 params, byte_count;
4178 cFYI(1, "In QPathInfo (Unix) the path %s", searchName);
4180 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4185 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4187 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4188 PATH_MAX, nls_codepage, remap);
4189 name_len++; /* trailing null */
4191 } else { /* BB improve the check for buffer overruns BB */
4192 name_len = strnlen(searchName, PATH_MAX);
4193 name_len++; /* trailing null */
4194 strncpy(pSMB->FileName, searchName, name_len);
4197 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4198 pSMB->TotalDataCount = 0;
4199 pSMB->MaxParameterCount = cpu_to_le16(2);
4200 /* BB find exact max SMB PDU from sess structure BB */
4201 pSMB->MaxDataCount = cpu_to_le16(4000);
4202 pSMB->MaxSetupCount = 0;
4206 pSMB->Reserved2 = 0;
4207 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4208 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4209 pSMB->DataCount = 0;
4210 pSMB->DataOffset = 0;
4211 pSMB->SetupCount = 1;
4212 pSMB->Reserved3 = 0;
4213 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4214 byte_count = params + 1 /* pad */ ;
4215 pSMB->TotalParameterCount = cpu_to_le16(params);
4216 pSMB->ParameterCount = pSMB->TotalParameterCount;
4217 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4218 pSMB->Reserved4 = 0;
4219 inc_rfc1001_len(pSMB, byte_count);
4220 pSMB->ByteCount = cpu_to_le16(byte_count);
4222 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4223 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4225 cFYI(1, "Send error in QPathInfo = %d", rc);
4226 } else { /* decode response */
4227 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4229 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4230 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response. "
4231 "Unix Extensions can be disabled on mount "
4232 "by specifying the nosfu mount option.");
4233 rc = -EIO; /* bad smb */
4235 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4236 memcpy((char *) pFindData,
4237 (char *) &pSMBr->hdr.Protocol +
4239 sizeof(FILE_UNIX_BASIC_INFO));
4242 cifs_buf_release(pSMB);
4244 goto UnixQPathInfoRetry;
4249 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4251 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4252 const char *searchName,
4253 const struct nls_table *nls_codepage,
4254 __u16 *pnetfid, __u16 search_flags,
4255 struct cifs_search_info *psrch_inf, int remap, const char dirsep)
4257 /* level 257 SMB_ */
4258 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4259 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4260 T2_FFIRST_RSP_PARMS *parms;
4262 int bytes_returned = 0;
4264 __u16 params, byte_count;
4266 cFYI(1, "In FindFirst for %s", searchName);
4269 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4274 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4276 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4277 PATH_MAX, nls_codepage, remap);
4278 /* We can not add the asterik earlier in case
4279 it got remapped to 0xF03A as if it were part of the
4280 directory name instead of a wildcard */
4282 pSMB->FileName[name_len] = dirsep;
4283 pSMB->FileName[name_len+1] = 0;
4284 pSMB->FileName[name_len+2] = '*';
4285 pSMB->FileName[name_len+3] = 0;
4286 name_len += 4; /* now the trailing null */
4287 pSMB->FileName[name_len] = 0; /* null terminate just in case */
4288 pSMB->FileName[name_len+1] = 0;
4290 } else { /* BB add check for overrun of SMB buf BB */
4291 name_len = strnlen(searchName, PATH_MAX);
4292 /* BB fix here and in unicode clause above ie
4293 if (name_len > buffersize-header)
4294 free buffer exit; BB */
4295 strncpy(pSMB->FileName, searchName, name_len);
4296 pSMB->FileName[name_len] = dirsep;
4297 pSMB->FileName[name_len+1] = '*';
4298 pSMB->FileName[name_len+2] = 0;
4302 params = 12 + name_len /* includes null */ ;
4303 pSMB->TotalDataCount = 0; /* no EAs */
4304 pSMB->MaxParameterCount = cpu_to_le16(10);
4305 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4306 pSMB->MaxSetupCount = 0;
4310 pSMB->Reserved2 = 0;
4311 byte_count = params + 1 /* pad */ ;
4312 pSMB->TotalParameterCount = cpu_to_le16(params);
4313 pSMB->ParameterCount = pSMB->TotalParameterCount;
4314 pSMB->ParameterOffset = cpu_to_le16(
4315 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4317 pSMB->DataCount = 0;
4318 pSMB->DataOffset = 0;
4319 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4320 pSMB->Reserved3 = 0;
4321 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4322 pSMB->SearchAttributes =
4323 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4325 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4326 pSMB->SearchFlags = cpu_to_le16(search_flags);
4327 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4329 /* BB what should we set StorageType to? Does it matter? BB */
4330 pSMB->SearchStorageType = 0;
4331 inc_rfc1001_len(pSMB, byte_count);
4332 pSMB->ByteCount = cpu_to_le16(byte_count);
4334 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4335 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4336 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4338 if (rc) {/* BB add logic to retry regular search if Unix search
4339 rejected unexpectedly by server */
4340 /* BB Add code to handle unsupported level rc */
4341 cFYI(1, "Error in FindFirst = %d", rc);
4343 cifs_buf_release(pSMB);
4345 /* BB eventually could optimize out free and realloc of buf */
4348 goto findFirstRetry;
4349 } else { /* decode response */
4350 /* BB remember to free buffer if error BB */
4351 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4355 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4356 psrch_inf->unicode = true;
4358 psrch_inf->unicode = false;
4360 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4361 psrch_inf->smallBuf = 0;
4362 psrch_inf->srch_entries_start =
4363 (char *) &pSMBr->hdr.Protocol +
4364 le16_to_cpu(pSMBr->t2.DataOffset);
4365 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4366 le16_to_cpu(pSMBr->t2.ParameterOffset));
4368 if (parms->EndofSearch)
4369 psrch_inf->endOfSearch = true;
4371 psrch_inf->endOfSearch = false;
4373 psrch_inf->entries_in_buffer =
4374 le16_to_cpu(parms->SearchCount);
4375 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4376 psrch_inf->entries_in_buffer;
4377 lnoff = le16_to_cpu(parms->LastNameOffset);
4378 if (CIFSMaxBufSize < lnoff) {
4379 cERROR(1, "ignoring corrupt resume name");
4380 psrch_inf->last_entry = NULL;
4384 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4387 *pnetfid = parms->SearchHandle;
4389 cifs_buf_release(pSMB);
4396 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4397 __u16 searchHandle, __u16 search_flags,
4398 struct cifs_search_info *psrch_inf)
4400 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4401 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4402 T2_FNEXT_RSP_PARMS *parms;
4403 char *response_data;
4406 unsigned int name_len;
4407 __u16 params, byte_count;
4409 cFYI(1, "In FindNext");
4411 if (psrch_inf->endOfSearch)
4414 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4419 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4421 pSMB->TotalDataCount = 0; /* no EAs */
4422 pSMB->MaxParameterCount = cpu_to_le16(8);
4423 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4424 pSMB->MaxSetupCount = 0;
4428 pSMB->Reserved2 = 0;
4429 pSMB->ParameterOffset = cpu_to_le16(
4430 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4431 pSMB->DataCount = 0;
4432 pSMB->DataOffset = 0;
4433 pSMB->SetupCount = 1;
4434 pSMB->Reserved3 = 0;
4435 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4436 pSMB->SearchHandle = searchHandle; /* always kept as le */
4438 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4439 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4440 pSMB->ResumeKey = psrch_inf->resume_key;
4441 pSMB->SearchFlags = cpu_to_le16(search_flags);
4443 name_len = psrch_inf->resume_name_len;
4445 if (name_len < PATH_MAX) {
4446 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4447 byte_count += name_len;
4448 /* 14 byte parm len above enough for 2 byte null terminator */
4449 pSMB->ResumeFileName[name_len] = 0;
4450 pSMB->ResumeFileName[name_len+1] = 0;
4453 goto FNext2_err_exit;
4455 byte_count = params + 1 /* pad */ ;
4456 pSMB->TotalParameterCount = cpu_to_le16(params);
4457 pSMB->ParameterCount = pSMB->TotalParameterCount;
4458 inc_rfc1001_len(pSMB, byte_count);
4459 pSMB->ByteCount = cpu_to_le16(byte_count);
4461 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4462 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4463 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4466 psrch_inf->endOfSearch = true;
4467 cifs_buf_release(pSMB);
4468 rc = 0; /* search probably was closed at end of search*/
4470 cFYI(1, "FindNext returned = %d", rc);
4471 } else { /* decode response */
4472 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4477 /* BB fixme add lock for file (srch_info) struct here */
4478 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4479 psrch_inf->unicode = true;
4481 psrch_inf->unicode = false;
4482 response_data = (char *) &pSMBr->hdr.Protocol +
4483 le16_to_cpu(pSMBr->t2.ParameterOffset);
4484 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4485 response_data = (char *)&pSMBr->hdr.Protocol +
4486 le16_to_cpu(pSMBr->t2.DataOffset);
4487 if (psrch_inf->smallBuf)
4488 cifs_small_buf_release(
4489 psrch_inf->ntwrk_buf_start);
4491 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4492 psrch_inf->srch_entries_start = response_data;
4493 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4494 psrch_inf->smallBuf = 0;
4495 if (parms->EndofSearch)
4496 psrch_inf->endOfSearch = true;
4498 psrch_inf->endOfSearch = false;
4499 psrch_inf->entries_in_buffer =
4500 le16_to_cpu(parms->SearchCount);
4501 psrch_inf->index_of_last_entry +=
4502 psrch_inf->entries_in_buffer;
4503 lnoff = le16_to_cpu(parms->LastNameOffset);
4504 if (CIFSMaxBufSize < lnoff) {
4505 cERROR(1, "ignoring corrupt resume name");
4506 psrch_inf->last_entry = NULL;
4509 psrch_inf->last_entry =
4510 psrch_inf->srch_entries_start + lnoff;
4512 /* cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
4513 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4515 /* BB fixme add unlock here */
4520 /* BB On error, should we leave previous search buf (and count and
4521 last entry fields) intact or free the previous one? */
4523 /* Note: On -EAGAIN error only caller can retry on handle based calls
4524 since file handle passed in no longer valid */
4527 cifs_buf_release(pSMB);
4532 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4533 const __u16 searchHandle)
4536 FINDCLOSE_REQ *pSMB = NULL;
4538 cFYI(1, "In CIFSSMBFindClose");
4539 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4541 /* no sense returning error if session restarted
4542 as file handle has been closed */
4548 pSMB->FileID = searchHandle;
4549 pSMB->ByteCount = 0;
4550 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4552 cERROR(1, "Send error in FindClose = %d", rc);
4554 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4556 /* Since session is dead, search handle closed on server already */
4564 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4565 const char *search_name, __u64 *inode_number,
4566 const struct nls_table *nls_codepage, int remap)
4569 TRANSACTION2_QPI_REQ *pSMB = NULL;
4570 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4571 int name_len, bytes_returned;
4572 __u16 params, byte_count;
4574 cFYI(1, "In GetSrvInodeNum for %s", search_name);
4578 GetInodeNumberRetry:
4579 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4584 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4586 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4587 search_name, PATH_MAX, nls_codepage,
4589 name_len++; /* trailing null */
4591 } else { /* BB improve the check for buffer overruns BB */
4592 name_len = strnlen(search_name, PATH_MAX);
4593 name_len++; /* trailing null */
4594 strncpy(pSMB->FileName, search_name, name_len);
4597 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4598 pSMB->TotalDataCount = 0;
4599 pSMB->MaxParameterCount = cpu_to_le16(2);
4600 /* BB find exact max data count below from sess structure BB */
4601 pSMB->MaxDataCount = cpu_to_le16(4000);
4602 pSMB->MaxSetupCount = 0;
4606 pSMB->Reserved2 = 0;
4607 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4608 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4609 pSMB->DataCount = 0;
4610 pSMB->DataOffset = 0;
4611 pSMB->SetupCount = 1;
4612 pSMB->Reserved3 = 0;
4613 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4614 byte_count = params + 1 /* pad */ ;
4615 pSMB->TotalParameterCount = cpu_to_le16(params);
4616 pSMB->ParameterCount = pSMB->TotalParameterCount;
4617 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4618 pSMB->Reserved4 = 0;
4619 inc_rfc1001_len(pSMB, byte_count);
4620 pSMB->ByteCount = cpu_to_le16(byte_count);
4622 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4623 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4625 cFYI(1, "error %d in QueryInternalInfo", rc);
4627 /* decode response */
4628 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4629 /* BB also check enough total bytes returned */
4630 if (rc || get_bcc(&pSMBr->hdr) < 2)
4631 /* If rc should we check for EOPNOSUPP and
4632 disable the srvino flag? or in caller? */
4633 rc = -EIO; /* bad smb */
4635 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4636 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4637 struct file_internal_info *pfinfo;
4638 /* BB Do we need a cast or hash here ? */
4640 cFYI(1, "Illegal size ret in QryIntrnlInf");
4642 goto GetInodeNumOut;
4644 pfinfo = (struct file_internal_info *)
4645 (data_offset + (char *) &pSMBr->hdr.Protocol);
4646 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4650 cifs_buf_release(pSMB);
4652 goto GetInodeNumberRetry;
4656 /* parses DFS refferal V3 structure
4657 * caller is responsible for freeing target_nodes
4660 * on failure - errno
4663 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4664 unsigned int *num_of_nodes,
4665 struct dfs_info3_param **target_nodes,
4666 const struct nls_table *nls_codepage, int remap,
4667 const char *searchName)
4672 struct dfs_referral_level_3 *ref;
4674 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4678 *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4680 if (*num_of_nodes < 1) {
4681 cERROR(1, "num_referrals: must be at least > 0,"
4682 "but we get num_referrals = %d", *num_of_nodes);
4684 goto parse_DFS_referrals_exit;
4687 ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4688 if (ref->VersionNumber != cpu_to_le16(3)) {
4689 cERROR(1, "Referrals of V%d version are not supported,"
4690 "should be V3", le16_to_cpu(ref->VersionNumber));
4692 goto parse_DFS_referrals_exit;
4695 /* get the upper boundary of the resp buffer */
4696 data_end = (char *)(&(pSMBr->PathConsumed)) +
4697 le16_to_cpu(pSMBr->t2.DataCount);
4699 cFYI(1, "num_referrals: %d dfs flags: 0x%x ...",
4701 le32_to_cpu(pSMBr->DFSFlags));
4703 *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
4704 *num_of_nodes, GFP_KERNEL);
4705 if (*target_nodes == NULL) {
4706 cERROR(1, "Failed to allocate buffer for target_nodes");
4708 goto parse_DFS_referrals_exit;
4711 /* collect necessary data from referrals */
4712 for (i = 0; i < *num_of_nodes; i++) {
4715 struct dfs_info3_param *node = (*target_nodes)+i;
4717 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4719 __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4723 goto parse_DFS_referrals_exit;
4725 cifsConvertToUTF16((__le16 *) tmp, searchName,
4726 PATH_MAX, nls_codepage, remap);
4727 node->path_consumed = cifs_utf16_bytes(tmp,
4728 le16_to_cpu(pSMBr->PathConsumed),
4732 node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4734 node->server_type = le16_to_cpu(ref->ServerType);
4735 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4738 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4739 max_len = data_end - temp;
4740 node->path_name = cifs_strndup_from_utf16(temp, max_len,
4741 is_unicode, nls_codepage);
4742 if (!node->path_name) {
4744 goto parse_DFS_referrals_exit;
4747 /* copy link target UNC */
4748 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4749 max_len = data_end - temp;
4750 node->node_name = cifs_strndup_from_utf16(temp, max_len,
4751 is_unicode, nls_codepage);
4752 if (!node->node_name) {
4754 goto parse_DFS_referrals_exit;
4760 parse_DFS_referrals_exit:
4762 free_dfs_info_array(*target_nodes, *num_of_nodes);
4763 *target_nodes = NULL;
4770 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4771 const char *search_name, struct dfs_info3_param **target_nodes,
4772 unsigned int *num_of_nodes,
4773 const struct nls_table *nls_codepage, int remap)
4775 /* TRANS2_GET_DFS_REFERRAL */
4776 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4777 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4781 __u16 params, byte_count;
4783 *target_nodes = NULL;
4785 cFYI(1, "In GetDFSRefer the path %s", search_name);
4789 rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4794 /* server pointer checked in called function,
4795 but should never be null here anyway */
4796 pSMB->hdr.Mid = get_next_mid(ses->server);
4797 pSMB->hdr.Tid = ses->ipc_tid;
4798 pSMB->hdr.Uid = ses->Suid;
4799 if (ses->capabilities & CAP_STATUS32)
4800 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4801 if (ses->capabilities & CAP_DFS)
4802 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4804 if (ses->capabilities & CAP_UNICODE) {
4805 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4807 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4808 search_name, PATH_MAX, nls_codepage,
4810 name_len++; /* trailing null */
4812 } else { /* BB improve the check for buffer overruns BB */
4813 name_len = strnlen(search_name, PATH_MAX);
4814 name_len++; /* trailing null */
4815 strncpy(pSMB->RequestFileName, search_name, name_len);
4819 if (ses->server->sec_mode &
4820 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4821 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4824 pSMB->hdr.Uid = ses->Suid;
4826 params = 2 /* level */ + name_len /*includes null */ ;
4827 pSMB->TotalDataCount = 0;
4828 pSMB->DataCount = 0;
4829 pSMB->DataOffset = 0;
4830 pSMB->MaxParameterCount = 0;
4831 /* BB find exact max SMB PDU from sess structure BB */
4832 pSMB->MaxDataCount = cpu_to_le16(4000);
4833 pSMB->MaxSetupCount = 0;
4837 pSMB->Reserved2 = 0;
4838 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4839 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4840 pSMB->SetupCount = 1;
4841 pSMB->Reserved3 = 0;
4842 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4843 byte_count = params + 3 /* pad */ ;
4844 pSMB->ParameterCount = cpu_to_le16(params);
4845 pSMB->TotalParameterCount = pSMB->ParameterCount;
4846 pSMB->MaxReferralLevel = cpu_to_le16(3);
4847 inc_rfc1001_len(pSMB, byte_count);
4848 pSMB->ByteCount = cpu_to_le16(byte_count);
4850 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4851 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4853 cFYI(1, "Send error in GetDFSRefer = %d", rc);
4856 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4858 /* BB Also check if enough total bytes returned? */
4859 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4860 rc = -EIO; /* bad smb */
4864 cFYI(1, "Decoding GetDFSRefer response BCC: %d Offset %d",
4865 get_bcc(&pSMBr->hdr),
4866 le16_to_cpu(pSMBr->t2.DataOffset));
4868 /* parse returned result into more usable form */
4869 rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4870 target_nodes, nls_codepage, remap,
4874 cifs_buf_release(pSMB);
4882 /* Query File System Info such as free space to old servers such as Win 9x */
4884 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4885 struct kstatfs *FSData)
4887 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4888 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4889 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4890 FILE_SYSTEM_ALLOC_INFO *response_data;
4892 int bytes_returned = 0;
4893 __u16 params, byte_count;
4895 cFYI(1, "OldQFSInfo");
4897 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4902 params = 2; /* level */
4903 pSMB->TotalDataCount = 0;
4904 pSMB->MaxParameterCount = cpu_to_le16(2);
4905 pSMB->MaxDataCount = cpu_to_le16(1000);
4906 pSMB->MaxSetupCount = 0;
4910 pSMB->Reserved2 = 0;
4911 byte_count = params + 1 /* pad */ ;
4912 pSMB->TotalParameterCount = cpu_to_le16(params);
4913 pSMB->ParameterCount = pSMB->TotalParameterCount;
4914 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4915 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4916 pSMB->DataCount = 0;
4917 pSMB->DataOffset = 0;
4918 pSMB->SetupCount = 1;
4919 pSMB->Reserved3 = 0;
4920 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4921 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4922 inc_rfc1001_len(pSMB, byte_count);
4923 pSMB->ByteCount = cpu_to_le16(byte_count);
4925 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4926 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4928 cFYI(1, "Send error in QFSInfo = %d", rc);
4929 } else { /* decode response */
4930 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4932 if (rc || get_bcc(&pSMBr->hdr) < 18)
4933 rc = -EIO; /* bad smb */
4935 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4936 cFYI(1, "qfsinf resp BCC: %d Offset %d",
4937 get_bcc(&pSMBr->hdr), data_offset);
4939 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4940 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4942 le16_to_cpu(response_data->BytesPerSector) *
4943 le32_to_cpu(response_data->
4944 SectorsPerAllocationUnit);
4946 le32_to_cpu(response_data->TotalAllocationUnits);
4947 FSData->f_bfree = FSData->f_bavail =
4948 le32_to_cpu(response_data->FreeAllocationUnits);
4949 cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
4950 (unsigned long long)FSData->f_blocks,
4951 (unsigned long long)FSData->f_bfree,
4955 cifs_buf_release(pSMB);
4958 goto oldQFSInfoRetry;
4964 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4965 struct kstatfs *FSData)
4967 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4968 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4969 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4970 FILE_SYSTEM_INFO *response_data;
4972 int bytes_returned = 0;
4973 __u16 params, byte_count;
4975 cFYI(1, "In QFSInfo");
4977 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4982 params = 2; /* level */
4983 pSMB->TotalDataCount = 0;
4984 pSMB->MaxParameterCount = cpu_to_le16(2);
4985 pSMB->MaxDataCount = cpu_to_le16(1000);
4986 pSMB->MaxSetupCount = 0;
4990 pSMB->Reserved2 = 0;
4991 byte_count = params + 1 /* pad */ ;
4992 pSMB->TotalParameterCount = cpu_to_le16(params);
4993 pSMB->ParameterCount = pSMB->TotalParameterCount;
4994 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4995 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4996 pSMB->DataCount = 0;
4997 pSMB->DataOffset = 0;
4998 pSMB->SetupCount = 1;
4999 pSMB->Reserved3 = 0;
5000 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5001 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5002 inc_rfc1001_len(pSMB, byte_count);
5003 pSMB->ByteCount = cpu_to_le16(byte_count);
5005 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5006 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5008 cFYI(1, "Send error in QFSInfo = %d", rc);
5009 } else { /* decode response */
5010 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5012 if (rc || get_bcc(&pSMBr->hdr) < 24)
5013 rc = -EIO; /* bad smb */
5015 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5019 *) (((char *) &pSMBr->hdr.Protocol) +
5022 le32_to_cpu(response_data->BytesPerSector) *
5023 le32_to_cpu(response_data->
5024 SectorsPerAllocationUnit);
5026 le64_to_cpu(response_data->TotalAllocationUnits);
5027 FSData->f_bfree = FSData->f_bavail =
5028 le64_to_cpu(response_data->FreeAllocationUnits);
5029 cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
5030 (unsigned long long)FSData->f_blocks,
5031 (unsigned long long)FSData->f_bfree,
5035 cifs_buf_release(pSMB);
5044 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5046 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5047 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5048 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5049 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5051 int bytes_returned = 0;
5052 __u16 params, byte_count;
5054 cFYI(1, "In QFSAttributeInfo");
5056 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5061 params = 2; /* level */
5062 pSMB->TotalDataCount = 0;
5063 pSMB->MaxParameterCount = cpu_to_le16(2);
5064 /* BB find exact max SMB PDU from sess structure BB */
5065 pSMB->MaxDataCount = cpu_to_le16(1000);
5066 pSMB->MaxSetupCount = 0;
5070 pSMB->Reserved2 = 0;
5071 byte_count = params + 1 /* pad */ ;
5072 pSMB->TotalParameterCount = cpu_to_le16(params);
5073 pSMB->ParameterCount = pSMB->TotalParameterCount;
5074 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5075 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5076 pSMB->DataCount = 0;
5077 pSMB->DataOffset = 0;
5078 pSMB->SetupCount = 1;
5079 pSMB->Reserved3 = 0;
5080 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5081 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5082 inc_rfc1001_len(pSMB, byte_count);
5083 pSMB->ByteCount = cpu_to_le16(byte_count);
5085 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5086 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5088 cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
5089 } else { /* decode response */
5090 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5092 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5093 /* BB also check if enough bytes returned */
5094 rc = -EIO; /* bad smb */
5096 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5098 (FILE_SYSTEM_ATTRIBUTE_INFO
5099 *) (((char *) &pSMBr->hdr.Protocol) +
5101 memcpy(&tcon->fsAttrInfo, response_data,
5102 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5105 cifs_buf_release(pSMB);
5108 goto QFSAttributeRetry;
5114 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5116 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5117 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5118 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5119 FILE_SYSTEM_DEVICE_INFO *response_data;
5121 int bytes_returned = 0;
5122 __u16 params, byte_count;
5124 cFYI(1, "In QFSDeviceInfo");
5126 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5131 params = 2; /* level */
5132 pSMB->TotalDataCount = 0;
5133 pSMB->MaxParameterCount = cpu_to_le16(2);
5134 /* BB find exact max SMB PDU from sess structure BB */
5135 pSMB->MaxDataCount = cpu_to_le16(1000);
5136 pSMB->MaxSetupCount = 0;
5140 pSMB->Reserved2 = 0;
5141 byte_count = params + 1 /* pad */ ;
5142 pSMB->TotalParameterCount = cpu_to_le16(params);
5143 pSMB->ParameterCount = pSMB->TotalParameterCount;
5144 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5145 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5147 pSMB->DataCount = 0;
5148 pSMB->DataOffset = 0;
5149 pSMB->SetupCount = 1;
5150 pSMB->Reserved3 = 0;
5151 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5152 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5153 inc_rfc1001_len(pSMB, byte_count);
5154 pSMB->ByteCount = cpu_to_le16(byte_count);
5156 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5157 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5159 cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
5160 } else { /* decode response */
5161 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5163 if (rc || get_bcc(&pSMBr->hdr) <
5164 sizeof(FILE_SYSTEM_DEVICE_INFO))
5165 rc = -EIO; /* bad smb */
5167 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5169 (FILE_SYSTEM_DEVICE_INFO *)
5170 (((char *) &pSMBr->hdr.Protocol) +
5172 memcpy(&tcon->fsDevInfo, response_data,
5173 sizeof(FILE_SYSTEM_DEVICE_INFO));
5176 cifs_buf_release(pSMB);
5179 goto QFSDeviceRetry;
5185 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5187 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5188 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5189 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5190 FILE_SYSTEM_UNIX_INFO *response_data;
5192 int bytes_returned = 0;
5193 __u16 params, byte_count;
5195 cFYI(1, "In QFSUnixInfo");
5197 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5198 (void **) &pSMB, (void **) &pSMBr);
5202 params = 2; /* level */
5203 pSMB->TotalDataCount = 0;
5204 pSMB->DataCount = 0;
5205 pSMB->DataOffset = 0;
5206 pSMB->MaxParameterCount = cpu_to_le16(2);
5207 /* BB find exact max SMB PDU from sess structure BB */
5208 pSMB->MaxDataCount = cpu_to_le16(100);
5209 pSMB->MaxSetupCount = 0;
5213 pSMB->Reserved2 = 0;
5214 byte_count = params + 1 /* pad */ ;
5215 pSMB->ParameterCount = cpu_to_le16(params);
5216 pSMB->TotalParameterCount = pSMB->ParameterCount;
5217 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5218 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5219 pSMB->SetupCount = 1;
5220 pSMB->Reserved3 = 0;
5221 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5222 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5223 inc_rfc1001_len(pSMB, byte_count);
5224 pSMB->ByteCount = cpu_to_le16(byte_count);
5226 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5227 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5229 cERROR(1, "Send error in QFSUnixInfo = %d", rc);
5230 } else { /* decode response */
5231 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5233 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5234 rc = -EIO; /* bad smb */
5236 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5238 (FILE_SYSTEM_UNIX_INFO
5239 *) (((char *) &pSMBr->hdr.Protocol) +
5241 memcpy(&tcon->fsUnixInfo, response_data,
5242 sizeof(FILE_SYSTEM_UNIX_INFO));
5245 cifs_buf_release(pSMB);
5255 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5257 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5258 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5259 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5261 int bytes_returned = 0;
5262 __u16 params, param_offset, offset, byte_count;
5264 cFYI(1, "In SETFSUnixInfo");
5266 /* BB switch to small buf init to save memory */
5267 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5268 (void **) &pSMB, (void **) &pSMBr);
5272 params = 4; /* 2 bytes zero followed by info level. */
5273 pSMB->MaxSetupCount = 0;
5277 pSMB->Reserved2 = 0;
5278 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5280 offset = param_offset + params;
5282 pSMB->MaxParameterCount = cpu_to_le16(4);
5283 /* BB find exact max SMB PDU from sess structure BB */
5284 pSMB->MaxDataCount = cpu_to_le16(100);
5285 pSMB->SetupCount = 1;
5286 pSMB->Reserved3 = 0;
5287 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5288 byte_count = 1 /* pad */ + params + 12;
5290 pSMB->DataCount = cpu_to_le16(12);
5291 pSMB->ParameterCount = cpu_to_le16(params);
5292 pSMB->TotalDataCount = pSMB->DataCount;
5293 pSMB->TotalParameterCount = pSMB->ParameterCount;
5294 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5295 pSMB->DataOffset = cpu_to_le16(offset);
5299 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5302 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5303 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5304 pSMB->ClientUnixCap = cpu_to_le64(cap);
5306 inc_rfc1001_len(pSMB, byte_count);
5307 pSMB->ByteCount = cpu_to_le16(byte_count);
5309 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5310 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5312 cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
5313 } else { /* decode response */
5314 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5316 rc = -EIO; /* bad smb */
5318 cifs_buf_release(pSMB);
5321 goto SETFSUnixRetry;
5329 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5330 struct kstatfs *FSData)
5332 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5333 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5334 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5335 FILE_SYSTEM_POSIX_INFO *response_data;
5337 int bytes_returned = 0;
5338 __u16 params, byte_count;
5340 cFYI(1, "In QFSPosixInfo");
5342 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5347 params = 2; /* level */
5348 pSMB->TotalDataCount = 0;
5349 pSMB->DataCount = 0;
5350 pSMB->DataOffset = 0;
5351 pSMB->MaxParameterCount = cpu_to_le16(2);
5352 /* BB find exact max SMB PDU from sess structure BB */
5353 pSMB->MaxDataCount = cpu_to_le16(100);
5354 pSMB->MaxSetupCount = 0;
5358 pSMB->Reserved2 = 0;
5359 byte_count = params + 1 /* pad */ ;
5360 pSMB->ParameterCount = cpu_to_le16(params);
5361 pSMB->TotalParameterCount = pSMB->ParameterCount;
5362 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5363 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5364 pSMB->SetupCount = 1;
5365 pSMB->Reserved3 = 0;
5366 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5367 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5368 inc_rfc1001_len(pSMB, byte_count);
5369 pSMB->ByteCount = cpu_to_le16(byte_count);
5371 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5372 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5374 cFYI(1, "Send error in QFSUnixInfo = %d", rc);
5375 } else { /* decode response */
5376 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5378 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5379 rc = -EIO; /* bad smb */
5381 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5383 (FILE_SYSTEM_POSIX_INFO
5384 *) (((char *) &pSMBr->hdr.Protocol) +
5387 le32_to_cpu(response_data->BlockSize);
5389 le64_to_cpu(response_data->TotalBlocks);
5391 le64_to_cpu(response_data->BlocksAvail);
5392 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5393 FSData->f_bavail = FSData->f_bfree;
5396 le64_to_cpu(response_data->UserBlocksAvail);
5398 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5400 le64_to_cpu(response_data->TotalFileNodes);
5401 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5403 le64_to_cpu(response_data->FreeFileNodes);
5406 cifs_buf_release(pSMB);
5415 /* We can not use write of zero bytes trick to
5416 set file size due to need for large file support. Also note that
5417 this SetPathInfo is preferred to SetFileInfo based method in next
5418 routine which is only needed to work around a sharing violation bug
5419 in Samba which this routine can run into */
5422 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5423 const char *fileName, __u64 size, bool SetAllocation,
5424 const struct nls_table *nls_codepage, int remap)
5426 struct smb_com_transaction2_spi_req *pSMB = NULL;
5427 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5428 struct file_end_of_file_info *parm_data;
5431 int bytes_returned = 0;
5432 __u16 params, byte_count, data_count, param_offset, offset;
5434 cFYI(1, "In SetEOF");
5436 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5441 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5443 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5444 PATH_MAX, nls_codepage, remap);
5445 name_len++; /* trailing null */
5447 } else { /* BB improve the check for buffer overruns BB */
5448 name_len = strnlen(fileName, PATH_MAX);
5449 name_len++; /* trailing null */
5450 strncpy(pSMB->FileName, fileName, name_len);
5452 params = 6 + name_len;
5453 data_count = sizeof(struct file_end_of_file_info);
5454 pSMB->MaxParameterCount = cpu_to_le16(2);
5455 pSMB->MaxDataCount = cpu_to_le16(4100);
5456 pSMB->MaxSetupCount = 0;
5460 pSMB->Reserved2 = 0;
5461 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5462 InformationLevel) - 4;
5463 offset = param_offset + params;
5464 if (SetAllocation) {
5465 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5466 pSMB->InformationLevel =
5467 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5469 pSMB->InformationLevel =
5470 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5471 } else /* Set File Size */ {
5472 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5473 pSMB->InformationLevel =
5474 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5476 pSMB->InformationLevel =
5477 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5481 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5483 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5484 pSMB->DataOffset = cpu_to_le16(offset);
5485 pSMB->SetupCount = 1;
5486 pSMB->Reserved3 = 0;
5487 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5488 byte_count = 3 /* pad */ + params + data_count;
5489 pSMB->DataCount = cpu_to_le16(data_count);
5490 pSMB->TotalDataCount = pSMB->DataCount;
5491 pSMB->ParameterCount = cpu_to_le16(params);
5492 pSMB->TotalParameterCount = pSMB->ParameterCount;
5493 pSMB->Reserved4 = 0;
5494 inc_rfc1001_len(pSMB, byte_count);
5495 parm_data->FileSize = cpu_to_le64(size);
5496 pSMB->ByteCount = cpu_to_le16(byte_count);
5497 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5498 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5500 cFYI(1, "SetPathInfo (file size) returned %d", rc);
5502 cifs_buf_release(pSMB);
5511 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, __u64 size,
5512 __u16 fid, __u32 pid_of_opener, bool SetAllocation)
5514 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5515 struct file_end_of_file_info *parm_data;
5517 __u16 params, param_offset, offset, byte_count, count;
5519 cFYI(1, "SetFileSize (via SetFileInfo) %lld",
5521 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5526 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5527 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5530 pSMB->MaxSetupCount = 0;
5534 pSMB->Reserved2 = 0;
5535 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5536 offset = param_offset + params;
5538 count = sizeof(struct file_end_of_file_info);
5539 pSMB->MaxParameterCount = cpu_to_le16(2);
5540 /* BB find exact max SMB PDU from sess structure BB */
5541 pSMB->MaxDataCount = cpu_to_le16(1000);
5542 pSMB->SetupCount = 1;
5543 pSMB->Reserved3 = 0;
5544 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5545 byte_count = 3 /* pad */ + params + count;
5546 pSMB->DataCount = cpu_to_le16(count);
5547 pSMB->ParameterCount = cpu_to_le16(params);
5548 pSMB->TotalDataCount = pSMB->DataCount;
5549 pSMB->TotalParameterCount = pSMB->ParameterCount;
5550 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5552 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5554 pSMB->DataOffset = cpu_to_le16(offset);
5555 parm_data->FileSize = cpu_to_le64(size);
5557 if (SetAllocation) {
5558 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5559 pSMB->InformationLevel =
5560 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5562 pSMB->InformationLevel =
5563 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5564 } else /* Set File Size */ {
5565 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5566 pSMB->InformationLevel =
5567 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5569 pSMB->InformationLevel =
5570 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5572 pSMB->Reserved4 = 0;
5573 inc_rfc1001_len(pSMB, byte_count);
5574 pSMB->ByteCount = cpu_to_le16(byte_count);
5575 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5577 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
5580 /* Note: On -EAGAIN error only caller can retry on handle based calls
5581 since file handle passed in no longer valid */
5586 /* Some legacy servers such as NT4 require that the file times be set on
5587 an open handle, rather than by pathname - this is awkward due to
5588 potential access conflicts on the open, but it is unavoidable for these
5589 old servers since the only other choice is to go from 100 nanosecond DCE
5590 time and resort to the original setpathinfo level which takes the ancient
5591 DOS time format with 2 second granularity */
5593 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5594 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5596 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5599 __u16 params, param_offset, offset, byte_count, count;
5601 cFYI(1, "Set Times (via SetFileInfo)");
5602 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5607 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5608 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5611 pSMB->MaxSetupCount = 0;
5615 pSMB->Reserved2 = 0;
5616 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5617 offset = param_offset + params;
5619 data_offset = (char *)pSMB +
5620 offsetof(struct smb_hdr, Protocol) + offset;
5622 count = sizeof(FILE_BASIC_INFO);
5623 pSMB->MaxParameterCount = cpu_to_le16(2);
5624 /* BB find max SMB PDU from sess */
5625 pSMB->MaxDataCount = cpu_to_le16(1000);
5626 pSMB->SetupCount = 1;
5627 pSMB->Reserved3 = 0;
5628 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5629 byte_count = 3 /* pad */ + params + count;
5630 pSMB->DataCount = cpu_to_le16(count);
5631 pSMB->ParameterCount = cpu_to_le16(params);
5632 pSMB->TotalDataCount = pSMB->DataCount;
5633 pSMB->TotalParameterCount = pSMB->ParameterCount;
5634 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5635 pSMB->DataOffset = cpu_to_le16(offset);
5637 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5638 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5640 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5641 pSMB->Reserved4 = 0;
5642 inc_rfc1001_len(pSMB, byte_count);
5643 pSMB->ByteCount = cpu_to_le16(byte_count);
5644 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5645 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5647 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5649 /* Note: On -EAGAIN error only caller can retry on handle based calls
5650 since file handle passed in no longer valid */
5656 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5657 bool delete_file, __u16 fid, __u32 pid_of_opener)
5659 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5662 __u16 params, param_offset, offset, byte_count, count;
5664 cFYI(1, "Set File Disposition (via SetFileInfo)");
5665 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5670 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5671 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5674 pSMB->MaxSetupCount = 0;
5678 pSMB->Reserved2 = 0;
5679 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5680 offset = param_offset + params;
5682 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5685 pSMB->MaxParameterCount = cpu_to_le16(2);
5686 /* BB find max SMB PDU from sess */
5687 pSMB->MaxDataCount = cpu_to_le16(1000);
5688 pSMB->SetupCount = 1;
5689 pSMB->Reserved3 = 0;
5690 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5691 byte_count = 3 /* pad */ + params + count;
5692 pSMB->DataCount = cpu_to_le16(count);
5693 pSMB->ParameterCount = cpu_to_le16(params);
5694 pSMB->TotalDataCount = pSMB->DataCount;
5695 pSMB->TotalParameterCount = pSMB->ParameterCount;
5696 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5697 pSMB->DataOffset = cpu_to_le16(offset);
5699 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5700 pSMB->Reserved4 = 0;
5701 inc_rfc1001_len(pSMB, byte_count);
5702 pSMB->ByteCount = cpu_to_le16(byte_count);
5703 *data_offset = delete_file ? 1 : 0;
5704 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5706 cFYI(1, "Send error in SetFileDisposition = %d", rc);
5712 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5713 const char *fileName, const FILE_BASIC_INFO *data,
5714 const struct nls_table *nls_codepage, int remap)
5716 TRANSACTION2_SPI_REQ *pSMB = NULL;
5717 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5720 int bytes_returned = 0;
5722 __u16 params, param_offset, offset, byte_count, count;
5724 cFYI(1, "In SetTimes");
5727 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5732 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5734 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5735 PATH_MAX, nls_codepage, remap);
5736 name_len++; /* trailing null */
5738 } else { /* BB improve the check for buffer overruns BB */
5739 name_len = strnlen(fileName, PATH_MAX);
5740 name_len++; /* trailing null */
5741 strncpy(pSMB->FileName, fileName, name_len);
5744 params = 6 + name_len;
5745 count = sizeof(FILE_BASIC_INFO);
5746 pSMB->MaxParameterCount = cpu_to_le16(2);
5747 /* BB find max SMB PDU from sess structure BB */
5748 pSMB->MaxDataCount = cpu_to_le16(1000);
5749 pSMB->MaxSetupCount = 0;
5753 pSMB->Reserved2 = 0;
5754 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5755 InformationLevel) - 4;
5756 offset = param_offset + params;
5757 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5758 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5759 pSMB->DataOffset = cpu_to_le16(offset);
5760 pSMB->SetupCount = 1;
5761 pSMB->Reserved3 = 0;
5762 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5763 byte_count = 3 /* pad */ + params + count;
5765 pSMB->DataCount = cpu_to_le16(count);
5766 pSMB->ParameterCount = cpu_to_le16(params);
5767 pSMB->TotalDataCount = pSMB->DataCount;
5768 pSMB->TotalParameterCount = pSMB->ParameterCount;
5769 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5770 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5772 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5773 pSMB->Reserved4 = 0;
5774 inc_rfc1001_len(pSMB, byte_count);
5775 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5776 pSMB->ByteCount = cpu_to_le16(byte_count);
5777 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5778 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5780 cFYI(1, "SetPathInfo (times) returned %d", rc);
5782 cifs_buf_release(pSMB);
5790 /* Can not be used to set time stamps yet (due to old DOS time format) */
5791 /* Can be used to set attributes */
5792 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5793 handling it anyway and NT4 was what we thought it would be needed for
5794 Do not delete it until we prove whether needed for Win9x though */
5796 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
5797 __u16 dos_attrs, const struct nls_table *nls_codepage)
5799 SETATTR_REQ *pSMB = NULL;
5800 SETATTR_RSP *pSMBr = NULL;
5805 cFYI(1, "In SetAttrLegacy");
5808 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5813 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5815 ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5816 PATH_MAX, nls_codepage);
5817 name_len++; /* trailing null */
5819 } else { /* BB improve the check for buffer overruns BB */
5820 name_len = strnlen(fileName, PATH_MAX);
5821 name_len++; /* trailing null */
5822 strncpy(pSMB->fileName, fileName, name_len);
5824 pSMB->attr = cpu_to_le16(dos_attrs);
5825 pSMB->BufferFormat = 0x04;
5826 inc_rfc1001_len(pSMB, name_len + 1);
5827 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5828 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5829 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5831 cFYI(1, "Error in LegacySetAttr = %d", rc);
5833 cifs_buf_release(pSMB);
5836 goto SetAttrLgcyRetry;
5840 #endif /* temporarily unneeded SetAttr legacy function */
5843 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5844 const struct cifs_unix_set_info_args *args)
5846 u64 mode = args->mode;
5849 * Samba server ignores set of file size to zero due to bugs in some
5850 * older clients, but we should be precise - we use SetFileSize to
5851 * set file size and do not want to truncate file size to zero
5852 * accidentally as happened on one Samba server beta by putting
5853 * zero instead of -1 here
5855 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5856 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5857 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5858 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5859 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5860 data_offset->Uid = cpu_to_le64(args->uid);
5861 data_offset->Gid = cpu_to_le64(args->gid);
5862 /* better to leave device as zero when it is */
5863 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5864 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5865 data_offset->Permissions = cpu_to_le64(mode);
5868 data_offset->Type = cpu_to_le32(UNIX_FILE);
5869 else if (S_ISDIR(mode))
5870 data_offset->Type = cpu_to_le32(UNIX_DIR);
5871 else if (S_ISLNK(mode))
5872 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5873 else if (S_ISCHR(mode))
5874 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5875 else if (S_ISBLK(mode))
5876 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5877 else if (S_ISFIFO(mode))
5878 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5879 else if (S_ISSOCK(mode))
5880 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5884 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5885 const struct cifs_unix_set_info_args *args,
5886 u16 fid, u32 pid_of_opener)
5888 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5891 u16 params, param_offset, offset, byte_count, count;
5893 cFYI(1, "Set Unix Info (via SetFileInfo)");
5894 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5899 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5900 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5903 pSMB->MaxSetupCount = 0;
5907 pSMB->Reserved2 = 0;
5908 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5909 offset = param_offset + params;
5911 data_offset = (char *)pSMB +
5912 offsetof(struct smb_hdr, Protocol) + offset;
5914 count = sizeof(FILE_UNIX_BASIC_INFO);
5916 pSMB->MaxParameterCount = cpu_to_le16(2);
5917 /* BB find max SMB PDU from sess */
5918 pSMB->MaxDataCount = cpu_to_le16(1000);
5919 pSMB->SetupCount = 1;
5920 pSMB->Reserved3 = 0;
5921 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5922 byte_count = 3 /* pad */ + params + count;
5923 pSMB->DataCount = cpu_to_le16(count);
5924 pSMB->ParameterCount = cpu_to_le16(params);
5925 pSMB->TotalDataCount = pSMB->DataCount;
5926 pSMB->TotalParameterCount = pSMB->ParameterCount;
5927 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5928 pSMB->DataOffset = cpu_to_le16(offset);
5930 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5931 pSMB->Reserved4 = 0;
5932 inc_rfc1001_len(pSMB, byte_count);
5933 pSMB->ByteCount = cpu_to_le16(byte_count);
5935 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5937 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5939 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5941 /* Note: On -EAGAIN error only caller can retry on handle based calls
5942 since file handle passed in no longer valid */
5948 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5949 const char *file_name,
5950 const struct cifs_unix_set_info_args *args,
5951 const struct nls_table *nls_codepage, int remap)
5953 TRANSACTION2_SPI_REQ *pSMB = NULL;
5954 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5957 int bytes_returned = 0;
5958 FILE_UNIX_BASIC_INFO *data_offset;
5959 __u16 params, param_offset, offset, count, byte_count;
5961 cFYI(1, "In SetUID/GID/Mode");
5963 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5968 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5970 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5971 PATH_MAX, nls_codepage, remap);
5972 name_len++; /* trailing null */
5974 } else { /* BB improve the check for buffer overruns BB */
5975 name_len = strnlen(file_name, PATH_MAX);
5976 name_len++; /* trailing null */
5977 strncpy(pSMB->FileName, file_name, name_len);
5980 params = 6 + name_len;
5981 count = sizeof(FILE_UNIX_BASIC_INFO);
5982 pSMB->MaxParameterCount = cpu_to_le16(2);
5983 /* BB find max SMB PDU from sess structure BB */
5984 pSMB->MaxDataCount = cpu_to_le16(1000);
5985 pSMB->MaxSetupCount = 0;
5989 pSMB->Reserved2 = 0;
5990 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5991 InformationLevel) - 4;
5992 offset = param_offset + params;
5994 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
5996 memset(data_offset, 0, count);
5997 pSMB->DataOffset = cpu_to_le16(offset);
5998 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5999 pSMB->SetupCount = 1;
6000 pSMB->Reserved3 = 0;
6001 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6002 byte_count = 3 /* pad */ + params + count;
6003 pSMB->ParameterCount = cpu_to_le16(params);
6004 pSMB->DataCount = cpu_to_le16(count);
6005 pSMB->TotalParameterCount = pSMB->ParameterCount;
6006 pSMB->TotalDataCount = pSMB->DataCount;
6007 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6008 pSMB->Reserved4 = 0;
6009 inc_rfc1001_len(pSMB, byte_count);
6011 cifs_fill_unix_set_info(data_offset, args);
6013 pSMB->ByteCount = cpu_to_le16(byte_count);
6014 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6015 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6017 cFYI(1, "SetPathInfo (perms) returned %d", rc);
6019 cifs_buf_release(pSMB);
6025 #ifdef CONFIG_CIFS_XATTR
6027 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6028 * function used by listxattr and getxattr type calls. When ea_name is set,
6029 * it looks for that attribute name and stuffs that value into the EAData
6030 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6031 * buffer. In both cases, the return value is either the length of the
6032 * resulting data or a negative error code. If EAData is a NULL pointer then
6033 * the data isn't copied to it, but the length is returned.
6036 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6037 const unsigned char *searchName, const unsigned char *ea_name,
6038 char *EAData, size_t buf_size,
6039 const struct nls_table *nls_codepage, int remap)
6041 /* BB assumes one setup word */
6042 TRANSACTION2_QPI_REQ *pSMB = NULL;
6043 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6047 struct fealist *ea_response_data;
6048 struct fea *temp_fea;
6051 __u16 params, byte_count, data_offset;
6052 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6054 cFYI(1, "In Query All EAs path %s", searchName);
6056 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6061 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6063 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6064 PATH_MAX, nls_codepage, remap);
6065 list_len++; /* trailing null */
6067 } else { /* BB improve the check for buffer overruns BB */
6068 list_len = strnlen(searchName, PATH_MAX);
6069 list_len++; /* trailing null */
6070 strncpy(pSMB->FileName, searchName, list_len);
6073 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6074 pSMB->TotalDataCount = 0;
6075 pSMB->MaxParameterCount = cpu_to_le16(2);
6076 /* BB find exact max SMB PDU from sess structure BB */
6077 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6078 pSMB->MaxSetupCount = 0;
6082 pSMB->Reserved2 = 0;
6083 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6084 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6085 pSMB->DataCount = 0;
6086 pSMB->DataOffset = 0;
6087 pSMB->SetupCount = 1;
6088 pSMB->Reserved3 = 0;
6089 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6090 byte_count = params + 1 /* pad */ ;
6091 pSMB->TotalParameterCount = cpu_to_le16(params);
6092 pSMB->ParameterCount = pSMB->TotalParameterCount;
6093 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6094 pSMB->Reserved4 = 0;
6095 inc_rfc1001_len(pSMB, byte_count);
6096 pSMB->ByteCount = cpu_to_le16(byte_count);
6098 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6099 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6101 cFYI(1, "Send error in QueryAllEAs = %d", rc);
6106 /* BB also check enough total bytes returned */
6107 /* BB we need to improve the validity checking
6108 of these trans2 responses */
6110 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6111 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6112 rc = -EIO; /* bad smb */
6116 /* check that length of list is not more than bcc */
6117 /* check that each entry does not go beyond length
6119 /* check that each element of each entry does not
6120 go beyond end of list */
6121 /* validate_trans2_offsets() */
6122 /* BB check if start of smb + data_offset > &bcc+ bcc */
6124 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6125 ea_response_data = (struct fealist *)
6126 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6128 list_len = le32_to_cpu(ea_response_data->list_len);
6129 cFYI(1, "ea length %d", list_len);
6130 if (list_len <= 8) {
6131 cFYI(1, "empty EA list returned from server");
6135 /* make sure list_len doesn't go past end of SMB */
6136 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6137 if ((char *)ea_response_data + list_len > end_of_smb) {
6138 cFYI(1, "EA list appears to go beyond SMB");
6143 /* account for ea list len */
6145 temp_fea = ea_response_data->list;
6146 temp_ptr = (char *)temp_fea;
6147 while (list_len > 0) {
6148 unsigned int name_len;
6153 /* make sure we can read name_len and value_len */
6155 cFYI(1, "EA entry goes beyond length of list");
6160 name_len = temp_fea->name_len;
6161 value_len = le16_to_cpu(temp_fea->value_len);
6162 list_len -= name_len + 1 + value_len;
6164 cFYI(1, "EA entry goes beyond length of list");
6170 if (ea_name_len == name_len &&
6171 memcmp(ea_name, temp_ptr, name_len) == 0) {
6172 temp_ptr += name_len + 1;
6176 if ((size_t)value_len > buf_size) {
6180 memcpy(EAData, temp_ptr, value_len);
6184 /* account for prefix user. and trailing null */
6185 rc += (5 + 1 + name_len);
6186 if (rc < (int) buf_size) {
6187 memcpy(EAData, "user.", 5);
6189 memcpy(EAData, temp_ptr, name_len);
6191 /* null terminate name */
6194 } else if (buf_size == 0) {
6195 /* skip copy - calc size only */
6197 /* stop before overrun buffer */
6202 temp_ptr += name_len + 1 + value_len;
6203 temp_fea = (struct fea *)temp_ptr;
6206 /* didn't find the named attribute */
6211 cifs_buf_release(pSMB);
6219 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6220 const char *fileName, const char *ea_name, const void *ea_value,
6221 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6224 struct smb_com_transaction2_spi_req *pSMB = NULL;
6225 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6226 struct fealist *parm_data;
6229 int bytes_returned = 0;
6230 __u16 params, param_offset, byte_count, offset, count;
6232 cFYI(1, "In SetEA");
6234 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6239 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6241 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6242 PATH_MAX, nls_codepage, remap);
6243 name_len++; /* trailing null */
6245 } else { /* BB improve the check for buffer overruns BB */
6246 name_len = strnlen(fileName, PATH_MAX);
6247 name_len++; /* trailing null */
6248 strncpy(pSMB->FileName, fileName, name_len);
6251 params = 6 + name_len;
6253 /* done calculating parms using name_len of file name,
6254 now use name_len to calculate length of ea name
6255 we are going to create in the inode xattrs */
6256 if (ea_name == NULL)
6259 name_len = strnlen(ea_name, 255);
6261 count = sizeof(*parm_data) + ea_value_len + name_len;
6262 pSMB->MaxParameterCount = cpu_to_le16(2);
6263 /* BB find max SMB PDU from sess */
6264 pSMB->MaxDataCount = cpu_to_le16(1000);
6265 pSMB->MaxSetupCount = 0;
6269 pSMB->Reserved2 = 0;
6270 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6271 InformationLevel) - 4;
6272 offset = param_offset + params;
6273 pSMB->InformationLevel =
6274 cpu_to_le16(SMB_SET_FILE_EA);
6277 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6279 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6280 pSMB->DataOffset = cpu_to_le16(offset);
6281 pSMB->SetupCount = 1;
6282 pSMB->Reserved3 = 0;
6283 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6284 byte_count = 3 /* pad */ + params + count;
6285 pSMB->DataCount = cpu_to_le16(count);
6286 parm_data->list_len = cpu_to_le32(count);
6287 parm_data->list[0].EA_flags = 0;
6288 /* we checked above that name len is less than 255 */
6289 parm_data->list[0].name_len = (__u8)name_len;
6290 /* EA names are always ASCII */
6292 strncpy(parm_data->list[0].name, ea_name, name_len);
6293 parm_data->list[0].name[name_len] = 0;
6294 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6295 /* caller ensures that ea_value_len is less than 64K but
6296 we need to ensure that it fits within the smb */
6298 /*BB add length check to see if it would fit in
6299 negotiated SMB buffer size BB */
6300 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6302 memcpy(parm_data->list[0].name+name_len+1,
6303 ea_value, ea_value_len);
6305 pSMB->TotalDataCount = pSMB->DataCount;
6306 pSMB->ParameterCount = cpu_to_le16(params);
6307 pSMB->TotalParameterCount = pSMB->ParameterCount;
6308 pSMB->Reserved4 = 0;
6309 inc_rfc1001_len(pSMB, byte_count);
6310 pSMB->ByteCount = cpu_to_le16(byte_count);
6311 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6312 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6314 cFYI(1, "SetPathInfo (EA) returned %d", rc);
6316 cifs_buf_release(pSMB);
6325 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6327 * Years ago the kernel added a "dnotify" function for Samba server,
6328 * to allow network clients (such as Windows) to display updated
6329 * lists of files in directory listings automatically when
6330 * files are added by one user when another user has the
6331 * same directory open on their desktop. The Linux cifs kernel
6332 * client hooked into the kernel side of this interface for
6333 * the same reason, but ironically when the VFS moved from
6334 * "dnotify" to "inotify" it became harder to plug in Linux
6335 * network file system clients (the most obvious use case
6336 * for notify interfaces is when multiple users can update
6337 * the contents of the same directory - exactly what network
6338 * file systems can do) although the server (Samba) could
6339 * still use it. For the short term we leave the worker
6340 * function ifdeffed out (below) until inotify is fixed
6341 * in the VFS to make it easier to plug in network file
6342 * system clients. If inotify turns out to be permanently
6343 * incompatible for network fs clients, we could instead simply
6344 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6346 int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
6347 const int notify_subdirs, const __u16 netfid,
6348 __u32 filter, struct file *pfile, int multishot,
6349 const struct nls_table *nls_codepage)
6352 struct smb_com_transaction_change_notify_req *pSMB = NULL;
6353 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6354 struct dir_notify_req *dnotify_req;
6357 cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
6358 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6363 pSMB->TotalParameterCount = 0 ;
6364 pSMB->TotalDataCount = 0;
6365 pSMB->MaxParameterCount = cpu_to_le32(2);
6366 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6367 pSMB->MaxSetupCount = 4;
6369 pSMB->ParameterOffset = 0;
6370 pSMB->DataCount = 0;
6371 pSMB->DataOffset = 0;
6372 pSMB->SetupCount = 4; /* single byte does not need le conversion */
6373 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6374 pSMB->ParameterCount = pSMB->TotalParameterCount;
6376 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6377 pSMB->Reserved2 = 0;
6378 pSMB->CompletionFilter = cpu_to_le32(filter);
6379 pSMB->Fid = netfid; /* file handle always le */
6380 pSMB->ByteCount = 0;
6382 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6383 (struct smb_hdr *)pSMBr, &bytes_returned,
6386 cFYI(1, "Error in Notify = %d", rc);
6388 /* Add file to outstanding requests */
6389 /* BB change to kmem cache alloc */
6390 dnotify_req = kmalloc(
6391 sizeof(struct dir_notify_req),
6394 dnotify_req->Pid = pSMB->hdr.Pid;
6395 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6396 dnotify_req->Mid = pSMB->hdr.Mid;
6397 dnotify_req->Tid = pSMB->hdr.Tid;
6398 dnotify_req->Uid = pSMB->hdr.Uid;
6399 dnotify_req->netfid = netfid;
6400 dnotify_req->pfile = pfile;
6401 dnotify_req->filter = filter;
6402 dnotify_req->multishot = multishot;
6403 spin_lock(&GlobalMid_Lock);
6404 list_add_tail(&dnotify_req->lhead,
6405 &GlobalDnotifyReqList);
6406 spin_unlock(&GlobalMid_Lock);
6410 cifs_buf_release(pSMB);
6413 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */