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 */
89 /* Forward declarations */
90 static void cifs_readv_complete(struct work_struct *work);
94 * On arches that have high memory, kmap address space is limited. By
95 * serializing the kmap operations on those arches, we ensure that we don't
96 * end up with a bunch of threads in writeback with partially mapped page
97 * arrays, stuck waiting for kmap to come back. That situation prevents
98 * progress and can deadlock.
100 static DEFINE_MUTEX(cifs_kmap_mutex);
105 mutex_lock(&cifs_kmap_mutex);
109 cifs_kmap_unlock(void)
111 mutex_unlock(&cifs_kmap_mutex);
113 #else /* !CONFIG_HIGHMEM */
114 #define cifs_kmap_lock() do { ; } while(0)
115 #define cifs_kmap_unlock() do { ; } while(0)
116 #endif /* CONFIG_HIGHMEM */
118 /* Mark as invalid, all open files on tree connections since they
119 were closed when session to server was lost */
120 static void mark_open_files_invalid(struct cifs_tcon *pTcon)
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, &pTcon->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);
134 /* BB Add call to invalidate_inodes(sb) for all superblocks mounted
138 /* reconnect the socket, tcon, and smb session if needed */
140 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
143 struct cifs_ses *ses;
144 struct TCP_Server_Info *server;
145 struct nls_table *nls_codepage;
148 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
149 * tcp and smb session status done differently for those three - in the
156 server = ses->server;
159 * only tree disconnect, open, and write, (and ulogoff which does not
160 * have tcon) are allowed as we start force umount
162 if (tcon->tidStatus == CifsExiting) {
163 if (smb_command != SMB_COM_WRITE_ANDX &&
164 smb_command != SMB_COM_OPEN_ANDX &&
165 smb_command != SMB_COM_TREE_DISCONNECT) {
166 cFYI(1, "can not send cmd %d while umounting",
173 * Give demultiplex thread up to 10 seconds to reconnect, should be
174 * greater than cifs socket timeout which is 7 seconds
176 while (server->tcpStatus == CifsNeedReconnect) {
177 wait_event_interruptible_timeout(server->response_q,
178 (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
180 /* are we still trying to reconnect? */
181 if (server->tcpStatus != CifsNeedReconnect)
185 * on "soft" mounts we wait once. Hard mounts keep
186 * retrying until process is killed or server comes
190 cFYI(1, "gave up waiting on reconnect in smb_init");
195 if (!ses->need_reconnect && !tcon->need_reconnect)
198 nls_codepage = load_nls_default();
201 * need to prevent multiple threads trying to simultaneously
202 * reconnect the same SMB session
204 mutex_lock(&ses->session_mutex);
205 rc = cifs_negotiate_protocol(0, ses);
206 if (rc == 0 && ses->need_reconnect)
207 rc = cifs_setup_session(0, ses, nls_codepage);
209 /* do we need to reconnect tcon? */
210 if (rc || !tcon->need_reconnect) {
211 mutex_unlock(&ses->session_mutex);
215 mark_open_files_invalid(tcon);
216 rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
217 mutex_unlock(&ses->session_mutex);
218 cFYI(1, "reconnect tcon rc = %d", rc);
224 * FIXME: check if wsize needs updated due to negotiated smb buffer
227 atomic_inc(&tconInfoReconnectCount);
229 /* tell server Unix caps we support */
230 if (ses->capabilities & CAP_UNIX)
231 reset_cifs_unix_caps(0, tcon, NULL, NULL);
234 * Removed call to reopen open files here. It is safer (and faster) to
235 * reopen files one at a time as needed in read and write.
237 * FIXME: what about file locks? don't we need to reclaim them ASAP?
242 * Check if handle based operation so we know whether we can continue
243 * or not without returning to caller to reset file handle
245 switch (smb_command) {
246 case SMB_COM_READ_ANDX:
247 case SMB_COM_WRITE_ANDX:
249 case SMB_COM_FIND_CLOSE2:
250 case SMB_COM_LOCKING_ANDX:
254 unload_nls(nls_codepage);
258 /* Allocate and return pointer to an SMB request buffer, and set basic
259 SMB information in the SMB header. If the return code is zero, this
260 function must have filled in request_buf pointer */
262 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
267 rc = cifs_reconnect_tcon(tcon, smb_command);
271 *request_buf = cifs_small_buf_get();
272 if (*request_buf == NULL) {
273 /* BB should we add a retry in here if not a writepage? */
277 header_assemble((struct smb_hdr *) *request_buf, smb_command,
281 cifs_stats_inc(&tcon->num_smbs_sent);
287 small_smb_init_no_tc(const int smb_command, const int wct,
288 struct cifs_ses *ses, void **request_buf)
291 struct smb_hdr *buffer;
293 rc = small_smb_init(smb_command, wct, NULL, request_buf);
297 buffer = (struct smb_hdr *)*request_buf;
298 buffer->Mid = GetNextMid(ses->server);
299 if (ses->capabilities & CAP_UNICODE)
300 buffer->Flags2 |= SMBFLG2_UNICODE;
301 if (ses->capabilities & CAP_STATUS32)
302 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
304 /* uid, tid can stay at zero as set in header assemble */
306 /* BB add support for turning on the signing when
307 this function is used after 1st of session setup requests */
312 /* If the return code is zero, this function must fill in request_buf pointer */
314 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
315 void **request_buf, void **response_buf)
317 *request_buf = cifs_buf_get();
318 if (*request_buf == NULL) {
319 /* BB should we add a retry in here if not a writepage? */
322 /* Although the original thought was we needed the response buf for */
323 /* potential retries of smb operations it turns out we can determine */
324 /* from the mid flags when the request buffer can be resent without */
325 /* having to use a second distinct buffer for the response */
327 *response_buf = *request_buf;
329 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
333 cifs_stats_inc(&tcon->num_smbs_sent);
338 /* If the return code is zero, this function must fill in request_buf pointer */
340 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
341 void **request_buf, void **response_buf)
345 rc = cifs_reconnect_tcon(tcon, smb_command);
349 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
353 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
354 void **request_buf, void **response_buf)
356 if (tcon->ses->need_reconnect || tcon->need_reconnect)
359 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
362 static int validate_t2(struct smb_t2_rsp *pSMB)
364 unsigned int total_size;
366 /* check for plausible wct */
367 if (pSMB->hdr.WordCount < 10)
370 /* check for parm and data offset going beyond end of smb */
371 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
372 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
375 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
376 if (total_size >= 512)
379 /* check that bcc is at least as big as parms + data, and that it is
380 * less than negotiated smb buffer
382 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
383 if (total_size > get_bcc(&pSMB->hdr) ||
384 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
389 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
390 sizeof(struct smb_t2_rsp) + 16);
394 static inline void inc_rfc1001_len(void *pSMB, int count)
396 struct smb_hdr *hdr = (struct smb_hdr *)pSMB;
398 be32_add_cpu(&hdr->smb_buf_length, count);
402 CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
405 NEGOTIATE_RSP *pSMBr;
409 struct TCP_Server_Info *server;
411 unsigned int secFlags;
414 server = ses->server;
419 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
420 (void **) &pSMB, (void **) &pSMBr);
424 /* if any of auth flags (ie not sign or seal) are overriden use them */
425 if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
426 secFlags = ses->overrideSecFlg; /* BB FIXME fix sign flags? */
427 else /* if override flags set only sign/seal OR them with global auth */
428 secFlags = global_secflags | ses->overrideSecFlg;
430 cFYI(1, "secFlags 0x%x", secFlags);
432 pSMB->hdr.Mid = GetNextMid(server);
433 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
435 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
436 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
437 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
438 cFYI(1, "Kerberos only mechanism, enable extended security");
439 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
440 } else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
441 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
442 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
443 cFYI(1, "NTLMSSP only mechanism, enable extended security");
444 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
448 for (i = 0; i < CIFS_NUM_PROT; i++) {
449 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
450 count += strlen(protocols[i].name) + 1;
451 /* null at end of source and target buffers anyway */
453 inc_rfc1001_len(pSMB, count);
454 pSMB->ByteCount = cpu_to_le16(count);
456 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
457 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
461 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
462 cFYI(1, "Dialect: %d", server->dialect);
463 /* Check wct = 1 error case */
464 if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
465 /* core returns wct = 1, but we do not ask for core - otherwise
466 small wct just comes when dialect index is -1 indicating we
467 could not negotiate a common dialect */
470 #ifdef CONFIG_CIFS_WEAK_PW_HASH
471 } else if ((pSMBr->hdr.WordCount == 13)
472 && ((server->dialect == LANMAN_PROT)
473 || (server->dialect == LANMAN2_PROT))) {
475 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
477 if ((secFlags & CIFSSEC_MAY_LANMAN) ||
478 (secFlags & CIFSSEC_MAY_PLNTXT))
479 server->secType = LANMAN;
481 cERROR(1, "mount failed weak security disabled"
482 " in /proc/fs/cifs/SecurityFlags");
486 server->sec_mode = (__u8)le16_to_cpu(rsp->SecurityMode);
487 server->maxReq = min_t(unsigned int,
488 le16_to_cpu(rsp->MaxMpxCount),
490 server->oplocks = server->maxReq > 1 ? enable_oplocks : false;
491 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
492 server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
493 /* even though we do not use raw we might as well set this
494 accurately, in case we ever find a need for it */
495 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
496 server->max_rw = 0xFF00;
497 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
499 server->max_rw = 0;/* do not need to use raw anyway */
500 server->capabilities = CAP_MPX_MODE;
502 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
504 /* OS/2 often does not set timezone therefore
505 * we must use server time to calc time zone.
506 * Could deviate slightly from the right zone.
507 * Smallest defined timezone difference is 15 minutes
508 * (i.e. Nepal). Rounding up/down is done to match
511 int val, seconds, remain, result;
512 struct timespec ts, utc;
514 ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
515 rsp->SrvTime.Time, 0);
516 cFYI(1, "SrvTime %d sec since 1970 (utc: %d) diff: %d",
517 (int)ts.tv_sec, (int)utc.tv_sec,
518 (int)(utc.tv_sec - ts.tv_sec));
519 val = (int)(utc.tv_sec - ts.tv_sec);
521 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
522 remain = seconds % MIN_TZ_ADJ;
523 if (remain >= (MIN_TZ_ADJ / 2))
524 result += MIN_TZ_ADJ;
527 server->timeAdj = result;
529 server->timeAdj = (int)tmp;
530 server->timeAdj *= 60; /* also in seconds */
532 cFYI(1, "server->timeAdj: %d seconds", server->timeAdj);
535 /* BB get server time for time conversions and add
536 code to use it and timezone since this is not UTC */
538 if (rsp->EncryptionKeyLength ==
539 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
540 memcpy(ses->server->cryptkey, rsp->EncryptionKey,
541 CIFS_CRYPTO_KEY_SIZE);
542 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
543 rc = -EIO; /* need cryptkey unless plain text */
547 cFYI(1, "LANMAN negotiated");
548 /* we will not end up setting signing flags - as no signing
549 was in LANMAN and server did not return the flags on */
551 #else /* weak security disabled */
552 } else if (pSMBr->hdr.WordCount == 13) {
553 cERROR(1, "mount failed, cifs module not built "
554 "with CIFS_WEAK_PW_HASH support");
556 #endif /* WEAK_PW_HASH */
558 } else if (pSMBr->hdr.WordCount != 17) {
563 /* else wct == 17 NTLM */
564 server->sec_mode = pSMBr->SecurityMode;
565 if ((server->sec_mode & SECMODE_USER) == 0)
566 cFYI(1, "share mode security");
568 if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
569 #ifdef CONFIG_CIFS_WEAK_PW_HASH
570 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
571 #endif /* CIFS_WEAK_PW_HASH */
572 cERROR(1, "Server requests plain text password"
573 " but client support disabled");
575 if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
576 server->secType = NTLMv2;
577 else if (secFlags & CIFSSEC_MAY_NTLM)
578 server->secType = NTLM;
579 else if (secFlags & CIFSSEC_MAY_NTLMV2)
580 server->secType = NTLMv2;
581 else if (secFlags & CIFSSEC_MAY_KRB5)
582 server->secType = Kerberos;
583 else if (secFlags & CIFSSEC_MAY_NTLMSSP)
584 server->secType = RawNTLMSSP;
585 else if (secFlags & CIFSSEC_MAY_LANMAN)
586 server->secType = LANMAN;
589 cERROR(1, "Invalid security type");
592 /* else ... any others ...? */
594 /* one byte, so no need to convert this or EncryptionKeyLen from
596 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
598 server->oplocks = server->maxReq > 1 ? enable_oplocks : false;
599 /* probably no need to store and check maxvcs */
600 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
601 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
602 cFYI(DBG2, "Max buf = %d", ses->server->maxBuf);
603 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
604 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
605 server->timeAdj *= 60;
606 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
607 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
608 CIFS_CRYPTO_KEY_SIZE);
609 } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
610 server->capabilities & CAP_EXTENDED_SECURITY) &&
611 (pSMBr->EncryptionKeyLength == 0)) {
612 /* decode security blob */
613 count = get_bcc(&pSMBr->hdr);
618 spin_lock(&cifs_tcp_ses_lock);
619 if (server->srv_count > 1) {
620 spin_unlock(&cifs_tcp_ses_lock);
621 if (memcmp(server->server_GUID,
622 pSMBr->u.extended_response.
624 cFYI(1, "server UID changed");
625 memcpy(server->server_GUID,
626 pSMBr->u.extended_response.GUID,
630 spin_unlock(&cifs_tcp_ses_lock);
631 memcpy(server->server_GUID,
632 pSMBr->u.extended_response.GUID, 16);
636 server->secType = RawNTLMSSP;
638 rc = decode_negTokenInit(pSMBr->u.extended_response.
639 SecurityBlob, count - 16,
645 if (server->secType == Kerberos) {
646 if (!server->sec_kerberos &&
647 !server->sec_mskerberos)
649 } else if (server->secType == RawNTLMSSP) {
650 if (!server->sec_ntlmssp)
655 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
656 rc = -EIO; /* no crypt key only if plain text pwd */
659 server->capabilities &= ~CAP_EXTENDED_SECURITY;
661 #ifdef CONFIG_CIFS_WEAK_PW_HASH
664 if ((secFlags & CIFSSEC_MAY_SIGN) == 0) {
665 /* MUST_SIGN already includes the MAY_SIGN FLAG
666 so if this is zero it means that signing is disabled */
667 cFYI(1, "Signing disabled");
668 if (server->sec_mode & SECMODE_SIGN_REQUIRED) {
669 cERROR(1, "Server requires "
670 "packet signing to be enabled in "
671 "/proc/fs/cifs/SecurityFlags.");
675 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
676 } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
677 /* signing required */
678 cFYI(1, "Must sign - secFlags 0x%x", secFlags);
679 if ((server->sec_mode &
680 (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
681 cERROR(1, "signing required but server lacks support");
684 server->sec_mode |= SECMODE_SIGN_REQUIRED;
686 /* signing optional ie CIFSSEC_MAY_SIGN */
687 if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0)
689 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
693 cifs_buf_release(pSMB);
695 cFYI(1, "negprot rc %d", rc);
700 CIFSSMBTDis(const int xid, struct cifs_tcon *tcon)
702 struct smb_hdr *smb_buffer;
705 cFYI(1, "In tree disconnect");
707 /* BB: do we need to check this? These should never be NULL. */
708 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
712 * No need to return error on this operation if tid invalidated and
713 * closed on server already e.g. due to tcp session crashing. Also,
714 * the tcon is no longer on the list, so no need to take lock before
717 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
720 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
721 (void **)&smb_buffer);
725 rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0);
727 cFYI(1, "Tree disconnect failed %d", rc);
729 /* No need to return error on this operation if tid invalidated and
730 closed on server already e.g. due to tcp session crashing */
738 * This is a no-op for now. We're not really interested in the reply, but
739 * rather in the fact that the server sent one and that server->lstrp
742 * FIXME: maybe we should consider checking that the reply matches request?
745 cifs_echo_callback(struct mid_q_entry *mid)
747 struct TCP_Server_Info *server = mid->callback_data;
749 DeleteMidQEntry(mid);
750 atomic_dec(&server->inFlight);
751 wake_up(&server->request_q);
755 CIFSSMBEcho(struct TCP_Server_Info *server)
761 cFYI(1, "In echo request");
763 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
767 /* set up echo request */
768 smb->hdr.Tid = 0xffff;
769 smb->hdr.WordCount = 1;
770 put_unaligned_le16(1, &smb->EchoCount);
771 put_bcc(1, &smb->hdr);
773 inc_rfc1001_len(smb, 3);
775 iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
777 rc = cifs_call_async(server, &iov, 1, NULL, cifs_echo_callback,
780 cFYI(1, "Echo request failed: %d", rc);
782 cifs_small_buf_release(smb);
788 CIFSSMBLogoff(const int xid, struct cifs_ses *ses)
790 LOGOFF_ANDX_REQ *pSMB;
793 cFYI(1, "In SMBLogoff for session disconnect");
796 * BB: do we need to check validity of ses and server? They should
797 * always be valid since we have an active reference. If not, that
798 * should probably be a BUG()
800 if (!ses || !ses->server)
803 mutex_lock(&ses->session_mutex);
804 if (ses->need_reconnect)
805 goto session_already_dead; /* no need to send SMBlogoff if uid
806 already closed due to reconnect */
807 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
809 mutex_unlock(&ses->session_mutex);
813 pSMB->hdr.Mid = GetNextMid(ses->server);
815 if (ses->server->sec_mode &
816 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
817 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
819 pSMB->hdr.Uid = ses->Suid;
821 pSMB->AndXCommand = 0xFF;
822 rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0);
823 session_already_dead:
824 mutex_unlock(&ses->session_mutex);
826 /* if session dead then we do not need to do ulogoff,
827 since server closed smb session, no sense reporting
835 CIFSPOSIXDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
836 __u16 type, const struct nls_table *nls_codepage, int remap)
838 TRANSACTION2_SPI_REQ *pSMB = NULL;
839 TRANSACTION2_SPI_RSP *pSMBr = NULL;
840 struct unlink_psx_rq *pRqD;
843 int bytes_returned = 0;
844 __u16 params, param_offset, offset, byte_count;
846 cFYI(1, "In POSIX delete");
848 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
853 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
855 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
856 PATH_MAX, nls_codepage, remap);
857 name_len++; /* trailing null */
859 } else { /* BB add path length overrun check */
860 name_len = strnlen(fileName, PATH_MAX);
861 name_len++; /* trailing null */
862 strncpy(pSMB->FileName, fileName, name_len);
865 params = 6 + name_len;
866 pSMB->MaxParameterCount = cpu_to_le16(2);
867 pSMB->MaxDataCount = 0; /* BB double check this with jra */
868 pSMB->MaxSetupCount = 0;
873 param_offset = offsetof(struct smb_com_transaction2_spi_req,
874 InformationLevel) - 4;
875 offset = param_offset + params;
877 /* Setup pointer to Request Data (inode type) */
878 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
879 pRqD->type = cpu_to_le16(type);
880 pSMB->ParameterOffset = cpu_to_le16(param_offset);
881 pSMB->DataOffset = cpu_to_le16(offset);
882 pSMB->SetupCount = 1;
884 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
885 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
887 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
888 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
889 pSMB->ParameterCount = cpu_to_le16(params);
890 pSMB->TotalParameterCount = pSMB->ParameterCount;
891 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
893 inc_rfc1001_len(pSMB, byte_count);
894 pSMB->ByteCount = cpu_to_le16(byte_count);
895 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
896 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
898 cFYI(1, "Posix delete returned %d", rc);
899 cifs_buf_release(pSMB);
901 cifs_stats_inc(&tcon->num_deletes);
910 CIFSSMBDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
911 const struct nls_table *nls_codepage, int remap)
913 DELETE_FILE_REQ *pSMB = NULL;
914 DELETE_FILE_RSP *pSMBr = NULL;
920 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
925 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
927 cifsConvertToUCS((__le16 *) pSMB->fileName, fileName,
928 PATH_MAX, nls_codepage, remap);
929 name_len++; /* trailing null */
931 } else { /* BB improve check for buffer overruns BB */
932 name_len = strnlen(fileName, PATH_MAX);
933 name_len++; /* trailing null */
934 strncpy(pSMB->fileName, fileName, name_len);
936 pSMB->SearchAttributes =
937 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
938 pSMB->BufferFormat = 0x04;
939 inc_rfc1001_len(pSMB, name_len + 1);
940 pSMB->ByteCount = cpu_to_le16(name_len + 1);
941 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
942 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
943 cifs_stats_inc(&tcon->num_deletes);
945 cFYI(1, "Error in RMFile = %d", rc);
947 cifs_buf_release(pSMB);
955 CIFSSMBRmDir(const int xid, struct cifs_tcon *tcon, const char *dirName,
956 const struct nls_table *nls_codepage, int remap)
958 DELETE_DIRECTORY_REQ *pSMB = NULL;
959 DELETE_DIRECTORY_RSP *pSMBr = NULL;
964 cFYI(1, "In CIFSSMBRmDir");
966 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
971 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
972 name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, dirName,
973 PATH_MAX, nls_codepage, remap);
974 name_len++; /* trailing null */
976 } else { /* BB improve check for buffer overruns BB */
977 name_len = strnlen(dirName, PATH_MAX);
978 name_len++; /* trailing null */
979 strncpy(pSMB->DirName, dirName, name_len);
982 pSMB->BufferFormat = 0x04;
983 inc_rfc1001_len(pSMB, name_len + 1);
984 pSMB->ByteCount = cpu_to_le16(name_len + 1);
985 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
986 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
987 cifs_stats_inc(&tcon->num_rmdirs);
989 cFYI(1, "Error in RMDir = %d", rc);
991 cifs_buf_release(pSMB);
998 CIFSSMBMkDir(const int xid, struct cifs_tcon *tcon,
999 const char *name, const struct nls_table *nls_codepage, int remap)
1002 CREATE_DIRECTORY_REQ *pSMB = NULL;
1003 CREATE_DIRECTORY_RSP *pSMBr = NULL;
1007 cFYI(1, "In CIFSSMBMkDir");
1009 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
1014 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1015 name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, name,
1016 PATH_MAX, nls_codepage, remap);
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->num_mkdirs);
1032 cFYI(1, "Error in Mkdir = %d", rc);
1034 cifs_buf_release(pSMB);
1041 CIFSPOSIXCreate(const int xid, struct cifs_tcon *tcon, __u32 posix_flags,
1042 __u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData,
1043 __u32 *pOplock, const char *name,
1044 const struct nls_table *nls_codepage, int remap)
1046 TRANSACTION2_SPI_REQ *pSMB = NULL;
1047 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1050 int bytes_returned = 0;
1051 __u16 params, param_offset, offset, byte_count, count;
1052 OPEN_PSX_REQ *pdata;
1053 OPEN_PSX_RSP *psx_rsp;
1055 cFYI(1, "In POSIX Create");
1057 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1062 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1064 cifsConvertToUCS((__le16 *) pSMB->FileName, name,
1065 PATH_MAX, nls_codepage, remap);
1066 name_len++; /* trailing null */
1068 } else { /* BB improve the check for buffer overruns BB */
1069 name_len = strnlen(name, PATH_MAX);
1070 name_len++; /* trailing null */
1071 strncpy(pSMB->FileName, name, name_len);
1074 params = 6 + name_len;
1075 count = sizeof(OPEN_PSX_REQ);
1076 pSMB->MaxParameterCount = cpu_to_le16(2);
1077 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1078 pSMB->MaxSetupCount = 0;
1082 pSMB->Reserved2 = 0;
1083 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1084 InformationLevel) - 4;
1085 offset = param_offset + params;
1086 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1087 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1088 pdata->Permissions = cpu_to_le64(mode);
1089 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1090 pdata->OpenFlags = cpu_to_le32(*pOplock);
1091 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1092 pSMB->DataOffset = cpu_to_le16(offset);
1093 pSMB->SetupCount = 1;
1094 pSMB->Reserved3 = 0;
1095 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1096 byte_count = 3 /* pad */ + params + count;
1098 pSMB->DataCount = cpu_to_le16(count);
1099 pSMB->ParameterCount = cpu_to_le16(params);
1100 pSMB->TotalDataCount = pSMB->DataCount;
1101 pSMB->TotalParameterCount = pSMB->ParameterCount;
1102 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1103 pSMB->Reserved4 = 0;
1104 inc_rfc1001_len(pSMB, byte_count);
1105 pSMB->ByteCount = cpu_to_le16(byte_count);
1106 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1107 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1109 cFYI(1, "Posix create returned %d", rc);
1110 goto psx_create_err;
1113 cFYI(1, "copying inode info");
1114 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1116 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1117 rc = -EIO; /* bad smb */
1118 goto psx_create_err;
1121 /* copy return information to pRetData */
1122 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1123 + le16_to_cpu(pSMBr->t2.DataOffset));
1125 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1127 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1128 /* Let caller know file was created so we can set the mode. */
1129 /* Do we care about the CreateAction in any other cases? */
1130 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1131 *pOplock |= CIFS_CREATE_ACTION;
1132 /* check to make sure response data is there */
1133 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1134 pRetData->Type = cpu_to_le32(-1); /* unknown */
1135 cFYI(DBG2, "unknown type");
1137 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1138 + sizeof(FILE_UNIX_BASIC_INFO)) {
1139 cERROR(1, "Open response data too small");
1140 pRetData->Type = cpu_to_le32(-1);
1141 goto psx_create_err;
1143 memcpy((char *) pRetData,
1144 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1145 sizeof(FILE_UNIX_BASIC_INFO));
1149 cifs_buf_release(pSMB);
1151 if (posix_flags & SMB_O_DIRECTORY)
1152 cifs_stats_inc(&tcon->num_posixmkdirs);
1154 cifs_stats_inc(&tcon->num_posixopens);
1162 static __u16 convert_disposition(int disposition)
1166 switch (disposition) {
1167 case FILE_SUPERSEDE:
1168 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1171 ofun = SMBOPEN_OAPPEND;
1174 ofun = SMBOPEN_OCREATE;
1177 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1179 case FILE_OVERWRITE:
1180 ofun = SMBOPEN_OTRUNC;
1182 case FILE_OVERWRITE_IF:
1183 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1186 cFYI(1, "unknown disposition %d", disposition);
1187 ofun = SMBOPEN_OAPPEND; /* regular open */
1193 access_flags_to_smbopen_mode(const int access_flags)
1195 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1197 if (masked_flags == GENERIC_READ)
1198 return SMBOPEN_READ;
1199 else if (masked_flags == GENERIC_WRITE)
1200 return SMBOPEN_WRITE;
1202 /* just go for read/write */
1203 return SMBOPEN_READWRITE;
1207 SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
1208 const char *fileName, const int openDisposition,
1209 const int access_flags, const int create_options, __u16 *netfid,
1210 int *pOplock, FILE_ALL_INFO *pfile_info,
1211 const struct nls_table *nls_codepage, int remap)
1214 OPENX_REQ *pSMB = NULL;
1215 OPENX_RSP *pSMBr = NULL;
1221 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1226 pSMB->AndXCommand = 0xFF; /* none */
1228 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1229 count = 1; /* account for one byte pad to word boundary */
1231 cifsConvertToUCS((__le16 *) (pSMB->fileName + 1),
1232 fileName, PATH_MAX, nls_codepage, remap);
1233 name_len++; /* trailing null */
1235 } else { /* BB improve check for buffer overruns BB */
1236 count = 0; /* no pad */
1237 name_len = strnlen(fileName, PATH_MAX);
1238 name_len++; /* trailing null */
1239 strncpy(pSMB->fileName, fileName, name_len);
1241 if (*pOplock & REQ_OPLOCK)
1242 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1243 else if (*pOplock & REQ_BATCHOPLOCK)
1244 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1246 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1247 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1248 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1249 /* set file as system file if special file such
1250 as fifo and server expecting SFU style and
1251 no Unix extensions */
1253 if (create_options & CREATE_OPTION_SPECIAL)
1254 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1255 else /* BB FIXME BB */
1256 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1258 if (create_options & CREATE_OPTION_READONLY)
1259 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1262 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1263 CREATE_OPTIONS_MASK); */
1264 /* BB FIXME END BB */
1266 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1267 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1269 inc_rfc1001_len(pSMB, count);
1271 pSMB->ByteCount = cpu_to_le16(count);
1272 /* long_op set to 1 to allow for oplock break timeouts */
1273 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1274 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1275 cifs_stats_inc(&tcon->num_opens);
1277 cFYI(1, "Error in Open = %d", rc);
1279 /* BB verify if wct == 15 */
1281 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1283 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1284 /* Let caller know file was created so we can set the mode. */
1285 /* Do we care about the CreateAction in any other cases? */
1287 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1288 *pOplock |= CIFS_CREATE_ACTION; */
1292 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1293 pfile_info->LastAccessTime = 0; /* BB fixme */
1294 pfile_info->LastWriteTime = 0; /* BB fixme */
1295 pfile_info->ChangeTime = 0; /* BB fixme */
1296 pfile_info->Attributes =
1297 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1298 /* the file_info buf is endian converted by caller */
1299 pfile_info->AllocationSize =
1300 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1301 pfile_info->EndOfFile = pfile_info->AllocationSize;
1302 pfile_info->NumberOfLinks = cpu_to_le32(1);
1303 pfile_info->DeletePending = 0;
1307 cifs_buf_release(pSMB);
1314 CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
1315 const char *fileName, const int openDisposition,
1316 const int access_flags, const int create_options, __u16 *netfid,
1317 int *pOplock, FILE_ALL_INFO *pfile_info,
1318 const struct nls_table *nls_codepage, int remap)
1321 OPEN_REQ *pSMB = NULL;
1322 OPEN_RSP *pSMBr = NULL;
1328 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **) &pSMB,
1333 pSMB->AndXCommand = 0xFF; /* none */
1335 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1336 count = 1; /* account for one byte pad to word boundary */
1338 cifsConvertToUCS((__le16 *) (pSMB->fileName + 1),
1339 fileName, PATH_MAX, nls_codepage, remap);
1340 name_len++; /* trailing null */
1342 pSMB->NameLength = cpu_to_le16(name_len);
1343 } else { /* BB improve check for buffer overruns BB */
1344 count = 0; /* no pad */
1345 name_len = strnlen(fileName, PATH_MAX);
1346 name_len++; /* trailing null */
1347 pSMB->NameLength = cpu_to_le16(name_len);
1348 strncpy(pSMB->fileName, fileName, name_len);
1350 if (*pOplock & REQ_OPLOCK)
1351 pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1352 else if (*pOplock & REQ_BATCHOPLOCK)
1353 pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1354 pSMB->DesiredAccess = cpu_to_le32(access_flags);
1355 pSMB->AllocationSize = 0;
1356 /* set file as system file if special file such
1357 as fifo and server expecting SFU style and
1358 no Unix extensions */
1359 if (create_options & CREATE_OPTION_SPECIAL)
1360 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1362 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1364 /* XP does not handle ATTR_POSIX_SEMANTICS */
1365 /* but it helps speed up case sensitive checks for other
1366 servers such as Samba */
1367 if (tcon->ses->capabilities & CAP_UNIX)
1368 pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1370 if (create_options & CREATE_OPTION_READONLY)
1371 pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1373 pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1374 pSMB->CreateDisposition = cpu_to_le32(openDisposition);
1375 pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1376 /* BB Expirement with various impersonation levels and verify */
1377 pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1378 pSMB->SecurityFlags =
1379 SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
1382 inc_rfc1001_len(pSMB, count);
1384 pSMB->ByteCount = cpu_to_le16(count);
1385 /* long_op set to 1 to allow for oplock break timeouts */
1386 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1387 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1388 cifs_stats_inc(&tcon->num_opens);
1390 cFYI(1, "Error in Open = %d", rc);
1392 *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
1393 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1394 /* Let caller know file was created so we can set the mode. */
1395 /* Do we care about the CreateAction in any other cases? */
1396 if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1397 *pOplock |= CIFS_CREATE_ACTION;
1399 memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
1400 36 /* CreationTime to Attributes */);
1401 /* the file_info buf is endian converted by caller */
1402 pfile_info->AllocationSize = pSMBr->AllocationSize;
1403 pfile_info->EndOfFile = pSMBr->EndOfFile;
1404 pfile_info->NumberOfLinks = cpu_to_le32(1);
1405 pfile_info->DeletePending = 0;
1409 cifs_buf_release(pSMB);
1415 struct cifs_readdata *
1416 cifs_readdata_alloc(unsigned int nr_pages)
1418 struct cifs_readdata *rdata;
1420 /* readdata + 1 kvec for each page */
1421 rdata = kzalloc(sizeof(*rdata) +
1422 sizeof(struct kvec) * nr_pages, GFP_KERNEL);
1423 if (rdata != NULL) {
1424 INIT_WORK(&rdata->work, cifs_readv_complete);
1425 INIT_LIST_HEAD(&rdata->pages);
1431 cifs_readdata_free(struct cifs_readdata *rdata)
1433 cifsFileInfo_put(rdata->cfile);
1438 * Discard any remaining data in the current SMB. To do this, we borrow the
1442 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1444 READ_RSP *rsp = (READ_RSP *)server->smallbuf;
1445 unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length);
1446 int remaining = rfclen + 4 - server->total_read;
1447 struct cifs_readdata *rdata = mid->callback_data;
1449 while (remaining > 0) {
1452 length = cifs_read_from_socket(server, server->bigbuf,
1453 min_t(unsigned int, remaining,
1454 CIFSMaxBufSize + MAX_CIFS_HDR_SIZE));
1457 server->total_read += length;
1458 remaining -= length;
1461 dequeue_mid(mid, rdata->result);
1466 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1469 unsigned int data_offset, remaining, data_len;
1470 struct cifs_readdata *rdata = mid->callback_data;
1471 READ_RSP *rsp = (READ_RSP *)server->smallbuf;
1472 unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length) + 4;
1475 struct page *page, *tpage;
1477 cFYI(1, "%s: mid=%u offset=%llu bytes=%u", __func__,
1478 mid->mid, rdata->offset, rdata->bytes);
1481 * read the rest of READ_RSP header (sans Data array), or whatever we
1482 * can if there's not enough data. At this point, we've read down to
1485 len = min_t(unsigned int, rfclen, sizeof(*rsp)) -
1486 sizeof(struct smb_hdr) + 1;
1488 rdata->iov[0].iov_base = server->smallbuf + sizeof(struct smb_hdr) - 1;
1489 rdata->iov[0].iov_len = len;
1491 length = cifs_readv_from_socket(server, rdata->iov, 1, len);
1494 server->total_read += length;
1496 /* Was the SMB read successful? */
1497 rdata->result = map_smb_to_linux_error(&rsp->hdr, false);
1498 if (rdata->result != 0) {
1499 cFYI(1, "%s: server returned error %d", __func__,
1501 return cifs_readv_discard(server, mid);
1504 /* Is there enough to get to the rest of the READ_RSP header? */
1505 if (server->total_read < sizeof(READ_RSP)) {
1506 cFYI(1, "%s: server returned short header. got=%u expected=%zu",
1507 __func__, server->total_read, sizeof(READ_RSP));
1508 rdata->result = -EIO;
1509 return cifs_readv_discard(server, mid);
1512 data_offset = le16_to_cpu(rsp->DataOffset) + 4;
1513 if (data_offset < server->total_read) {
1515 * win2k8 sometimes sends an offset of 0 when the read
1516 * is beyond the EOF. Treat it as if the data starts just after
1519 cFYI(1, "%s: data offset (%u) inside read response header",
1520 __func__, data_offset);
1521 data_offset = server->total_read;
1522 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1523 /* data_offset is beyond the end of smallbuf */
1524 cFYI(1, "%s: data offset (%u) beyond end of smallbuf",
1525 __func__, data_offset);
1526 rdata->result = -EIO;
1527 return cifs_readv_discard(server, mid);
1530 cFYI(1, "%s: total_read=%u data_offset=%u", __func__,
1531 server->total_read, data_offset);
1533 len = data_offset - server->total_read;
1535 /* read any junk before data into the rest of smallbuf */
1536 rdata->iov[0].iov_base = server->smallbuf + server->total_read;
1537 rdata->iov[0].iov_len = len;
1538 length = cifs_readv_from_socket(server, rdata->iov, 1, len);
1541 server->total_read += length;
1544 /* set up first iov for signature check */
1545 rdata->iov[0].iov_base = server->smallbuf;
1546 rdata->iov[0].iov_len = server->total_read;
1547 cFYI(1, "0: iov_base=%p iov_len=%zu",
1548 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1550 /* how much data is in the response? */
1551 data_len = le16_to_cpu(rsp->DataLengthHigh) << 16;
1552 data_len += le16_to_cpu(rsp->DataLength);
1553 if (data_offset + data_len > rfclen) {
1554 /* data_len is corrupt -- discard frame */
1555 rdata->result = -EIO;
1556 return cifs_readv_discard(server, mid);
1559 /* marshal up the page array */
1561 remaining = data_len;
1564 /* determine the eof that the server (probably) has */
1565 eof = CIFS_I(rdata->mapping->host)->server_eof;
1566 eof_index = eof ? (eof - 1) >> PAGE_CACHE_SHIFT : 0;
1567 cFYI(1, "eof=%llu eof_index=%lu", eof, eof_index);
1570 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
1571 if (remaining >= PAGE_CACHE_SIZE) {
1572 /* enough data to fill the page */
1573 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
1574 rdata->iov[rdata->nr_iov].iov_len = PAGE_CACHE_SIZE;
1575 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
1576 rdata->nr_iov, page->index,
1577 rdata->iov[rdata->nr_iov].iov_base,
1578 rdata->iov[rdata->nr_iov].iov_len);
1580 len += PAGE_CACHE_SIZE;
1581 remaining -= PAGE_CACHE_SIZE;
1582 } else if (remaining > 0) {
1583 /* enough for partial page, fill and zero the rest */
1584 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
1585 rdata->iov[rdata->nr_iov].iov_len = remaining;
1586 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
1587 rdata->nr_iov, page->index,
1588 rdata->iov[rdata->nr_iov].iov_base,
1589 rdata->iov[rdata->nr_iov].iov_len);
1590 memset(rdata->iov[rdata->nr_iov].iov_base + remaining,
1591 '\0', PAGE_CACHE_SIZE - remaining);
1595 } else if (page->index > eof_index) {
1597 * The VFS will not try to do readahead past the
1598 * i_size, but it's possible that we have outstanding
1599 * writes with gaps in the middle and the i_size hasn't
1600 * caught up yet. Populate those with zeroed out pages
1601 * to prevent the VFS from repeatedly attempting to
1602 * fill them until the writes are flushed.
1604 zero_user(page, 0, PAGE_CACHE_SIZE);
1605 list_del(&page->lru);
1606 lru_cache_add_file(page);
1607 flush_dcache_page(page);
1608 SetPageUptodate(page);
1610 page_cache_release(page);
1612 /* no need to hold page hostage */
1613 list_del(&page->lru);
1614 lru_cache_add_file(page);
1616 page_cache_release(page);
1621 /* issue the read if we have any iovecs left to fill */
1622 if (rdata->nr_iov > 1) {
1623 length = cifs_readv_from_socket(server, &rdata->iov[1],
1624 rdata->nr_iov - 1, len);
1627 server->total_read += length;
1632 rdata->bytes = length;
1634 cFYI(1, "total_read=%u rfclen=%u remaining=%u", server->total_read,
1637 /* discard anything left over */
1638 if (server->total_read < rfclen)
1639 return cifs_readv_discard(server, mid);
1641 dequeue_mid(mid, false);
1646 cifs_readv_complete(struct work_struct *work)
1648 struct cifs_readdata *rdata = container_of(work,
1649 struct cifs_readdata, work);
1650 struct page *page, *tpage;
1652 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
1653 list_del(&page->lru);
1654 lru_cache_add_file(page);
1656 if (rdata->result == 0) {
1658 flush_dcache_page(page);
1659 SetPageUptodate(page);
1664 if (rdata->result == 0)
1665 cifs_readpage_to_fscache(rdata->mapping->host, page);
1667 page_cache_release(page);
1669 cifs_readdata_free(rdata);
1673 cifs_readv_callback(struct mid_q_entry *mid)
1675 struct cifs_readdata *rdata = mid->callback_data;
1676 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1677 struct TCP_Server_Info *server = tcon->ses->server;
1679 cFYI(1, "%s: mid=%u state=%d result=%d bytes=%u", __func__,
1680 mid->mid, mid->midState, rdata->result, rdata->bytes);
1682 switch (mid->midState) {
1683 case MID_RESPONSE_RECEIVED:
1684 /* result already set, check signature */
1685 if (server->sec_mode &
1686 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
1687 if (cifs_verify_signature(rdata->iov, rdata->nr_iov,
1688 server, mid->sequence_number + 1))
1689 cERROR(1, "Unexpected SMB signature");
1691 /* FIXME: should this be counted toward the initiating task? */
1692 task_io_account_read(rdata->bytes);
1693 cifs_stats_bytes_read(tcon, rdata->bytes);
1695 case MID_REQUEST_SUBMITTED:
1696 case MID_RETRY_NEEDED:
1697 rdata->result = -EAGAIN;
1700 rdata->result = -EIO;
1703 queue_work(system_nrt_wq, &rdata->work);
1704 DeleteMidQEntry(mid);
1705 atomic_dec(&server->inFlight);
1706 wake_up(&server->request_q);
1709 /* cifs_async_readv - send an async write, and set up mid to handle result */
1711 cifs_async_readv(struct cifs_readdata *rdata)
1714 READ_REQ *smb = NULL;
1716 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1718 cFYI(1, "%s: offset=%llu bytes=%u", __func__,
1719 rdata->offset, rdata->bytes);
1721 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1724 wct = 10; /* old style read */
1725 if ((rdata->offset >> 32) > 0) {
1726 /* can not handle this big offset for old */
1731 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1735 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1736 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1738 smb->AndXCommand = 0xFF; /* none */
1739 smb->Fid = rdata->cfile->netfid;
1740 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1742 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1744 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1745 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1749 /* old style read */
1750 struct smb_com_readx_req *smbr =
1751 (struct smb_com_readx_req *)smb;
1752 smbr->ByteCount = 0;
1755 /* 4 for RFC1001 length + 1 for BCC */
1756 rdata->iov[0].iov_base = smb;
1757 rdata->iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
1759 rc = cifs_call_async(tcon->ses->server, rdata->iov, 1,
1760 cifs_readv_receive, cifs_readv_callback,
1764 cifs_stats_inc(&tcon->num_reads);
1766 cifs_small_buf_release(smb);
1771 CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms, unsigned int *nbytes,
1772 char **buf, int *pbuf_type)
1775 READ_REQ *pSMB = NULL;
1776 READ_RSP *pSMBr = NULL;
1777 char *pReadData = NULL;
1779 int resp_buf_type = 0;
1781 __u32 pid = io_parms->pid;
1782 __u16 netfid = io_parms->netfid;
1783 __u64 offset = io_parms->offset;
1784 struct cifs_tcon *tcon = io_parms->tcon;
1785 unsigned int count = io_parms->length;
1787 cFYI(1, "Reading %d bytes on fid %d", count, netfid);
1788 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1791 wct = 10; /* old style read */
1792 if ((offset >> 32) > 0) {
1793 /* can not handle this big offset for old */
1799 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1803 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1804 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1806 /* tcon and ses pointer are checked in smb_init */
1807 if (tcon->ses->server == NULL)
1808 return -ECONNABORTED;
1810 pSMB->AndXCommand = 0xFF; /* none */
1812 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1814 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1816 pSMB->Remaining = 0;
1817 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1818 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1820 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1822 /* old style read */
1823 struct smb_com_readx_req *pSMBW =
1824 (struct smb_com_readx_req *)pSMB;
1825 pSMBW->ByteCount = 0;
1828 iov[0].iov_base = (char *)pSMB;
1829 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1830 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1831 &resp_buf_type, CIFS_LOG_ERROR);
1832 cifs_stats_inc(&tcon->num_reads);
1833 pSMBr = (READ_RSP *)iov[0].iov_base;
1835 cERROR(1, "Send error in read = %d", rc);
1837 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1838 data_length = data_length << 16;
1839 data_length += le16_to_cpu(pSMBr->DataLength);
1840 *nbytes = data_length;
1842 /*check that DataLength would not go beyond end of SMB */
1843 if ((data_length > CIFSMaxBufSize)
1844 || (data_length > count)) {
1845 cFYI(1, "bad length %d for count %d",
1846 data_length, count);
1850 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1851 le16_to_cpu(pSMBr->DataOffset);
1852 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1853 cERROR(1, "Faulting on read rc = %d",rc);
1855 }*/ /* can not use copy_to_user when using page cache*/
1857 memcpy(*buf, pReadData, data_length);
1861 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1863 if (resp_buf_type == CIFS_SMALL_BUFFER)
1864 cifs_small_buf_release(iov[0].iov_base);
1865 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1866 cifs_buf_release(iov[0].iov_base);
1867 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1868 /* return buffer to caller to free */
1869 *buf = iov[0].iov_base;
1870 if (resp_buf_type == CIFS_SMALL_BUFFER)
1871 *pbuf_type = CIFS_SMALL_BUFFER;
1872 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1873 *pbuf_type = CIFS_LARGE_BUFFER;
1874 } /* else no valid buffer on return - leave as null */
1876 /* Note: On -EAGAIN error only caller can retry on handle based calls
1877 since file handle passed in no longer valid */
1883 CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
1884 unsigned int *nbytes, const char *buf,
1885 const char __user *ubuf, const int long_op)
1888 WRITE_REQ *pSMB = NULL;
1889 WRITE_RSP *pSMBr = NULL;
1890 int bytes_returned, wct;
1893 __u32 pid = io_parms->pid;
1894 __u16 netfid = io_parms->netfid;
1895 __u64 offset = io_parms->offset;
1896 struct cifs_tcon *tcon = io_parms->tcon;
1897 unsigned int count = io_parms->length;
1901 /* cFYI(1, "write at %lld %d bytes", offset, count);*/
1902 if (tcon->ses == NULL)
1903 return -ECONNABORTED;
1905 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1909 if ((offset >> 32) > 0) {
1910 /* can not handle big offset for old srv */
1915 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1920 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1921 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1923 /* tcon and ses pointer are checked in smb_init */
1924 if (tcon->ses->server == NULL)
1925 return -ECONNABORTED;
1927 pSMB->AndXCommand = 0xFF; /* none */
1929 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1931 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1933 pSMB->Reserved = 0xFFFFFFFF;
1934 pSMB->WriteMode = 0;
1935 pSMB->Remaining = 0;
1937 /* Can increase buffer size if buffer is big enough in some cases ie we
1938 can send more if LARGE_WRITE_X capability returned by the server and if
1939 our buffer is big enough or if we convert to iovecs on socket writes
1940 and eliminate the copy to the CIFS buffer */
1941 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1942 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1944 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1948 if (bytes_sent > count)
1951 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1953 memcpy(pSMB->Data, buf, bytes_sent);
1955 if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
1956 cifs_buf_release(pSMB);
1959 } else if (count != 0) {
1961 cifs_buf_release(pSMB);
1963 } /* else setting file size with write of zero bytes */
1965 byte_count = bytes_sent + 1; /* pad */
1966 else /* wct == 12 */
1967 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1969 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1970 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1971 inc_rfc1001_len(pSMB, byte_count);
1974 pSMB->ByteCount = cpu_to_le16(byte_count);
1975 else { /* old style write has byte count 4 bytes earlier
1977 struct smb_com_writex_req *pSMBW =
1978 (struct smb_com_writex_req *)pSMB;
1979 pSMBW->ByteCount = cpu_to_le16(byte_count);
1982 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1983 (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
1984 cifs_stats_inc(&tcon->num_writes);
1986 cFYI(1, "Send error in write = %d", rc);
1988 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1989 *nbytes = (*nbytes) << 16;
1990 *nbytes += le16_to_cpu(pSMBr->Count);
1993 * Mask off high 16 bits when bytes written as returned by the
1994 * server is greater than bytes requested by the client. Some
1995 * OS/2 servers are known to set incorrect CountHigh values.
1997 if (*nbytes > count)
2001 cifs_buf_release(pSMB);
2003 /* Note: On -EAGAIN error only caller can retry on handle based calls
2004 since file handle passed in no longer valid */
2010 cifs_writedata_release(struct kref *refcount)
2012 struct cifs_writedata *wdata = container_of(refcount,
2013 struct cifs_writedata, refcount);
2016 cifsFileInfo_put(wdata->cfile);
2022 * Write failed with a retryable error. Resend the write request. It's also
2023 * possible that the page was redirtied so re-clean the page.
2026 cifs_writev_requeue(struct cifs_writedata *wdata)
2029 struct inode *inode = wdata->cfile->dentry->d_inode;
2031 for (i = 0; i < wdata->nr_pages; i++) {
2032 lock_page(wdata->pages[i]);
2033 clear_page_dirty_for_io(wdata->pages[i]);
2037 rc = cifs_async_writev(wdata);
2038 } while (rc == -EAGAIN);
2040 for (i = 0; i < wdata->nr_pages; i++) {
2042 SetPageError(wdata->pages[i]);
2043 unlock_page(wdata->pages[i]);
2046 mapping_set_error(inode->i_mapping, rc);
2047 kref_put(&wdata->refcount, cifs_writedata_release);
2051 cifs_writev_complete(struct work_struct *work)
2053 struct cifs_writedata *wdata = container_of(work,
2054 struct cifs_writedata, work);
2055 struct inode *inode = wdata->cfile->dentry->d_inode;
2058 if (wdata->result == 0) {
2059 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2060 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2062 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2063 return cifs_writev_requeue(wdata);
2065 for (i = 0; i < wdata->nr_pages; i++) {
2066 struct page *page = wdata->pages[i];
2067 if (wdata->result == -EAGAIN)
2068 __set_page_dirty_nobuffers(page);
2069 else if (wdata->result < 0)
2071 end_page_writeback(page);
2072 page_cache_release(page);
2074 if (wdata->result != -EAGAIN)
2075 mapping_set_error(inode->i_mapping, wdata->result);
2076 kref_put(&wdata->refcount, cifs_writedata_release);
2079 struct cifs_writedata *
2080 cifs_writedata_alloc(unsigned int nr_pages)
2082 struct cifs_writedata *wdata;
2084 /* this would overflow */
2085 if (nr_pages == 0) {
2086 cERROR(1, "%s: called with nr_pages == 0!", __func__);
2090 /* writedata + number of page pointers */
2091 wdata = kzalloc(sizeof(*wdata) +
2092 sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
2093 if (wdata != NULL) {
2094 INIT_WORK(&wdata->work, cifs_writev_complete);
2095 kref_init(&wdata->refcount);
2101 * Check the midState and signature on received buffer (if any), and queue the
2102 * workqueue completion task.
2105 cifs_writev_callback(struct mid_q_entry *mid)
2107 struct cifs_writedata *wdata = mid->callback_data;
2108 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2109 unsigned int written;
2110 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2112 switch (mid->midState) {
2113 case MID_RESPONSE_RECEIVED:
2114 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2115 if (wdata->result != 0)
2118 written = le16_to_cpu(smb->CountHigh);
2120 written += le16_to_cpu(smb->Count);
2122 * Mask off high 16 bits when bytes written as returned
2123 * by the server is greater than bytes requested by the
2124 * client. OS/2 servers are known to set incorrect
2127 if (written > wdata->bytes)
2130 if (written < wdata->bytes)
2131 wdata->result = -ENOSPC;
2133 wdata->bytes = written;
2135 case MID_REQUEST_SUBMITTED:
2136 case MID_RETRY_NEEDED:
2137 wdata->result = -EAGAIN;
2140 wdata->result = -EIO;
2144 queue_work(system_nrt_wq, &wdata->work);
2145 DeleteMidQEntry(mid);
2146 atomic_dec(&tcon->ses->server->inFlight);
2147 wake_up(&tcon->ses->server->request_q);
2150 /* cifs_async_writev - send an async write, and set up mid to handle result */
2152 cifs_async_writev(struct cifs_writedata *wdata)
2154 int i, rc = -EACCES;
2155 WRITE_REQ *smb = NULL;
2157 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2158 struct inode *inode = wdata->cfile->dentry->d_inode;
2159 struct kvec *iov = NULL;
2161 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2165 if (wdata->offset >> 32 > 0) {
2166 /* can not handle big offset for old srv */
2171 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2173 goto async_writev_out;
2175 /* 1 iov per page + 1 for header */
2176 iov = kzalloc((wdata->nr_pages + 1) * sizeof(*iov), GFP_NOFS);
2179 goto async_writev_out;
2182 smb->hdr.Pid = cpu_to_le16((__u16)wdata->cfile->pid);
2183 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->cfile->pid >> 16));
2185 smb->AndXCommand = 0xFF; /* none */
2186 smb->Fid = wdata->cfile->netfid;
2187 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2189 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2190 smb->Reserved = 0xFFFFFFFF;
2195 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2197 /* 4 for RFC1001 length + 1 for BCC */
2198 iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
2199 iov[0].iov_base = smb;
2201 /* marshal up the pages into iov array */
2204 for (i = 0; i < wdata->nr_pages; i++) {
2205 iov[i + 1].iov_len = min(inode->i_size -
2206 page_offset(wdata->pages[i]),
2207 (loff_t)PAGE_CACHE_SIZE);
2208 iov[i + 1].iov_base = kmap(wdata->pages[i]);
2209 wdata->bytes += iov[i + 1].iov_len;
2213 cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
2215 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2216 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2219 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2220 put_bcc(wdata->bytes + 1, &smb->hdr);
2223 struct smb_com_writex_req *smbw =
2224 (struct smb_com_writex_req *)smb;
2225 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2226 put_bcc(wdata->bytes + 5, &smbw->hdr);
2227 iov[0].iov_len += 4; /* pad bigger by four bytes */
2230 kref_get(&wdata->refcount);
2231 rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1,
2232 NULL, cifs_writev_callback, wdata, false);
2235 cifs_stats_inc(&tcon->num_writes);
2237 kref_put(&wdata->refcount, cifs_writedata_release);
2239 /* send is done, unmap pages */
2240 for (i = 0; i < wdata->nr_pages; i++)
2241 kunmap(wdata->pages[i]);
2244 cifs_small_buf_release(smb);
2250 CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
2251 unsigned int *nbytes, struct kvec *iov, int n_vec,
2255 WRITE_REQ *pSMB = NULL;
2258 int resp_buf_type = 0;
2259 __u32 pid = io_parms->pid;
2260 __u16 netfid = io_parms->netfid;
2261 __u64 offset = io_parms->offset;
2262 struct cifs_tcon *tcon = io_parms->tcon;
2263 unsigned int count = io_parms->length;
2267 cFYI(1, "write2 at %lld %d bytes", (long long)offset, count);
2269 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2273 if ((offset >> 32) > 0) {
2274 /* can not handle big offset for old srv */
2278 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2282 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2283 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2285 /* tcon and ses pointer are checked in smb_init */
2286 if (tcon->ses->server == NULL)
2287 return -ECONNABORTED;
2289 pSMB->AndXCommand = 0xFF; /* none */
2291 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2293 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2294 pSMB->Reserved = 0xFFFFFFFF;
2295 pSMB->WriteMode = 0;
2296 pSMB->Remaining = 0;
2299 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2301 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2302 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2303 /* header + 1 byte pad */
2304 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2306 inc_rfc1001_len(pSMB, count + 1);
2307 else /* wct == 12 */
2308 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2310 pSMB->ByteCount = cpu_to_le16(count + 1);
2311 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2312 struct smb_com_writex_req *pSMBW =
2313 (struct smb_com_writex_req *)pSMB;
2314 pSMBW->ByteCount = cpu_to_le16(count + 5);
2316 iov[0].iov_base = pSMB;
2318 iov[0].iov_len = smb_hdr_len + 4;
2319 else /* wct == 12 pad bigger by four bytes */
2320 iov[0].iov_len = smb_hdr_len + 8;
2323 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
2325 cifs_stats_inc(&tcon->num_writes);
2327 cFYI(1, "Send error Write2 = %d", rc);
2328 } else if (resp_buf_type == 0) {
2329 /* presumably this can not happen, but best to be safe */
2332 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base;
2333 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2334 *nbytes = (*nbytes) << 16;
2335 *nbytes += le16_to_cpu(pSMBr->Count);
2338 * Mask off high 16 bits when bytes written as returned by the
2339 * server is greater than bytes requested by the client. OS/2
2340 * servers are known to set incorrect CountHigh values.
2342 if (*nbytes > count)
2346 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2347 if (resp_buf_type == CIFS_SMALL_BUFFER)
2348 cifs_small_buf_release(iov[0].iov_base);
2349 else if (resp_buf_type == CIFS_LARGE_BUFFER)
2350 cifs_buf_release(iov[0].iov_base);
2352 /* Note: On -EAGAIN error only caller can retry on handle based calls
2353 since file handle passed in no longer valid */
2358 int cifs_lockv(const int xid, struct cifs_tcon *tcon, const __u16 netfid,
2359 const __u8 lock_type, const __u32 num_unlock,
2360 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2363 LOCK_REQ *pSMB = NULL;
2368 cFYI(1, "cifs_lockv num lock %d num unlock %d", num_lock, num_unlock);
2370 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2375 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2376 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2377 pSMB->LockType = lock_type;
2378 pSMB->AndXCommand = 0xFF; /* none */
2379 pSMB->Fid = netfid; /* netfid stays le */
2381 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2382 inc_rfc1001_len(pSMB, count);
2383 pSMB->ByteCount = cpu_to_le16(count);
2385 iov[0].iov_base = (char *)pSMB;
2386 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2387 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2388 iov[1].iov_base = (char *)buf;
2389 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2391 cifs_stats_inc(&tcon->num_locks);
2392 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
2394 cFYI(1, "Send error in cifs_lockv = %d", rc);
2400 CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
2401 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2402 const __u64 offset, const __u32 numUnlock,
2403 const __u32 numLock, const __u8 lockType,
2404 const bool waitFlag, const __u8 oplock_level)
2407 LOCK_REQ *pSMB = NULL;
2408 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2413 cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock);
2414 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2419 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2420 timeout = CIFS_ASYNC_OP; /* no response expected */
2422 } else if (waitFlag) {
2423 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2424 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2429 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2430 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2431 pSMB->LockType = lockType;
2432 pSMB->OplockLevel = oplock_level;
2433 pSMB->AndXCommand = 0xFF; /* none */
2434 pSMB->Fid = smb_file_id; /* netfid stays le */
2436 if ((numLock != 0) || (numUnlock != 0)) {
2437 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2438 /* BB where to store pid high? */
2439 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2440 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2441 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2442 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2443 count = sizeof(LOCKING_ANDX_RANGE);
2448 inc_rfc1001_len(pSMB, count);
2449 pSMB->ByteCount = cpu_to_le16(count);
2452 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2453 (struct smb_hdr *) pSMB, &bytes_returned);
2454 cifs_small_buf_release(pSMB);
2456 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
2458 /* SMB buffer freed by function above */
2460 cifs_stats_inc(&tcon->num_locks);
2462 cFYI(1, "Send error in Lock = %d", rc);
2464 /* Note: On -EAGAIN error only caller can retry on handle based calls
2465 since file handle passed in no longer valid */
2470 CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
2471 const __u16 smb_file_id, const __u32 netpid, const int get_flag,
2472 const __u64 len, struct file_lock *pLockData,
2473 const __u16 lock_type, const bool waitFlag)
2475 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2476 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2477 struct cifs_posix_lock *parm_data;
2480 int bytes_returned = 0;
2481 int resp_buf_type = 0;
2482 __u16 params, param_offset, offset, byte_count, count;
2485 cFYI(1, "Posix Lock");
2487 if (pLockData == NULL)
2490 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2495 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2498 pSMB->MaxSetupCount = 0;
2501 pSMB->Reserved2 = 0;
2502 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2503 offset = param_offset + params;
2505 count = sizeof(struct cifs_posix_lock);
2506 pSMB->MaxParameterCount = cpu_to_le16(2);
2507 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2508 pSMB->SetupCount = 1;
2509 pSMB->Reserved3 = 0;
2511 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2513 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2514 byte_count = 3 /* pad */ + params + count;
2515 pSMB->DataCount = cpu_to_le16(count);
2516 pSMB->ParameterCount = cpu_to_le16(params);
2517 pSMB->TotalDataCount = pSMB->DataCount;
2518 pSMB->TotalParameterCount = pSMB->ParameterCount;
2519 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2520 parm_data = (struct cifs_posix_lock *)
2521 (((char *) &pSMB->hdr.Protocol) + offset);
2523 parm_data->lock_type = cpu_to_le16(lock_type);
2525 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2526 parm_data->lock_flags = cpu_to_le16(1);
2527 pSMB->Timeout = cpu_to_le32(-1);
2531 parm_data->pid = cpu_to_le32(netpid);
2532 parm_data->start = cpu_to_le64(pLockData->fl_start);
2533 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2535 pSMB->DataOffset = cpu_to_le16(offset);
2536 pSMB->Fid = smb_file_id;
2537 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2538 pSMB->Reserved4 = 0;
2539 inc_rfc1001_len(pSMB, byte_count);
2540 pSMB->ByteCount = cpu_to_le16(byte_count);
2542 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2543 (struct smb_hdr *) pSMBr, &bytes_returned);
2545 iov[0].iov_base = (char *)pSMB;
2546 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2547 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2548 &resp_buf_type, timeout);
2549 pSMB = NULL; /* request buf already freed by SendReceive2. Do
2550 not try to free it twice below on exit */
2551 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
2555 cFYI(1, "Send error in Posix Lock = %d", rc);
2556 } else if (get_flag) {
2557 /* lock structure can be returned on get */
2560 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2562 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2563 rc = -EIO; /* bad smb */
2566 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2567 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2568 if (data_count < sizeof(struct cifs_posix_lock)) {
2572 parm_data = (struct cifs_posix_lock *)
2573 ((char *)&pSMBr->hdr.Protocol + data_offset);
2574 if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
2575 pLockData->fl_type = F_UNLCK;
2577 if (parm_data->lock_type ==
2578 __constant_cpu_to_le16(CIFS_RDLCK))
2579 pLockData->fl_type = F_RDLCK;
2580 else if (parm_data->lock_type ==
2581 __constant_cpu_to_le16(CIFS_WRLCK))
2582 pLockData->fl_type = F_WRLCK;
2584 pLockData->fl_start = le64_to_cpu(parm_data->start);
2585 pLockData->fl_end = pLockData->fl_start +
2586 le64_to_cpu(parm_data->length) - 1;
2587 pLockData->fl_pid = le32_to_cpu(parm_data->pid);
2593 cifs_small_buf_release(pSMB);
2595 if (resp_buf_type == CIFS_SMALL_BUFFER)
2596 cifs_small_buf_release(iov[0].iov_base);
2597 else if (resp_buf_type == CIFS_LARGE_BUFFER)
2598 cifs_buf_release(iov[0].iov_base);
2600 /* Note: On -EAGAIN error only caller can retry on handle based calls
2601 since file handle passed in no longer valid */
2608 CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id)
2611 CLOSE_REQ *pSMB = NULL;
2612 cFYI(1, "In CIFSSMBClose");
2614 /* do not retry on dead session on close */
2615 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2621 pSMB->FileID = (__u16) smb_file_id;
2622 pSMB->LastWriteTime = 0xFFFFFFFF;
2623 pSMB->ByteCount = 0;
2624 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
2625 cifs_stats_inc(&tcon->num_closes);
2628 /* EINTR is expected when user ctl-c to kill app */
2629 cERROR(1, "Send error in Close = %d", rc);
2633 /* Since session is dead, file will be closed on server already */
2641 CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id)
2644 FLUSH_REQ *pSMB = NULL;
2645 cFYI(1, "In CIFSSMBFlush");
2647 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2651 pSMB->FileID = (__u16) smb_file_id;
2652 pSMB->ByteCount = 0;
2653 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
2654 cifs_stats_inc(&tcon->num_flushes);
2656 cERROR(1, "Send error in Flush = %d", rc);
2662 CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
2663 const char *fromName, const char *toName,
2664 const struct nls_table *nls_codepage, int remap)
2667 RENAME_REQ *pSMB = NULL;
2668 RENAME_RSP *pSMBr = NULL;
2670 int name_len, name_len2;
2673 cFYI(1, "In CIFSSMBRename");
2675 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2680 pSMB->BufferFormat = 0x04;
2681 pSMB->SearchAttributes =
2682 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2685 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2687 cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName,
2688 PATH_MAX, nls_codepage, remap);
2689 name_len++; /* trailing null */
2691 pSMB->OldFileName[name_len] = 0x04; /* pad */
2692 /* protocol requires ASCII signature byte on Unicode string */
2693 pSMB->OldFileName[name_len + 1] = 0x00;
2695 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
2696 toName, PATH_MAX, nls_codepage, remap);
2697 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2698 name_len2 *= 2; /* convert to bytes */
2699 } else { /* BB improve the check for buffer overruns BB */
2700 name_len = strnlen(fromName, PATH_MAX);
2701 name_len++; /* trailing null */
2702 strncpy(pSMB->OldFileName, fromName, name_len);
2703 name_len2 = strnlen(toName, PATH_MAX);
2704 name_len2++; /* trailing null */
2705 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2706 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2707 name_len2++; /* trailing null */
2708 name_len2++; /* signature byte */
2711 count = 1 /* 1st signature byte */ + name_len + name_len2;
2712 inc_rfc1001_len(pSMB, count);
2713 pSMB->ByteCount = cpu_to_le16(count);
2715 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2716 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2717 cifs_stats_inc(&tcon->num_renames);
2719 cFYI(1, "Send error in rename = %d", rc);
2721 cifs_buf_release(pSMB);
2729 int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
2730 int netfid, const char *target_name,
2731 const struct nls_table *nls_codepage, int remap)
2733 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2734 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2735 struct set_file_rename *rename_info;
2737 char dummy_string[30];
2739 int bytes_returned = 0;
2741 __u16 params, param_offset, offset, count, byte_count;
2743 cFYI(1, "Rename to File by handle");
2744 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2750 pSMB->MaxSetupCount = 0;
2754 pSMB->Reserved2 = 0;
2755 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2756 offset = param_offset + params;
2758 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2759 rename_info = (struct set_file_rename *) data_offset;
2760 pSMB->MaxParameterCount = cpu_to_le16(2);
2761 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2762 pSMB->SetupCount = 1;
2763 pSMB->Reserved3 = 0;
2764 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2765 byte_count = 3 /* pad */ + params;
2766 pSMB->ParameterCount = cpu_to_le16(params);
2767 pSMB->TotalParameterCount = pSMB->ParameterCount;
2768 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2769 pSMB->DataOffset = cpu_to_le16(offset);
2770 /* construct random name ".cifs_tmp<inodenum><mid>" */
2771 rename_info->overwrite = cpu_to_le32(1);
2772 rename_info->root_fid = 0;
2773 /* unicode only call */
2774 if (target_name == NULL) {
2775 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2776 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
2777 dummy_string, 24, nls_codepage, remap);
2779 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
2780 target_name, PATH_MAX, nls_codepage,
2783 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2784 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2785 byte_count += count;
2786 pSMB->DataCount = cpu_to_le16(count);
2787 pSMB->TotalDataCount = pSMB->DataCount;
2789 pSMB->InformationLevel =
2790 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2791 pSMB->Reserved4 = 0;
2792 inc_rfc1001_len(pSMB, byte_count);
2793 pSMB->ByteCount = cpu_to_le16(byte_count);
2794 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2795 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2796 cifs_stats_inc(&pTcon->num_t2renames);
2798 cFYI(1, "Send error in Rename (by file handle) = %d", rc);
2800 cifs_buf_release(pSMB);
2802 /* Note: On -EAGAIN error only caller can retry on handle based calls
2803 since file handle passed in no longer valid */
2809 CIFSSMBCopy(const int xid, struct cifs_tcon *tcon, const char *fromName,
2810 const __u16 target_tid, const char *toName, const int flags,
2811 const struct nls_table *nls_codepage, int remap)
2814 COPY_REQ *pSMB = NULL;
2815 COPY_RSP *pSMBr = NULL;
2817 int name_len, name_len2;
2820 cFYI(1, "In CIFSSMBCopy");
2822 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2827 pSMB->BufferFormat = 0x04;
2828 pSMB->Tid2 = target_tid;
2830 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2832 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2833 name_len = cifsConvertToUCS((__le16 *) pSMB->OldFileName,
2834 fromName, PATH_MAX, nls_codepage,
2836 name_len++; /* trailing null */
2838 pSMB->OldFileName[name_len] = 0x04; /* pad */
2839 /* protocol requires ASCII signature byte on Unicode string */
2840 pSMB->OldFileName[name_len + 1] = 0x00;
2842 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
2843 toName, PATH_MAX, nls_codepage, remap);
2844 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2845 name_len2 *= 2; /* convert to bytes */
2846 } else { /* BB improve the check for buffer overruns BB */
2847 name_len = strnlen(fromName, PATH_MAX);
2848 name_len++; /* trailing null */
2849 strncpy(pSMB->OldFileName, fromName, name_len);
2850 name_len2 = strnlen(toName, PATH_MAX);
2851 name_len2++; /* trailing null */
2852 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2853 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2854 name_len2++; /* trailing null */
2855 name_len2++; /* signature byte */
2858 count = 1 /* 1st signature byte */ + name_len + name_len2;
2859 inc_rfc1001_len(pSMB, count);
2860 pSMB->ByteCount = cpu_to_le16(count);
2862 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2863 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2865 cFYI(1, "Send error in copy = %d with %d files copied",
2866 rc, le16_to_cpu(pSMBr->CopyCount));
2868 cifs_buf_release(pSMB);
2877 CIFSUnixCreateSymLink(const int xid, struct cifs_tcon *tcon,
2878 const char *fromName, const char *toName,
2879 const struct nls_table *nls_codepage)
2881 TRANSACTION2_SPI_REQ *pSMB = NULL;
2882 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2885 int name_len_target;
2887 int bytes_returned = 0;
2888 __u16 params, param_offset, offset, byte_count;
2890 cFYI(1, "In Symlink Unix style");
2892 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2897 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2899 cifs_strtoUCS((__le16 *) pSMB->FileName, fromName, PATH_MAX
2900 /* find define for this maxpathcomponent */
2902 name_len++; /* trailing null */
2905 } else { /* BB improve the check for buffer overruns BB */
2906 name_len = strnlen(fromName, PATH_MAX);
2907 name_len++; /* trailing null */
2908 strncpy(pSMB->FileName, fromName, name_len);
2910 params = 6 + name_len;
2911 pSMB->MaxSetupCount = 0;
2915 pSMB->Reserved2 = 0;
2916 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2917 InformationLevel) - 4;
2918 offset = param_offset + params;
2920 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2921 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2923 cifs_strtoUCS((__le16 *) data_offset, toName, PATH_MAX
2924 /* find define for this maxpathcomponent */
2926 name_len_target++; /* trailing null */
2927 name_len_target *= 2;
2928 } else { /* BB improve the check for buffer overruns BB */
2929 name_len_target = strnlen(toName, PATH_MAX);
2930 name_len_target++; /* trailing null */
2931 strncpy(data_offset, toName, name_len_target);
2934 pSMB->MaxParameterCount = cpu_to_le16(2);
2935 /* BB find exact max on data count below from sess */
2936 pSMB->MaxDataCount = cpu_to_le16(1000);
2937 pSMB->SetupCount = 1;
2938 pSMB->Reserved3 = 0;
2939 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2940 byte_count = 3 /* pad */ + params + name_len_target;
2941 pSMB->DataCount = cpu_to_le16(name_len_target);
2942 pSMB->ParameterCount = cpu_to_le16(params);
2943 pSMB->TotalDataCount = pSMB->DataCount;
2944 pSMB->TotalParameterCount = pSMB->ParameterCount;
2945 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2946 pSMB->DataOffset = cpu_to_le16(offset);
2947 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2948 pSMB->Reserved4 = 0;
2949 inc_rfc1001_len(pSMB, byte_count);
2950 pSMB->ByteCount = cpu_to_le16(byte_count);
2951 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2952 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2953 cifs_stats_inc(&tcon->num_symlinks);
2955 cFYI(1, "Send error in SetPathInfo create symlink = %d", rc);
2957 cifs_buf_release(pSMB);
2960 goto createSymLinkRetry;
2966 CIFSUnixCreateHardLink(const int xid, struct cifs_tcon *tcon,
2967 const char *fromName, const char *toName,
2968 const struct nls_table *nls_codepage, int remap)
2970 TRANSACTION2_SPI_REQ *pSMB = NULL;
2971 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2974 int name_len_target;
2976 int bytes_returned = 0;
2977 __u16 params, param_offset, offset, byte_count;
2979 cFYI(1, "In Create Hard link Unix style");
2980 createHardLinkRetry:
2981 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2986 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2987 name_len = cifsConvertToUCS((__le16 *) pSMB->FileName, toName,
2988 PATH_MAX, nls_codepage, remap);
2989 name_len++; /* trailing null */
2992 } else { /* BB improve the check for buffer overruns BB */
2993 name_len = strnlen(toName, PATH_MAX);
2994 name_len++; /* trailing null */
2995 strncpy(pSMB->FileName, toName, name_len);
2997 params = 6 + name_len;
2998 pSMB->MaxSetupCount = 0;
3002 pSMB->Reserved2 = 0;
3003 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3004 InformationLevel) - 4;
3005 offset = param_offset + params;
3007 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
3008 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3010 cifsConvertToUCS((__le16 *) data_offset, fromName, PATH_MAX,
3011 nls_codepage, remap);
3012 name_len_target++; /* trailing null */
3013 name_len_target *= 2;
3014 } else { /* BB improve the check for buffer overruns BB */
3015 name_len_target = strnlen(fromName, PATH_MAX);
3016 name_len_target++; /* trailing null */
3017 strncpy(data_offset, fromName, name_len_target);
3020 pSMB->MaxParameterCount = cpu_to_le16(2);
3021 /* BB find exact max on data count below from sess*/
3022 pSMB->MaxDataCount = cpu_to_le16(1000);
3023 pSMB->SetupCount = 1;
3024 pSMB->Reserved3 = 0;
3025 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3026 byte_count = 3 /* pad */ + params + name_len_target;
3027 pSMB->ParameterCount = cpu_to_le16(params);
3028 pSMB->TotalParameterCount = pSMB->ParameterCount;
3029 pSMB->DataCount = cpu_to_le16(name_len_target);
3030 pSMB->TotalDataCount = pSMB->DataCount;
3031 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3032 pSMB->DataOffset = cpu_to_le16(offset);
3033 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3034 pSMB->Reserved4 = 0;
3035 inc_rfc1001_len(pSMB, byte_count);
3036 pSMB->ByteCount = cpu_to_le16(byte_count);
3037 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3038 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3039 cifs_stats_inc(&tcon->num_hardlinks);
3041 cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc);
3043 cifs_buf_release(pSMB);
3045 goto createHardLinkRetry;
3051 CIFSCreateHardLink(const int xid, struct cifs_tcon *tcon,
3052 const char *fromName, const char *toName,
3053 const struct nls_table *nls_codepage, int remap)
3056 NT_RENAME_REQ *pSMB = NULL;
3057 RENAME_RSP *pSMBr = NULL;
3059 int name_len, name_len2;
3062 cFYI(1, "In CIFSCreateHardLink");
3063 winCreateHardLinkRetry:
3065 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3070 pSMB->SearchAttributes =
3071 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3073 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3074 pSMB->ClusterCount = 0;
3076 pSMB->BufferFormat = 0x04;
3078 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3080 cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName,
3081 PATH_MAX, nls_codepage, remap);
3082 name_len++; /* trailing null */
3085 /* protocol specifies ASCII buffer format (0x04) for unicode */
3086 pSMB->OldFileName[name_len] = 0x04;
3087 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3089 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
3090 toName, PATH_MAX, nls_codepage, remap);
3091 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3092 name_len2 *= 2; /* convert to bytes */
3093 } else { /* BB improve the check for buffer overruns BB */
3094 name_len = strnlen(fromName, PATH_MAX);
3095 name_len++; /* trailing null */
3096 strncpy(pSMB->OldFileName, fromName, name_len);
3097 name_len2 = strnlen(toName, PATH_MAX);
3098 name_len2++; /* trailing null */
3099 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3100 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
3101 name_len2++; /* trailing null */
3102 name_len2++; /* signature byte */
3105 count = 1 /* string type byte */ + name_len + name_len2;
3106 inc_rfc1001_len(pSMB, count);
3107 pSMB->ByteCount = cpu_to_le16(count);
3109 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3110 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3111 cifs_stats_inc(&tcon->num_hardlinks);
3113 cFYI(1, "Send error in hard link (NT rename) = %d", rc);
3115 cifs_buf_release(pSMB);
3117 goto winCreateHardLinkRetry;
3123 CIFSSMBUnixQuerySymLink(const int xid, struct cifs_tcon *tcon,
3124 const unsigned char *searchName, char **symlinkinfo,
3125 const struct nls_table *nls_codepage)
3127 /* SMB_QUERY_FILE_UNIX_LINK */
3128 TRANSACTION2_QPI_REQ *pSMB = NULL;
3129 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3133 __u16 params, byte_count;
3136 cFYI(1, "In QPathSymLinkInfo (Unix) for path %s", searchName);
3139 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3144 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3146 cifs_strtoUCS((__le16 *) pSMB->FileName, searchName,
3147 PATH_MAX, nls_codepage);
3148 name_len++; /* trailing null */
3150 } else { /* BB improve the check for buffer overruns BB */
3151 name_len = strnlen(searchName, PATH_MAX);
3152 name_len++; /* trailing null */
3153 strncpy(pSMB->FileName, searchName, name_len);
3156 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3157 pSMB->TotalDataCount = 0;
3158 pSMB->MaxParameterCount = cpu_to_le16(2);
3159 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3160 pSMB->MaxSetupCount = 0;
3164 pSMB->Reserved2 = 0;
3165 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3166 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3167 pSMB->DataCount = 0;
3168 pSMB->DataOffset = 0;
3169 pSMB->SetupCount = 1;
3170 pSMB->Reserved3 = 0;
3171 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3172 byte_count = params + 1 /* pad */ ;
3173 pSMB->TotalParameterCount = cpu_to_le16(params);
3174 pSMB->ParameterCount = pSMB->TotalParameterCount;
3175 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3176 pSMB->Reserved4 = 0;
3177 inc_rfc1001_len(pSMB, byte_count);
3178 pSMB->ByteCount = cpu_to_le16(byte_count);
3180 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3181 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3183 cFYI(1, "Send error in QuerySymLinkInfo = %d", rc);
3185 /* decode response */
3187 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3188 /* BB also check enough total bytes returned */
3189 if (rc || get_bcc(&pSMBr->hdr) < 2)
3193 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3195 data_start = ((char *) &pSMBr->hdr.Protocol) +
3196 le16_to_cpu(pSMBr->t2.DataOffset);
3198 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3203 /* BB FIXME investigate remapping reserved chars here */
3204 *symlinkinfo = cifs_strndup_from_ucs(data_start, count,
3205 is_unicode, nls_codepage);
3210 cifs_buf_release(pSMB);
3212 goto querySymLinkRetry;
3216 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3218 * Recent Windows versions now create symlinks more frequently
3219 * and they use the "reparse point" mechanism below. We can of course
3220 * do symlinks nicely to Samba and other servers which support the
3221 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3222 * "MF" symlinks optionally, but for recent Windows we really need to
3223 * reenable the code below and fix the cifs_symlink callers to handle this.
3224 * In the interim this code has been moved to its own config option so
3225 * it is not compiled in by default until callers fixed up and more tested.
3228 CIFSSMBQueryReparseLinkInfo(const int xid, struct cifs_tcon *tcon,
3229 const unsigned char *searchName,
3230 char *symlinkinfo, const int buflen, __u16 fid,
3231 const struct nls_table *nls_codepage)
3235 struct smb_com_transaction_ioctl_req *pSMB;
3236 struct smb_com_transaction_ioctl_rsp *pSMBr;
3238 cFYI(1, "In Windows reparse style QueryLink for path %s", searchName);
3239 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3244 pSMB->TotalParameterCount = 0 ;
3245 pSMB->TotalDataCount = 0;
3246 pSMB->MaxParameterCount = cpu_to_le32(2);
3247 /* BB find exact data count max from sess structure BB */
3248 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3249 pSMB->MaxSetupCount = 4;
3251 pSMB->ParameterOffset = 0;
3252 pSMB->DataCount = 0;
3253 pSMB->DataOffset = 0;
3254 pSMB->SetupCount = 4;
3255 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3256 pSMB->ParameterCount = pSMB->TotalParameterCount;
3257 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3258 pSMB->IsFsctl = 1; /* FSCTL */
3259 pSMB->IsRootFlag = 0;
3260 pSMB->Fid = fid; /* file handle always le */
3261 pSMB->ByteCount = 0;
3263 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3264 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3266 cFYI(1, "Send error in QueryReparseLinkInfo = %d", rc);
3267 } else { /* decode response */
3268 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
3269 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
3270 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3271 /* BB also check enough total bytes returned */
3272 rc = -EIO; /* bad smb */
3275 if (data_count && (data_count < 2048)) {
3276 char *end_of_smb = 2 /* sizeof byte count */ +
3277 get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3279 struct reparse_data *reparse_buf =
3280 (struct reparse_data *)
3281 ((char *)&pSMBr->hdr.Protocol
3283 if ((char *)reparse_buf >= end_of_smb) {
3287 if ((reparse_buf->LinkNamesBuf +
3288 reparse_buf->TargetNameOffset +
3289 reparse_buf->TargetNameLen) > end_of_smb) {
3290 cFYI(1, "reparse buf beyond SMB");
3295 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3296 cifs_from_ucs2(symlinkinfo, (__le16 *)
3297 (reparse_buf->LinkNamesBuf +
3298 reparse_buf->TargetNameOffset),
3300 reparse_buf->TargetNameLen,
3302 } else { /* ASCII names */
3303 strncpy(symlinkinfo,
3304 reparse_buf->LinkNamesBuf +
3305 reparse_buf->TargetNameOffset,
3306 min_t(const int, buflen,
3307 reparse_buf->TargetNameLen));
3311 cFYI(1, "Invalid return data count on "
3312 "get reparse info ioctl");
3314 symlinkinfo[buflen] = 0; /* just in case so the caller
3315 does not go off the end of the buffer */
3316 cFYI(1, "readlink result - %s", symlinkinfo);
3320 cifs_buf_release(pSMB);
3322 /* Note: On -EAGAIN error only caller can retry on handle based calls
3323 since file handle passed in no longer valid */
3327 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3329 #ifdef CONFIG_CIFS_POSIX
3331 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3332 static void cifs_convert_ace(posix_acl_xattr_entry *ace,
3333 struct cifs_posix_ace *cifs_ace)
3335 /* u8 cifs fields do not need le conversion */
3336 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3337 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3338 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3339 /* cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id); */
3344 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3345 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3346 const int acl_type, const int size_of_data_area)
3351 struct cifs_posix_ace *pACE;
3352 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3353 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
3355 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3358 if (acl_type & ACL_TYPE_ACCESS) {
3359 count = le16_to_cpu(cifs_acl->access_entry_count);
3360 pACE = &cifs_acl->ace_array[0];
3361 size = sizeof(struct cifs_posix_acl);
3362 size += sizeof(struct cifs_posix_ace) * count;
3363 /* check if we would go beyond end of SMB */
3364 if (size_of_data_area < size) {
3365 cFYI(1, "bad CIFS POSIX ACL size %d vs. %d",
3366 size_of_data_area, size);
3369 } else if (acl_type & ACL_TYPE_DEFAULT) {
3370 count = le16_to_cpu(cifs_acl->access_entry_count);
3371 size = sizeof(struct cifs_posix_acl);
3372 size += sizeof(struct cifs_posix_ace) * count;
3373 /* skip past access ACEs to get to default ACEs */
3374 pACE = &cifs_acl->ace_array[count];
3375 count = le16_to_cpu(cifs_acl->default_entry_count);
3376 size += sizeof(struct cifs_posix_ace) * count;
3377 /* check if we would go beyond end of SMB */
3378 if (size_of_data_area < size)
3385 size = posix_acl_xattr_size(count);
3386 if ((buflen == 0) || (local_acl == NULL)) {
3387 /* used to query ACL EA size */
3388 } else if (size > buflen) {
3390 } else /* buffer big enough */ {
3391 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3392 for (i = 0; i < count ; i++) {
3393 cifs_convert_ace(&local_acl->a_entries[i], pACE);
3400 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3401 const posix_acl_xattr_entry *local_ace)
3403 __u16 rc = 0; /* 0 = ACL converted ok */
3405 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3406 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3407 /* BB is there a better way to handle the large uid? */
3408 if (local_ace->e_id == cpu_to_le32(-1)) {
3409 /* Probably no need to le convert -1 on any arch but can not hurt */
3410 cifs_ace->cifs_uid = cpu_to_le64(-1);
3412 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3413 /*cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id);*/
3417 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3418 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3419 const int buflen, const int acl_type)
3422 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3423 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
3427 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3430 count = posix_acl_xattr_count((size_t)buflen);
3431 cFYI(1, "setting acl with %d entries from buf of length %d and "
3433 count, buflen, le32_to_cpu(local_acl->a_version));
3434 if (le32_to_cpu(local_acl->a_version) != 2) {
3435 cFYI(1, "unknown POSIX ACL version %d",
3436 le32_to_cpu(local_acl->a_version));
3439 cifs_acl->version = cpu_to_le16(1);
3440 if (acl_type == ACL_TYPE_ACCESS) {
3441 cifs_acl->access_entry_count = cpu_to_le16(count);
3442 cifs_acl->default_entry_count = __constant_cpu_to_le16(0xFFFF);
3443 } else if (acl_type == ACL_TYPE_DEFAULT) {
3444 cifs_acl->default_entry_count = cpu_to_le16(count);
3445 cifs_acl->access_entry_count = __constant_cpu_to_le16(0xFFFF);
3447 cFYI(1, "unknown ACL type %d", acl_type);
3450 for (i = 0; i < count; i++) {
3451 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3452 &local_acl->a_entries[i]);
3454 /* ACE not converted */
3459 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3460 rc += sizeof(struct cifs_posix_acl);
3461 /* BB add check to make sure ACL does not overflow SMB */
3467 CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
3468 const unsigned char *searchName,
3469 char *acl_inf, const int buflen, const int acl_type,
3470 const struct nls_table *nls_codepage, int remap)
3472 /* SMB_QUERY_POSIX_ACL */
3473 TRANSACTION2_QPI_REQ *pSMB = NULL;
3474 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3478 __u16 params, byte_count;
3480 cFYI(1, "In GetPosixACL (Unix) for path %s", searchName);
3483 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3488 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3490 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3491 PATH_MAX, nls_codepage, remap);
3492 name_len++; /* trailing null */
3494 pSMB->FileName[name_len] = 0;
3495 pSMB->FileName[name_len+1] = 0;
3496 } else { /* BB improve the check for buffer overruns BB */
3497 name_len = strnlen(searchName, PATH_MAX);
3498 name_len++; /* trailing null */
3499 strncpy(pSMB->FileName, searchName, name_len);
3502 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3503 pSMB->TotalDataCount = 0;
3504 pSMB->MaxParameterCount = cpu_to_le16(2);
3505 /* BB find exact max data count below from sess structure BB */
3506 pSMB->MaxDataCount = cpu_to_le16(4000);
3507 pSMB->MaxSetupCount = 0;
3511 pSMB->Reserved2 = 0;
3512 pSMB->ParameterOffset = cpu_to_le16(
3513 offsetof(struct smb_com_transaction2_qpi_req,
3514 InformationLevel) - 4);
3515 pSMB->DataCount = 0;
3516 pSMB->DataOffset = 0;
3517 pSMB->SetupCount = 1;
3518 pSMB->Reserved3 = 0;
3519 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3520 byte_count = params + 1 /* pad */ ;
3521 pSMB->TotalParameterCount = cpu_to_le16(params);
3522 pSMB->ParameterCount = pSMB->TotalParameterCount;
3523 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3524 pSMB->Reserved4 = 0;
3525 inc_rfc1001_len(pSMB, byte_count);
3526 pSMB->ByteCount = cpu_to_le16(byte_count);
3528 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3529 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3530 cifs_stats_inc(&tcon->num_acl_get);
3532 cFYI(1, "Send error in Query POSIX ACL = %d", rc);
3534 /* decode response */
3536 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3537 /* BB also check enough total bytes returned */
3538 if (rc || get_bcc(&pSMBr->hdr) < 2)
3539 rc = -EIO; /* bad smb */
3541 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3542 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3543 rc = cifs_copy_posix_acl(acl_inf,
3544 (char *)&pSMBr->hdr.Protocol+data_offset,
3545 buflen, acl_type, count);
3548 cifs_buf_release(pSMB);
3555 CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
3556 const unsigned char *fileName,
3557 const char *local_acl, const int buflen,
3559 const struct nls_table *nls_codepage, int remap)
3561 struct smb_com_transaction2_spi_req *pSMB = NULL;
3562 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3566 int bytes_returned = 0;
3567 __u16 params, byte_count, data_count, param_offset, offset;
3569 cFYI(1, "In SetPosixACL (Unix) for path %s", fileName);
3571 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3575 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3577 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
3578 PATH_MAX, nls_codepage, remap);
3579 name_len++; /* trailing null */
3581 } else { /* BB improve the check for buffer overruns BB */
3582 name_len = strnlen(fileName, PATH_MAX);
3583 name_len++; /* trailing null */
3584 strncpy(pSMB->FileName, fileName, name_len);
3586 params = 6 + name_len;
3587 pSMB->MaxParameterCount = cpu_to_le16(2);
3588 /* BB find max SMB size from sess */
3589 pSMB->MaxDataCount = cpu_to_le16(1000);
3590 pSMB->MaxSetupCount = 0;
3594 pSMB->Reserved2 = 0;
3595 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3596 InformationLevel) - 4;
3597 offset = param_offset + params;
3598 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3599 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3601 /* convert to on the wire format for POSIX ACL */
3602 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3604 if (data_count == 0) {
3606 goto setACLerrorExit;
3608 pSMB->DataOffset = cpu_to_le16(offset);
3609 pSMB->SetupCount = 1;
3610 pSMB->Reserved3 = 0;
3611 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3612 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3613 byte_count = 3 /* pad */ + params + data_count;
3614 pSMB->DataCount = cpu_to_le16(data_count);
3615 pSMB->TotalDataCount = pSMB->DataCount;
3616 pSMB->ParameterCount = cpu_to_le16(params);
3617 pSMB->TotalParameterCount = pSMB->ParameterCount;
3618 pSMB->Reserved4 = 0;
3619 inc_rfc1001_len(pSMB, byte_count);
3620 pSMB->ByteCount = cpu_to_le16(byte_count);
3621 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3622 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3624 cFYI(1, "Set POSIX ACL returned %d", rc);
3627 cifs_buf_release(pSMB);
3633 /* BB fix tabs in this function FIXME BB */
3635 CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
3636 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3639 struct smb_t2_qfi_req *pSMB = NULL;
3640 struct smb_t2_qfi_rsp *pSMBr = NULL;
3642 __u16 params, byte_count;
3644 cFYI(1, "In GetExtAttr");
3649 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3654 params = 2 /* level */ + 2 /* fid */;
3655 pSMB->t2.TotalDataCount = 0;
3656 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3657 /* BB find exact max data count below from sess structure BB */
3658 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3659 pSMB->t2.MaxSetupCount = 0;
3660 pSMB->t2.Reserved = 0;
3662 pSMB->t2.Timeout = 0;
3663 pSMB->t2.Reserved2 = 0;
3664 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3666 pSMB->t2.DataCount = 0;
3667 pSMB->t2.DataOffset = 0;
3668 pSMB->t2.SetupCount = 1;
3669 pSMB->t2.Reserved3 = 0;
3670 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3671 byte_count = params + 1 /* pad */ ;
3672 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3673 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3674 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3677 inc_rfc1001_len(pSMB, byte_count);
3678 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3680 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3681 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3683 cFYI(1, "error %d in GetExtAttr", rc);
3685 /* decode response */
3686 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3687 /* BB also check enough total bytes returned */
3688 if (rc || get_bcc(&pSMBr->hdr) < 2)
3689 /* If rc should we check for EOPNOSUPP and
3690 disable the srvino flag? or in caller? */
3691 rc = -EIO; /* bad smb */
3693 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3694 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3695 struct file_chattr_info *pfinfo;
3696 /* BB Do we need a cast or hash here ? */
3698 cFYI(1, "Illegal size ret in GetExtAttr");
3702 pfinfo = (struct file_chattr_info *)
3703 (data_offset + (char *) &pSMBr->hdr.Protocol);
3704 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3705 *pMask = le64_to_cpu(pfinfo->mask);
3709 cifs_buf_release(pSMB);
3711 goto GetExtAttrRetry;
3715 #endif /* CONFIG_POSIX */
3717 #ifdef CONFIG_CIFS_ACL
3719 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3720 * all NT TRANSACTS that we init here have total parm and data under about 400
3721 * bytes (to fit in small cifs buffer size), which is the case so far, it
3722 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3723 * returned setup area) and MaxParameterCount (returned parms size) must be set
3727 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3728 const int parm_len, struct cifs_tcon *tcon,
3733 struct smb_com_ntransact_req *pSMB;
3735 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3739 *ret_buf = (void *)pSMB;
3741 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3742 pSMB->TotalDataCount = 0;
3743 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3744 pSMB->ParameterCount = pSMB->TotalParameterCount;
3745 pSMB->DataCount = pSMB->TotalDataCount;
3746 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3747 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3748 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3749 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3750 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3751 pSMB->SubCommand = cpu_to_le16(sub_command);
3756 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3757 __u32 *pparmlen, __u32 *pdatalen)
3760 __u32 data_count, data_offset, parm_count, parm_offset;
3761 struct smb_com_ntransact_rsp *pSMBr;
3770 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3772 bcc = get_bcc(&pSMBr->hdr);
3773 end_of_smb = 2 /* sizeof byte count */ + bcc +
3774 (char *)&pSMBr->ByteCount;
3776 data_offset = le32_to_cpu(pSMBr->DataOffset);
3777 data_count = le32_to_cpu(pSMBr->DataCount);
3778 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3779 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3781 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3782 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3784 /* should we also check that parm and data areas do not overlap? */
3785 if (*ppparm > end_of_smb) {
3786 cFYI(1, "parms start after end of smb");
3788 } else if (parm_count + *ppparm > end_of_smb) {
3789 cFYI(1, "parm end after end of smb");
3791 } else if (*ppdata > end_of_smb) {
3792 cFYI(1, "data starts after end of smb");
3794 } else if (data_count + *ppdata > end_of_smb) {
3795 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
3796 *ppdata, data_count, (data_count + *ppdata),
3799 } else if (parm_count + data_count > bcc) {
3800 cFYI(1, "parm count and data count larger than SMB");
3803 *pdatalen = data_count;
3804 *pparmlen = parm_count;
3808 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3810 CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3811 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3815 QUERY_SEC_DESC_REQ *pSMB;
3818 cFYI(1, "GetCifsACL");
3823 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3824 8 /* parm len */, tcon, (void **) &pSMB);
3828 pSMB->MaxParameterCount = cpu_to_le32(4);
3829 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3830 pSMB->MaxSetupCount = 0;
3831 pSMB->Fid = fid; /* file handle always le */
3832 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3834 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3835 inc_rfc1001_len(pSMB, 11);
3836 iov[0].iov_base = (char *)pSMB;
3837 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3839 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3841 cifs_stats_inc(&tcon->num_acl_get);
3843 cFYI(1, "Send error in QuerySecDesc = %d", rc);
3844 } else { /* decode response */
3848 struct smb_com_ntransact_rsp *pSMBr;
3851 /* validate_nttransact */
3852 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3853 &pdata, &parm_len, pbuflen);
3856 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3858 cFYI(1, "smb %p parm %p data %p", pSMBr, parm, *acl_inf);
3860 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3861 rc = -EIO; /* bad smb */
3866 /* BB check that data area is minimum length and as big as acl_len */
3868 acl_len = le32_to_cpu(*parm);
3869 if (acl_len != *pbuflen) {
3870 cERROR(1, "acl length %d does not match %d",
3872 if (*pbuflen > acl_len)
3876 /* check if buffer is big enough for the acl
3877 header followed by the smallest SID */
3878 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3879 (*pbuflen >= 64 * 1024)) {
3880 cERROR(1, "bad acl length %d", *pbuflen);
3884 *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
3885 if (*acl_inf == NULL) {
3889 memcpy(*acl_inf, pdata, *pbuflen);
3893 if (buf_type == CIFS_SMALL_BUFFER)
3894 cifs_small_buf_release(iov[0].iov_base);
3895 else if (buf_type == CIFS_LARGE_BUFFER)
3896 cifs_buf_release(iov[0].iov_base);
3897 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3902 CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3903 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3905 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3907 int bytes_returned = 0;
3908 SET_SEC_DESC_REQ *pSMB = NULL;
3909 NTRANSACT_RSP *pSMBr = NULL;
3912 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB,
3917 pSMB->MaxSetupCount = 0;
3921 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3922 data_count = acllen;
3923 data_offset = param_offset + param_count;
3924 byte_count = 3 /* pad */ + param_count;
3926 pSMB->DataCount = cpu_to_le32(data_count);
3927 pSMB->TotalDataCount = pSMB->DataCount;
3928 pSMB->MaxParameterCount = cpu_to_le32(4);
3929 pSMB->MaxDataCount = cpu_to_le32(16384);
3930 pSMB->ParameterCount = cpu_to_le32(param_count);
3931 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3932 pSMB->TotalParameterCount = pSMB->ParameterCount;
3933 pSMB->DataOffset = cpu_to_le32(data_offset);
3934 pSMB->SetupCount = 0;
3935 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3936 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3938 pSMB->Fid = fid; /* file handle always le */
3939 pSMB->Reserved2 = 0;
3940 pSMB->AclFlags = cpu_to_le32(aclflag);
3942 if (pntsd && acllen) {
3943 memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
3946 inc_rfc1001_len(pSMB, byte_count + data_count);
3948 inc_rfc1001_len(pSMB, byte_count);
3950 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3951 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3953 cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
3955 cFYI(1, "Set CIFS ACL returned %d", rc);
3956 cifs_buf_release(pSMB);
3959 goto setCifsAclRetry;
3964 #endif /* CONFIG_CIFS_ACL */
3966 /* Legacy Query Path Information call for lookup to old servers such
3968 int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
3969 const unsigned char *searchName,
3970 FILE_ALL_INFO *pFinfo,
3971 const struct nls_table *nls_codepage, int remap)
3973 QUERY_INFORMATION_REQ *pSMB;
3974 QUERY_INFORMATION_RSP *pSMBr;
3979 cFYI(1, "In SMBQPath path %s", searchName);
3981 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3986 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3988 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3989 PATH_MAX, nls_codepage, remap);
3990 name_len++; /* trailing null */
3993 name_len = strnlen(searchName, PATH_MAX);
3994 name_len++; /* trailing null */
3995 strncpy(pSMB->FileName, searchName, name_len);
3997 pSMB->BufferFormat = 0x04;
3998 name_len++; /* account for buffer type byte */
3999 inc_rfc1001_len(pSMB, (__u16)name_len);
4000 pSMB->ByteCount = cpu_to_le16(name_len);
4002 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4003 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4005 cFYI(1, "Send error in QueryInfo = %d", rc);
4006 } else if (pFinfo) {
4008 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4010 /* decode response */
4011 /* BB FIXME - add time zone adjustment BB */
4012 memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
4015 /* decode time fields */
4016 pFinfo->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4017 pFinfo->LastWriteTime = pFinfo->ChangeTime;
4018 pFinfo->LastAccessTime = 0;
4019 pFinfo->AllocationSize =
4020 cpu_to_le64(le32_to_cpu(pSMBr->size));
4021 pFinfo->EndOfFile = pFinfo->AllocationSize;
4022 pFinfo->Attributes =
4023 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4025 rc = -EIO; /* bad buffer passed in */
4027 cifs_buf_release(pSMB);
4036 CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
4037 u16 netfid, FILE_ALL_INFO *pFindData)
4039 struct smb_t2_qfi_req *pSMB = NULL;
4040 struct smb_t2_qfi_rsp *pSMBr = NULL;
4043 __u16 params, byte_count;
4046 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4051 params = 2 /* level */ + 2 /* fid */;
4052 pSMB->t2.TotalDataCount = 0;
4053 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4054 /* BB find exact max data count below from sess structure BB */
4055 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4056 pSMB->t2.MaxSetupCount = 0;
4057 pSMB->t2.Reserved = 0;
4059 pSMB->t2.Timeout = 0;
4060 pSMB->t2.Reserved2 = 0;
4061 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4063 pSMB->t2.DataCount = 0;
4064 pSMB->t2.DataOffset = 0;
4065 pSMB->t2.SetupCount = 1;
4066 pSMB->t2.Reserved3 = 0;
4067 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4068 byte_count = params + 1 /* pad */ ;
4069 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4070 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4071 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4074 inc_rfc1001_len(pSMB, byte_count);
4076 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4077 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4079 cFYI(1, "Send error in QPathInfo = %d", rc);
4080 } else { /* decode response */
4081 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4083 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4085 else if (get_bcc(&pSMBr->hdr) < 40)
4086 rc = -EIO; /* bad smb */
4087 else if (pFindData) {
4088 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4089 memcpy((char *) pFindData,
4090 (char *) &pSMBr->hdr.Protocol +
4091 data_offset, sizeof(FILE_ALL_INFO));
4095 cifs_buf_release(pSMB);
4097 goto QFileInfoRetry;
4103 CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
4104 const unsigned char *searchName,
4105 FILE_ALL_INFO *pFindData,
4106 int legacy /* old style infolevel */,
4107 const struct nls_table *nls_codepage, int remap)
4109 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4110 TRANSACTION2_QPI_REQ *pSMB = NULL;
4111 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4115 __u16 params, byte_count;
4117 /* cFYI(1, "In QPathInfo path %s", searchName); */
4119 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4124 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4126 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4127 PATH_MAX, nls_codepage, remap);
4128 name_len++; /* trailing null */
4130 } else { /* BB improve the check for buffer overruns BB */
4131 name_len = strnlen(searchName, PATH_MAX);
4132 name_len++; /* trailing null */
4133 strncpy(pSMB->FileName, searchName, name_len);
4136 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4137 pSMB->TotalDataCount = 0;
4138 pSMB->MaxParameterCount = cpu_to_le16(2);
4139 /* BB find exact max SMB PDU from sess structure BB */
4140 pSMB->MaxDataCount = cpu_to_le16(4000);
4141 pSMB->MaxSetupCount = 0;
4145 pSMB->Reserved2 = 0;
4146 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4147 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4148 pSMB->DataCount = 0;
4149 pSMB->DataOffset = 0;
4150 pSMB->SetupCount = 1;
4151 pSMB->Reserved3 = 0;
4152 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4153 byte_count = params + 1 /* pad */ ;
4154 pSMB->TotalParameterCount = cpu_to_le16(params);
4155 pSMB->ParameterCount = pSMB->TotalParameterCount;
4157 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4159 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4160 pSMB->Reserved4 = 0;
4161 inc_rfc1001_len(pSMB, byte_count);
4162 pSMB->ByteCount = cpu_to_le16(byte_count);
4164 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4165 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4167 cFYI(1, "Send error in QPathInfo = %d", rc);
4168 } else { /* decode response */
4169 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4171 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4173 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4174 rc = -EIO; /* bad smb */
4175 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4176 rc = -EIO; /* 24 or 26 expected but we do not read
4178 else if (pFindData) {
4180 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4182 /* On legacy responses we do not read the last field,
4183 EAsize, fortunately since it varies by subdialect and
4184 also note it differs on Set vs. Get, ie two bytes or 4
4185 bytes depending but we don't care here */
4187 size = sizeof(FILE_INFO_STANDARD);
4189 size = sizeof(FILE_ALL_INFO);
4190 memcpy((char *) pFindData,
4191 (char *) &pSMBr->hdr.Protocol +
4196 cifs_buf_release(pSMB);
4198 goto QPathInfoRetry;
4204 CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
4205 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4207 struct smb_t2_qfi_req *pSMB = NULL;
4208 struct smb_t2_qfi_rsp *pSMBr = NULL;
4211 __u16 params, byte_count;
4214 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4219 params = 2 /* level */ + 2 /* fid */;
4220 pSMB->t2.TotalDataCount = 0;
4221 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4222 /* BB find exact max data count below from sess structure BB */
4223 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4224 pSMB->t2.MaxSetupCount = 0;
4225 pSMB->t2.Reserved = 0;
4227 pSMB->t2.Timeout = 0;
4228 pSMB->t2.Reserved2 = 0;
4229 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4231 pSMB->t2.DataCount = 0;
4232 pSMB->t2.DataOffset = 0;
4233 pSMB->t2.SetupCount = 1;
4234 pSMB->t2.Reserved3 = 0;
4235 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4236 byte_count = params + 1 /* pad */ ;
4237 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4238 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4239 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4242 inc_rfc1001_len(pSMB, byte_count);
4244 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4245 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4247 cFYI(1, "Send error in QPathInfo = %d", rc);
4248 } else { /* decode response */
4249 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4251 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4252 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
4253 "Unix Extensions can be disabled on mount "
4254 "by specifying the nosfu mount option.");
4255 rc = -EIO; /* bad smb */
4257 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4258 memcpy((char *) pFindData,
4259 (char *) &pSMBr->hdr.Protocol +
4261 sizeof(FILE_UNIX_BASIC_INFO));
4265 cifs_buf_release(pSMB);
4267 goto UnixQFileInfoRetry;
4273 CIFSSMBUnixQPathInfo(const int xid, struct cifs_tcon *tcon,
4274 const unsigned char *searchName,
4275 FILE_UNIX_BASIC_INFO *pFindData,
4276 const struct nls_table *nls_codepage, int remap)
4278 /* SMB_QUERY_FILE_UNIX_BASIC */
4279 TRANSACTION2_QPI_REQ *pSMB = NULL;
4280 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4282 int bytes_returned = 0;
4284 __u16 params, byte_count;
4286 cFYI(1, "In QPathInfo (Unix) the path %s", searchName);
4288 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4293 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4295 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4296 PATH_MAX, nls_codepage, remap);
4297 name_len++; /* trailing null */
4299 } else { /* BB improve the check for buffer overruns BB */
4300 name_len = strnlen(searchName, PATH_MAX);
4301 name_len++; /* trailing null */
4302 strncpy(pSMB->FileName, searchName, name_len);
4305 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4306 pSMB->TotalDataCount = 0;
4307 pSMB->MaxParameterCount = cpu_to_le16(2);
4308 /* BB find exact max SMB PDU from sess structure BB */
4309 pSMB->MaxDataCount = cpu_to_le16(4000);
4310 pSMB->MaxSetupCount = 0;
4314 pSMB->Reserved2 = 0;
4315 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4316 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4317 pSMB->DataCount = 0;
4318 pSMB->DataOffset = 0;
4319 pSMB->SetupCount = 1;
4320 pSMB->Reserved3 = 0;
4321 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4322 byte_count = params + 1 /* pad */ ;
4323 pSMB->TotalParameterCount = cpu_to_le16(params);
4324 pSMB->ParameterCount = pSMB->TotalParameterCount;
4325 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4326 pSMB->Reserved4 = 0;
4327 inc_rfc1001_len(pSMB, byte_count);
4328 pSMB->ByteCount = cpu_to_le16(byte_count);
4330 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4331 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4333 cFYI(1, "Send error in QPathInfo = %d", rc);
4334 } else { /* decode response */
4335 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4337 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4338 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
4339 "Unix Extensions can be disabled on mount "
4340 "by specifying the nosfu mount option.");
4341 rc = -EIO; /* bad smb */
4343 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4344 memcpy((char *) pFindData,
4345 (char *) &pSMBr->hdr.Protocol +
4347 sizeof(FILE_UNIX_BASIC_INFO));
4350 cifs_buf_release(pSMB);
4352 goto UnixQPathInfoRetry;
4357 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4359 CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
4360 const char *searchName,
4361 const struct nls_table *nls_codepage,
4362 __u16 *pnetfid, __u16 search_flags,
4363 struct cifs_search_info *psrch_inf, int remap, const char dirsep)
4365 /* level 257 SMB_ */
4366 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4367 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4368 T2_FFIRST_RSP_PARMS *parms;
4370 int bytes_returned = 0;
4372 __u16 params, byte_count;
4374 cFYI(1, "In FindFirst for %s", searchName);
4377 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4382 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4384 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4385 PATH_MAX, nls_codepage, remap);
4386 /* We can not add the asterik earlier in case
4387 it got remapped to 0xF03A as if it were part of the
4388 directory name instead of a wildcard */
4390 pSMB->FileName[name_len] = dirsep;
4391 pSMB->FileName[name_len+1] = 0;
4392 pSMB->FileName[name_len+2] = '*';
4393 pSMB->FileName[name_len+3] = 0;
4394 name_len += 4; /* now the trailing null */
4395 pSMB->FileName[name_len] = 0; /* null terminate just in case */
4396 pSMB->FileName[name_len+1] = 0;
4398 } else { /* BB add check for overrun of SMB buf BB */
4399 name_len = strnlen(searchName, PATH_MAX);
4400 /* BB fix here and in unicode clause above ie
4401 if (name_len > buffersize-header)
4402 free buffer exit; BB */
4403 strncpy(pSMB->FileName, searchName, name_len);
4404 pSMB->FileName[name_len] = dirsep;
4405 pSMB->FileName[name_len+1] = '*';
4406 pSMB->FileName[name_len+2] = 0;
4410 params = 12 + name_len /* includes null */ ;
4411 pSMB->TotalDataCount = 0; /* no EAs */
4412 pSMB->MaxParameterCount = cpu_to_le16(10);
4413 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4414 pSMB->MaxSetupCount = 0;
4418 pSMB->Reserved2 = 0;
4419 byte_count = params + 1 /* pad */ ;
4420 pSMB->TotalParameterCount = cpu_to_le16(params);
4421 pSMB->ParameterCount = pSMB->TotalParameterCount;
4422 pSMB->ParameterOffset = cpu_to_le16(
4423 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4425 pSMB->DataCount = 0;
4426 pSMB->DataOffset = 0;
4427 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4428 pSMB->Reserved3 = 0;
4429 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4430 pSMB->SearchAttributes =
4431 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4433 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4434 pSMB->SearchFlags = cpu_to_le16(search_flags);
4435 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4437 /* BB what should we set StorageType to? Does it matter? BB */
4438 pSMB->SearchStorageType = 0;
4439 inc_rfc1001_len(pSMB, byte_count);
4440 pSMB->ByteCount = cpu_to_le16(byte_count);
4442 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4443 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4444 cifs_stats_inc(&tcon->num_ffirst);
4446 if (rc) {/* BB add logic to retry regular search if Unix search
4447 rejected unexpectedly by server */
4448 /* BB Add code to handle unsupported level rc */
4449 cFYI(1, "Error in FindFirst = %d", rc);
4451 cifs_buf_release(pSMB);
4453 /* BB eventually could optimize out free and realloc of buf */
4456 goto findFirstRetry;
4457 } else { /* decode response */
4458 /* BB remember to free buffer if error BB */
4459 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4463 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4464 psrch_inf->unicode = true;
4466 psrch_inf->unicode = false;
4468 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4469 psrch_inf->smallBuf = 0;
4470 psrch_inf->srch_entries_start =
4471 (char *) &pSMBr->hdr.Protocol +
4472 le16_to_cpu(pSMBr->t2.DataOffset);
4473 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4474 le16_to_cpu(pSMBr->t2.ParameterOffset));
4476 if (parms->EndofSearch)
4477 psrch_inf->endOfSearch = true;
4479 psrch_inf->endOfSearch = false;
4481 psrch_inf->entries_in_buffer =
4482 le16_to_cpu(parms->SearchCount);
4483 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4484 psrch_inf->entries_in_buffer;
4485 lnoff = le16_to_cpu(parms->LastNameOffset);
4486 if (CIFSMaxBufSize < lnoff) {
4487 cERROR(1, "ignoring corrupt resume name");
4488 psrch_inf->last_entry = NULL;
4492 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4495 *pnetfid = parms->SearchHandle;
4497 cifs_buf_release(pSMB);
4504 int CIFSFindNext(const int xid, struct cifs_tcon *tcon, __u16 searchHandle,
4505 __u16 search_flags, struct cifs_search_info *psrch_inf)
4507 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4508 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4509 T2_FNEXT_RSP_PARMS *parms;
4510 char *response_data;
4513 unsigned int name_len;
4514 __u16 params, byte_count;
4516 cFYI(1, "In FindNext");
4518 if (psrch_inf->endOfSearch)
4521 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4526 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4528 pSMB->TotalDataCount = 0; /* no EAs */
4529 pSMB->MaxParameterCount = cpu_to_le16(8);
4530 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4531 pSMB->MaxSetupCount = 0;
4535 pSMB->Reserved2 = 0;
4536 pSMB->ParameterOffset = cpu_to_le16(
4537 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4538 pSMB->DataCount = 0;
4539 pSMB->DataOffset = 0;
4540 pSMB->SetupCount = 1;
4541 pSMB->Reserved3 = 0;
4542 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4543 pSMB->SearchHandle = searchHandle; /* always kept as le */
4545 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4546 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4547 pSMB->ResumeKey = psrch_inf->resume_key;
4548 pSMB->SearchFlags = cpu_to_le16(search_flags);
4550 name_len = psrch_inf->resume_name_len;
4552 if (name_len < PATH_MAX) {
4553 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4554 byte_count += name_len;
4555 /* 14 byte parm len above enough for 2 byte null terminator */
4556 pSMB->ResumeFileName[name_len] = 0;
4557 pSMB->ResumeFileName[name_len+1] = 0;
4560 goto FNext2_err_exit;
4562 byte_count = params + 1 /* pad */ ;
4563 pSMB->TotalParameterCount = cpu_to_le16(params);
4564 pSMB->ParameterCount = pSMB->TotalParameterCount;
4565 inc_rfc1001_len(pSMB, byte_count);
4566 pSMB->ByteCount = cpu_to_le16(byte_count);
4568 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4569 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4570 cifs_stats_inc(&tcon->num_fnext);
4573 psrch_inf->endOfSearch = true;
4574 cifs_buf_release(pSMB);
4575 rc = 0; /* search probably was closed at end of search*/
4577 cFYI(1, "FindNext returned = %d", rc);
4578 } else { /* decode response */
4579 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4584 /* BB fixme add lock for file (srch_info) struct here */
4585 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4586 psrch_inf->unicode = true;
4588 psrch_inf->unicode = false;
4589 response_data = (char *) &pSMBr->hdr.Protocol +
4590 le16_to_cpu(pSMBr->t2.ParameterOffset);
4591 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4592 response_data = (char *)&pSMBr->hdr.Protocol +
4593 le16_to_cpu(pSMBr->t2.DataOffset);
4594 if (psrch_inf->smallBuf)
4595 cifs_small_buf_release(
4596 psrch_inf->ntwrk_buf_start);
4598 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4599 psrch_inf->srch_entries_start = response_data;
4600 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4601 psrch_inf->smallBuf = 0;
4602 if (parms->EndofSearch)
4603 psrch_inf->endOfSearch = true;
4605 psrch_inf->endOfSearch = false;
4606 psrch_inf->entries_in_buffer =
4607 le16_to_cpu(parms->SearchCount);
4608 psrch_inf->index_of_last_entry +=
4609 psrch_inf->entries_in_buffer;
4610 lnoff = le16_to_cpu(parms->LastNameOffset);
4611 if (CIFSMaxBufSize < lnoff) {
4612 cERROR(1, "ignoring corrupt resume name");
4613 psrch_inf->last_entry = NULL;
4616 psrch_inf->last_entry =
4617 psrch_inf->srch_entries_start + lnoff;
4619 /* cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
4620 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4622 /* BB fixme add unlock here */
4627 /* BB On error, should we leave previous search buf (and count and
4628 last entry fields) intact or free the previous one? */
4630 /* Note: On -EAGAIN error only caller can retry on handle based calls
4631 since file handle passed in no longer valid */
4634 cifs_buf_release(pSMB);
4639 CIFSFindClose(const int xid, struct cifs_tcon *tcon,
4640 const __u16 searchHandle)
4643 FINDCLOSE_REQ *pSMB = NULL;
4645 cFYI(1, "In CIFSSMBFindClose");
4646 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4648 /* no sense returning error if session restarted
4649 as file handle has been closed */
4655 pSMB->FileID = searchHandle;
4656 pSMB->ByteCount = 0;
4657 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4659 cERROR(1, "Send error in FindClose = %d", rc);
4661 cifs_stats_inc(&tcon->num_fclose);
4663 /* Since session is dead, search handle closed on server already */
4671 CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
4672 const unsigned char *searchName,
4673 __u64 *inode_number,
4674 const struct nls_table *nls_codepage, int remap)
4677 TRANSACTION2_QPI_REQ *pSMB = NULL;
4678 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4679 int name_len, bytes_returned;
4680 __u16 params, byte_count;
4682 cFYI(1, "In GetSrvInodeNum for %s", searchName);
4686 GetInodeNumberRetry:
4687 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4692 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4694 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4695 PATH_MAX, nls_codepage, remap);
4696 name_len++; /* trailing null */
4698 } else { /* BB improve the check for buffer overruns BB */
4699 name_len = strnlen(searchName, PATH_MAX);
4700 name_len++; /* trailing null */
4701 strncpy(pSMB->FileName, searchName, name_len);
4704 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4705 pSMB->TotalDataCount = 0;
4706 pSMB->MaxParameterCount = cpu_to_le16(2);
4707 /* BB find exact max data count below from sess structure BB */
4708 pSMB->MaxDataCount = cpu_to_le16(4000);
4709 pSMB->MaxSetupCount = 0;
4713 pSMB->Reserved2 = 0;
4714 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4715 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4716 pSMB->DataCount = 0;
4717 pSMB->DataOffset = 0;
4718 pSMB->SetupCount = 1;
4719 pSMB->Reserved3 = 0;
4720 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4721 byte_count = params + 1 /* pad */ ;
4722 pSMB->TotalParameterCount = cpu_to_le16(params);
4723 pSMB->ParameterCount = pSMB->TotalParameterCount;
4724 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4725 pSMB->Reserved4 = 0;
4726 inc_rfc1001_len(pSMB, byte_count);
4727 pSMB->ByteCount = cpu_to_le16(byte_count);
4729 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4730 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4732 cFYI(1, "error %d in QueryInternalInfo", rc);
4734 /* decode response */
4735 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4736 /* BB also check enough total bytes returned */
4737 if (rc || get_bcc(&pSMBr->hdr) < 2)
4738 /* If rc should we check for EOPNOSUPP and
4739 disable the srvino flag? or in caller? */
4740 rc = -EIO; /* bad smb */
4742 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4743 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4744 struct file_internal_info *pfinfo;
4745 /* BB Do we need a cast or hash here ? */
4747 cFYI(1, "Illegal size ret in QryIntrnlInf");
4749 goto GetInodeNumOut;
4751 pfinfo = (struct file_internal_info *)
4752 (data_offset + (char *) &pSMBr->hdr.Protocol);
4753 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4757 cifs_buf_release(pSMB);
4759 goto GetInodeNumberRetry;
4763 /* parses DFS refferal V3 structure
4764 * caller is responsible for freeing target_nodes
4767 * on failure - errno
4770 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4771 unsigned int *num_of_nodes,
4772 struct dfs_info3_param **target_nodes,
4773 const struct nls_table *nls_codepage, int remap,
4774 const char *searchName)
4779 struct dfs_referral_level_3 *ref;
4781 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4785 *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4787 if (*num_of_nodes < 1) {
4788 cERROR(1, "num_referrals: must be at least > 0,"
4789 "but we get num_referrals = %d\n", *num_of_nodes);
4791 goto parse_DFS_referrals_exit;
4794 ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4795 if (ref->VersionNumber != cpu_to_le16(3)) {
4796 cERROR(1, "Referrals of V%d version are not supported,"
4797 "should be V3", le16_to_cpu(ref->VersionNumber));
4799 goto parse_DFS_referrals_exit;
4802 /* get the upper boundary of the resp buffer */
4803 data_end = (char *)(&(pSMBr->PathConsumed)) +
4804 le16_to_cpu(pSMBr->t2.DataCount);
4806 cFYI(1, "num_referrals: %d dfs flags: 0x%x ...\n",
4808 le32_to_cpu(pSMBr->DFSFlags));
4810 *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
4811 *num_of_nodes, GFP_KERNEL);
4812 if (*target_nodes == NULL) {
4813 cERROR(1, "Failed to allocate buffer for target_nodes\n");
4815 goto parse_DFS_referrals_exit;
4818 /* collect necessary data from referrals */
4819 for (i = 0; i < *num_of_nodes; i++) {
4822 struct dfs_info3_param *node = (*target_nodes)+i;
4824 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4826 __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4830 goto parse_DFS_referrals_exit;
4832 cifsConvertToUCS((__le16 *) tmp, searchName,
4833 PATH_MAX, nls_codepage, remap);
4834 node->path_consumed = cifs_ucs2_bytes(tmp,
4835 le16_to_cpu(pSMBr->PathConsumed),
4839 node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4841 node->server_type = le16_to_cpu(ref->ServerType);
4842 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4845 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4846 max_len = data_end - temp;
4847 node->path_name = cifs_strndup_from_ucs(temp, max_len,
4848 is_unicode, nls_codepage);
4849 if (!node->path_name) {
4851 goto parse_DFS_referrals_exit;
4854 /* copy link target UNC */
4855 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4856 max_len = data_end - temp;
4857 node->node_name = cifs_strndup_from_ucs(temp, max_len,
4858 is_unicode, nls_codepage);
4859 if (!node->node_name) {
4861 goto parse_DFS_referrals_exit;
4867 parse_DFS_referrals_exit:
4869 free_dfs_info_array(*target_nodes, *num_of_nodes);
4870 *target_nodes = NULL;
4877 CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
4878 const unsigned char *searchName,
4879 struct dfs_info3_param **target_nodes,
4880 unsigned int *num_of_nodes,
4881 const struct nls_table *nls_codepage, int remap)
4883 /* TRANS2_GET_DFS_REFERRAL */
4884 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4885 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4889 __u16 params, byte_count;
4891 *target_nodes = NULL;
4893 cFYI(1, "In GetDFSRefer the path %s", searchName);
4897 rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4902 /* server pointer checked in called function,
4903 but should never be null here anyway */
4904 pSMB->hdr.Mid = GetNextMid(ses->server);
4905 pSMB->hdr.Tid = ses->ipc_tid;
4906 pSMB->hdr.Uid = ses->Suid;
4907 if (ses->capabilities & CAP_STATUS32)
4908 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4909 if (ses->capabilities & CAP_DFS)
4910 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4912 if (ses->capabilities & CAP_UNICODE) {
4913 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4915 cifsConvertToUCS((__le16 *) pSMB->RequestFileName,
4916 searchName, PATH_MAX, nls_codepage, remap);
4917 name_len++; /* trailing null */
4919 } else { /* BB improve the check for buffer overruns BB */
4920 name_len = strnlen(searchName, PATH_MAX);
4921 name_len++; /* trailing null */
4922 strncpy(pSMB->RequestFileName, searchName, name_len);
4926 if (ses->server->sec_mode &
4927 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4928 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4931 pSMB->hdr.Uid = ses->Suid;
4933 params = 2 /* level */ + name_len /*includes null */ ;
4934 pSMB->TotalDataCount = 0;
4935 pSMB->DataCount = 0;
4936 pSMB->DataOffset = 0;
4937 pSMB->MaxParameterCount = 0;
4938 /* BB find exact max SMB PDU from sess structure BB */
4939 pSMB->MaxDataCount = cpu_to_le16(4000);
4940 pSMB->MaxSetupCount = 0;
4944 pSMB->Reserved2 = 0;
4945 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4946 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4947 pSMB->SetupCount = 1;
4948 pSMB->Reserved3 = 0;
4949 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4950 byte_count = params + 3 /* pad */ ;
4951 pSMB->ParameterCount = cpu_to_le16(params);
4952 pSMB->TotalParameterCount = pSMB->ParameterCount;
4953 pSMB->MaxReferralLevel = cpu_to_le16(3);
4954 inc_rfc1001_len(pSMB, byte_count);
4955 pSMB->ByteCount = cpu_to_le16(byte_count);
4957 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4958 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4960 cFYI(1, "Send error in GetDFSRefer = %d", rc);
4963 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4965 /* BB Also check if enough total bytes returned? */
4966 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4967 rc = -EIO; /* bad smb */
4971 cFYI(1, "Decoding GetDFSRefer response BCC: %d Offset %d",
4972 get_bcc(&pSMBr->hdr),
4973 le16_to_cpu(pSMBr->t2.DataOffset));
4975 /* parse returned result into more usable form */
4976 rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4977 target_nodes, nls_codepage, remap,
4981 cifs_buf_release(pSMB);
4989 /* Query File System Info such as free space to old servers such as Win 9x */
4991 SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4993 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4994 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4995 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4996 FILE_SYSTEM_ALLOC_INFO *response_data;
4998 int bytes_returned = 0;
4999 __u16 params, byte_count;
5001 cFYI(1, "OldQFSInfo");
5003 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5008 params = 2; /* level */
5009 pSMB->TotalDataCount = 0;
5010 pSMB->MaxParameterCount = cpu_to_le16(2);
5011 pSMB->MaxDataCount = cpu_to_le16(1000);
5012 pSMB->MaxSetupCount = 0;
5016 pSMB->Reserved2 = 0;
5017 byte_count = params + 1 /* pad */ ;
5018 pSMB->TotalParameterCount = cpu_to_le16(params);
5019 pSMB->ParameterCount = pSMB->TotalParameterCount;
5020 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5021 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5022 pSMB->DataCount = 0;
5023 pSMB->DataOffset = 0;
5024 pSMB->SetupCount = 1;
5025 pSMB->Reserved3 = 0;
5026 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5027 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
5028 inc_rfc1001_len(pSMB, byte_count);
5029 pSMB->ByteCount = cpu_to_le16(byte_count);
5031 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5032 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5034 cFYI(1, "Send error in QFSInfo = %d", rc);
5035 } else { /* decode response */
5036 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5038 if (rc || get_bcc(&pSMBr->hdr) < 18)
5039 rc = -EIO; /* bad smb */
5041 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5042 cFYI(1, "qfsinf resp BCC: %d Offset %d",
5043 get_bcc(&pSMBr->hdr), data_offset);
5045 response_data = (FILE_SYSTEM_ALLOC_INFO *)
5046 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5048 le16_to_cpu(response_data->BytesPerSector) *
5049 le32_to_cpu(response_data->
5050 SectorsPerAllocationUnit);
5052 le32_to_cpu(response_data->TotalAllocationUnits);
5053 FSData->f_bfree = FSData->f_bavail =
5054 le32_to_cpu(response_data->FreeAllocationUnits);
5055 cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
5056 (unsigned long long)FSData->f_blocks,
5057 (unsigned long long)FSData->f_bfree,
5061 cifs_buf_release(pSMB);
5064 goto oldQFSInfoRetry;
5070 CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
5072 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5073 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5074 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5075 FILE_SYSTEM_INFO *response_data;
5077 int bytes_returned = 0;
5078 __u16 params, byte_count;
5080 cFYI(1, "In QFSInfo");
5082 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5087 params = 2; /* level */
5088 pSMB->TotalDataCount = 0;
5089 pSMB->MaxParameterCount = cpu_to_le16(2);
5090 pSMB->MaxDataCount = cpu_to_le16(1000);
5091 pSMB->MaxSetupCount = 0;
5095 pSMB->Reserved2 = 0;
5096 byte_count = params + 1 /* pad */ ;
5097 pSMB->TotalParameterCount = cpu_to_le16(params);
5098 pSMB->ParameterCount = pSMB->TotalParameterCount;
5099 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5100 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5101 pSMB->DataCount = 0;
5102 pSMB->DataOffset = 0;
5103 pSMB->SetupCount = 1;
5104 pSMB->Reserved3 = 0;
5105 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5106 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5107 inc_rfc1001_len(pSMB, byte_count);
5108 pSMB->ByteCount = cpu_to_le16(byte_count);
5110 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5111 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5113 cFYI(1, "Send error in QFSInfo = %d", rc);
5114 } else { /* decode response */
5115 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5117 if (rc || get_bcc(&pSMBr->hdr) < 24)
5118 rc = -EIO; /* bad smb */
5120 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5124 *) (((char *) &pSMBr->hdr.Protocol) +
5127 le32_to_cpu(response_data->BytesPerSector) *
5128 le32_to_cpu(response_data->
5129 SectorsPerAllocationUnit);
5131 le64_to_cpu(response_data->TotalAllocationUnits);
5132 FSData->f_bfree = FSData->f_bavail =
5133 le64_to_cpu(response_data->FreeAllocationUnits);
5134 cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
5135 (unsigned long long)FSData->f_blocks,
5136 (unsigned long long)FSData->f_bfree,
5140 cifs_buf_release(pSMB);
5149 CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
5151 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5152 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5153 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5154 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5156 int bytes_returned = 0;
5157 __u16 params, byte_count;
5159 cFYI(1, "In QFSAttributeInfo");
5161 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5166 params = 2; /* level */
5167 pSMB->TotalDataCount = 0;
5168 pSMB->MaxParameterCount = cpu_to_le16(2);
5169 /* BB find exact max SMB PDU from sess structure BB */
5170 pSMB->MaxDataCount = cpu_to_le16(1000);
5171 pSMB->MaxSetupCount = 0;
5175 pSMB->Reserved2 = 0;
5176 byte_count = params + 1 /* pad */ ;
5177 pSMB->TotalParameterCount = cpu_to_le16(params);
5178 pSMB->ParameterCount = pSMB->TotalParameterCount;
5179 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5180 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5181 pSMB->DataCount = 0;
5182 pSMB->DataOffset = 0;
5183 pSMB->SetupCount = 1;
5184 pSMB->Reserved3 = 0;
5185 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5186 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5187 inc_rfc1001_len(pSMB, byte_count);
5188 pSMB->ByteCount = cpu_to_le16(byte_count);
5190 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5191 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5193 cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
5194 } else { /* decode response */
5195 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5197 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5198 /* BB also check if enough bytes returned */
5199 rc = -EIO; /* bad smb */
5201 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5203 (FILE_SYSTEM_ATTRIBUTE_INFO
5204 *) (((char *) &pSMBr->hdr.Protocol) +
5206 memcpy(&tcon->fsAttrInfo, response_data,
5207 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5210 cifs_buf_release(pSMB);
5213 goto QFSAttributeRetry;
5219 CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
5221 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5222 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5223 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5224 FILE_SYSTEM_DEVICE_INFO *response_data;
5226 int bytes_returned = 0;
5227 __u16 params, byte_count;
5229 cFYI(1, "In QFSDeviceInfo");
5231 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5236 params = 2; /* level */
5237 pSMB->TotalDataCount = 0;
5238 pSMB->MaxParameterCount = cpu_to_le16(2);
5239 /* BB find exact max SMB PDU from sess structure BB */
5240 pSMB->MaxDataCount = cpu_to_le16(1000);
5241 pSMB->MaxSetupCount = 0;
5245 pSMB->Reserved2 = 0;
5246 byte_count = params + 1 /* pad */ ;
5247 pSMB->TotalParameterCount = cpu_to_le16(params);
5248 pSMB->ParameterCount = pSMB->TotalParameterCount;
5249 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5250 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5252 pSMB->DataCount = 0;
5253 pSMB->DataOffset = 0;
5254 pSMB->SetupCount = 1;
5255 pSMB->Reserved3 = 0;
5256 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5257 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5258 inc_rfc1001_len(pSMB, byte_count);
5259 pSMB->ByteCount = cpu_to_le16(byte_count);
5261 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5262 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5264 cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
5265 } else { /* decode response */
5266 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5268 if (rc || get_bcc(&pSMBr->hdr) <
5269 sizeof(FILE_SYSTEM_DEVICE_INFO))
5270 rc = -EIO; /* bad smb */
5272 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5274 (FILE_SYSTEM_DEVICE_INFO *)
5275 (((char *) &pSMBr->hdr.Protocol) +
5277 memcpy(&tcon->fsDevInfo, response_data,
5278 sizeof(FILE_SYSTEM_DEVICE_INFO));
5281 cifs_buf_release(pSMB);
5284 goto QFSDeviceRetry;
5290 CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
5292 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5293 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5294 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5295 FILE_SYSTEM_UNIX_INFO *response_data;
5297 int bytes_returned = 0;
5298 __u16 params, byte_count;
5300 cFYI(1, "In QFSUnixInfo");
5302 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5303 (void **) &pSMB, (void **) &pSMBr);
5307 params = 2; /* level */
5308 pSMB->TotalDataCount = 0;
5309 pSMB->DataCount = 0;
5310 pSMB->DataOffset = 0;
5311 pSMB->MaxParameterCount = cpu_to_le16(2);
5312 /* BB find exact max SMB PDU from sess structure BB */
5313 pSMB->MaxDataCount = cpu_to_le16(100);
5314 pSMB->MaxSetupCount = 0;
5318 pSMB->Reserved2 = 0;
5319 byte_count = params + 1 /* pad */ ;
5320 pSMB->ParameterCount = cpu_to_le16(params);
5321 pSMB->TotalParameterCount = pSMB->ParameterCount;
5322 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5323 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5324 pSMB->SetupCount = 1;
5325 pSMB->Reserved3 = 0;
5326 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5327 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5328 inc_rfc1001_len(pSMB, byte_count);
5329 pSMB->ByteCount = cpu_to_le16(byte_count);
5331 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5332 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5334 cERROR(1, "Send error in QFSUnixInfo = %d", rc);
5335 } else { /* decode response */
5336 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5338 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5339 rc = -EIO; /* bad smb */
5341 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5343 (FILE_SYSTEM_UNIX_INFO
5344 *) (((char *) &pSMBr->hdr.Protocol) +
5346 memcpy(&tcon->fsUnixInfo, response_data,
5347 sizeof(FILE_SYSTEM_UNIX_INFO));
5350 cifs_buf_release(pSMB);
5360 CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
5362 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5363 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5364 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5366 int bytes_returned = 0;
5367 __u16 params, param_offset, offset, byte_count;
5369 cFYI(1, "In SETFSUnixInfo");
5371 /* BB switch to small buf init to save memory */
5372 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5373 (void **) &pSMB, (void **) &pSMBr);
5377 params = 4; /* 2 bytes zero followed by info level. */
5378 pSMB->MaxSetupCount = 0;
5382 pSMB->Reserved2 = 0;
5383 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5385 offset = param_offset + params;
5387 pSMB->MaxParameterCount = cpu_to_le16(4);
5388 /* BB find exact max SMB PDU from sess structure BB */
5389 pSMB->MaxDataCount = cpu_to_le16(100);
5390 pSMB->SetupCount = 1;
5391 pSMB->Reserved3 = 0;
5392 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5393 byte_count = 1 /* pad */ + params + 12;
5395 pSMB->DataCount = cpu_to_le16(12);
5396 pSMB->ParameterCount = cpu_to_le16(params);
5397 pSMB->TotalDataCount = pSMB->DataCount;
5398 pSMB->TotalParameterCount = pSMB->ParameterCount;
5399 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5400 pSMB->DataOffset = cpu_to_le16(offset);
5404 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5407 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5408 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5409 pSMB->ClientUnixCap = cpu_to_le64(cap);
5411 inc_rfc1001_len(pSMB, byte_count);
5412 pSMB->ByteCount = cpu_to_le16(byte_count);
5414 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5415 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5417 cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
5418 } else { /* decode response */
5419 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5421 rc = -EIO; /* bad smb */
5423 cifs_buf_release(pSMB);
5426 goto SETFSUnixRetry;
5434 CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
5435 struct kstatfs *FSData)
5437 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5438 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5439 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5440 FILE_SYSTEM_POSIX_INFO *response_data;
5442 int bytes_returned = 0;
5443 __u16 params, byte_count;
5445 cFYI(1, "In QFSPosixInfo");
5447 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5452 params = 2; /* level */
5453 pSMB->TotalDataCount = 0;
5454 pSMB->DataCount = 0;
5455 pSMB->DataOffset = 0;
5456 pSMB->MaxParameterCount = cpu_to_le16(2);
5457 /* BB find exact max SMB PDU from sess structure BB */
5458 pSMB->MaxDataCount = cpu_to_le16(100);
5459 pSMB->MaxSetupCount = 0;
5463 pSMB->Reserved2 = 0;
5464 byte_count = params + 1 /* pad */ ;
5465 pSMB->ParameterCount = cpu_to_le16(params);
5466 pSMB->TotalParameterCount = pSMB->ParameterCount;
5467 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5468 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5469 pSMB->SetupCount = 1;
5470 pSMB->Reserved3 = 0;
5471 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5472 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5473 inc_rfc1001_len(pSMB, byte_count);
5474 pSMB->ByteCount = cpu_to_le16(byte_count);
5476 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5477 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5479 cFYI(1, "Send error in QFSUnixInfo = %d", rc);
5480 } else { /* decode response */
5481 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5483 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5484 rc = -EIO; /* bad smb */
5486 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5488 (FILE_SYSTEM_POSIX_INFO
5489 *) (((char *) &pSMBr->hdr.Protocol) +
5492 le32_to_cpu(response_data->BlockSize);
5494 le64_to_cpu(response_data->TotalBlocks);
5496 le64_to_cpu(response_data->BlocksAvail);
5497 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5498 FSData->f_bavail = FSData->f_bfree;
5501 le64_to_cpu(response_data->UserBlocksAvail);
5503 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5505 le64_to_cpu(response_data->TotalFileNodes);
5506 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5508 le64_to_cpu(response_data->FreeFileNodes);
5511 cifs_buf_release(pSMB);
5520 /* We can not use write of zero bytes trick to
5521 set file size due to need for large file support. Also note that
5522 this SetPathInfo is preferred to SetFileInfo based method in next
5523 routine which is only needed to work around a sharing violation bug
5524 in Samba which this routine can run into */
5527 CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
5528 __u64 size, bool SetAllocation,
5529 const struct nls_table *nls_codepage, int remap)
5531 struct smb_com_transaction2_spi_req *pSMB = NULL;
5532 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5533 struct file_end_of_file_info *parm_data;
5536 int bytes_returned = 0;
5537 __u16 params, byte_count, data_count, param_offset, offset;
5539 cFYI(1, "In SetEOF");
5541 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5546 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5548 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
5549 PATH_MAX, nls_codepage, remap);
5550 name_len++; /* trailing null */
5552 } else { /* BB improve the check for buffer overruns BB */
5553 name_len = strnlen(fileName, PATH_MAX);
5554 name_len++; /* trailing null */
5555 strncpy(pSMB->FileName, fileName, name_len);
5557 params = 6 + name_len;
5558 data_count = sizeof(struct file_end_of_file_info);
5559 pSMB->MaxParameterCount = cpu_to_le16(2);
5560 pSMB->MaxDataCount = cpu_to_le16(4100);
5561 pSMB->MaxSetupCount = 0;
5565 pSMB->Reserved2 = 0;
5566 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5567 InformationLevel) - 4;
5568 offset = param_offset + params;
5569 if (SetAllocation) {
5570 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5571 pSMB->InformationLevel =
5572 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5574 pSMB->InformationLevel =
5575 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5576 } else /* Set File Size */ {
5577 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5578 pSMB->InformationLevel =
5579 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5581 pSMB->InformationLevel =
5582 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5586 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5588 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5589 pSMB->DataOffset = cpu_to_le16(offset);
5590 pSMB->SetupCount = 1;
5591 pSMB->Reserved3 = 0;
5592 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5593 byte_count = 3 /* pad */ + params + data_count;
5594 pSMB->DataCount = cpu_to_le16(data_count);
5595 pSMB->TotalDataCount = pSMB->DataCount;
5596 pSMB->ParameterCount = cpu_to_le16(params);
5597 pSMB->TotalParameterCount = pSMB->ParameterCount;
5598 pSMB->Reserved4 = 0;
5599 inc_rfc1001_len(pSMB, byte_count);
5600 parm_data->FileSize = cpu_to_le64(size);
5601 pSMB->ByteCount = cpu_to_le16(byte_count);
5602 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5603 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5605 cFYI(1, "SetPathInfo (file size) returned %d", rc);
5607 cifs_buf_release(pSMB);
5616 CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
5617 __u16 fid, __u32 pid_of_opener, bool SetAllocation)
5619 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5620 struct file_end_of_file_info *parm_data;
5622 __u16 params, param_offset, offset, byte_count, count;
5624 cFYI(1, "SetFileSize (via SetFileInfo) %lld",
5626 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5631 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5632 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5635 pSMB->MaxSetupCount = 0;
5639 pSMB->Reserved2 = 0;
5640 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5641 offset = param_offset + params;
5643 count = sizeof(struct file_end_of_file_info);
5644 pSMB->MaxParameterCount = cpu_to_le16(2);
5645 /* BB find exact max SMB PDU from sess structure BB */
5646 pSMB->MaxDataCount = cpu_to_le16(1000);
5647 pSMB->SetupCount = 1;
5648 pSMB->Reserved3 = 0;
5649 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5650 byte_count = 3 /* pad */ + params + count;
5651 pSMB->DataCount = cpu_to_le16(count);
5652 pSMB->ParameterCount = cpu_to_le16(params);
5653 pSMB->TotalDataCount = pSMB->DataCount;
5654 pSMB->TotalParameterCount = pSMB->ParameterCount;
5655 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5657 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5659 pSMB->DataOffset = cpu_to_le16(offset);
5660 parm_data->FileSize = cpu_to_le64(size);
5662 if (SetAllocation) {
5663 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5664 pSMB->InformationLevel =
5665 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5667 pSMB->InformationLevel =
5668 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5669 } else /* Set File Size */ {
5670 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5671 pSMB->InformationLevel =
5672 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5674 pSMB->InformationLevel =
5675 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5677 pSMB->Reserved4 = 0;
5678 inc_rfc1001_len(pSMB, byte_count);
5679 pSMB->ByteCount = cpu_to_le16(byte_count);
5680 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5682 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
5685 /* Note: On -EAGAIN error only caller can retry on handle based calls
5686 since file handle passed in no longer valid */
5691 /* Some legacy servers such as NT4 require that the file times be set on
5692 an open handle, rather than by pathname - this is awkward due to
5693 potential access conflicts on the open, but it is unavoidable for these
5694 old servers since the only other choice is to go from 100 nanosecond DCE
5695 time and resort to the original setpathinfo level which takes the ancient
5696 DOS time format with 2 second granularity */
5698 CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
5699 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5701 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5704 __u16 params, param_offset, offset, byte_count, count;
5706 cFYI(1, "Set Times (via SetFileInfo)");
5707 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5712 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5713 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5716 pSMB->MaxSetupCount = 0;
5720 pSMB->Reserved2 = 0;
5721 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5722 offset = param_offset + params;
5724 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5726 count = sizeof(FILE_BASIC_INFO);
5727 pSMB->MaxParameterCount = cpu_to_le16(2);
5728 /* BB find max SMB PDU from sess */
5729 pSMB->MaxDataCount = cpu_to_le16(1000);
5730 pSMB->SetupCount = 1;
5731 pSMB->Reserved3 = 0;
5732 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5733 byte_count = 3 /* pad */ + params + count;
5734 pSMB->DataCount = cpu_to_le16(count);
5735 pSMB->ParameterCount = cpu_to_le16(params);
5736 pSMB->TotalDataCount = pSMB->DataCount;
5737 pSMB->TotalParameterCount = pSMB->ParameterCount;
5738 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5739 pSMB->DataOffset = cpu_to_le16(offset);
5741 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5742 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5744 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5745 pSMB->Reserved4 = 0;
5746 inc_rfc1001_len(pSMB, byte_count);
5747 pSMB->ByteCount = cpu_to_le16(byte_count);
5748 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5749 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5751 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5753 /* Note: On -EAGAIN error only caller can retry on handle based calls
5754 since file handle passed in no longer valid */
5760 CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
5761 bool delete_file, __u16 fid, __u32 pid_of_opener)
5763 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5766 __u16 params, param_offset, offset, byte_count, count;
5768 cFYI(1, "Set File Disposition (via SetFileInfo)");
5769 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5774 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5775 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5778 pSMB->MaxSetupCount = 0;
5782 pSMB->Reserved2 = 0;
5783 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5784 offset = param_offset + params;
5786 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5789 pSMB->MaxParameterCount = cpu_to_le16(2);
5790 /* BB find max SMB PDU from sess */
5791 pSMB->MaxDataCount = cpu_to_le16(1000);
5792 pSMB->SetupCount = 1;
5793 pSMB->Reserved3 = 0;
5794 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5795 byte_count = 3 /* pad */ + params + count;
5796 pSMB->DataCount = cpu_to_le16(count);
5797 pSMB->ParameterCount = cpu_to_le16(params);
5798 pSMB->TotalDataCount = pSMB->DataCount;
5799 pSMB->TotalParameterCount = pSMB->ParameterCount;
5800 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5801 pSMB->DataOffset = cpu_to_le16(offset);
5803 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5804 pSMB->Reserved4 = 0;
5805 inc_rfc1001_len(pSMB, byte_count);
5806 pSMB->ByteCount = cpu_to_le16(byte_count);
5807 *data_offset = delete_file ? 1 : 0;
5808 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5810 cFYI(1, "Send error in SetFileDisposition = %d", rc);
5816 CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
5817 const char *fileName, const FILE_BASIC_INFO *data,
5818 const struct nls_table *nls_codepage, int remap)
5820 TRANSACTION2_SPI_REQ *pSMB = NULL;
5821 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5824 int bytes_returned = 0;
5826 __u16 params, param_offset, offset, byte_count, count;
5828 cFYI(1, "In SetTimes");
5831 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5836 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5838 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
5839 PATH_MAX, nls_codepage, remap);
5840 name_len++; /* trailing null */
5842 } else { /* BB improve the check for buffer overruns BB */
5843 name_len = strnlen(fileName, PATH_MAX);
5844 name_len++; /* trailing null */
5845 strncpy(pSMB->FileName, fileName, name_len);
5848 params = 6 + name_len;
5849 count = sizeof(FILE_BASIC_INFO);
5850 pSMB->MaxParameterCount = cpu_to_le16(2);
5851 /* BB find max SMB PDU from sess structure BB */
5852 pSMB->MaxDataCount = cpu_to_le16(1000);
5853 pSMB->MaxSetupCount = 0;
5857 pSMB->Reserved2 = 0;
5858 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5859 InformationLevel) - 4;
5860 offset = param_offset + params;
5861 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5862 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5863 pSMB->DataOffset = cpu_to_le16(offset);
5864 pSMB->SetupCount = 1;
5865 pSMB->Reserved3 = 0;
5866 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5867 byte_count = 3 /* pad */ + params + count;
5869 pSMB->DataCount = cpu_to_le16(count);
5870 pSMB->ParameterCount = cpu_to_le16(params);
5871 pSMB->TotalDataCount = pSMB->DataCount;
5872 pSMB->TotalParameterCount = pSMB->ParameterCount;
5873 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5874 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5876 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5877 pSMB->Reserved4 = 0;
5878 inc_rfc1001_len(pSMB, byte_count);
5879 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5880 pSMB->ByteCount = cpu_to_le16(byte_count);
5881 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5882 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5884 cFYI(1, "SetPathInfo (times) returned %d", rc);
5886 cifs_buf_release(pSMB);
5894 /* Can not be used to set time stamps yet (due to old DOS time format) */
5895 /* Can be used to set attributes */
5896 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5897 handling it anyway and NT4 was what we thought it would be needed for
5898 Do not delete it until we prove whether needed for Win9x though */
5900 CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon, char *fileName,
5901 __u16 dos_attrs, const struct nls_table *nls_codepage)
5903 SETATTR_REQ *pSMB = NULL;
5904 SETATTR_RSP *pSMBr = NULL;
5909 cFYI(1, "In SetAttrLegacy");
5912 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5917 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5919 ConvertToUCS((__le16 *) pSMB->fileName, fileName,
5920 PATH_MAX, nls_codepage);
5921 name_len++; /* trailing null */
5923 } else { /* BB improve the check for buffer overruns BB */
5924 name_len = strnlen(fileName, PATH_MAX);
5925 name_len++; /* trailing null */
5926 strncpy(pSMB->fileName, fileName, name_len);
5928 pSMB->attr = cpu_to_le16(dos_attrs);
5929 pSMB->BufferFormat = 0x04;
5930 inc_rfc1001_len(pSMB, name_len + 1);
5931 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5932 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5933 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5935 cFYI(1, "Error in LegacySetAttr = %d", rc);
5937 cifs_buf_release(pSMB);
5940 goto SetAttrLgcyRetry;
5944 #endif /* temporarily unneeded SetAttr legacy function */
5947 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5948 const struct cifs_unix_set_info_args *args)
5950 u64 mode = args->mode;
5953 * Samba server ignores set of file size to zero due to bugs in some
5954 * older clients, but we should be precise - we use SetFileSize to
5955 * set file size and do not want to truncate file size to zero
5956 * accidentally as happened on one Samba server beta by putting
5957 * zero instead of -1 here
5959 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5960 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5961 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5962 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5963 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5964 data_offset->Uid = cpu_to_le64(args->uid);
5965 data_offset->Gid = cpu_to_le64(args->gid);
5966 /* better to leave device as zero when it is */
5967 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5968 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5969 data_offset->Permissions = cpu_to_le64(mode);
5972 data_offset->Type = cpu_to_le32(UNIX_FILE);
5973 else if (S_ISDIR(mode))
5974 data_offset->Type = cpu_to_le32(UNIX_DIR);
5975 else if (S_ISLNK(mode))
5976 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5977 else if (S_ISCHR(mode))
5978 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5979 else if (S_ISBLK(mode))
5980 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5981 else if (S_ISFIFO(mode))
5982 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5983 else if (S_ISSOCK(mode))
5984 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5988 CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
5989 const struct cifs_unix_set_info_args *args,
5990 u16 fid, u32 pid_of_opener)
5992 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5993 FILE_UNIX_BASIC_INFO *data_offset;
5995 u16 params, param_offset, offset, byte_count, count;
5997 cFYI(1, "Set Unix Info (via SetFileInfo)");
5998 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
6003 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
6004 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
6007 pSMB->MaxSetupCount = 0;
6011 pSMB->Reserved2 = 0;
6012 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
6013 offset = param_offset + params;
6015 data_offset = (FILE_UNIX_BASIC_INFO *)
6016 ((char *)(&pSMB->hdr.Protocol) + offset);
6017 count = sizeof(FILE_UNIX_BASIC_INFO);
6019 pSMB->MaxParameterCount = cpu_to_le16(2);
6020 /* BB find max SMB PDU from sess */
6021 pSMB->MaxDataCount = cpu_to_le16(1000);
6022 pSMB->SetupCount = 1;
6023 pSMB->Reserved3 = 0;
6024 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
6025 byte_count = 3 /* pad */ + params + count;
6026 pSMB->DataCount = cpu_to_le16(count);
6027 pSMB->ParameterCount = cpu_to_le16(params);
6028 pSMB->TotalDataCount = pSMB->DataCount;
6029 pSMB->TotalParameterCount = pSMB->ParameterCount;
6030 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6031 pSMB->DataOffset = cpu_to_le16(offset);
6033 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6034 pSMB->Reserved4 = 0;
6035 inc_rfc1001_len(pSMB, byte_count);
6036 pSMB->ByteCount = cpu_to_le16(byte_count);
6038 cifs_fill_unix_set_info(data_offset, args);
6040 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
6042 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
6044 /* Note: On -EAGAIN error only caller can retry on handle based calls
6045 since file handle passed in no longer valid */
6051 CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *tcon, char *fileName,
6052 const struct cifs_unix_set_info_args *args,
6053 const struct nls_table *nls_codepage, int remap)
6055 TRANSACTION2_SPI_REQ *pSMB = NULL;
6056 TRANSACTION2_SPI_RSP *pSMBr = NULL;
6059 int bytes_returned = 0;
6060 FILE_UNIX_BASIC_INFO *data_offset;
6061 __u16 params, param_offset, offset, count, byte_count;
6063 cFYI(1, "In SetUID/GID/Mode");
6065 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6070 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6072 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
6073 PATH_MAX, nls_codepage, remap);
6074 name_len++; /* trailing null */
6076 } else { /* BB improve the check for buffer overruns BB */
6077 name_len = strnlen(fileName, PATH_MAX);
6078 name_len++; /* trailing null */
6079 strncpy(pSMB->FileName, fileName, name_len);
6082 params = 6 + name_len;
6083 count = sizeof(FILE_UNIX_BASIC_INFO);
6084 pSMB->MaxParameterCount = cpu_to_le16(2);
6085 /* BB find max SMB PDU from sess structure BB */
6086 pSMB->MaxDataCount = cpu_to_le16(1000);
6087 pSMB->MaxSetupCount = 0;
6091 pSMB->Reserved2 = 0;
6092 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6093 InformationLevel) - 4;
6094 offset = param_offset + params;
6096 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6098 memset(data_offset, 0, count);
6099 pSMB->DataOffset = cpu_to_le16(offset);
6100 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6101 pSMB->SetupCount = 1;
6102 pSMB->Reserved3 = 0;
6103 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6104 byte_count = 3 /* pad */ + params + count;
6105 pSMB->ParameterCount = cpu_to_le16(params);
6106 pSMB->DataCount = cpu_to_le16(count);
6107 pSMB->TotalParameterCount = pSMB->ParameterCount;
6108 pSMB->TotalDataCount = pSMB->DataCount;
6109 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6110 pSMB->Reserved4 = 0;
6111 inc_rfc1001_len(pSMB, byte_count);
6113 cifs_fill_unix_set_info(data_offset, args);
6115 pSMB->ByteCount = cpu_to_le16(byte_count);
6116 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6117 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6119 cFYI(1, "SetPathInfo (perms) returned %d", rc);
6121 cifs_buf_release(pSMB);
6127 #ifdef CONFIG_CIFS_XATTR
6129 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6130 * function used by listxattr and getxattr type calls. When ea_name is set,
6131 * it looks for that attribute name and stuffs that value into the EAData
6132 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6133 * buffer. In both cases, the return value is either the length of the
6134 * resulting data or a negative error code. If EAData is a NULL pointer then
6135 * the data isn't copied to it, but the length is returned.
6138 CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
6139 const unsigned char *searchName, const unsigned char *ea_name,
6140 char *EAData, size_t buf_size,
6141 const struct nls_table *nls_codepage, int remap)
6143 /* BB assumes one setup word */
6144 TRANSACTION2_QPI_REQ *pSMB = NULL;
6145 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6149 struct fealist *ea_response_data;
6150 struct fea *temp_fea;
6153 __u16 params, byte_count, data_offset;
6154 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6156 cFYI(1, "In Query All EAs path %s", searchName);
6158 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6163 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6165 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
6166 PATH_MAX, nls_codepage, remap);
6167 list_len++; /* trailing null */
6169 } else { /* BB improve the check for buffer overruns BB */
6170 list_len = strnlen(searchName, PATH_MAX);
6171 list_len++; /* trailing null */
6172 strncpy(pSMB->FileName, searchName, list_len);
6175 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6176 pSMB->TotalDataCount = 0;
6177 pSMB->MaxParameterCount = cpu_to_le16(2);
6178 /* BB find exact max SMB PDU from sess structure BB */
6179 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6180 pSMB->MaxSetupCount = 0;
6184 pSMB->Reserved2 = 0;
6185 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6186 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6187 pSMB->DataCount = 0;
6188 pSMB->DataOffset = 0;
6189 pSMB->SetupCount = 1;
6190 pSMB->Reserved3 = 0;
6191 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6192 byte_count = params + 1 /* pad */ ;
6193 pSMB->TotalParameterCount = cpu_to_le16(params);
6194 pSMB->ParameterCount = pSMB->TotalParameterCount;
6195 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6196 pSMB->Reserved4 = 0;
6197 inc_rfc1001_len(pSMB, byte_count);
6198 pSMB->ByteCount = cpu_to_le16(byte_count);
6200 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6201 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6203 cFYI(1, "Send error in QueryAllEAs = %d", rc);
6208 /* BB also check enough total bytes returned */
6209 /* BB we need to improve the validity checking
6210 of these trans2 responses */
6212 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6213 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6214 rc = -EIO; /* bad smb */
6218 /* check that length of list is not more than bcc */
6219 /* check that each entry does not go beyond length
6221 /* check that each element of each entry does not
6222 go beyond end of list */
6223 /* validate_trans2_offsets() */
6224 /* BB check if start of smb + data_offset > &bcc+ bcc */
6226 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6227 ea_response_data = (struct fealist *)
6228 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6230 list_len = le32_to_cpu(ea_response_data->list_len);
6231 cFYI(1, "ea length %d", list_len);
6232 if (list_len <= 8) {
6233 cFYI(1, "empty EA list returned from server");
6237 /* make sure list_len doesn't go past end of SMB */
6238 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6239 if ((char *)ea_response_data + list_len > end_of_smb) {
6240 cFYI(1, "EA list appears to go beyond SMB");
6245 /* account for ea list len */
6247 temp_fea = ea_response_data->list;
6248 temp_ptr = (char *)temp_fea;
6249 while (list_len > 0) {
6250 unsigned int name_len;
6255 /* make sure we can read name_len and value_len */
6257 cFYI(1, "EA entry goes beyond length of list");
6262 name_len = temp_fea->name_len;
6263 value_len = le16_to_cpu(temp_fea->value_len);
6264 list_len -= name_len + 1 + value_len;
6266 cFYI(1, "EA entry goes beyond length of list");
6272 if (ea_name_len == name_len &&
6273 memcmp(ea_name, temp_ptr, name_len) == 0) {
6274 temp_ptr += name_len + 1;
6278 if ((size_t)value_len > buf_size) {
6282 memcpy(EAData, temp_ptr, value_len);
6286 /* account for prefix user. and trailing null */
6287 rc += (5 + 1 + name_len);
6288 if (rc < (int) buf_size) {
6289 memcpy(EAData, "user.", 5);
6291 memcpy(EAData, temp_ptr, name_len);
6293 /* null terminate name */
6296 } else if (buf_size == 0) {
6297 /* skip copy - calc size only */
6299 /* stop before overrun buffer */
6304 temp_ptr += name_len + 1 + value_len;
6305 temp_fea = (struct fea *)temp_ptr;
6308 /* didn't find the named attribute */
6313 cifs_buf_release(pSMB);
6321 CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon, const char *fileName,
6322 const char *ea_name, const void *ea_value,
6323 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6326 struct smb_com_transaction2_spi_req *pSMB = NULL;
6327 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6328 struct fealist *parm_data;
6331 int bytes_returned = 0;
6332 __u16 params, param_offset, byte_count, offset, count;
6334 cFYI(1, "In SetEA");
6336 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6341 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6343 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
6344 PATH_MAX, nls_codepage, remap);
6345 name_len++; /* trailing null */
6347 } else { /* BB improve the check for buffer overruns BB */
6348 name_len = strnlen(fileName, PATH_MAX);
6349 name_len++; /* trailing null */
6350 strncpy(pSMB->FileName, fileName, name_len);
6353 params = 6 + name_len;
6355 /* done calculating parms using name_len of file name,
6356 now use name_len to calculate length of ea name
6357 we are going to create in the inode xattrs */
6358 if (ea_name == NULL)
6361 name_len = strnlen(ea_name, 255);
6363 count = sizeof(*parm_data) + ea_value_len + name_len;
6364 pSMB->MaxParameterCount = cpu_to_le16(2);
6365 /* BB find max SMB PDU from sess */
6366 pSMB->MaxDataCount = cpu_to_le16(1000);
6367 pSMB->MaxSetupCount = 0;
6371 pSMB->Reserved2 = 0;
6372 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6373 InformationLevel) - 4;
6374 offset = param_offset + params;
6375 pSMB->InformationLevel =
6376 cpu_to_le16(SMB_SET_FILE_EA);
6379 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6381 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6382 pSMB->DataOffset = cpu_to_le16(offset);
6383 pSMB->SetupCount = 1;
6384 pSMB->Reserved3 = 0;
6385 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6386 byte_count = 3 /* pad */ + params + count;
6387 pSMB->DataCount = cpu_to_le16(count);
6388 parm_data->list_len = cpu_to_le32(count);
6389 parm_data->list[0].EA_flags = 0;
6390 /* we checked above that name len is less than 255 */
6391 parm_data->list[0].name_len = (__u8)name_len;
6392 /* EA names are always ASCII */
6394 strncpy(parm_data->list[0].name, ea_name, name_len);
6395 parm_data->list[0].name[name_len] = 0;
6396 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6397 /* caller ensures that ea_value_len is less than 64K but
6398 we need to ensure that it fits within the smb */
6400 /*BB add length check to see if it would fit in
6401 negotiated SMB buffer size BB */
6402 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6404 memcpy(parm_data->list[0].name+name_len+1,
6405 ea_value, ea_value_len);
6407 pSMB->TotalDataCount = pSMB->DataCount;
6408 pSMB->ParameterCount = cpu_to_le16(params);
6409 pSMB->TotalParameterCount = pSMB->ParameterCount;
6410 pSMB->Reserved4 = 0;
6411 inc_rfc1001_len(pSMB, byte_count);
6412 pSMB->ByteCount = cpu_to_le16(byte_count);
6413 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6414 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6416 cFYI(1, "SetPathInfo (EA) returned %d", rc);
6418 cifs_buf_release(pSMB);
6427 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6429 * Years ago the kernel added a "dnotify" function for Samba server,
6430 * to allow network clients (such as Windows) to display updated
6431 * lists of files in directory listings automatically when
6432 * files are added by one user when another user has the
6433 * same directory open on their desktop. The Linux cifs kernel
6434 * client hooked into the kernel side of this interface for
6435 * the same reason, but ironically when the VFS moved from
6436 * "dnotify" to "inotify" it became harder to plug in Linux
6437 * network file system clients (the most obvious use case
6438 * for notify interfaces is when multiple users can update
6439 * the contents of the same directory - exactly what network
6440 * file systems can do) although the server (Samba) could
6441 * still use it. For the short term we leave the worker
6442 * function ifdeffed out (below) until inotify is fixed
6443 * in the VFS to make it easier to plug in network file
6444 * system clients. If inotify turns out to be permanently
6445 * incompatible for network fs clients, we could instead simply
6446 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6448 int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
6449 const int notify_subdirs, const __u16 netfid,
6450 __u32 filter, struct file *pfile, int multishot,
6451 const struct nls_table *nls_codepage)
6454 struct smb_com_transaction_change_notify_req *pSMB = NULL;
6455 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6456 struct dir_notify_req *dnotify_req;
6459 cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
6460 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6465 pSMB->TotalParameterCount = 0 ;
6466 pSMB->TotalDataCount = 0;
6467 pSMB->MaxParameterCount = cpu_to_le32(2);
6468 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6469 pSMB->MaxSetupCount = 4;
6471 pSMB->ParameterOffset = 0;
6472 pSMB->DataCount = 0;
6473 pSMB->DataOffset = 0;
6474 pSMB->SetupCount = 4; /* single byte does not need le conversion */
6475 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6476 pSMB->ParameterCount = pSMB->TotalParameterCount;
6478 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6479 pSMB->Reserved2 = 0;
6480 pSMB->CompletionFilter = cpu_to_le32(filter);
6481 pSMB->Fid = netfid; /* file handle always le */
6482 pSMB->ByteCount = 0;
6484 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6485 (struct smb_hdr *)pSMBr, &bytes_returned,
6488 cFYI(1, "Error in Notify = %d", rc);
6490 /* Add file to outstanding requests */
6491 /* BB change to kmem cache alloc */
6492 dnotify_req = kmalloc(
6493 sizeof(struct dir_notify_req),
6496 dnotify_req->Pid = pSMB->hdr.Pid;
6497 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6498 dnotify_req->Mid = pSMB->hdr.Mid;
6499 dnotify_req->Tid = pSMB->hdr.Tid;
6500 dnotify_req->Uid = pSMB->hdr.Uid;
6501 dnotify_req->netfid = netfid;
6502 dnotify_req->pfile = pfile;
6503 dnotify_req->filter = filter;
6504 dnotify_req->multishot = multishot;
6505 spin_lock(&GlobalMid_Lock);
6506 list_add_tail(&dnotify_req->lhead,
6507 &GlobalDnotifyReqList);
6508 spin_unlock(&GlobalMid_Lock);
6512 cifs_buf_release(pSMB);
6515 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */