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 else if (acl_type == ACL_TYPE_DEFAULT)
3443 cifs_acl->default_entry_count = cpu_to_le16(count);
3445 cFYI(1, "unknown ACL type %d", acl_type);
3448 for (i = 0; i < count; i++) {
3449 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3450 &local_acl->a_entries[i]);
3452 /* ACE not converted */
3457 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3458 rc += sizeof(struct cifs_posix_acl);
3459 /* BB add check to make sure ACL does not overflow SMB */
3465 CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
3466 const unsigned char *searchName,
3467 char *acl_inf, const int buflen, const int acl_type,
3468 const struct nls_table *nls_codepage, int remap)
3470 /* SMB_QUERY_POSIX_ACL */
3471 TRANSACTION2_QPI_REQ *pSMB = NULL;
3472 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3476 __u16 params, byte_count;
3478 cFYI(1, "In GetPosixACL (Unix) for path %s", searchName);
3481 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3486 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3488 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3489 PATH_MAX, nls_codepage, remap);
3490 name_len++; /* trailing null */
3492 pSMB->FileName[name_len] = 0;
3493 pSMB->FileName[name_len+1] = 0;
3494 } else { /* BB improve the check for buffer overruns BB */
3495 name_len = strnlen(searchName, PATH_MAX);
3496 name_len++; /* trailing null */
3497 strncpy(pSMB->FileName, searchName, name_len);
3500 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3501 pSMB->TotalDataCount = 0;
3502 pSMB->MaxParameterCount = cpu_to_le16(2);
3503 /* BB find exact max data count below from sess structure BB */
3504 pSMB->MaxDataCount = cpu_to_le16(4000);
3505 pSMB->MaxSetupCount = 0;
3509 pSMB->Reserved2 = 0;
3510 pSMB->ParameterOffset = cpu_to_le16(
3511 offsetof(struct smb_com_transaction2_qpi_req,
3512 InformationLevel) - 4);
3513 pSMB->DataCount = 0;
3514 pSMB->DataOffset = 0;
3515 pSMB->SetupCount = 1;
3516 pSMB->Reserved3 = 0;
3517 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3518 byte_count = params + 1 /* pad */ ;
3519 pSMB->TotalParameterCount = cpu_to_le16(params);
3520 pSMB->ParameterCount = pSMB->TotalParameterCount;
3521 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3522 pSMB->Reserved4 = 0;
3523 inc_rfc1001_len(pSMB, byte_count);
3524 pSMB->ByteCount = cpu_to_le16(byte_count);
3526 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3527 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3528 cifs_stats_inc(&tcon->num_acl_get);
3530 cFYI(1, "Send error in Query POSIX ACL = %d", rc);
3532 /* decode response */
3534 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3535 /* BB also check enough total bytes returned */
3536 if (rc || get_bcc(&pSMBr->hdr) < 2)
3537 rc = -EIO; /* bad smb */
3539 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3540 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3541 rc = cifs_copy_posix_acl(acl_inf,
3542 (char *)&pSMBr->hdr.Protocol+data_offset,
3543 buflen, acl_type, count);
3546 cifs_buf_release(pSMB);
3553 CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
3554 const unsigned char *fileName,
3555 const char *local_acl, const int buflen,
3557 const struct nls_table *nls_codepage, int remap)
3559 struct smb_com_transaction2_spi_req *pSMB = NULL;
3560 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3564 int bytes_returned = 0;
3565 __u16 params, byte_count, data_count, param_offset, offset;
3567 cFYI(1, "In SetPosixACL (Unix) for path %s", fileName);
3569 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3573 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3575 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
3576 PATH_MAX, nls_codepage, remap);
3577 name_len++; /* trailing null */
3579 } else { /* BB improve the check for buffer overruns BB */
3580 name_len = strnlen(fileName, PATH_MAX);
3581 name_len++; /* trailing null */
3582 strncpy(pSMB->FileName, fileName, name_len);
3584 params = 6 + name_len;
3585 pSMB->MaxParameterCount = cpu_to_le16(2);
3586 /* BB find max SMB size from sess */
3587 pSMB->MaxDataCount = cpu_to_le16(1000);
3588 pSMB->MaxSetupCount = 0;
3592 pSMB->Reserved2 = 0;
3593 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3594 InformationLevel) - 4;
3595 offset = param_offset + params;
3596 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3597 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3599 /* convert to on the wire format for POSIX ACL */
3600 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3602 if (data_count == 0) {
3604 goto setACLerrorExit;
3606 pSMB->DataOffset = cpu_to_le16(offset);
3607 pSMB->SetupCount = 1;
3608 pSMB->Reserved3 = 0;
3609 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3610 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3611 byte_count = 3 /* pad */ + params + data_count;
3612 pSMB->DataCount = cpu_to_le16(data_count);
3613 pSMB->TotalDataCount = pSMB->DataCount;
3614 pSMB->ParameterCount = cpu_to_le16(params);
3615 pSMB->TotalParameterCount = pSMB->ParameterCount;
3616 pSMB->Reserved4 = 0;
3617 inc_rfc1001_len(pSMB, byte_count);
3618 pSMB->ByteCount = cpu_to_le16(byte_count);
3619 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3620 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3622 cFYI(1, "Set POSIX ACL returned %d", rc);
3625 cifs_buf_release(pSMB);
3631 /* BB fix tabs in this function FIXME BB */
3633 CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
3634 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3637 struct smb_t2_qfi_req *pSMB = NULL;
3638 struct smb_t2_qfi_rsp *pSMBr = NULL;
3640 __u16 params, byte_count;
3642 cFYI(1, "In GetExtAttr");
3647 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3652 params = 2 /* level */ + 2 /* fid */;
3653 pSMB->t2.TotalDataCount = 0;
3654 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3655 /* BB find exact max data count below from sess structure BB */
3656 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3657 pSMB->t2.MaxSetupCount = 0;
3658 pSMB->t2.Reserved = 0;
3660 pSMB->t2.Timeout = 0;
3661 pSMB->t2.Reserved2 = 0;
3662 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3664 pSMB->t2.DataCount = 0;
3665 pSMB->t2.DataOffset = 0;
3666 pSMB->t2.SetupCount = 1;
3667 pSMB->t2.Reserved3 = 0;
3668 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3669 byte_count = params + 1 /* pad */ ;
3670 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3671 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3672 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3675 inc_rfc1001_len(pSMB, byte_count);
3676 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3678 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3679 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3681 cFYI(1, "error %d in GetExtAttr", rc);
3683 /* decode response */
3684 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3685 /* BB also check enough total bytes returned */
3686 if (rc || get_bcc(&pSMBr->hdr) < 2)
3687 /* If rc should we check for EOPNOSUPP and
3688 disable the srvino flag? or in caller? */
3689 rc = -EIO; /* bad smb */
3691 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3692 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3693 struct file_chattr_info *pfinfo;
3694 /* BB Do we need a cast or hash here ? */
3696 cFYI(1, "Illegal size ret in GetExtAttr");
3700 pfinfo = (struct file_chattr_info *)
3701 (data_offset + (char *) &pSMBr->hdr.Protocol);
3702 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3703 *pMask = le64_to_cpu(pfinfo->mask);
3707 cifs_buf_release(pSMB);
3709 goto GetExtAttrRetry;
3713 #endif /* CONFIG_POSIX */
3715 #ifdef CONFIG_CIFS_ACL
3717 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3718 * all NT TRANSACTS that we init here have total parm and data under about 400
3719 * bytes (to fit in small cifs buffer size), which is the case so far, it
3720 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3721 * returned setup area) and MaxParameterCount (returned parms size) must be set
3725 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3726 const int parm_len, struct cifs_tcon *tcon,
3731 struct smb_com_ntransact_req *pSMB;
3733 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3737 *ret_buf = (void *)pSMB;
3739 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3740 pSMB->TotalDataCount = 0;
3741 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3742 pSMB->ParameterCount = pSMB->TotalParameterCount;
3743 pSMB->DataCount = pSMB->TotalDataCount;
3744 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3745 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3746 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3747 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3748 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3749 pSMB->SubCommand = cpu_to_le16(sub_command);
3754 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3755 __u32 *pparmlen, __u32 *pdatalen)
3758 __u32 data_count, data_offset, parm_count, parm_offset;
3759 struct smb_com_ntransact_rsp *pSMBr;
3768 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3770 bcc = get_bcc(&pSMBr->hdr);
3771 end_of_smb = 2 /* sizeof byte count */ + bcc +
3772 (char *)&pSMBr->ByteCount;
3774 data_offset = le32_to_cpu(pSMBr->DataOffset);
3775 data_count = le32_to_cpu(pSMBr->DataCount);
3776 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3777 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3779 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3780 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3782 /* should we also check that parm and data areas do not overlap? */
3783 if (*ppparm > end_of_smb) {
3784 cFYI(1, "parms start after end of smb");
3786 } else if (parm_count + *ppparm > end_of_smb) {
3787 cFYI(1, "parm end after end of smb");
3789 } else if (*ppdata > end_of_smb) {
3790 cFYI(1, "data starts after end of smb");
3792 } else if (data_count + *ppdata > end_of_smb) {
3793 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
3794 *ppdata, data_count, (data_count + *ppdata),
3797 } else if (parm_count + data_count > bcc) {
3798 cFYI(1, "parm count and data count larger than SMB");
3801 *pdatalen = data_count;
3802 *pparmlen = parm_count;
3806 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3808 CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3809 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3813 QUERY_SEC_DESC_REQ *pSMB;
3816 cFYI(1, "GetCifsACL");
3821 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3822 8 /* parm len */, tcon, (void **) &pSMB);
3826 pSMB->MaxParameterCount = cpu_to_le32(4);
3827 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3828 pSMB->MaxSetupCount = 0;
3829 pSMB->Fid = fid; /* file handle always le */
3830 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3832 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3833 inc_rfc1001_len(pSMB, 11);
3834 iov[0].iov_base = (char *)pSMB;
3835 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3837 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3839 cifs_stats_inc(&tcon->num_acl_get);
3841 cFYI(1, "Send error in QuerySecDesc = %d", rc);
3842 } else { /* decode response */
3846 struct smb_com_ntransact_rsp *pSMBr;
3849 /* validate_nttransact */
3850 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3851 &pdata, &parm_len, pbuflen);
3854 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3856 cFYI(1, "smb %p parm %p data %p", pSMBr, parm, *acl_inf);
3858 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3859 rc = -EIO; /* bad smb */
3864 /* BB check that data area is minimum length and as big as acl_len */
3866 acl_len = le32_to_cpu(*parm);
3867 if (acl_len != *pbuflen) {
3868 cERROR(1, "acl length %d does not match %d",
3870 if (*pbuflen > acl_len)
3874 /* check if buffer is big enough for the acl
3875 header followed by the smallest SID */
3876 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3877 (*pbuflen >= 64 * 1024)) {
3878 cERROR(1, "bad acl length %d", *pbuflen);
3882 *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
3883 if (*acl_inf == NULL) {
3887 memcpy(*acl_inf, pdata, *pbuflen);
3891 if (buf_type == CIFS_SMALL_BUFFER)
3892 cifs_small_buf_release(iov[0].iov_base);
3893 else if (buf_type == CIFS_LARGE_BUFFER)
3894 cifs_buf_release(iov[0].iov_base);
3895 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3900 CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3901 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3903 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3905 int bytes_returned = 0;
3906 SET_SEC_DESC_REQ *pSMB = NULL;
3907 NTRANSACT_RSP *pSMBr = NULL;
3910 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB,
3915 pSMB->MaxSetupCount = 0;
3919 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3920 data_count = acllen;
3921 data_offset = param_offset + param_count;
3922 byte_count = 3 /* pad */ + param_count;
3924 pSMB->DataCount = cpu_to_le32(data_count);
3925 pSMB->TotalDataCount = pSMB->DataCount;
3926 pSMB->MaxParameterCount = cpu_to_le32(4);
3927 pSMB->MaxDataCount = cpu_to_le32(16384);
3928 pSMB->ParameterCount = cpu_to_le32(param_count);
3929 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3930 pSMB->TotalParameterCount = pSMB->ParameterCount;
3931 pSMB->DataOffset = cpu_to_le32(data_offset);
3932 pSMB->SetupCount = 0;
3933 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3934 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3936 pSMB->Fid = fid; /* file handle always le */
3937 pSMB->Reserved2 = 0;
3938 pSMB->AclFlags = cpu_to_le32(aclflag);
3940 if (pntsd && acllen) {
3941 memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
3944 inc_rfc1001_len(pSMB, byte_count + data_count);
3946 inc_rfc1001_len(pSMB, byte_count);
3948 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3949 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3951 cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
3953 cFYI(1, "Set CIFS ACL returned %d", rc);
3954 cifs_buf_release(pSMB);
3957 goto setCifsAclRetry;
3962 #endif /* CONFIG_CIFS_ACL */
3964 /* Legacy Query Path Information call for lookup to old servers such
3966 int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
3967 const unsigned char *searchName,
3968 FILE_ALL_INFO *pFinfo,
3969 const struct nls_table *nls_codepage, int remap)
3971 QUERY_INFORMATION_REQ *pSMB;
3972 QUERY_INFORMATION_RSP *pSMBr;
3977 cFYI(1, "In SMBQPath path %s", searchName);
3979 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3984 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3986 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3987 PATH_MAX, nls_codepage, remap);
3988 name_len++; /* trailing null */
3991 name_len = strnlen(searchName, PATH_MAX);
3992 name_len++; /* trailing null */
3993 strncpy(pSMB->FileName, searchName, name_len);
3995 pSMB->BufferFormat = 0x04;
3996 name_len++; /* account for buffer type byte */
3997 inc_rfc1001_len(pSMB, (__u16)name_len);
3998 pSMB->ByteCount = cpu_to_le16(name_len);
4000 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4001 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4003 cFYI(1, "Send error in QueryInfo = %d", rc);
4004 } else if (pFinfo) {
4006 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4008 /* decode response */
4009 /* BB FIXME - add time zone adjustment BB */
4010 memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
4013 /* decode time fields */
4014 pFinfo->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4015 pFinfo->LastWriteTime = pFinfo->ChangeTime;
4016 pFinfo->LastAccessTime = 0;
4017 pFinfo->AllocationSize =
4018 cpu_to_le64(le32_to_cpu(pSMBr->size));
4019 pFinfo->EndOfFile = pFinfo->AllocationSize;
4020 pFinfo->Attributes =
4021 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4023 rc = -EIO; /* bad buffer passed in */
4025 cifs_buf_release(pSMB);
4034 CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
4035 u16 netfid, FILE_ALL_INFO *pFindData)
4037 struct smb_t2_qfi_req *pSMB = NULL;
4038 struct smb_t2_qfi_rsp *pSMBr = NULL;
4041 __u16 params, byte_count;
4044 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4049 params = 2 /* level */ + 2 /* fid */;
4050 pSMB->t2.TotalDataCount = 0;
4051 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4052 /* BB find exact max data count below from sess structure BB */
4053 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4054 pSMB->t2.MaxSetupCount = 0;
4055 pSMB->t2.Reserved = 0;
4057 pSMB->t2.Timeout = 0;
4058 pSMB->t2.Reserved2 = 0;
4059 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4061 pSMB->t2.DataCount = 0;
4062 pSMB->t2.DataOffset = 0;
4063 pSMB->t2.SetupCount = 1;
4064 pSMB->t2.Reserved3 = 0;
4065 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4066 byte_count = params + 1 /* pad */ ;
4067 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4068 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4069 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4072 inc_rfc1001_len(pSMB, byte_count);
4074 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4075 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4077 cFYI(1, "Send error in QPathInfo = %d", rc);
4078 } else { /* decode response */
4079 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4081 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4083 else if (get_bcc(&pSMBr->hdr) < 40)
4084 rc = -EIO; /* bad smb */
4085 else if (pFindData) {
4086 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4087 memcpy((char *) pFindData,
4088 (char *) &pSMBr->hdr.Protocol +
4089 data_offset, sizeof(FILE_ALL_INFO));
4093 cifs_buf_release(pSMB);
4095 goto QFileInfoRetry;
4101 CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
4102 const unsigned char *searchName,
4103 FILE_ALL_INFO *pFindData,
4104 int legacy /* old style infolevel */,
4105 const struct nls_table *nls_codepage, int remap)
4107 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4108 TRANSACTION2_QPI_REQ *pSMB = NULL;
4109 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4113 __u16 params, byte_count;
4115 /* cFYI(1, "In QPathInfo path %s", searchName); */
4117 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4122 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4124 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4125 PATH_MAX, nls_codepage, remap);
4126 name_len++; /* trailing null */
4128 } else { /* BB improve the check for buffer overruns BB */
4129 name_len = strnlen(searchName, PATH_MAX);
4130 name_len++; /* trailing null */
4131 strncpy(pSMB->FileName, searchName, name_len);
4134 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4135 pSMB->TotalDataCount = 0;
4136 pSMB->MaxParameterCount = cpu_to_le16(2);
4137 /* BB find exact max SMB PDU from sess structure BB */
4138 pSMB->MaxDataCount = cpu_to_le16(4000);
4139 pSMB->MaxSetupCount = 0;
4143 pSMB->Reserved2 = 0;
4144 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4145 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4146 pSMB->DataCount = 0;
4147 pSMB->DataOffset = 0;
4148 pSMB->SetupCount = 1;
4149 pSMB->Reserved3 = 0;
4150 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4151 byte_count = params + 1 /* pad */ ;
4152 pSMB->TotalParameterCount = cpu_to_le16(params);
4153 pSMB->ParameterCount = pSMB->TotalParameterCount;
4155 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4157 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4158 pSMB->Reserved4 = 0;
4159 inc_rfc1001_len(pSMB, byte_count);
4160 pSMB->ByteCount = cpu_to_le16(byte_count);
4162 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4163 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4165 cFYI(1, "Send error in QPathInfo = %d", rc);
4166 } else { /* decode response */
4167 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4169 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4171 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4172 rc = -EIO; /* bad smb */
4173 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4174 rc = -EIO; /* 24 or 26 expected but we do not read
4176 else if (pFindData) {
4178 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4180 /* On legacy responses we do not read the last field,
4181 EAsize, fortunately since it varies by subdialect and
4182 also note it differs on Set vs. Get, ie two bytes or 4
4183 bytes depending but we don't care here */
4185 size = sizeof(FILE_INFO_STANDARD);
4187 size = sizeof(FILE_ALL_INFO);
4188 memcpy((char *) pFindData,
4189 (char *) &pSMBr->hdr.Protocol +
4194 cifs_buf_release(pSMB);
4196 goto QPathInfoRetry;
4202 CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
4203 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4205 struct smb_t2_qfi_req *pSMB = NULL;
4206 struct smb_t2_qfi_rsp *pSMBr = NULL;
4209 __u16 params, byte_count;
4212 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4217 params = 2 /* level */ + 2 /* fid */;
4218 pSMB->t2.TotalDataCount = 0;
4219 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4220 /* BB find exact max data count below from sess structure BB */
4221 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4222 pSMB->t2.MaxSetupCount = 0;
4223 pSMB->t2.Reserved = 0;
4225 pSMB->t2.Timeout = 0;
4226 pSMB->t2.Reserved2 = 0;
4227 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4229 pSMB->t2.DataCount = 0;
4230 pSMB->t2.DataOffset = 0;
4231 pSMB->t2.SetupCount = 1;
4232 pSMB->t2.Reserved3 = 0;
4233 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4234 byte_count = params + 1 /* pad */ ;
4235 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4236 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4237 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4240 inc_rfc1001_len(pSMB, byte_count);
4242 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4243 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4245 cFYI(1, "Send error in QPathInfo = %d", rc);
4246 } else { /* decode response */
4247 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4249 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4250 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
4251 "Unix Extensions can be disabled on mount "
4252 "by specifying the nosfu mount option.");
4253 rc = -EIO; /* bad smb */
4255 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4256 memcpy((char *) pFindData,
4257 (char *) &pSMBr->hdr.Protocol +
4259 sizeof(FILE_UNIX_BASIC_INFO));
4263 cifs_buf_release(pSMB);
4265 goto UnixQFileInfoRetry;
4271 CIFSSMBUnixQPathInfo(const int xid, struct cifs_tcon *tcon,
4272 const unsigned char *searchName,
4273 FILE_UNIX_BASIC_INFO *pFindData,
4274 const struct nls_table *nls_codepage, int remap)
4276 /* SMB_QUERY_FILE_UNIX_BASIC */
4277 TRANSACTION2_QPI_REQ *pSMB = NULL;
4278 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4280 int bytes_returned = 0;
4282 __u16 params, byte_count;
4284 cFYI(1, "In QPathInfo (Unix) the path %s", searchName);
4286 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4291 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4293 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4294 PATH_MAX, nls_codepage, remap);
4295 name_len++; /* trailing null */
4297 } else { /* BB improve the check for buffer overruns BB */
4298 name_len = strnlen(searchName, PATH_MAX);
4299 name_len++; /* trailing null */
4300 strncpy(pSMB->FileName, searchName, name_len);
4303 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4304 pSMB->TotalDataCount = 0;
4305 pSMB->MaxParameterCount = cpu_to_le16(2);
4306 /* BB find exact max SMB PDU from sess structure BB */
4307 pSMB->MaxDataCount = cpu_to_le16(4000);
4308 pSMB->MaxSetupCount = 0;
4312 pSMB->Reserved2 = 0;
4313 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4314 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4315 pSMB->DataCount = 0;
4316 pSMB->DataOffset = 0;
4317 pSMB->SetupCount = 1;
4318 pSMB->Reserved3 = 0;
4319 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4320 byte_count = params + 1 /* pad */ ;
4321 pSMB->TotalParameterCount = cpu_to_le16(params);
4322 pSMB->ParameterCount = pSMB->TotalParameterCount;
4323 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4324 pSMB->Reserved4 = 0;
4325 inc_rfc1001_len(pSMB, byte_count);
4326 pSMB->ByteCount = cpu_to_le16(byte_count);
4328 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4329 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4331 cFYI(1, "Send error in QPathInfo = %d", rc);
4332 } else { /* decode response */
4333 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4335 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4336 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
4337 "Unix Extensions can be disabled on mount "
4338 "by specifying the nosfu mount option.");
4339 rc = -EIO; /* bad smb */
4341 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4342 memcpy((char *) pFindData,
4343 (char *) &pSMBr->hdr.Protocol +
4345 sizeof(FILE_UNIX_BASIC_INFO));
4348 cifs_buf_release(pSMB);
4350 goto UnixQPathInfoRetry;
4355 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4357 CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
4358 const char *searchName,
4359 const struct nls_table *nls_codepage,
4360 __u16 *pnetfid, __u16 search_flags,
4361 struct cifs_search_info *psrch_inf, int remap, const char dirsep)
4363 /* level 257 SMB_ */
4364 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4365 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4366 T2_FFIRST_RSP_PARMS *parms;
4368 int bytes_returned = 0;
4370 __u16 params, byte_count;
4372 cFYI(1, "In FindFirst for %s", searchName);
4375 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4380 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4382 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4383 PATH_MAX, nls_codepage, remap);
4384 /* We can not add the asterik earlier in case
4385 it got remapped to 0xF03A as if it were part of the
4386 directory name instead of a wildcard */
4388 pSMB->FileName[name_len] = dirsep;
4389 pSMB->FileName[name_len+1] = 0;
4390 pSMB->FileName[name_len+2] = '*';
4391 pSMB->FileName[name_len+3] = 0;
4392 name_len += 4; /* now the trailing null */
4393 pSMB->FileName[name_len] = 0; /* null terminate just in case */
4394 pSMB->FileName[name_len+1] = 0;
4396 } else { /* BB add check for overrun of SMB buf BB */
4397 name_len = strnlen(searchName, PATH_MAX);
4398 /* BB fix here and in unicode clause above ie
4399 if (name_len > buffersize-header)
4400 free buffer exit; BB */
4401 strncpy(pSMB->FileName, searchName, name_len);
4402 pSMB->FileName[name_len] = dirsep;
4403 pSMB->FileName[name_len+1] = '*';
4404 pSMB->FileName[name_len+2] = 0;
4408 params = 12 + name_len /* includes null */ ;
4409 pSMB->TotalDataCount = 0; /* no EAs */
4410 pSMB->MaxParameterCount = cpu_to_le16(10);
4411 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4412 pSMB->MaxSetupCount = 0;
4416 pSMB->Reserved2 = 0;
4417 byte_count = params + 1 /* pad */ ;
4418 pSMB->TotalParameterCount = cpu_to_le16(params);
4419 pSMB->ParameterCount = pSMB->TotalParameterCount;
4420 pSMB->ParameterOffset = cpu_to_le16(
4421 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4423 pSMB->DataCount = 0;
4424 pSMB->DataOffset = 0;
4425 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4426 pSMB->Reserved3 = 0;
4427 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4428 pSMB->SearchAttributes =
4429 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4431 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4432 pSMB->SearchFlags = cpu_to_le16(search_flags);
4433 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4435 /* BB what should we set StorageType to? Does it matter? BB */
4436 pSMB->SearchStorageType = 0;
4437 inc_rfc1001_len(pSMB, byte_count);
4438 pSMB->ByteCount = cpu_to_le16(byte_count);
4440 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4441 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4442 cifs_stats_inc(&tcon->num_ffirst);
4444 if (rc) {/* BB add logic to retry regular search if Unix search
4445 rejected unexpectedly by server */
4446 /* BB Add code to handle unsupported level rc */
4447 cFYI(1, "Error in FindFirst = %d", rc);
4449 cifs_buf_release(pSMB);
4451 /* BB eventually could optimize out free and realloc of buf */
4454 goto findFirstRetry;
4455 } else { /* decode response */
4456 /* BB remember to free buffer if error BB */
4457 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4461 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4462 psrch_inf->unicode = true;
4464 psrch_inf->unicode = false;
4466 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4467 psrch_inf->smallBuf = 0;
4468 psrch_inf->srch_entries_start =
4469 (char *) &pSMBr->hdr.Protocol +
4470 le16_to_cpu(pSMBr->t2.DataOffset);
4471 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4472 le16_to_cpu(pSMBr->t2.ParameterOffset));
4474 if (parms->EndofSearch)
4475 psrch_inf->endOfSearch = true;
4477 psrch_inf->endOfSearch = false;
4479 psrch_inf->entries_in_buffer =
4480 le16_to_cpu(parms->SearchCount);
4481 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4482 psrch_inf->entries_in_buffer;
4483 lnoff = le16_to_cpu(parms->LastNameOffset);
4484 if (CIFSMaxBufSize < lnoff) {
4485 cERROR(1, "ignoring corrupt resume name");
4486 psrch_inf->last_entry = NULL;
4490 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4493 *pnetfid = parms->SearchHandle;
4495 cifs_buf_release(pSMB);
4502 int CIFSFindNext(const int xid, struct cifs_tcon *tcon, __u16 searchHandle,
4503 __u16 search_flags, struct cifs_search_info *psrch_inf)
4505 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4506 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4507 T2_FNEXT_RSP_PARMS *parms;
4508 char *response_data;
4511 unsigned int name_len;
4512 __u16 params, byte_count;
4514 cFYI(1, "In FindNext");
4516 if (psrch_inf->endOfSearch)
4519 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4524 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4526 pSMB->TotalDataCount = 0; /* no EAs */
4527 pSMB->MaxParameterCount = cpu_to_le16(8);
4528 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4529 pSMB->MaxSetupCount = 0;
4533 pSMB->Reserved2 = 0;
4534 pSMB->ParameterOffset = cpu_to_le16(
4535 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4536 pSMB->DataCount = 0;
4537 pSMB->DataOffset = 0;
4538 pSMB->SetupCount = 1;
4539 pSMB->Reserved3 = 0;
4540 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4541 pSMB->SearchHandle = searchHandle; /* always kept as le */
4543 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4544 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4545 pSMB->ResumeKey = psrch_inf->resume_key;
4546 pSMB->SearchFlags = cpu_to_le16(search_flags);
4548 name_len = psrch_inf->resume_name_len;
4550 if (name_len < PATH_MAX) {
4551 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4552 byte_count += name_len;
4553 /* 14 byte parm len above enough for 2 byte null terminator */
4554 pSMB->ResumeFileName[name_len] = 0;
4555 pSMB->ResumeFileName[name_len+1] = 0;
4558 goto FNext2_err_exit;
4560 byte_count = params + 1 /* pad */ ;
4561 pSMB->TotalParameterCount = cpu_to_le16(params);
4562 pSMB->ParameterCount = pSMB->TotalParameterCount;
4563 inc_rfc1001_len(pSMB, byte_count);
4564 pSMB->ByteCount = cpu_to_le16(byte_count);
4566 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4567 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4568 cifs_stats_inc(&tcon->num_fnext);
4571 psrch_inf->endOfSearch = true;
4572 cifs_buf_release(pSMB);
4573 rc = 0; /* search probably was closed at end of search*/
4575 cFYI(1, "FindNext returned = %d", rc);
4576 } else { /* decode response */
4577 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4582 /* BB fixme add lock for file (srch_info) struct here */
4583 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4584 psrch_inf->unicode = true;
4586 psrch_inf->unicode = false;
4587 response_data = (char *) &pSMBr->hdr.Protocol +
4588 le16_to_cpu(pSMBr->t2.ParameterOffset);
4589 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4590 response_data = (char *)&pSMBr->hdr.Protocol +
4591 le16_to_cpu(pSMBr->t2.DataOffset);
4592 if (psrch_inf->smallBuf)
4593 cifs_small_buf_release(
4594 psrch_inf->ntwrk_buf_start);
4596 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4597 psrch_inf->srch_entries_start = response_data;
4598 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4599 psrch_inf->smallBuf = 0;
4600 if (parms->EndofSearch)
4601 psrch_inf->endOfSearch = true;
4603 psrch_inf->endOfSearch = false;
4604 psrch_inf->entries_in_buffer =
4605 le16_to_cpu(parms->SearchCount);
4606 psrch_inf->index_of_last_entry +=
4607 psrch_inf->entries_in_buffer;
4608 lnoff = le16_to_cpu(parms->LastNameOffset);
4609 if (CIFSMaxBufSize < lnoff) {
4610 cERROR(1, "ignoring corrupt resume name");
4611 psrch_inf->last_entry = NULL;
4614 psrch_inf->last_entry =
4615 psrch_inf->srch_entries_start + lnoff;
4617 /* cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
4618 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4620 /* BB fixme add unlock here */
4625 /* BB On error, should we leave previous search buf (and count and
4626 last entry fields) intact or free the previous one? */
4628 /* Note: On -EAGAIN error only caller can retry on handle based calls
4629 since file handle passed in no longer valid */
4632 cifs_buf_release(pSMB);
4637 CIFSFindClose(const int xid, struct cifs_tcon *tcon,
4638 const __u16 searchHandle)
4641 FINDCLOSE_REQ *pSMB = NULL;
4643 cFYI(1, "In CIFSSMBFindClose");
4644 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4646 /* no sense returning error if session restarted
4647 as file handle has been closed */
4653 pSMB->FileID = searchHandle;
4654 pSMB->ByteCount = 0;
4655 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4657 cERROR(1, "Send error in FindClose = %d", rc);
4659 cifs_stats_inc(&tcon->num_fclose);
4661 /* Since session is dead, search handle closed on server already */
4669 CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
4670 const unsigned char *searchName,
4671 __u64 *inode_number,
4672 const struct nls_table *nls_codepage, int remap)
4675 TRANSACTION2_QPI_REQ *pSMB = NULL;
4676 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4677 int name_len, bytes_returned;
4678 __u16 params, byte_count;
4680 cFYI(1, "In GetSrvInodeNum for %s", searchName);
4684 GetInodeNumberRetry:
4685 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4690 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4692 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4693 PATH_MAX, nls_codepage, remap);
4694 name_len++; /* trailing null */
4696 } else { /* BB improve the check for buffer overruns BB */
4697 name_len = strnlen(searchName, PATH_MAX);
4698 name_len++; /* trailing null */
4699 strncpy(pSMB->FileName, searchName, name_len);
4702 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4703 pSMB->TotalDataCount = 0;
4704 pSMB->MaxParameterCount = cpu_to_le16(2);
4705 /* BB find exact max data count below from sess structure BB */
4706 pSMB->MaxDataCount = cpu_to_le16(4000);
4707 pSMB->MaxSetupCount = 0;
4711 pSMB->Reserved2 = 0;
4712 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4713 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4714 pSMB->DataCount = 0;
4715 pSMB->DataOffset = 0;
4716 pSMB->SetupCount = 1;
4717 pSMB->Reserved3 = 0;
4718 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4719 byte_count = params + 1 /* pad */ ;
4720 pSMB->TotalParameterCount = cpu_to_le16(params);
4721 pSMB->ParameterCount = pSMB->TotalParameterCount;
4722 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4723 pSMB->Reserved4 = 0;
4724 inc_rfc1001_len(pSMB, byte_count);
4725 pSMB->ByteCount = cpu_to_le16(byte_count);
4727 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4728 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4730 cFYI(1, "error %d in QueryInternalInfo", rc);
4732 /* decode response */
4733 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4734 /* BB also check enough total bytes returned */
4735 if (rc || get_bcc(&pSMBr->hdr) < 2)
4736 /* If rc should we check for EOPNOSUPP and
4737 disable the srvino flag? or in caller? */
4738 rc = -EIO; /* bad smb */
4740 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4741 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4742 struct file_internal_info *pfinfo;
4743 /* BB Do we need a cast or hash here ? */
4745 cFYI(1, "Illegal size ret in QryIntrnlInf");
4747 goto GetInodeNumOut;
4749 pfinfo = (struct file_internal_info *)
4750 (data_offset + (char *) &pSMBr->hdr.Protocol);
4751 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4755 cifs_buf_release(pSMB);
4757 goto GetInodeNumberRetry;
4761 /* parses DFS refferal V3 structure
4762 * caller is responsible for freeing target_nodes
4765 * on failure - errno
4768 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4769 unsigned int *num_of_nodes,
4770 struct dfs_info3_param **target_nodes,
4771 const struct nls_table *nls_codepage, int remap,
4772 const char *searchName)
4777 struct dfs_referral_level_3 *ref;
4779 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4783 *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4785 if (*num_of_nodes < 1) {
4786 cERROR(1, "num_referrals: must be at least > 0,"
4787 "but we get num_referrals = %d\n", *num_of_nodes);
4789 goto parse_DFS_referrals_exit;
4792 ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4793 if (ref->VersionNumber != cpu_to_le16(3)) {
4794 cERROR(1, "Referrals of V%d version are not supported,"
4795 "should be V3", le16_to_cpu(ref->VersionNumber));
4797 goto parse_DFS_referrals_exit;
4800 /* get the upper boundary of the resp buffer */
4801 data_end = (char *)(&(pSMBr->PathConsumed)) +
4802 le16_to_cpu(pSMBr->t2.DataCount);
4804 cFYI(1, "num_referrals: %d dfs flags: 0x%x ...\n",
4806 le32_to_cpu(pSMBr->DFSFlags));
4808 *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
4809 *num_of_nodes, GFP_KERNEL);
4810 if (*target_nodes == NULL) {
4811 cERROR(1, "Failed to allocate buffer for target_nodes\n");
4813 goto parse_DFS_referrals_exit;
4816 /* collect necessary data from referrals */
4817 for (i = 0; i < *num_of_nodes; i++) {
4820 struct dfs_info3_param *node = (*target_nodes)+i;
4822 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4824 __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4828 goto parse_DFS_referrals_exit;
4830 cifsConvertToUCS((__le16 *) tmp, searchName,
4831 PATH_MAX, nls_codepage, remap);
4832 node->path_consumed = cifs_ucs2_bytes(tmp,
4833 le16_to_cpu(pSMBr->PathConsumed),
4837 node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4839 node->server_type = le16_to_cpu(ref->ServerType);
4840 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4843 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4844 max_len = data_end - temp;
4845 node->path_name = cifs_strndup_from_ucs(temp, max_len,
4846 is_unicode, nls_codepage);
4847 if (!node->path_name) {
4849 goto parse_DFS_referrals_exit;
4852 /* copy link target UNC */
4853 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4854 max_len = data_end - temp;
4855 node->node_name = cifs_strndup_from_ucs(temp, max_len,
4856 is_unicode, nls_codepage);
4857 if (!node->node_name) {
4859 goto parse_DFS_referrals_exit;
4865 parse_DFS_referrals_exit:
4867 free_dfs_info_array(*target_nodes, *num_of_nodes);
4868 *target_nodes = NULL;
4875 CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
4876 const unsigned char *searchName,
4877 struct dfs_info3_param **target_nodes,
4878 unsigned int *num_of_nodes,
4879 const struct nls_table *nls_codepage, int remap)
4881 /* TRANS2_GET_DFS_REFERRAL */
4882 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4883 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4887 __u16 params, byte_count;
4889 *target_nodes = NULL;
4891 cFYI(1, "In GetDFSRefer the path %s", searchName);
4895 rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4900 /* server pointer checked in called function,
4901 but should never be null here anyway */
4902 pSMB->hdr.Mid = GetNextMid(ses->server);
4903 pSMB->hdr.Tid = ses->ipc_tid;
4904 pSMB->hdr.Uid = ses->Suid;
4905 if (ses->capabilities & CAP_STATUS32)
4906 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4907 if (ses->capabilities & CAP_DFS)
4908 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4910 if (ses->capabilities & CAP_UNICODE) {
4911 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4913 cifsConvertToUCS((__le16 *) pSMB->RequestFileName,
4914 searchName, PATH_MAX, nls_codepage, remap);
4915 name_len++; /* trailing null */
4917 } else { /* BB improve the check for buffer overruns BB */
4918 name_len = strnlen(searchName, PATH_MAX);
4919 name_len++; /* trailing null */
4920 strncpy(pSMB->RequestFileName, searchName, name_len);
4924 if (ses->server->sec_mode &
4925 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4926 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4929 pSMB->hdr.Uid = ses->Suid;
4931 params = 2 /* level */ + name_len /*includes null */ ;
4932 pSMB->TotalDataCount = 0;
4933 pSMB->DataCount = 0;
4934 pSMB->DataOffset = 0;
4935 pSMB->MaxParameterCount = 0;
4936 /* BB find exact max SMB PDU from sess structure BB */
4937 pSMB->MaxDataCount = cpu_to_le16(4000);
4938 pSMB->MaxSetupCount = 0;
4942 pSMB->Reserved2 = 0;
4943 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4944 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4945 pSMB->SetupCount = 1;
4946 pSMB->Reserved3 = 0;
4947 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4948 byte_count = params + 3 /* pad */ ;
4949 pSMB->ParameterCount = cpu_to_le16(params);
4950 pSMB->TotalParameterCount = pSMB->ParameterCount;
4951 pSMB->MaxReferralLevel = cpu_to_le16(3);
4952 inc_rfc1001_len(pSMB, byte_count);
4953 pSMB->ByteCount = cpu_to_le16(byte_count);
4955 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4956 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4958 cFYI(1, "Send error in GetDFSRefer = %d", rc);
4961 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4963 /* BB Also check if enough total bytes returned? */
4964 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4965 rc = -EIO; /* bad smb */
4969 cFYI(1, "Decoding GetDFSRefer response BCC: %d Offset %d",
4970 get_bcc(&pSMBr->hdr),
4971 le16_to_cpu(pSMBr->t2.DataOffset));
4973 /* parse returned result into more usable form */
4974 rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4975 target_nodes, nls_codepage, remap,
4979 cifs_buf_release(pSMB);
4987 /* Query File System Info such as free space to old servers such as Win 9x */
4989 SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4991 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4992 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4993 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4994 FILE_SYSTEM_ALLOC_INFO *response_data;
4996 int bytes_returned = 0;
4997 __u16 params, byte_count;
4999 cFYI(1, "OldQFSInfo");
5001 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5006 params = 2; /* level */
5007 pSMB->TotalDataCount = 0;
5008 pSMB->MaxParameterCount = cpu_to_le16(2);
5009 pSMB->MaxDataCount = cpu_to_le16(1000);
5010 pSMB->MaxSetupCount = 0;
5014 pSMB->Reserved2 = 0;
5015 byte_count = params + 1 /* pad */ ;
5016 pSMB->TotalParameterCount = cpu_to_le16(params);
5017 pSMB->ParameterCount = pSMB->TotalParameterCount;
5018 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5019 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5020 pSMB->DataCount = 0;
5021 pSMB->DataOffset = 0;
5022 pSMB->SetupCount = 1;
5023 pSMB->Reserved3 = 0;
5024 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5025 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
5026 inc_rfc1001_len(pSMB, byte_count);
5027 pSMB->ByteCount = cpu_to_le16(byte_count);
5029 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5030 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5032 cFYI(1, "Send error in QFSInfo = %d", rc);
5033 } else { /* decode response */
5034 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5036 if (rc || get_bcc(&pSMBr->hdr) < 18)
5037 rc = -EIO; /* bad smb */
5039 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5040 cFYI(1, "qfsinf resp BCC: %d Offset %d",
5041 get_bcc(&pSMBr->hdr), data_offset);
5043 response_data = (FILE_SYSTEM_ALLOC_INFO *)
5044 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5046 le16_to_cpu(response_data->BytesPerSector) *
5047 le32_to_cpu(response_data->
5048 SectorsPerAllocationUnit);
5050 le32_to_cpu(response_data->TotalAllocationUnits);
5051 FSData->f_bfree = FSData->f_bavail =
5052 le32_to_cpu(response_data->FreeAllocationUnits);
5053 cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
5054 (unsigned long long)FSData->f_blocks,
5055 (unsigned long long)FSData->f_bfree,
5059 cifs_buf_release(pSMB);
5062 goto oldQFSInfoRetry;
5068 CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
5070 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5071 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5072 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5073 FILE_SYSTEM_INFO *response_data;
5075 int bytes_returned = 0;
5076 __u16 params, byte_count;
5078 cFYI(1, "In QFSInfo");
5080 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5085 params = 2; /* level */
5086 pSMB->TotalDataCount = 0;
5087 pSMB->MaxParameterCount = cpu_to_le16(2);
5088 pSMB->MaxDataCount = cpu_to_le16(1000);
5089 pSMB->MaxSetupCount = 0;
5093 pSMB->Reserved2 = 0;
5094 byte_count = params + 1 /* pad */ ;
5095 pSMB->TotalParameterCount = cpu_to_le16(params);
5096 pSMB->ParameterCount = pSMB->TotalParameterCount;
5097 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5098 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5099 pSMB->DataCount = 0;
5100 pSMB->DataOffset = 0;
5101 pSMB->SetupCount = 1;
5102 pSMB->Reserved3 = 0;
5103 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5104 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5105 inc_rfc1001_len(pSMB, byte_count);
5106 pSMB->ByteCount = cpu_to_le16(byte_count);
5108 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5109 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5111 cFYI(1, "Send error in QFSInfo = %d", rc);
5112 } else { /* decode response */
5113 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5115 if (rc || get_bcc(&pSMBr->hdr) < 24)
5116 rc = -EIO; /* bad smb */
5118 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5122 *) (((char *) &pSMBr->hdr.Protocol) +
5125 le32_to_cpu(response_data->BytesPerSector) *
5126 le32_to_cpu(response_data->
5127 SectorsPerAllocationUnit);
5129 le64_to_cpu(response_data->TotalAllocationUnits);
5130 FSData->f_bfree = FSData->f_bavail =
5131 le64_to_cpu(response_data->FreeAllocationUnits);
5132 cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
5133 (unsigned long long)FSData->f_blocks,
5134 (unsigned long long)FSData->f_bfree,
5138 cifs_buf_release(pSMB);
5147 CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
5149 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5150 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5151 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5152 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5154 int bytes_returned = 0;
5155 __u16 params, byte_count;
5157 cFYI(1, "In QFSAttributeInfo");
5159 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5164 params = 2; /* level */
5165 pSMB->TotalDataCount = 0;
5166 pSMB->MaxParameterCount = cpu_to_le16(2);
5167 /* BB find exact max SMB PDU from sess structure BB */
5168 pSMB->MaxDataCount = cpu_to_le16(1000);
5169 pSMB->MaxSetupCount = 0;
5173 pSMB->Reserved2 = 0;
5174 byte_count = params + 1 /* pad */ ;
5175 pSMB->TotalParameterCount = cpu_to_le16(params);
5176 pSMB->ParameterCount = pSMB->TotalParameterCount;
5177 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5178 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5179 pSMB->DataCount = 0;
5180 pSMB->DataOffset = 0;
5181 pSMB->SetupCount = 1;
5182 pSMB->Reserved3 = 0;
5183 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5184 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5185 inc_rfc1001_len(pSMB, byte_count);
5186 pSMB->ByteCount = cpu_to_le16(byte_count);
5188 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5189 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5191 cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
5192 } else { /* decode response */
5193 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5195 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5196 /* BB also check if enough bytes returned */
5197 rc = -EIO; /* bad smb */
5199 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5201 (FILE_SYSTEM_ATTRIBUTE_INFO
5202 *) (((char *) &pSMBr->hdr.Protocol) +
5204 memcpy(&tcon->fsAttrInfo, response_data,
5205 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5208 cifs_buf_release(pSMB);
5211 goto QFSAttributeRetry;
5217 CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
5219 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5220 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5221 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5222 FILE_SYSTEM_DEVICE_INFO *response_data;
5224 int bytes_returned = 0;
5225 __u16 params, byte_count;
5227 cFYI(1, "In QFSDeviceInfo");
5229 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5234 params = 2; /* level */
5235 pSMB->TotalDataCount = 0;
5236 pSMB->MaxParameterCount = cpu_to_le16(2);
5237 /* BB find exact max SMB PDU from sess structure BB */
5238 pSMB->MaxDataCount = cpu_to_le16(1000);
5239 pSMB->MaxSetupCount = 0;
5243 pSMB->Reserved2 = 0;
5244 byte_count = params + 1 /* pad */ ;
5245 pSMB->TotalParameterCount = cpu_to_le16(params);
5246 pSMB->ParameterCount = pSMB->TotalParameterCount;
5247 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5248 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5250 pSMB->DataCount = 0;
5251 pSMB->DataOffset = 0;
5252 pSMB->SetupCount = 1;
5253 pSMB->Reserved3 = 0;
5254 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5255 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5256 inc_rfc1001_len(pSMB, byte_count);
5257 pSMB->ByteCount = cpu_to_le16(byte_count);
5259 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5260 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5262 cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
5263 } else { /* decode response */
5264 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5266 if (rc || get_bcc(&pSMBr->hdr) <
5267 sizeof(FILE_SYSTEM_DEVICE_INFO))
5268 rc = -EIO; /* bad smb */
5270 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5272 (FILE_SYSTEM_DEVICE_INFO *)
5273 (((char *) &pSMBr->hdr.Protocol) +
5275 memcpy(&tcon->fsDevInfo, response_data,
5276 sizeof(FILE_SYSTEM_DEVICE_INFO));
5279 cifs_buf_release(pSMB);
5282 goto QFSDeviceRetry;
5288 CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
5290 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5291 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5292 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5293 FILE_SYSTEM_UNIX_INFO *response_data;
5295 int bytes_returned = 0;
5296 __u16 params, byte_count;
5298 cFYI(1, "In QFSUnixInfo");
5300 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5301 (void **) &pSMB, (void **) &pSMBr);
5305 params = 2; /* level */
5306 pSMB->TotalDataCount = 0;
5307 pSMB->DataCount = 0;
5308 pSMB->DataOffset = 0;
5309 pSMB->MaxParameterCount = cpu_to_le16(2);
5310 /* BB find exact max SMB PDU from sess structure BB */
5311 pSMB->MaxDataCount = cpu_to_le16(100);
5312 pSMB->MaxSetupCount = 0;
5316 pSMB->Reserved2 = 0;
5317 byte_count = params + 1 /* pad */ ;
5318 pSMB->ParameterCount = cpu_to_le16(params);
5319 pSMB->TotalParameterCount = pSMB->ParameterCount;
5320 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5321 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5322 pSMB->SetupCount = 1;
5323 pSMB->Reserved3 = 0;
5324 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5325 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5326 inc_rfc1001_len(pSMB, byte_count);
5327 pSMB->ByteCount = cpu_to_le16(byte_count);
5329 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5330 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5332 cERROR(1, "Send error in QFSUnixInfo = %d", rc);
5333 } else { /* decode response */
5334 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5336 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5337 rc = -EIO; /* bad smb */
5339 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5341 (FILE_SYSTEM_UNIX_INFO
5342 *) (((char *) &pSMBr->hdr.Protocol) +
5344 memcpy(&tcon->fsUnixInfo, response_data,
5345 sizeof(FILE_SYSTEM_UNIX_INFO));
5348 cifs_buf_release(pSMB);
5358 CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
5360 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5361 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5362 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5364 int bytes_returned = 0;
5365 __u16 params, param_offset, offset, byte_count;
5367 cFYI(1, "In SETFSUnixInfo");
5369 /* BB switch to small buf init to save memory */
5370 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5371 (void **) &pSMB, (void **) &pSMBr);
5375 params = 4; /* 2 bytes zero followed by info level. */
5376 pSMB->MaxSetupCount = 0;
5380 pSMB->Reserved2 = 0;
5381 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5383 offset = param_offset + params;
5385 pSMB->MaxParameterCount = cpu_to_le16(4);
5386 /* BB find exact max SMB PDU from sess structure BB */
5387 pSMB->MaxDataCount = cpu_to_le16(100);
5388 pSMB->SetupCount = 1;
5389 pSMB->Reserved3 = 0;
5390 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5391 byte_count = 1 /* pad */ + params + 12;
5393 pSMB->DataCount = cpu_to_le16(12);
5394 pSMB->ParameterCount = cpu_to_le16(params);
5395 pSMB->TotalDataCount = pSMB->DataCount;
5396 pSMB->TotalParameterCount = pSMB->ParameterCount;
5397 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5398 pSMB->DataOffset = cpu_to_le16(offset);
5402 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5405 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5406 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5407 pSMB->ClientUnixCap = cpu_to_le64(cap);
5409 inc_rfc1001_len(pSMB, byte_count);
5410 pSMB->ByteCount = cpu_to_le16(byte_count);
5412 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5413 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5415 cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
5416 } else { /* decode response */
5417 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5419 rc = -EIO; /* bad smb */
5421 cifs_buf_release(pSMB);
5424 goto SETFSUnixRetry;
5432 CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
5433 struct kstatfs *FSData)
5435 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5436 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5437 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5438 FILE_SYSTEM_POSIX_INFO *response_data;
5440 int bytes_returned = 0;
5441 __u16 params, byte_count;
5443 cFYI(1, "In QFSPosixInfo");
5445 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5450 params = 2; /* level */
5451 pSMB->TotalDataCount = 0;
5452 pSMB->DataCount = 0;
5453 pSMB->DataOffset = 0;
5454 pSMB->MaxParameterCount = cpu_to_le16(2);
5455 /* BB find exact max SMB PDU from sess structure BB */
5456 pSMB->MaxDataCount = cpu_to_le16(100);
5457 pSMB->MaxSetupCount = 0;
5461 pSMB->Reserved2 = 0;
5462 byte_count = params + 1 /* pad */ ;
5463 pSMB->ParameterCount = cpu_to_le16(params);
5464 pSMB->TotalParameterCount = pSMB->ParameterCount;
5465 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5466 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5467 pSMB->SetupCount = 1;
5468 pSMB->Reserved3 = 0;
5469 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5470 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5471 inc_rfc1001_len(pSMB, byte_count);
5472 pSMB->ByteCount = cpu_to_le16(byte_count);
5474 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5475 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5477 cFYI(1, "Send error in QFSUnixInfo = %d", rc);
5478 } else { /* decode response */
5479 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5481 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5482 rc = -EIO; /* bad smb */
5484 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5486 (FILE_SYSTEM_POSIX_INFO
5487 *) (((char *) &pSMBr->hdr.Protocol) +
5490 le32_to_cpu(response_data->BlockSize);
5492 le64_to_cpu(response_data->TotalBlocks);
5494 le64_to_cpu(response_data->BlocksAvail);
5495 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5496 FSData->f_bavail = FSData->f_bfree;
5499 le64_to_cpu(response_data->UserBlocksAvail);
5501 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5503 le64_to_cpu(response_data->TotalFileNodes);
5504 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5506 le64_to_cpu(response_data->FreeFileNodes);
5509 cifs_buf_release(pSMB);
5518 /* We can not use write of zero bytes trick to
5519 set file size due to need for large file support. Also note that
5520 this SetPathInfo is preferred to SetFileInfo based method in next
5521 routine which is only needed to work around a sharing violation bug
5522 in Samba which this routine can run into */
5525 CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
5526 __u64 size, bool SetAllocation,
5527 const struct nls_table *nls_codepage, int remap)
5529 struct smb_com_transaction2_spi_req *pSMB = NULL;
5530 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5531 struct file_end_of_file_info *parm_data;
5534 int bytes_returned = 0;
5535 __u16 params, byte_count, data_count, param_offset, offset;
5537 cFYI(1, "In SetEOF");
5539 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5544 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5546 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
5547 PATH_MAX, nls_codepage, remap);
5548 name_len++; /* trailing null */
5550 } else { /* BB improve the check for buffer overruns BB */
5551 name_len = strnlen(fileName, PATH_MAX);
5552 name_len++; /* trailing null */
5553 strncpy(pSMB->FileName, fileName, name_len);
5555 params = 6 + name_len;
5556 data_count = sizeof(struct file_end_of_file_info);
5557 pSMB->MaxParameterCount = cpu_to_le16(2);
5558 pSMB->MaxDataCount = cpu_to_le16(4100);
5559 pSMB->MaxSetupCount = 0;
5563 pSMB->Reserved2 = 0;
5564 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5565 InformationLevel) - 4;
5566 offset = param_offset + params;
5567 if (SetAllocation) {
5568 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5569 pSMB->InformationLevel =
5570 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5572 pSMB->InformationLevel =
5573 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5574 } else /* Set File Size */ {
5575 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5576 pSMB->InformationLevel =
5577 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5579 pSMB->InformationLevel =
5580 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5584 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5586 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5587 pSMB->DataOffset = cpu_to_le16(offset);
5588 pSMB->SetupCount = 1;
5589 pSMB->Reserved3 = 0;
5590 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5591 byte_count = 3 /* pad */ + params + data_count;
5592 pSMB->DataCount = cpu_to_le16(data_count);
5593 pSMB->TotalDataCount = pSMB->DataCount;
5594 pSMB->ParameterCount = cpu_to_le16(params);
5595 pSMB->TotalParameterCount = pSMB->ParameterCount;
5596 pSMB->Reserved4 = 0;
5597 inc_rfc1001_len(pSMB, byte_count);
5598 parm_data->FileSize = cpu_to_le64(size);
5599 pSMB->ByteCount = cpu_to_le16(byte_count);
5600 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5601 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5603 cFYI(1, "SetPathInfo (file size) returned %d", rc);
5605 cifs_buf_release(pSMB);
5614 CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
5615 __u16 fid, __u32 pid_of_opener, bool SetAllocation)
5617 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5618 struct file_end_of_file_info *parm_data;
5620 __u16 params, param_offset, offset, byte_count, count;
5622 cFYI(1, "SetFileSize (via SetFileInfo) %lld",
5624 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5629 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5630 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5633 pSMB->MaxSetupCount = 0;
5637 pSMB->Reserved2 = 0;
5638 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5639 offset = param_offset + params;
5641 count = sizeof(struct file_end_of_file_info);
5642 pSMB->MaxParameterCount = cpu_to_le16(2);
5643 /* BB find exact max SMB PDU from sess structure BB */
5644 pSMB->MaxDataCount = cpu_to_le16(1000);
5645 pSMB->SetupCount = 1;
5646 pSMB->Reserved3 = 0;
5647 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5648 byte_count = 3 /* pad */ + params + count;
5649 pSMB->DataCount = cpu_to_le16(count);
5650 pSMB->ParameterCount = cpu_to_le16(params);
5651 pSMB->TotalDataCount = pSMB->DataCount;
5652 pSMB->TotalParameterCount = pSMB->ParameterCount;
5653 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5655 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5657 pSMB->DataOffset = cpu_to_le16(offset);
5658 parm_data->FileSize = cpu_to_le64(size);
5660 if (SetAllocation) {
5661 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5662 pSMB->InformationLevel =
5663 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5665 pSMB->InformationLevel =
5666 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5667 } else /* Set File Size */ {
5668 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5669 pSMB->InformationLevel =
5670 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5672 pSMB->InformationLevel =
5673 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5675 pSMB->Reserved4 = 0;
5676 inc_rfc1001_len(pSMB, byte_count);
5677 pSMB->ByteCount = cpu_to_le16(byte_count);
5678 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5680 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
5683 /* Note: On -EAGAIN error only caller can retry on handle based calls
5684 since file handle passed in no longer valid */
5689 /* Some legacy servers such as NT4 require that the file times be set on
5690 an open handle, rather than by pathname - this is awkward due to
5691 potential access conflicts on the open, but it is unavoidable for these
5692 old servers since the only other choice is to go from 100 nanosecond DCE
5693 time and resort to the original setpathinfo level which takes the ancient
5694 DOS time format with 2 second granularity */
5696 CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
5697 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5699 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5702 __u16 params, param_offset, offset, byte_count, count;
5704 cFYI(1, "Set Times (via SetFileInfo)");
5705 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5710 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5711 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5714 pSMB->MaxSetupCount = 0;
5718 pSMB->Reserved2 = 0;
5719 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5720 offset = param_offset + params;
5722 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5724 count = sizeof(FILE_BASIC_INFO);
5725 pSMB->MaxParameterCount = cpu_to_le16(2);
5726 /* BB find max SMB PDU from sess */
5727 pSMB->MaxDataCount = cpu_to_le16(1000);
5728 pSMB->SetupCount = 1;
5729 pSMB->Reserved3 = 0;
5730 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5731 byte_count = 3 /* pad */ + params + count;
5732 pSMB->DataCount = cpu_to_le16(count);
5733 pSMB->ParameterCount = cpu_to_le16(params);
5734 pSMB->TotalDataCount = pSMB->DataCount;
5735 pSMB->TotalParameterCount = pSMB->ParameterCount;
5736 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5737 pSMB->DataOffset = cpu_to_le16(offset);
5739 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5740 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5742 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5743 pSMB->Reserved4 = 0;
5744 inc_rfc1001_len(pSMB, byte_count);
5745 pSMB->ByteCount = cpu_to_le16(byte_count);
5746 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5747 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5749 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5751 /* Note: On -EAGAIN error only caller can retry on handle based calls
5752 since file handle passed in no longer valid */
5758 CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
5759 bool delete_file, __u16 fid, __u32 pid_of_opener)
5761 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5764 __u16 params, param_offset, offset, byte_count, count;
5766 cFYI(1, "Set File Disposition (via SetFileInfo)");
5767 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5772 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5773 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5776 pSMB->MaxSetupCount = 0;
5780 pSMB->Reserved2 = 0;
5781 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5782 offset = param_offset + params;
5784 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5787 pSMB->MaxParameterCount = cpu_to_le16(2);
5788 /* BB find max SMB PDU from sess */
5789 pSMB->MaxDataCount = cpu_to_le16(1000);
5790 pSMB->SetupCount = 1;
5791 pSMB->Reserved3 = 0;
5792 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5793 byte_count = 3 /* pad */ + params + count;
5794 pSMB->DataCount = cpu_to_le16(count);
5795 pSMB->ParameterCount = cpu_to_le16(params);
5796 pSMB->TotalDataCount = pSMB->DataCount;
5797 pSMB->TotalParameterCount = pSMB->ParameterCount;
5798 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5799 pSMB->DataOffset = cpu_to_le16(offset);
5801 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5802 pSMB->Reserved4 = 0;
5803 inc_rfc1001_len(pSMB, byte_count);
5804 pSMB->ByteCount = cpu_to_le16(byte_count);
5805 *data_offset = delete_file ? 1 : 0;
5806 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5808 cFYI(1, "Send error in SetFileDisposition = %d", rc);
5814 CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
5815 const char *fileName, const FILE_BASIC_INFO *data,
5816 const struct nls_table *nls_codepage, int remap)
5818 TRANSACTION2_SPI_REQ *pSMB = NULL;
5819 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5822 int bytes_returned = 0;
5824 __u16 params, param_offset, offset, byte_count, count;
5826 cFYI(1, "In SetTimes");
5829 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5834 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5836 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
5837 PATH_MAX, nls_codepage, remap);
5838 name_len++; /* trailing null */
5840 } else { /* BB improve the check for buffer overruns BB */
5841 name_len = strnlen(fileName, PATH_MAX);
5842 name_len++; /* trailing null */
5843 strncpy(pSMB->FileName, fileName, name_len);
5846 params = 6 + name_len;
5847 count = sizeof(FILE_BASIC_INFO);
5848 pSMB->MaxParameterCount = cpu_to_le16(2);
5849 /* BB find max SMB PDU from sess structure BB */
5850 pSMB->MaxDataCount = cpu_to_le16(1000);
5851 pSMB->MaxSetupCount = 0;
5855 pSMB->Reserved2 = 0;
5856 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5857 InformationLevel) - 4;
5858 offset = param_offset + params;
5859 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5860 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5861 pSMB->DataOffset = cpu_to_le16(offset);
5862 pSMB->SetupCount = 1;
5863 pSMB->Reserved3 = 0;
5864 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5865 byte_count = 3 /* pad */ + params + count;
5867 pSMB->DataCount = cpu_to_le16(count);
5868 pSMB->ParameterCount = cpu_to_le16(params);
5869 pSMB->TotalDataCount = pSMB->DataCount;
5870 pSMB->TotalParameterCount = pSMB->ParameterCount;
5871 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5872 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5874 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5875 pSMB->Reserved4 = 0;
5876 inc_rfc1001_len(pSMB, byte_count);
5877 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5878 pSMB->ByteCount = cpu_to_le16(byte_count);
5879 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5880 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5882 cFYI(1, "SetPathInfo (times) returned %d", rc);
5884 cifs_buf_release(pSMB);
5892 /* Can not be used to set time stamps yet (due to old DOS time format) */
5893 /* Can be used to set attributes */
5894 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5895 handling it anyway and NT4 was what we thought it would be needed for
5896 Do not delete it until we prove whether needed for Win9x though */
5898 CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon, char *fileName,
5899 __u16 dos_attrs, const struct nls_table *nls_codepage)
5901 SETATTR_REQ *pSMB = NULL;
5902 SETATTR_RSP *pSMBr = NULL;
5907 cFYI(1, "In SetAttrLegacy");
5910 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5915 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5917 ConvertToUCS((__le16 *) pSMB->fileName, fileName,
5918 PATH_MAX, nls_codepage);
5919 name_len++; /* trailing null */
5921 } else { /* BB improve the check for buffer overruns BB */
5922 name_len = strnlen(fileName, PATH_MAX);
5923 name_len++; /* trailing null */
5924 strncpy(pSMB->fileName, fileName, name_len);
5926 pSMB->attr = cpu_to_le16(dos_attrs);
5927 pSMB->BufferFormat = 0x04;
5928 inc_rfc1001_len(pSMB, name_len + 1);
5929 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5930 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5931 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5933 cFYI(1, "Error in LegacySetAttr = %d", rc);
5935 cifs_buf_release(pSMB);
5938 goto SetAttrLgcyRetry;
5942 #endif /* temporarily unneeded SetAttr legacy function */
5945 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5946 const struct cifs_unix_set_info_args *args)
5948 u64 mode = args->mode;
5951 * Samba server ignores set of file size to zero due to bugs in some
5952 * older clients, but we should be precise - we use SetFileSize to
5953 * set file size and do not want to truncate file size to zero
5954 * accidentally as happened on one Samba server beta by putting
5955 * zero instead of -1 here
5957 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5958 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5959 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5960 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5961 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5962 data_offset->Uid = cpu_to_le64(args->uid);
5963 data_offset->Gid = cpu_to_le64(args->gid);
5964 /* better to leave device as zero when it is */
5965 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5966 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5967 data_offset->Permissions = cpu_to_le64(mode);
5970 data_offset->Type = cpu_to_le32(UNIX_FILE);
5971 else if (S_ISDIR(mode))
5972 data_offset->Type = cpu_to_le32(UNIX_DIR);
5973 else if (S_ISLNK(mode))
5974 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5975 else if (S_ISCHR(mode))
5976 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5977 else if (S_ISBLK(mode))
5978 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5979 else if (S_ISFIFO(mode))
5980 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5981 else if (S_ISSOCK(mode))
5982 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5986 CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
5987 const struct cifs_unix_set_info_args *args,
5988 u16 fid, u32 pid_of_opener)
5990 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5991 FILE_UNIX_BASIC_INFO *data_offset;
5993 u16 params, param_offset, offset, byte_count, count;
5995 cFYI(1, "Set Unix Info (via SetFileInfo)");
5996 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
6001 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
6002 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
6005 pSMB->MaxSetupCount = 0;
6009 pSMB->Reserved2 = 0;
6010 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
6011 offset = param_offset + params;
6013 data_offset = (FILE_UNIX_BASIC_INFO *)
6014 ((char *)(&pSMB->hdr.Protocol) + offset);
6015 count = sizeof(FILE_UNIX_BASIC_INFO);
6017 pSMB->MaxParameterCount = cpu_to_le16(2);
6018 /* BB find max SMB PDU from sess */
6019 pSMB->MaxDataCount = cpu_to_le16(1000);
6020 pSMB->SetupCount = 1;
6021 pSMB->Reserved3 = 0;
6022 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
6023 byte_count = 3 /* pad */ + params + count;
6024 pSMB->DataCount = cpu_to_le16(count);
6025 pSMB->ParameterCount = cpu_to_le16(params);
6026 pSMB->TotalDataCount = pSMB->DataCount;
6027 pSMB->TotalParameterCount = pSMB->ParameterCount;
6028 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6029 pSMB->DataOffset = cpu_to_le16(offset);
6031 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6032 pSMB->Reserved4 = 0;
6033 inc_rfc1001_len(pSMB, byte_count);
6034 pSMB->ByteCount = cpu_to_le16(byte_count);
6036 cifs_fill_unix_set_info(data_offset, args);
6038 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
6040 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
6042 /* Note: On -EAGAIN error only caller can retry on handle based calls
6043 since file handle passed in no longer valid */
6049 CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *tcon, char *fileName,
6050 const struct cifs_unix_set_info_args *args,
6051 const struct nls_table *nls_codepage, int remap)
6053 TRANSACTION2_SPI_REQ *pSMB = NULL;
6054 TRANSACTION2_SPI_RSP *pSMBr = NULL;
6057 int bytes_returned = 0;
6058 FILE_UNIX_BASIC_INFO *data_offset;
6059 __u16 params, param_offset, offset, count, byte_count;
6061 cFYI(1, "In SetUID/GID/Mode");
6063 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6068 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6070 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
6071 PATH_MAX, nls_codepage, remap);
6072 name_len++; /* trailing null */
6074 } else { /* BB improve the check for buffer overruns BB */
6075 name_len = strnlen(fileName, PATH_MAX);
6076 name_len++; /* trailing null */
6077 strncpy(pSMB->FileName, fileName, name_len);
6080 params = 6 + name_len;
6081 count = sizeof(FILE_UNIX_BASIC_INFO);
6082 pSMB->MaxParameterCount = cpu_to_le16(2);
6083 /* BB find max SMB PDU from sess structure BB */
6084 pSMB->MaxDataCount = cpu_to_le16(1000);
6085 pSMB->MaxSetupCount = 0;
6089 pSMB->Reserved2 = 0;
6090 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6091 InformationLevel) - 4;
6092 offset = param_offset + params;
6094 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6096 memset(data_offset, 0, count);
6097 pSMB->DataOffset = cpu_to_le16(offset);
6098 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6099 pSMB->SetupCount = 1;
6100 pSMB->Reserved3 = 0;
6101 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6102 byte_count = 3 /* pad */ + params + count;
6103 pSMB->ParameterCount = cpu_to_le16(params);
6104 pSMB->DataCount = cpu_to_le16(count);
6105 pSMB->TotalParameterCount = pSMB->ParameterCount;
6106 pSMB->TotalDataCount = pSMB->DataCount;
6107 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6108 pSMB->Reserved4 = 0;
6109 inc_rfc1001_len(pSMB, byte_count);
6111 cifs_fill_unix_set_info(data_offset, args);
6113 pSMB->ByteCount = cpu_to_le16(byte_count);
6114 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6115 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6117 cFYI(1, "SetPathInfo (perms) returned %d", rc);
6119 cifs_buf_release(pSMB);
6125 #ifdef CONFIG_CIFS_XATTR
6127 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6128 * function used by listxattr and getxattr type calls. When ea_name is set,
6129 * it looks for that attribute name and stuffs that value into the EAData
6130 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6131 * buffer. In both cases, the return value is either the length of the
6132 * resulting data or a negative error code. If EAData is a NULL pointer then
6133 * the data isn't copied to it, but the length is returned.
6136 CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
6137 const unsigned char *searchName, const unsigned char *ea_name,
6138 char *EAData, size_t buf_size,
6139 const struct nls_table *nls_codepage, int remap)
6141 /* BB assumes one setup word */
6142 TRANSACTION2_QPI_REQ *pSMB = NULL;
6143 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6147 struct fealist *ea_response_data;
6148 struct fea *temp_fea;
6151 __u16 params, byte_count, data_offset;
6152 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6154 cFYI(1, "In Query All EAs path %s", searchName);
6156 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6161 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6163 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
6164 PATH_MAX, nls_codepage, remap);
6165 list_len++; /* trailing null */
6167 } else { /* BB improve the check for buffer overruns BB */
6168 list_len = strnlen(searchName, PATH_MAX);
6169 list_len++; /* trailing null */
6170 strncpy(pSMB->FileName, searchName, list_len);
6173 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6174 pSMB->TotalDataCount = 0;
6175 pSMB->MaxParameterCount = cpu_to_le16(2);
6176 /* BB find exact max SMB PDU from sess structure BB */
6177 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6178 pSMB->MaxSetupCount = 0;
6182 pSMB->Reserved2 = 0;
6183 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6184 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6185 pSMB->DataCount = 0;
6186 pSMB->DataOffset = 0;
6187 pSMB->SetupCount = 1;
6188 pSMB->Reserved3 = 0;
6189 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6190 byte_count = params + 1 /* pad */ ;
6191 pSMB->TotalParameterCount = cpu_to_le16(params);
6192 pSMB->ParameterCount = pSMB->TotalParameterCount;
6193 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6194 pSMB->Reserved4 = 0;
6195 inc_rfc1001_len(pSMB, byte_count);
6196 pSMB->ByteCount = cpu_to_le16(byte_count);
6198 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6199 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6201 cFYI(1, "Send error in QueryAllEAs = %d", rc);
6206 /* BB also check enough total bytes returned */
6207 /* BB we need to improve the validity checking
6208 of these trans2 responses */
6210 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6211 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6212 rc = -EIO; /* bad smb */
6216 /* check that length of list is not more than bcc */
6217 /* check that each entry does not go beyond length
6219 /* check that each element of each entry does not
6220 go beyond end of list */
6221 /* validate_trans2_offsets() */
6222 /* BB check if start of smb + data_offset > &bcc+ bcc */
6224 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6225 ea_response_data = (struct fealist *)
6226 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6228 list_len = le32_to_cpu(ea_response_data->list_len);
6229 cFYI(1, "ea length %d", list_len);
6230 if (list_len <= 8) {
6231 cFYI(1, "empty EA list returned from server");
6235 /* make sure list_len doesn't go past end of SMB */
6236 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6237 if ((char *)ea_response_data + list_len > end_of_smb) {
6238 cFYI(1, "EA list appears to go beyond SMB");
6243 /* account for ea list len */
6245 temp_fea = ea_response_data->list;
6246 temp_ptr = (char *)temp_fea;
6247 while (list_len > 0) {
6248 unsigned int name_len;
6253 /* make sure we can read name_len and value_len */
6255 cFYI(1, "EA entry goes beyond length of list");
6260 name_len = temp_fea->name_len;
6261 value_len = le16_to_cpu(temp_fea->value_len);
6262 list_len -= name_len + 1 + value_len;
6264 cFYI(1, "EA entry goes beyond length of list");
6270 if (ea_name_len == name_len &&
6271 memcmp(ea_name, temp_ptr, name_len) == 0) {
6272 temp_ptr += name_len + 1;
6276 if ((size_t)value_len > buf_size) {
6280 memcpy(EAData, temp_ptr, value_len);
6284 /* account for prefix user. and trailing null */
6285 rc += (5 + 1 + name_len);
6286 if (rc < (int) buf_size) {
6287 memcpy(EAData, "user.", 5);
6289 memcpy(EAData, temp_ptr, name_len);
6291 /* null terminate name */
6294 } else if (buf_size == 0) {
6295 /* skip copy - calc size only */
6297 /* stop before overrun buffer */
6302 temp_ptr += name_len + 1 + value_len;
6303 temp_fea = (struct fea *)temp_ptr;
6306 /* didn't find the named attribute */
6311 cifs_buf_release(pSMB);
6319 CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon, const char *fileName,
6320 const char *ea_name, const void *ea_value,
6321 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6324 struct smb_com_transaction2_spi_req *pSMB = NULL;
6325 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6326 struct fealist *parm_data;
6329 int bytes_returned = 0;
6330 __u16 params, param_offset, byte_count, offset, count;
6332 cFYI(1, "In SetEA");
6334 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6339 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6341 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
6342 PATH_MAX, nls_codepage, remap);
6343 name_len++; /* trailing null */
6345 } else { /* BB improve the check for buffer overruns BB */
6346 name_len = strnlen(fileName, PATH_MAX);
6347 name_len++; /* trailing null */
6348 strncpy(pSMB->FileName, fileName, name_len);
6351 params = 6 + name_len;
6353 /* done calculating parms using name_len of file name,
6354 now use name_len to calculate length of ea name
6355 we are going to create in the inode xattrs */
6356 if (ea_name == NULL)
6359 name_len = strnlen(ea_name, 255);
6361 count = sizeof(*parm_data) + ea_value_len + name_len;
6362 pSMB->MaxParameterCount = cpu_to_le16(2);
6363 /* BB find max SMB PDU from sess */
6364 pSMB->MaxDataCount = cpu_to_le16(1000);
6365 pSMB->MaxSetupCount = 0;
6369 pSMB->Reserved2 = 0;
6370 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6371 InformationLevel) - 4;
6372 offset = param_offset + params;
6373 pSMB->InformationLevel =
6374 cpu_to_le16(SMB_SET_FILE_EA);
6377 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6379 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6380 pSMB->DataOffset = cpu_to_le16(offset);
6381 pSMB->SetupCount = 1;
6382 pSMB->Reserved3 = 0;
6383 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6384 byte_count = 3 /* pad */ + params + count;
6385 pSMB->DataCount = cpu_to_le16(count);
6386 parm_data->list_len = cpu_to_le32(count);
6387 parm_data->list[0].EA_flags = 0;
6388 /* we checked above that name len is less than 255 */
6389 parm_data->list[0].name_len = (__u8)name_len;
6390 /* EA names are always ASCII */
6392 strncpy(parm_data->list[0].name, ea_name, name_len);
6393 parm_data->list[0].name[name_len] = 0;
6394 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6395 /* caller ensures that ea_value_len is less than 64K but
6396 we need to ensure that it fits within the smb */
6398 /*BB add length check to see if it would fit in
6399 negotiated SMB buffer size BB */
6400 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6402 memcpy(parm_data->list[0].name+name_len+1,
6403 ea_value, ea_value_len);
6405 pSMB->TotalDataCount = pSMB->DataCount;
6406 pSMB->ParameterCount = cpu_to_le16(params);
6407 pSMB->TotalParameterCount = pSMB->ParameterCount;
6408 pSMB->Reserved4 = 0;
6409 inc_rfc1001_len(pSMB, byte_count);
6410 pSMB->ByteCount = cpu_to_le16(byte_count);
6411 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6412 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6414 cFYI(1, "SetPathInfo (EA) returned %d", rc);
6416 cifs_buf_release(pSMB);
6425 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6427 * Years ago the kernel added a "dnotify" function for Samba server,
6428 * to allow network clients (such as Windows) to display updated
6429 * lists of files in directory listings automatically when
6430 * files are added by one user when another user has the
6431 * same directory open on their desktop. The Linux cifs kernel
6432 * client hooked into the kernel side of this interface for
6433 * the same reason, but ironically when the VFS moved from
6434 * "dnotify" to "inotify" it became harder to plug in Linux
6435 * network file system clients (the most obvious use case
6436 * for notify interfaces is when multiple users can update
6437 * the contents of the same directory - exactly what network
6438 * file systems can do) although the server (Samba) could
6439 * still use it. For the short term we leave the worker
6440 * function ifdeffed out (below) until inotify is fixed
6441 * in the VFS to make it easier to plug in network file
6442 * system clients. If inotify turns out to be permanently
6443 * incompatible for network fs clients, we could instead simply
6444 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6446 int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
6447 const int notify_subdirs, const __u16 netfid,
6448 __u32 filter, struct file *pfile, int multishot,
6449 const struct nls_table *nls_codepage)
6452 struct smb_com_transaction_change_notify_req *pSMB = NULL;
6453 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6454 struct dir_notify_req *dnotify_req;
6457 cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
6458 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6463 pSMB->TotalParameterCount = 0 ;
6464 pSMB->TotalDataCount = 0;
6465 pSMB->MaxParameterCount = cpu_to_le32(2);
6466 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6467 pSMB->MaxSetupCount = 4;
6469 pSMB->ParameterOffset = 0;
6470 pSMB->DataCount = 0;
6471 pSMB->DataOffset = 0;
6472 pSMB->SetupCount = 4; /* single byte does not need le conversion */
6473 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6474 pSMB->ParameterCount = pSMB->TotalParameterCount;
6476 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6477 pSMB->Reserved2 = 0;
6478 pSMB->CompletionFilter = cpu_to_le32(filter);
6479 pSMB->Fid = netfid; /* file handle always le */
6480 pSMB->ByteCount = 0;
6482 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6483 (struct smb_hdr *)pSMBr, &bytes_returned,
6486 cFYI(1, "Error in Notify = %d", rc);
6488 /* Add file to outstanding requests */
6489 /* BB change to kmem cache alloc */
6490 dnotify_req = kmalloc(
6491 sizeof(struct dir_notify_req),
6494 dnotify_req->Pid = pSMB->hdr.Pid;
6495 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6496 dnotify_req->Mid = pSMB->hdr.Mid;
6497 dnotify_req->Tid = pSMB->hdr.Tid;
6498 dnotify_req->Uid = pSMB->hdr.Uid;
6499 dnotify_req->netfid = netfid;
6500 dnotify_req->pfile = pfile;
6501 dnotify_req->filter = filter;
6502 dnotify_req->multishot = multishot;
6503 spin_lock(&GlobalMid_Lock);
6504 list_add_tail(&dnotify_req->lhead,
6505 &GlobalDnotifyReqList);
6506 spin_unlock(&GlobalMid_Lock);
6510 cifs_buf_release(pSMB);
6513 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */