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 if (server->capabilities & CAP_UNICODE)
768 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
770 /* set up echo request */
771 smb->hdr.Tid = 0xffff;
772 smb->hdr.WordCount = 1;
773 put_unaligned_le16(1, &smb->EchoCount);
774 put_bcc(1, &smb->hdr);
776 inc_rfc1001_len(smb, 3);
778 iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
780 rc = cifs_call_async(server, &iov, 1, NULL, cifs_echo_callback,
783 cFYI(1, "Echo request failed: %d", rc);
785 cifs_small_buf_release(smb);
791 CIFSSMBLogoff(const int xid, struct cifs_ses *ses)
793 LOGOFF_ANDX_REQ *pSMB;
796 cFYI(1, "In SMBLogoff for session disconnect");
799 * BB: do we need to check validity of ses and server? They should
800 * always be valid since we have an active reference. If not, that
801 * should probably be a BUG()
803 if (!ses || !ses->server)
806 mutex_lock(&ses->session_mutex);
807 if (ses->need_reconnect)
808 goto session_already_dead; /* no need to send SMBlogoff if uid
809 already closed due to reconnect */
810 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
812 mutex_unlock(&ses->session_mutex);
816 pSMB->hdr.Mid = GetNextMid(ses->server);
818 if (ses->server->sec_mode &
819 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
820 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
822 pSMB->hdr.Uid = ses->Suid;
824 pSMB->AndXCommand = 0xFF;
825 rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0);
826 session_already_dead:
827 mutex_unlock(&ses->session_mutex);
829 /* if session dead then we do not need to do ulogoff,
830 since server closed smb session, no sense reporting
838 CIFSPOSIXDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
839 __u16 type, const struct nls_table *nls_codepage, int remap)
841 TRANSACTION2_SPI_REQ *pSMB = NULL;
842 TRANSACTION2_SPI_RSP *pSMBr = NULL;
843 struct unlink_psx_rq *pRqD;
846 int bytes_returned = 0;
847 __u16 params, param_offset, offset, byte_count;
849 cFYI(1, "In POSIX delete");
851 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
856 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
858 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
859 PATH_MAX, nls_codepage, remap);
860 name_len++; /* trailing null */
862 } else { /* BB add path length overrun check */
863 name_len = strnlen(fileName, PATH_MAX);
864 name_len++; /* trailing null */
865 strncpy(pSMB->FileName, fileName, name_len);
868 params = 6 + name_len;
869 pSMB->MaxParameterCount = cpu_to_le16(2);
870 pSMB->MaxDataCount = 0; /* BB double check this with jra */
871 pSMB->MaxSetupCount = 0;
876 param_offset = offsetof(struct smb_com_transaction2_spi_req,
877 InformationLevel) - 4;
878 offset = param_offset + params;
880 /* Setup pointer to Request Data (inode type) */
881 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
882 pRqD->type = cpu_to_le16(type);
883 pSMB->ParameterOffset = cpu_to_le16(param_offset);
884 pSMB->DataOffset = cpu_to_le16(offset);
885 pSMB->SetupCount = 1;
887 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
888 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
890 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
891 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
892 pSMB->ParameterCount = cpu_to_le16(params);
893 pSMB->TotalParameterCount = pSMB->ParameterCount;
894 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
896 inc_rfc1001_len(pSMB, byte_count);
897 pSMB->ByteCount = cpu_to_le16(byte_count);
898 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
899 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
901 cFYI(1, "Posix delete returned %d", rc);
902 cifs_buf_release(pSMB);
904 cifs_stats_inc(&tcon->num_deletes);
913 CIFSSMBDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
914 const struct nls_table *nls_codepage, int remap)
916 DELETE_FILE_REQ *pSMB = NULL;
917 DELETE_FILE_RSP *pSMBr = NULL;
923 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
928 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
930 cifsConvertToUCS((__le16 *) pSMB->fileName, fileName,
931 PATH_MAX, nls_codepage, remap);
932 name_len++; /* trailing null */
934 } else { /* BB improve check for buffer overruns BB */
935 name_len = strnlen(fileName, PATH_MAX);
936 name_len++; /* trailing null */
937 strncpy(pSMB->fileName, fileName, name_len);
939 pSMB->SearchAttributes =
940 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
941 pSMB->BufferFormat = 0x04;
942 inc_rfc1001_len(pSMB, name_len + 1);
943 pSMB->ByteCount = cpu_to_le16(name_len + 1);
944 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
945 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
946 cifs_stats_inc(&tcon->num_deletes);
948 cFYI(1, "Error in RMFile = %d", rc);
950 cifs_buf_release(pSMB);
958 CIFSSMBRmDir(const int xid, struct cifs_tcon *tcon, const char *dirName,
959 const struct nls_table *nls_codepage, int remap)
961 DELETE_DIRECTORY_REQ *pSMB = NULL;
962 DELETE_DIRECTORY_RSP *pSMBr = NULL;
967 cFYI(1, "In CIFSSMBRmDir");
969 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
974 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
975 name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, dirName,
976 PATH_MAX, nls_codepage, remap);
977 name_len++; /* trailing null */
979 } else { /* BB improve check for buffer overruns BB */
980 name_len = strnlen(dirName, PATH_MAX);
981 name_len++; /* trailing null */
982 strncpy(pSMB->DirName, dirName, name_len);
985 pSMB->BufferFormat = 0x04;
986 inc_rfc1001_len(pSMB, name_len + 1);
987 pSMB->ByteCount = cpu_to_le16(name_len + 1);
988 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
989 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
990 cifs_stats_inc(&tcon->num_rmdirs);
992 cFYI(1, "Error in RMDir = %d", rc);
994 cifs_buf_release(pSMB);
1001 CIFSSMBMkDir(const int xid, struct cifs_tcon *tcon,
1002 const char *name, const struct nls_table *nls_codepage, int remap)
1005 CREATE_DIRECTORY_REQ *pSMB = NULL;
1006 CREATE_DIRECTORY_RSP *pSMBr = NULL;
1010 cFYI(1, "In CIFSSMBMkDir");
1012 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
1017 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1018 name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, name,
1019 PATH_MAX, nls_codepage, remap);
1020 name_len++; /* trailing null */
1022 } else { /* BB improve check for buffer overruns BB */
1023 name_len = strnlen(name, PATH_MAX);
1024 name_len++; /* trailing null */
1025 strncpy(pSMB->DirName, name, name_len);
1028 pSMB->BufferFormat = 0x04;
1029 inc_rfc1001_len(pSMB, name_len + 1);
1030 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1031 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1032 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1033 cifs_stats_inc(&tcon->num_mkdirs);
1035 cFYI(1, "Error in Mkdir = %d", rc);
1037 cifs_buf_release(pSMB);
1044 CIFSPOSIXCreate(const int xid, struct cifs_tcon *tcon, __u32 posix_flags,
1045 __u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData,
1046 __u32 *pOplock, const char *name,
1047 const struct nls_table *nls_codepage, int remap)
1049 TRANSACTION2_SPI_REQ *pSMB = NULL;
1050 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1053 int bytes_returned = 0;
1054 __u16 params, param_offset, offset, byte_count, count;
1055 OPEN_PSX_REQ *pdata;
1056 OPEN_PSX_RSP *psx_rsp;
1058 cFYI(1, "In POSIX Create");
1060 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1065 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1067 cifsConvertToUCS((__le16 *) pSMB->FileName, name,
1068 PATH_MAX, nls_codepage, remap);
1069 name_len++; /* trailing null */
1071 } else { /* BB improve the check for buffer overruns BB */
1072 name_len = strnlen(name, PATH_MAX);
1073 name_len++; /* trailing null */
1074 strncpy(pSMB->FileName, name, name_len);
1077 params = 6 + name_len;
1078 count = sizeof(OPEN_PSX_REQ);
1079 pSMB->MaxParameterCount = cpu_to_le16(2);
1080 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1081 pSMB->MaxSetupCount = 0;
1085 pSMB->Reserved2 = 0;
1086 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1087 InformationLevel) - 4;
1088 offset = param_offset + params;
1089 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1090 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1091 pdata->Permissions = cpu_to_le64(mode);
1092 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1093 pdata->OpenFlags = cpu_to_le32(*pOplock);
1094 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1095 pSMB->DataOffset = cpu_to_le16(offset);
1096 pSMB->SetupCount = 1;
1097 pSMB->Reserved3 = 0;
1098 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1099 byte_count = 3 /* pad */ + params + count;
1101 pSMB->DataCount = cpu_to_le16(count);
1102 pSMB->ParameterCount = cpu_to_le16(params);
1103 pSMB->TotalDataCount = pSMB->DataCount;
1104 pSMB->TotalParameterCount = pSMB->ParameterCount;
1105 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1106 pSMB->Reserved4 = 0;
1107 inc_rfc1001_len(pSMB, byte_count);
1108 pSMB->ByteCount = cpu_to_le16(byte_count);
1109 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1110 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1112 cFYI(1, "Posix create returned %d", rc);
1113 goto psx_create_err;
1116 cFYI(1, "copying inode info");
1117 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1119 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1120 rc = -EIO; /* bad smb */
1121 goto psx_create_err;
1124 /* copy return information to pRetData */
1125 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1126 + le16_to_cpu(pSMBr->t2.DataOffset));
1128 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1130 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1131 /* Let caller know file was created so we can set the mode. */
1132 /* Do we care about the CreateAction in any other cases? */
1133 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1134 *pOplock |= CIFS_CREATE_ACTION;
1135 /* check to make sure response data is there */
1136 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1137 pRetData->Type = cpu_to_le32(-1); /* unknown */
1138 cFYI(DBG2, "unknown type");
1140 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1141 + sizeof(FILE_UNIX_BASIC_INFO)) {
1142 cERROR(1, "Open response data too small");
1143 pRetData->Type = cpu_to_le32(-1);
1144 goto psx_create_err;
1146 memcpy((char *) pRetData,
1147 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1148 sizeof(FILE_UNIX_BASIC_INFO));
1152 cifs_buf_release(pSMB);
1154 if (posix_flags & SMB_O_DIRECTORY)
1155 cifs_stats_inc(&tcon->num_posixmkdirs);
1157 cifs_stats_inc(&tcon->num_posixopens);
1165 static __u16 convert_disposition(int disposition)
1169 switch (disposition) {
1170 case FILE_SUPERSEDE:
1171 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1174 ofun = SMBOPEN_OAPPEND;
1177 ofun = SMBOPEN_OCREATE;
1180 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1182 case FILE_OVERWRITE:
1183 ofun = SMBOPEN_OTRUNC;
1185 case FILE_OVERWRITE_IF:
1186 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1189 cFYI(1, "unknown disposition %d", disposition);
1190 ofun = SMBOPEN_OAPPEND; /* regular open */
1196 access_flags_to_smbopen_mode(const int access_flags)
1198 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1200 if (masked_flags == GENERIC_READ)
1201 return SMBOPEN_READ;
1202 else if (masked_flags == GENERIC_WRITE)
1203 return SMBOPEN_WRITE;
1205 /* just go for read/write */
1206 return SMBOPEN_READWRITE;
1210 SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
1211 const char *fileName, const int openDisposition,
1212 const int access_flags, const int create_options, __u16 *netfid,
1213 int *pOplock, FILE_ALL_INFO *pfile_info,
1214 const struct nls_table *nls_codepage, int remap)
1217 OPENX_REQ *pSMB = NULL;
1218 OPENX_RSP *pSMBr = NULL;
1224 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1229 pSMB->AndXCommand = 0xFF; /* none */
1231 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1232 count = 1; /* account for one byte pad to word boundary */
1234 cifsConvertToUCS((__le16 *) (pSMB->fileName + 1),
1235 fileName, PATH_MAX, nls_codepage, remap);
1236 name_len++; /* trailing null */
1238 } else { /* BB improve check for buffer overruns BB */
1239 count = 0; /* no pad */
1240 name_len = strnlen(fileName, PATH_MAX);
1241 name_len++; /* trailing null */
1242 strncpy(pSMB->fileName, fileName, name_len);
1244 if (*pOplock & REQ_OPLOCK)
1245 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1246 else if (*pOplock & REQ_BATCHOPLOCK)
1247 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1249 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1250 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1251 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1252 /* set file as system file if special file such
1253 as fifo and server expecting SFU style and
1254 no Unix extensions */
1256 if (create_options & CREATE_OPTION_SPECIAL)
1257 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1258 else /* BB FIXME BB */
1259 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1261 if (create_options & CREATE_OPTION_READONLY)
1262 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1265 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1266 CREATE_OPTIONS_MASK); */
1267 /* BB FIXME END BB */
1269 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1270 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1272 inc_rfc1001_len(pSMB, count);
1274 pSMB->ByteCount = cpu_to_le16(count);
1275 /* long_op set to 1 to allow for oplock break timeouts */
1276 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1277 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1278 cifs_stats_inc(&tcon->num_opens);
1280 cFYI(1, "Error in Open = %d", rc);
1282 /* BB verify if wct == 15 */
1284 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1286 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1287 /* Let caller know file was created so we can set the mode. */
1288 /* Do we care about the CreateAction in any other cases? */
1290 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1291 *pOplock |= CIFS_CREATE_ACTION; */
1295 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1296 pfile_info->LastAccessTime = 0; /* BB fixme */
1297 pfile_info->LastWriteTime = 0; /* BB fixme */
1298 pfile_info->ChangeTime = 0; /* BB fixme */
1299 pfile_info->Attributes =
1300 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1301 /* the file_info buf is endian converted by caller */
1302 pfile_info->AllocationSize =
1303 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1304 pfile_info->EndOfFile = pfile_info->AllocationSize;
1305 pfile_info->NumberOfLinks = cpu_to_le32(1);
1306 pfile_info->DeletePending = 0;
1310 cifs_buf_release(pSMB);
1317 CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
1318 const char *fileName, const int openDisposition,
1319 const int access_flags, const int create_options, __u16 *netfid,
1320 int *pOplock, FILE_ALL_INFO *pfile_info,
1321 const struct nls_table *nls_codepage, int remap)
1324 OPEN_REQ *pSMB = NULL;
1325 OPEN_RSP *pSMBr = NULL;
1331 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **) &pSMB,
1336 pSMB->AndXCommand = 0xFF; /* none */
1338 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1339 count = 1; /* account for one byte pad to word boundary */
1341 cifsConvertToUCS((__le16 *) (pSMB->fileName + 1),
1342 fileName, PATH_MAX, nls_codepage, remap);
1343 name_len++; /* trailing null */
1345 pSMB->NameLength = cpu_to_le16(name_len);
1346 } else { /* BB improve check for buffer overruns BB */
1347 count = 0; /* no pad */
1348 name_len = strnlen(fileName, PATH_MAX);
1349 name_len++; /* trailing null */
1350 pSMB->NameLength = cpu_to_le16(name_len);
1351 strncpy(pSMB->fileName, fileName, name_len);
1353 if (*pOplock & REQ_OPLOCK)
1354 pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1355 else if (*pOplock & REQ_BATCHOPLOCK)
1356 pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1357 pSMB->DesiredAccess = cpu_to_le32(access_flags);
1358 pSMB->AllocationSize = 0;
1359 /* set file as system file if special file such
1360 as fifo and server expecting SFU style and
1361 no Unix extensions */
1362 if (create_options & CREATE_OPTION_SPECIAL)
1363 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1365 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1367 /* XP does not handle ATTR_POSIX_SEMANTICS */
1368 /* but it helps speed up case sensitive checks for other
1369 servers such as Samba */
1370 if (tcon->ses->capabilities & CAP_UNIX)
1371 pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1373 if (create_options & CREATE_OPTION_READONLY)
1374 pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1376 pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1377 pSMB->CreateDisposition = cpu_to_le32(openDisposition);
1378 pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1379 /* BB Expirement with various impersonation levels and verify */
1380 pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1381 pSMB->SecurityFlags =
1382 SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
1385 inc_rfc1001_len(pSMB, count);
1387 pSMB->ByteCount = cpu_to_le16(count);
1388 /* long_op set to 1 to allow for oplock break timeouts */
1389 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1390 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1391 cifs_stats_inc(&tcon->num_opens);
1393 cFYI(1, "Error in Open = %d", rc);
1395 *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
1396 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1397 /* Let caller know file was created so we can set the mode. */
1398 /* Do we care about the CreateAction in any other cases? */
1399 if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1400 *pOplock |= CIFS_CREATE_ACTION;
1402 memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
1403 36 /* CreationTime to Attributes */);
1404 /* the file_info buf is endian converted by caller */
1405 pfile_info->AllocationSize = pSMBr->AllocationSize;
1406 pfile_info->EndOfFile = pSMBr->EndOfFile;
1407 pfile_info->NumberOfLinks = cpu_to_le32(1);
1408 pfile_info->DeletePending = 0;
1412 cifs_buf_release(pSMB);
1418 struct cifs_readdata *
1419 cifs_readdata_alloc(unsigned int nr_pages)
1421 struct cifs_readdata *rdata;
1423 /* readdata + 1 kvec for each page */
1424 rdata = kzalloc(sizeof(*rdata) +
1425 sizeof(struct kvec) * nr_pages, GFP_KERNEL);
1426 if (rdata != NULL) {
1427 INIT_WORK(&rdata->work, cifs_readv_complete);
1428 INIT_LIST_HEAD(&rdata->pages);
1434 cifs_readdata_free(struct cifs_readdata *rdata)
1436 cifsFileInfo_put(rdata->cfile);
1441 * Discard any remaining data in the current SMB. To do this, we borrow the
1445 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1447 READ_RSP *rsp = (READ_RSP *)server->smallbuf;
1448 unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length);
1449 int remaining = rfclen + 4 - server->total_read;
1450 struct cifs_readdata *rdata = mid->callback_data;
1452 while (remaining > 0) {
1455 length = cifs_read_from_socket(server, server->bigbuf,
1456 min_t(unsigned int, remaining,
1457 CIFSMaxBufSize + MAX_CIFS_HDR_SIZE));
1460 server->total_read += length;
1461 remaining -= length;
1464 dequeue_mid(mid, rdata->result);
1469 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1472 unsigned int data_offset, remaining, data_len;
1473 struct cifs_readdata *rdata = mid->callback_data;
1474 READ_RSP *rsp = (READ_RSP *)server->smallbuf;
1475 unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length) + 4;
1478 struct page *page, *tpage;
1480 cFYI(1, "%s: mid=%u offset=%llu bytes=%u", __func__,
1481 mid->mid, rdata->offset, rdata->bytes);
1484 * read the rest of READ_RSP header (sans Data array), or whatever we
1485 * can if there's not enough data. At this point, we've read down to
1488 len = min_t(unsigned int, rfclen, sizeof(*rsp)) -
1489 sizeof(struct smb_hdr) + 1;
1491 rdata->iov[0].iov_base = server->smallbuf + sizeof(struct smb_hdr) - 1;
1492 rdata->iov[0].iov_len = len;
1494 length = cifs_readv_from_socket(server, rdata->iov, 1, len);
1497 server->total_read += length;
1499 /* Was the SMB read successful? */
1500 rdata->result = map_smb_to_linux_error(&rsp->hdr, false);
1501 if (rdata->result != 0) {
1502 cFYI(1, "%s: server returned error %d", __func__,
1504 return cifs_readv_discard(server, mid);
1507 /* Is there enough to get to the rest of the READ_RSP header? */
1508 if (server->total_read < sizeof(READ_RSP)) {
1509 cFYI(1, "%s: server returned short header. got=%u expected=%zu",
1510 __func__, server->total_read, sizeof(READ_RSP));
1511 rdata->result = -EIO;
1512 return cifs_readv_discard(server, mid);
1515 data_offset = le16_to_cpu(rsp->DataOffset) + 4;
1516 if (data_offset < server->total_read) {
1518 * win2k8 sometimes sends an offset of 0 when the read
1519 * is beyond the EOF. Treat it as if the data starts just after
1522 cFYI(1, "%s: data offset (%u) inside read response header",
1523 __func__, data_offset);
1524 data_offset = server->total_read;
1525 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1526 /* data_offset is beyond the end of smallbuf */
1527 cFYI(1, "%s: data offset (%u) beyond end of smallbuf",
1528 __func__, data_offset);
1529 rdata->result = -EIO;
1530 return cifs_readv_discard(server, mid);
1533 cFYI(1, "%s: total_read=%u data_offset=%u", __func__,
1534 server->total_read, data_offset);
1536 len = data_offset - server->total_read;
1538 /* read any junk before data into the rest of smallbuf */
1539 rdata->iov[0].iov_base = server->smallbuf + server->total_read;
1540 rdata->iov[0].iov_len = len;
1541 length = cifs_readv_from_socket(server, rdata->iov, 1, len);
1544 server->total_read += length;
1547 /* set up first iov for signature check */
1548 rdata->iov[0].iov_base = server->smallbuf;
1549 rdata->iov[0].iov_len = server->total_read;
1550 cFYI(1, "0: iov_base=%p iov_len=%zu",
1551 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1553 /* how much data is in the response? */
1554 data_len = le16_to_cpu(rsp->DataLengthHigh) << 16;
1555 data_len += le16_to_cpu(rsp->DataLength);
1556 if (data_offset + data_len > rfclen) {
1557 /* data_len is corrupt -- discard frame */
1558 rdata->result = -EIO;
1559 return cifs_readv_discard(server, mid);
1562 /* marshal up the page array */
1564 remaining = data_len;
1567 /* determine the eof that the server (probably) has */
1568 eof = CIFS_I(rdata->mapping->host)->server_eof;
1569 eof_index = eof ? (eof - 1) >> PAGE_CACHE_SHIFT : 0;
1570 cFYI(1, "eof=%llu eof_index=%lu", eof, eof_index);
1573 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
1574 if (remaining >= PAGE_CACHE_SIZE) {
1575 /* enough data to fill the page */
1576 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
1577 rdata->iov[rdata->nr_iov].iov_len = PAGE_CACHE_SIZE;
1578 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
1579 rdata->nr_iov, page->index,
1580 rdata->iov[rdata->nr_iov].iov_base,
1581 rdata->iov[rdata->nr_iov].iov_len);
1583 len += PAGE_CACHE_SIZE;
1584 remaining -= PAGE_CACHE_SIZE;
1585 } else if (remaining > 0) {
1586 /* enough for partial page, fill and zero the rest */
1587 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
1588 rdata->iov[rdata->nr_iov].iov_len = remaining;
1589 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
1590 rdata->nr_iov, page->index,
1591 rdata->iov[rdata->nr_iov].iov_base,
1592 rdata->iov[rdata->nr_iov].iov_len);
1593 memset(rdata->iov[rdata->nr_iov].iov_base + remaining,
1594 '\0', PAGE_CACHE_SIZE - remaining);
1598 } else if (page->index > eof_index) {
1600 * The VFS will not try to do readahead past the
1601 * i_size, but it's possible that we have outstanding
1602 * writes with gaps in the middle and the i_size hasn't
1603 * caught up yet. Populate those with zeroed out pages
1604 * to prevent the VFS from repeatedly attempting to
1605 * fill them until the writes are flushed.
1607 zero_user(page, 0, PAGE_CACHE_SIZE);
1608 list_del(&page->lru);
1609 lru_cache_add_file(page);
1610 flush_dcache_page(page);
1611 SetPageUptodate(page);
1613 page_cache_release(page);
1615 /* no need to hold page hostage */
1616 list_del(&page->lru);
1617 lru_cache_add_file(page);
1619 page_cache_release(page);
1624 /* issue the read if we have any iovecs left to fill */
1625 if (rdata->nr_iov > 1) {
1626 length = cifs_readv_from_socket(server, &rdata->iov[1],
1627 rdata->nr_iov - 1, len);
1630 server->total_read += length;
1635 rdata->bytes = length;
1637 cFYI(1, "total_read=%u rfclen=%u remaining=%u", server->total_read,
1640 /* discard anything left over */
1641 if (server->total_read < rfclen)
1642 return cifs_readv_discard(server, mid);
1644 dequeue_mid(mid, false);
1649 cifs_readv_complete(struct work_struct *work)
1651 struct cifs_readdata *rdata = container_of(work,
1652 struct cifs_readdata, work);
1653 struct page *page, *tpage;
1655 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
1656 list_del(&page->lru);
1657 lru_cache_add_file(page);
1659 if (rdata->result == 0) {
1661 flush_dcache_page(page);
1662 SetPageUptodate(page);
1667 if (rdata->result == 0)
1668 cifs_readpage_to_fscache(rdata->mapping->host, page);
1670 page_cache_release(page);
1672 cifs_readdata_free(rdata);
1676 cifs_readv_callback(struct mid_q_entry *mid)
1678 struct cifs_readdata *rdata = mid->callback_data;
1679 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1680 struct TCP_Server_Info *server = tcon->ses->server;
1682 cFYI(1, "%s: mid=%u state=%d result=%d bytes=%u", __func__,
1683 mid->mid, mid->midState, rdata->result, rdata->bytes);
1685 switch (mid->midState) {
1686 case MID_RESPONSE_RECEIVED:
1687 /* result already set, check signature */
1688 if (server->sec_mode &
1689 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
1690 if (cifs_verify_signature(rdata->iov, rdata->nr_iov,
1691 server, mid->sequence_number + 1))
1692 cERROR(1, "Unexpected SMB signature");
1694 /* FIXME: should this be counted toward the initiating task? */
1695 task_io_account_read(rdata->bytes);
1696 cifs_stats_bytes_read(tcon, rdata->bytes);
1698 case MID_REQUEST_SUBMITTED:
1699 case MID_RETRY_NEEDED:
1700 rdata->result = -EAGAIN;
1703 rdata->result = -EIO;
1706 queue_work(system_nrt_wq, &rdata->work);
1707 DeleteMidQEntry(mid);
1708 atomic_dec(&server->inFlight);
1709 wake_up(&server->request_q);
1712 /* cifs_async_readv - send an async write, and set up mid to handle result */
1714 cifs_async_readv(struct cifs_readdata *rdata)
1717 READ_REQ *smb = NULL;
1719 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1721 cFYI(1, "%s: offset=%llu bytes=%u", __func__,
1722 rdata->offset, rdata->bytes);
1724 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1727 wct = 10; /* old style read */
1728 if ((rdata->offset >> 32) > 0) {
1729 /* can not handle this big offset for old */
1734 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1738 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1739 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1741 smb->AndXCommand = 0xFF; /* none */
1742 smb->Fid = rdata->cfile->netfid;
1743 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1745 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1747 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1748 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1752 /* old style read */
1753 struct smb_com_readx_req *smbr =
1754 (struct smb_com_readx_req *)smb;
1755 smbr->ByteCount = 0;
1758 /* 4 for RFC1001 length + 1 for BCC */
1759 rdata->iov[0].iov_base = smb;
1760 rdata->iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
1762 rc = cifs_call_async(tcon->ses->server, rdata->iov, 1,
1763 cifs_readv_receive, cifs_readv_callback,
1767 cifs_stats_inc(&tcon->num_reads);
1769 cifs_small_buf_release(smb);
1774 CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms, unsigned int *nbytes,
1775 char **buf, int *pbuf_type)
1778 READ_REQ *pSMB = NULL;
1779 READ_RSP *pSMBr = NULL;
1780 char *pReadData = NULL;
1782 int resp_buf_type = 0;
1784 __u32 pid = io_parms->pid;
1785 __u16 netfid = io_parms->netfid;
1786 __u64 offset = io_parms->offset;
1787 struct cifs_tcon *tcon = io_parms->tcon;
1788 unsigned int count = io_parms->length;
1790 cFYI(1, "Reading %d bytes on fid %d", count, netfid);
1791 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1794 wct = 10; /* old style read */
1795 if ((offset >> 32) > 0) {
1796 /* can not handle this big offset for old */
1802 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1806 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1807 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1809 /* tcon and ses pointer are checked in smb_init */
1810 if (tcon->ses->server == NULL)
1811 return -ECONNABORTED;
1813 pSMB->AndXCommand = 0xFF; /* none */
1815 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1817 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1819 pSMB->Remaining = 0;
1820 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1821 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1823 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1825 /* old style read */
1826 struct smb_com_readx_req *pSMBW =
1827 (struct smb_com_readx_req *)pSMB;
1828 pSMBW->ByteCount = 0;
1831 iov[0].iov_base = (char *)pSMB;
1832 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1833 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1834 &resp_buf_type, CIFS_LOG_ERROR);
1835 cifs_stats_inc(&tcon->num_reads);
1836 pSMBr = (READ_RSP *)iov[0].iov_base;
1838 cERROR(1, "Send error in read = %d", rc);
1840 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1841 data_length = data_length << 16;
1842 data_length += le16_to_cpu(pSMBr->DataLength);
1843 *nbytes = data_length;
1845 /*check that DataLength would not go beyond end of SMB */
1846 if ((data_length > CIFSMaxBufSize)
1847 || (data_length > count)) {
1848 cFYI(1, "bad length %d for count %d",
1849 data_length, count);
1853 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1854 le16_to_cpu(pSMBr->DataOffset);
1855 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1856 cERROR(1, "Faulting on read rc = %d",rc);
1858 }*/ /* can not use copy_to_user when using page cache*/
1860 memcpy(*buf, pReadData, data_length);
1864 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1866 if (resp_buf_type == CIFS_SMALL_BUFFER)
1867 cifs_small_buf_release(iov[0].iov_base);
1868 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1869 cifs_buf_release(iov[0].iov_base);
1870 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1871 /* return buffer to caller to free */
1872 *buf = iov[0].iov_base;
1873 if (resp_buf_type == CIFS_SMALL_BUFFER)
1874 *pbuf_type = CIFS_SMALL_BUFFER;
1875 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1876 *pbuf_type = CIFS_LARGE_BUFFER;
1877 } /* else no valid buffer on return - leave as null */
1879 /* Note: On -EAGAIN error only caller can retry on handle based calls
1880 since file handle passed in no longer valid */
1886 CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
1887 unsigned int *nbytes, const char *buf,
1888 const char __user *ubuf, const int long_op)
1891 WRITE_REQ *pSMB = NULL;
1892 WRITE_RSP *pSMBr = NULL;
1893 int bytes_returned, wct;
1896 __u32 pid = io_parms->pid;
1897 __u16 netfid = io_parms->netfid;
1898 __u64 offset = io_parms->offset;
1899 struct cifs_tcon *tcon = io_parms->tcon;
1900 unsigned int count = io_parms->length;
1904 /* cFYI(1, "write at %lld %d bytes", offset, count);*/
1905 if (tcon->ses == NULL)
1906 return -ECONNABORTED;
1908 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1912 if ((offset >> 32) > 0) {
1913 /* can not handle big offset for old srv */
1918 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1923 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1924 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1926 /* tcon and ses pointer are checked in smb_init */
1927 if (tcon->ses->server == NULL)
1928 return -ECONNABORTED;
1930 pSMB->AndXCommand = 0xFF; /* none */
1932 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1934 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1936 pSMB->Reserved = 0xFFFFFFFF;
1937 pSMB->WriteMode = 0;
1938 pSMB->Remaining = 0;
1940 /* Can increase buffer size if buffer is big enough in some cases ie we
1941 can send more if LARGE_WRITE_X capability returned by the server and if
1942 our buffer is big enough or if we convert to iovecs on socket writes
1943 and eliminate the copy to the CIFS buffer */
1944 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1945 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1947 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1951 if (bytes_sent > count)
1954 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1956 memcpy(pSMB->Data, buf, bytes_sent);
1958 if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
1959 cifs_buf_release(pSMB);
1962 } else if (count != 0) {
1964 cifs_buf_release(pSMB);
1966 } /* else setting file size with write of zero bytes */
1968 byte_count = bytes_sent + 1; /* pad */
1969 else /* wct == 12 */
1970 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1972 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1973 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1974 inc_rfc1001_len(pSMB, byte_count);
1977 pSMB->ByteCount = cpu_to_le16(byte_count);
1978 else { /* old style write has byte count 4 bytes earlier
1980 struct smb_com_writex_req *pSMBW =
1981 (struct smb_com_writex_req *)pSMB;
1982 pSMBW->ByteCount = cpu_to_le16(byte_count);
1985 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1986 (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
1987 cifs_stats_inc(&tcon->num_writes);
1989 cFYI(1, "Send error in write = %d", rc);
1991 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1992 *nbytes = (*nbytes) << 16;
1993 *nbytes += le16_to_cpu(pSMBr->Count);
1996 * Mask off high 16 bits when bytes written as returned by the
1997 * server is greater than bytes requested by the client. Some
1998 * OS/2 servers are known to set incorrect CountHigh values.
2000 if (*nbytes > count)
2004 cifs_buf_release(pSMB);
2006 /* Note: On -EAGAIN error only caller can retry on handle based calls
2007 since file handle passed in no longer valid */
2013 cifs_writedata_release(struct kref *refcount)
2015 struct cifs_writedata *wdata = container_of(refcount,
2016 struct cifs_writedata, refcount);
2019 cifsFileInfo_put(wdata->cfile);
2025 * Write failed with a retryable error. Resend the write request. It's also
2026 * possible that the page was redirtied so re-clean the page.
2029 cifs_writev_requeue(struct cifs_writedata *wdata)
2032 struct inode *inode = wdata->cfile->dentry->d_inode;
2034 for (i = 0; i < wdata->nr_pages; i++) {
2035 lock_page(wdata->pages[i]);
2036 clear_page_dirty_for_io(wdata->pages[i]);
2040 rc = cifs_async_writev(wdata);
2041 } while (rc == -EAGAIN);
2043 for (i = 0; i < wdata->nr_pages; i++) {
2045 SetPageError(wdata->pages[i]);
2046 unlock_page(wdata->pages[i]);
2049 mapping_set_error(inode->i_mapping, rc);
2050 kref_put(&wdata->refcount, cifs_writedata_release);
2054 cifs_writev_complete(struct work_struct *work)
2056 struct cifs_writedata *wdata = container_of(work,
2057 struct cifs_writedata, work);
2058 struct inode *inode = wdata->cfile->dentry->d_inode;
2061 if (wdata->result == 0) {
2062 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2063 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2065 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2066 return cifs_writev_requeue(wdata);
2068 for (i = 0; i < wdata->nr_pages; i++) {
2069 struct page *page = wdata->pages[i];
2070 if (wdata->result == -EAGAIN)
2071 __set_page_dirty_nobuffers(page);
2072 else if (wdata->result < 0)
2074 end_page_writeback(page);
2075 page_cache_release(page);
2077 if (wdata->result != -EAGAIN)
2078 mapping_set_error(inode->i_mapping, wdata->result);
2079 kref_put(&wdata->refcount, cifs_writedata_release);
2082 struct cifs_writedata *
2083 cifs_writedata_alloc(unsigned int nr_pages)
2085 struct cifs_writedata *wdata;
2087 /* this would overflow */
2088 if (nr_pages == 0) {
2089 cERROR(1, "%s: called with nr_pages == 0!", __func__);
2093 /* writedata + number of page pointers */
2094 wdata = kzalloc(sizeof(*wdata) +
2095 sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
2096 if (wdata != NULL) {
2097 INIT_WORK(&wdata->work, cifs_writev_complete);
2098 kref_init(&wdata->refcount);
2104 * Check the midState and signature on received buffer (if any), and queue the
2105 * workqueue completion task.
2108 cifs_writev_callback(struct mid_q_entry *mid)
2110 struct cifs_writedata *wdata = mid->callback_data;
2111 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2112 unsigned int written;
2113 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2115 switch (mid->midState) {
2116 case MID_RESPONSE_RECEIVED:
2117 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2118 if (wdata->result != 0)
2121 written = le16_to_cpu(smb->CountHigh);
2123 written += le16_to_cpu(smb->Count);
2125 * Mask off high 16 bits when bytes written as returned
2126 * by the server is greater than bytes requested by the
2127 * client. OS/2 servers are known to set incorrect
2130 if (written > wdata->bytes)
2133 if (written < wdata->bytes)
2134 wdata->result = -ENOSPC;
2136 wdata->bytes = written;
2138 case MID_REQUEST_SUBMITTED:
2139 case MID_RETRY_NEEDED:
2140 wdata->result = -EAGAIN;
2143 wdata->result = -EIO;
2147 queue_work(system_nrt_wq, &wdata->work);
2148 DeleteMidQEntry(mid);
2149 atomic_dec(&tcon->ses->server->inFlight);
2150 wake_up(&tcon->ses->server->request_q);
2153 /* cifs_async_writev - send an async write, and set up mid to handle result */
2155 cifs_async_writev(struct cifs_writedata *wdata)
2157 int i, rc = -EACCES;
2158 WRITE_REQ *smb = NULL;
2160 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2161 struct inode *inode = wdata->cfile->dentry->d_inode;
2162 struct kvec *iov = NULL;
2164 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2168 if (wdata->offset >> 32 > 0) {
2169 /* can not handle big offset for old srv */
2174 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2176 goto async_writev_out;
2178 /* 1 iov per page + 1 for header */
2179 iov = kzalloc((wdata->nr_pages + 1) * sizeof(*iov), GFP_NOFS);
2182 goto async_writev_out;
2185 smb->hdr.Pid = cpu_to_le16((__u16)wdata->cfile->pid);
2186 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->cfile->pid >> 16));
2188 smb->AndXCommand = 0xFF; /* none */
2189 smb->Fid = wdata->cfile->netfid;
2190 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2192 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2193 smb->Reserved = 0xFFFFFFFF;
2198 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2200 /* 4 for RFC1001 length + 1 for BCC */
2201 iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
2202 iov[0].iov_base = smb;
2204 /* marshal up the pages into iov array */
2207 for (i = 0; i < wdata->nr_pages; i++) {
2208 iov[i + 1].iov_len = min(inode->i_size -
2209 page_offset(wdata->pages[i]),
2210 (loff_t)PAGE_CACHE_SIZE);
2211 iov[i + 1].iov_base = kmap(wdata->pages[i]);
2212 wdata->bytes += iov[i + 1].iov_len;
2216 cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
2218 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2219 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2222 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2223 put_bcc(wdata->bytes + 1, &smb->hdr);
2226 struct smb_com_writex_req *smbw =
2227 (struct smb_com_writex_req *)smb;
2228 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2229 put_bcc(wdata->bytes + 5, &smbw->hdr);
2230 iov[0].iov_len += 4; /* pad bigger by four bytes */
2233 kref_get(&wdata->refcount);
2234 rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1,
2235 NULL, cifs_writev_callback, wdata, false);
2238 cifs_stats_inc(&tcon->num_writes);
2240 kref_put(&wdata->refcount, cifs_writedata_release);
2242 /* send is done, unmap pages */
2243 for (i = 0; i < wdata->nr_pages; i++)
2244 kunmap(wdata->pages[i]);
2247 cifs_small_buf_release(smb);
2253 CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
2254 unsigned int *nbytes, struct kvec *iov, int n_vec,
2258 WRITE_REQ *pSMB = NULL;
2261 int resp_buf_type = 0;
2262 __u32 pid = io_parms->pid;
2263 __u16 netfid = io_parms->netfid;
2264 __u64 offset = io_parms->offset;
2265 struct cifs_tcon *tcon = io_parms->tcon;
2266 unsigned int count = io_parms->length;
2270 cFYI(1, "write2 at %lld %d bytes", (long long)offset, count);
2272 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2276 if ((offset >> 32) > 0) {
2277 /* can not handle big offset for old srv */
2281 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2285 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2286 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2288 /* tcon and ses pointer are checked in smb_init */
2289 if (tcon->ses->server == NULL)
2290 return -ECONNABORTED;
2292 pSMB->AndXCommand = 0xFF; /* none */
2294 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2296 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2297 pSMB->Reserved = 0xFFFFFFFF;
2298 pSMB->WriteMode = 0;
2299 pSMB->Remaining = 0;
2302 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2304 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2305 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2306 /* header + 1 byte pad */
2307 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2309 inc_rfc1001_len(pSMB, count + 1);
2310 else /* wct == 12 */
2311 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2313 pSMB->ByteCount = cpu_to_le16(count + 1);
2314 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2315 struct smb_com_writex_req *pSMBW =
2316 (struct smb_com_writex_req *)pSMB;
2317 pSMBW->ByteCount = cpu_to_le16(count + 5);
2319 iov[0].iov_base = pSMB;
2321 iov[0].iov_len = smb_hdr_len + 4;
2322 else /* wct == 12 pad bigger by four bytes */
2323 iov[0].iov_len = smb_hdr_len + 8;
2326 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
2328 cifs_stats_inc(&tcon->num_writes);
2330 cFYI(1, "Send error Write2 = %d", rc);
2331 } else if (resp_buf_type == 0) {
2332 /* presumably this can not happen, but best to be safe */
2335 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base;
2336 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2337 *nbytes = (*nbytes) << 16;
2338 *nbytes += le16_to_cpu(pSMBr->Count);
2341 * Mask off high 16 bits when bytes written as returned by the
2342 * server is greater than bytes requested by the client. OS/2
2343 * servers are known to set incorrect CountHigh values.
2345 if (*nbytes > count)
2349 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2350 if (resp_buf_type == CIFS_SMALL_BUFFER)
2351 cifs_small_buf_release(iov[0].iov_base);
2352 else if (resp_buf_type == CIFS_LARGE_BUFFER)
2353 cifs_buf_release(iov[0].iov_base);
2355 /* Note: On -EAGAIN error only caller can retry on handle based calls
2356 since file handle passed in no longer valid */
2361 int cifs_lockv(const int xid, struct cifs_tcon *tcon, const __u16 netfid,
2362 const __u8 lock_type, const __u32 num_unlock,
2363 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2366 LOCK_REQ *pSMB = NULL;
2371 cFYI(1, "cifs_lockv num lock %d num unlock %d", num_lock, num_unlock);
2373 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2378 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2379 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2380 pSMB->LockType = lock_type;
2381 pSMB->AndXCommand = 0xFF; /* none */
2382 pSMB->Fid = netfid; /* netfid stays le */
2384 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2385 inc_rfc1001_len(pSMB, count);
2386 pSMB->ByteCount = cpu_to_le16(count);
2388 iov[0].iov_base = (char *)pSMB;
2389 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2390 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2391 iov[1].iov_base = (char *)buf;
2392 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2394 cifs_stats_inc(&tcon->num_locks);
2395 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
2397 cFYI(1, "Send error in cifs_lockv = %d", rc);
2403 CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
2404 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2405 const __u64 offset, const __u32 numUnlock,
2406 const __u32 numLock, const __u8 lockType,
2407 const bool waitFlag, const __u8 oplock_level)
2410 LOCK_REQ *pSMB = NULL;
2411 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2416 cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock);
2417 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2422 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2423 timeout = CIFS_ASYNC_OP; /* no response expected */
2425 } else if (waitFlag) {
2426 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2427 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2432 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2433 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2434 pSMB->LockType = lockType;
2435 pSMB->OplockLevel = oplock_level;
2436 pSMB->AndXCommand = 0xFF; /* none */
2437 pSMB->Fid = smb_file_id; /* netfid stays le */
2439 if ((numLock != 0) || (numUnlock != 0)) {
2440 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2441 /* BB where to store pid high? */
2442 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2443 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2444 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2445 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2446 count = sizeof(LOCKING_ANDX_RANGE);
2451 inc_rfc1001_len(pSMB, count);
2452 pSMB->ByteCount = cpu_to_le16(count);
2455 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2456 (struct smb_hdr *) pSMB, &bytes_returned);
2457 cifs_small_buf_release(pSMB);
2459 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
2461 /* SMB buffer freed by function above */
2463 cifs_stats_inc(&tcon->num_locks);
2465 cFYI(1, "Send error in Lock = %d", rc);
2467 /* Note: On -EAGAIN error only caller can retry on handle based calls
2468 since file handle passed in no longer valid */
2473 CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
2474 const __u16 smb_file_id, const __u32 netpid, const int get_flag,
2475 const __u64 len, struct file_lock *pLockData,
2476 const __u16 lock_type, const bool waitFlag)
2478 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2479 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2480 struct cifs_posix_lock *parm_data;
2483 int bytes_returned = 0;
2484 int resp_buf_type = 0;
2485 __u16 params, param_offset, offset, byte_count, count;
2488 cFYI(1, "Posix Lock");
2490 if (pLockData == NULL)
2493 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2498 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2501 pSMB->MaxSetupCount = 0;
2504 pSMB->Reserved2 = 0;
2505 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2506 offset = param_offset + params;
2508 count = sizeof(struct cifs_posix_lock);
2509 pSMB->MaxParameterCount = cpu_to_le16(2);
2510 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2511 pSMB->SetupCount = 1;
2512 pSMB->Reserved3 = 0;
2514 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2516 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2517 byte_count = 3 /* pad */ + params + count;
2518 pSMB->DataCount = cpu_to_le16(count);
2519 pSMB->ParameterCount = cpu_to_le16(params);
2520 pSMB->TotalDataCount = pSMB->DataCount;
2521 pSMB->TotalParameterCount = pSMB->ParameterCount;
2522 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2523 parm_data = (struct cifs_posix_lock *)
2524 (((char *) &pSMB->hdr.Protocol) + offset);
2526 parm_data->lock_type = cpu_to_le16(lock_type);
2528 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2529 parm_data->lock_flags = cpu_to_le16(1);
2530 pSMB->Timeout = cpu_to_le32(-1);
2534 parm_data->pid = cpu_to_le32(netpid);
2535 parm_data->start = cpu_to_le64(pLockData->fl_start);
2536 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2538 pSMB->DataOffset = cpu_to_le16(offset);
2539 pSMB->Fid = smb_file_id;
2540 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2541 pSMB->Reserved4 = 0;
2542 inc_rfc1001_len(pSMB, byte_count);
2543 pSMB->ByteCount = cpu_to_le16(byte_count);
2545 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2546 (struct smb_hdr *) pSMBr, &bytes_returned);
2548 iov[0].iov_base = (char *)pSMB;
2549 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2550 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2551 &resp_buf_type, timeout);
2552 pSMB = NULL; /* request buf already freed by SendReceive2. Do
2553 not try to free it twice below on exit */
2554 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
2558 cFYI(1, "Send error in Posix Lock = %d", rc);
2559 } else if (get_flag) {
2560 /* lock structure can be returned on get */
2563 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2565 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2566 rc = -EIO; /* bad smb */
2569 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2570 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2571 if (data_count < sizeof(struct cifs_posix_lock)) {
2575 parm_data = (struct cifs_posix_lock *)
2576 ((char *)&pSMBr->hdr.Protocol + data_offset);
2577 if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
2578 pLockData->fl_type = F_UNLCK;
2580 if (parm_data->lock_type ==
2581 __constant_cpu_to_le16(CIFS_RDLCK))
2582 pLockData->fl_type = F_RDLCK;
2583 else if (parm_data->lock_type ==
2584 __constant_cpu_to_le16(CIFS_WRLCK))
2585 pLockData->fl_type = F_WRLCK;
2587 pLockData->fl_start = le64_to_cpu(parm_data->start);
2588 pLockData->fl_end = pLockData->fl_start +
2589 le64_to_cpu(parm_data->length) - 1;
2590 pLockData->fl_pid = le32_to_cpu(parm_data->pid);
2596 cifs_small_buf_release(pSMB);
2598 if (resp_buf_type == CIFS_SMALL_BUFFER)
2599 cifs_small_buf_release(iov[0].iov_base);
2600 else if (resp_buf_type == CIFS_LARGE_BUFFER)
2601 cifs_buf_release(iov[0].iov_base);
2603 /* Note: On -EAGAIN error only caller can retry on handle based calls
2604 since file handle passed in no longer valid */
2611 CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id)
2614 CLOSE_REQ *pSMB = NULL;
2615 cFYI(1, "In CIFSSMBClose");
2617 /* do not retry on dead session on close */
2618 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2624 pSMB->FileID = (__u16) smb_file_id;
2625 pSMB->LastWriteTime = 0xFFFFFFFF;
2626 pSMB->ByteCount = 0;
2627 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
2628 cifs_stats_inc(&tcon->num_closes);
2631 /* EINTR is expected when user ctl-c to kill app */
2632 cERROR(1, "Send error in Close = %d", rc);
2636 /* Since session is dead, file will be closed on server already */
2644 CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id)
2647 FLUSH_REQ *pSMB = NULL;
2648 cFYI(1, "In CIFSSMBFlush");
2650 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2654 pSMB->FileID = (__u16) smb_file_id;
2655 pSMB->ByteCount = 0;
2656 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
2657 cifs_stats_inc(&tcon->num_flushes);
2659 cERROR(1, "Send error in Flush = %d", rc);
2665 CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
2666 const char *fromName, const char *toName,
2667 const struct nls_table *nls_codepage, int remap)
2670 RENAME_REQ *pSMB = NULL;
2671 RENAME_RSP *pSMBr = NULL;
2673 int name_len, name_len2;
2676 cFYI(1, "In CIFSSMBRename");
2678 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2683 pSMB->BufferFormat = 0x04;
2684 pSMB->SearchAttributes =
2685 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2688 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2690 cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName,
2691 PATH_MAX, nls_codepage, remap);
2692 name_len++; /* trailing null */
2694 pSMB->OldFileName[name_len] = 0x04; /* pad */
2695 /* protocol requires ASCII signature byte on Unicode string */
2696 pSMB->OldFileName[name_len + 1] = 0x00;
2698 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
2699 toName, PATH_MAX, nls_codepage, remap);
2700 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2701 name_len2 *= 2; /* convert to bytes */
2702 } else { /* BB improve the check for buffer overruns BB */
2703 name_len = strnlen(fromName, PATH_MAX);
2704 name_len++; /* trailing null */
2705 strncpy(pSMB->OldFileName, fromName, name_len);
2706 name_len2 = strnlen(toName, PATH_MAX);
2707 name_len2++; /* trailing null */
2708 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2709 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2710 name_len2++; /* trailing null */
2711 name_len2++; /* signature byte */
2714 count = 1 /* 1st signature byte */ + name_len + name_len2;
2715 inc_rfc1001_len(pSMB, count);
2716 pSMB->ByteCount = cpu_to_le16(count);
2718 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2719 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2720 cifs_stats_inc(&tcon->num_renames);
2722 cFYI(1, "Send error in rename = %d", rc);
2724 cifs_buf_release(pSMB);
2732 int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
2733 int netfid, const char *target_name,
2734 const struct nls_table *nls_codepage, int remap)
2736 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2737 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2738 struct set_file_rename *rename_info;
2740 char dummy_string[30];
2742 int bytes_returned = 0;
2744 __u16 params, param_offset, offset, count, byte_count;
2746 cFYI(1, "Rename to File by handle");
2747 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2753 pSMB->MaxSetupCount = 0;
2757 pSMB->Reserved2 = 0;
2758 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2759 offset = param_offset + params;
2761 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2762 rename_info = (struct set_file_rename *) data_offset;
2763 pSMB->MaxParameterCount = cpu_to_le16(2);
2764 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2765 pSMB->SetupCount = 1;
2766 pSMB->Reserved3 = 0;
2767 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2768 byte_count = 3 /* pad */ + params;
2769 pSMB->ParameterCount = cpu_to_le16(params);
2770 pSMB->TotalParameterCount = pSMB->ParameterCount;
2771 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2772 pSMB->DataOffset = cpu_to_le16(offset);
2773 /* construct random name ".cifs_tmp<inodenum><mid>" */
2774 rename_info->overwrite = cpu_to_le32(1);
2775 rename_info->root_fid = 0;
2776 /* unicode only call */
2777 if (target_name == NULL) {
2778 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2779 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
2780 dummy_string, 24, nls_codepage, remap);
2782 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
2783 target_name, PATH_MAX, nls_codepage,
2786 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2787 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2788 byte_count += count;
2789 pSMB->DataCount = cpu_to_le16(count);
2790 pSMB->TotalDataCount = pSMB->DataCount;
2792 pSMB->InformationLevel =
2793 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2794 pSMB->Reserved4 = 0;
2795 inc_rfc1001_len(pSMB, byte_count);
2796 pSMB->ByteCount = cpu_to_le16(byte_count);
2797 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2798 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2799 cifs_stats_inc(&pTcon->num_t2renames);
2801 cFYI(1, "Send error in Rename (by file handle) = %d", rc);
2803 cifs_buf_release(pSMB);
2805 /* Note: On -EAGAIN error only caller can retry on handle based calls
2806 since file handle passed in no longer valid */
2812 CIFSSMBCopy(const int xid, struct cifs_tcon *tcon, const char *fromName,
2813 const __u16 target_tid, const char *toName, const int flags,
2814 const struct nls_table *nls_codepage, int remap)
2817 COPY_REQ *pSMB = NULL;
2818 COPY_RSP *pSMBr = NULL;
2820 int name_len, name_len2;
2823 cFYI(1, "In CIFSSMBCopy");
2825 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2830 pSMB->BufferFormat = 0x04;
2831 pSMB->Tid2 = target_tid;
2833 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2835 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2836 name_len = cifsConvertToUCS((__le16 *) pSMB->OldFileName,
2837 fromName, PATH_MAX, nls_codepage,
2839 name_len++; /* trailing null */
2841 pSMB->OldFileName[name_len] = 0x04; /* pad */
2842 /* protocol requires ASCII signature byte on Unicode string */
2843 pSMB->OldFileName[name_len + 1] = 0x00;
2845 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
2846 toName, PATH_MAX, nls_codepage, remap);
2847 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2848 name_len2 *= 2; /* convert to bytes */
2849 } else { /* BB improve the check for buffer overruns BB */
2850 name_len = strnlen(fromName, PATH_MAX);
2851 name_len++; /* trailing null */
2852 strncpy(pSMB->OldFileName, fromName, name_len);
2853 name_len2 = strnlen(toName, PATH_MAX);
2854 name_len2++; /* trailing null */
2855 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2856 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2857 name_len2++; /* trailing null */
2858 name_len2++; /* signature byte */
2861 count = 1 /* 1st signature byte */ + name_len + name_len2;
2862 inc_rfc1001_len(pSMB, count);
2863 pSMB->ByteCount = cpu_to_le16(count);
2865 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2866 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2868 cFYI(1, "Send error in copy = %d with %d files copied",
2869 rc, le16_to_cpu(pSMBr->CopyCount));
2871 cifs_buf_release(pSMB);
2880 CIFSUnixCreateSymLink(const int xid, struct cifs_tcon *tcon,
2881 const char *fromName, const char *toName,
2882 const struct nls_table *nls_codepage)
2884 TRANSACTION2_SPI_REQ *pSMB = NULL;
2885 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2888 int name_len_target;
2890 int bytes_returned = 0;
2891 __u16 params, param_offset, offset, byte_count;
2893 cFYI(1, "In Symlink Unix style");
2895 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2900 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2902 cifs_strtoUCS((__le16 *) pSMB->FileName, fromName, PATH_MAX
2903 /* find define for this maxpathcomponent */
2905 name_len++; /* trailing null */
2908 } else { /* BB improve the check for buffer overruns BB */
2909 name_len = strnlen(fromName, PATH_MAX);
2910 name_len++; /* trailing null */
2911 strncpy(pSMB->FileName, fromName, name_len);
2913 params = 6 + name_len;
2914 pSMB->MaxSetupCount = 0;
2918 pSMB->Reserved2 = 0;
2919 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2920 InformationLevel) - 4;
2921 offset = param_offset + params;
2923 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2924 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2926 cifs_strtoUCS((__le16 *) data_offset, toName, PATH_MAX
2927 /* find define for this maxpathcomponent */
2929 name_len_target++; /* trailing null */
2930 name_len_target *= 2;
2931 } else { /* BB improve the check for buffer overruns BB */
2932 name_len_target = strnlen(toName, PATH_MAX);
2933 name_len_target++; /* trailing null */
2934 strncpy(data_offset, toName, name_len_target);
2937 pSMB->MaxParameterCount = cpu_to_le16(2);
2938 /* BB find exact max on data count below from sess */
2939 pSMB->MaxDataCount = cpu_to_le16(1000);
2940 pSMB->SetupCount = 1;
2941 pSMB->Reserved3 = 0;
2942 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2943 byte_count = 3 /* pad */ + params + name_len_target;
2944 pSMB->DataCount = cpu_to_le16(name_len_target);
2945 pSMB->ParameterCount = cpu_to_le16(params);
2946 pSMB->TotalDataCount = pSMB->DataCount;
2947 pSMB->TotalParameterCount = pSMB->ParameterCount;
2948 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2949 pSMB->DataOffset = cpu_to_le16(offset);
2950 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2951 pSMB->Reserved4 = 0;
2952 inc_rfc1001_len(pSMB, byte_count);
2953 pSMB->ByteCount = cpu_to_le16(byte_count);
2954 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2955 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2956 cifs_stats_inc(&tcon->num_symlinks);
2958 cFYI(1, "Send error in SetPathInfo create symlink = %d", rc);
2960 cifs_buf_release(pSMB);
2963 goto createSymLinkRetry;
2969 CIFSUnixCreateHardLink(const int xid, struct cifs_tcon *tcon,
2970 const char *fromName, const char *toName,
2971 const struct nls_table *nls_codepage, int remap)
2973 TRANSACTION2_SPI_REQ *pSMB = NULL;
2974 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2977 int name_len_target;
2979 int bytes_returned = 0;
2980 __u16 params, param_offset, offset, byte_count;
2982 cFYI(1, "In Create Hard link Unix style");
2983 createHardLinkRetry:
2984 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2989 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2990 name_len = cifsConvertToUCS((__le16 *) pSMB->FileName, toName,
2991 PATH_MAX, nls_codepage, remap);
2992 name_len++; /* trailing null */
2995 } else { /* BB improve the check for buffer overruns BB */
2996 name_len = strnlen(toName, PATH_MAX);
2997 name_len++; /* trailing null */
2998 strncpy(pSMB->FileName, toName, name_len);
3000 params = 6 + name_len;
3001 pSMB->MaxSetupCount = 0;
3005 pSMB->Reserved2 = 0;
3006 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3007 InformationLevel) - 4;
3008 offset = param_offset + params;
3010 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
3011 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3013 cifsConvertToUCS((__le16 *) data_offset, fromName, PATH_MAX,
3014 nls_codepage, remap);
3015 name_len_target++; /* trailing null */
3016 name_len_target *= 2;
3017 } else { /* BB improve the check for buffer overruns BB */
3018 name_len_target = strnlen(fromName, PATH_MAX);
3019 name_len_target++; /* trailing null */
3020 strncpy(data_offset, fromName, name_len_target);
3023 pSMB->MaxParameterCount = cpu_to_le16(2);
3024 /* BB find exact max on data count below from sess*/
3025 pSMB->MaxDataCount = cpu_to_le16(1000);
3026 pSMB->SetupCount = 1;
3027 pSMB->Reserved3 = 0;
3028 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3029 byte_count = 3 /* pad */ + params + name_len_target;
3030 pSMB->ParameterCount = cpu_to_le16(params);
3031 pSMB->TotalParameterCount = pSMB->ParameterCount;
3032 pSMB->DataCount = cpu_to_le16(name_len_target);
3033 pSMB->TotalDataCount = pSMB->DataCount;
3034 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3035 pSMB->DataOffset = cpu_to_le16(offset);
3036 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3037 pSMB->Reserved4 = 0;
3038 inc_rfc1001_len(pSMB, byte_count);
3039 pSMB->ByteCount = cpu_to_le16(byte_count);
3040 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3041 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3042 cifs_stats_inc(&tcon->num_hardlinks);
3044 cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc);
3046 cifs_buf_release(pSMB);
3048 goto createHardLinkRetry;
3054 CIFSCreateHardLink(const int xid, struct cifs_tcon *tcon,
3055 const char *fromName, const char *toName,
3056 const struct nls_table *nls_codepage, int remap)
3059 NT_RENAME_REQ *pSMB = NULL;
3060 RENAME_RSP *pSMBr = NULL;
3062 int name_len, name_len2;
3065 cFYI(1, "In CIFSCreateHardLink");
3066 winCreateHardLinkRetry:
3068 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3073 pSMB->SearchAttributes =
3074 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3076 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3077 pSMB->ClusterCount = 0;
3079 pSMB->BufferFormat = 0x04;
3081 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3083 cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName,
3084 PATH_MAX, nls_codepage, remap);
3085 name_len++; /* trailing null */
3088 /* protocol specifies ASCII buffer format (0x04) for unicode */
3089 pSMB->OldFileName[name_len] = 0x04;
3090 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3092 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
3093 toName, PATH_MAX, nls_codepage, remap);
3094 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3095 name_len2 *= 2; /* convert to bytes */
3096 } else { /* BB improve the check for buffer overruns BB */
3097 name_len = strnlen(fromName, PATH_MAX);
3098 name_len++; /* trailing null */
3099 strncpy(pSMB->OldFileName, fromName, name_len);
3100 name_len2 = strnlen(toName, PATH_MAX);
3101 name_len2++; /* trailing null */
3102 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3103 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
3104 name_len2++; /* trailing null */
3105 name_len2++; /* signature byte */
3108 count = 1 /* string type byte */ + name_len + name_len2;
3109 inc_rfc1001_len(pSMB, count);
3110 pSMB->ByteCount = cpu_to_le16(count);
3112 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3113 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3114 cifs_stats_inc(&tcon->num_hardlinks);
3116 cFYI(1, "Send error in hard link (NT rename) = %d", rc);
3118 cifs_buf_release(pSMB);
3120 goto winCreateHardLinkRetry;
3126 CIFSSMBUnixQuerySymLink(const int xid, struct cifs_tcon *tcon,
3127 const unsigned char *searchName, char **symlinkinfo,
3128 const struct nls_table *nls_codepage)
3130 /* SMB_QUERY_FILE_UNIX_LINK */
3131 TRANSACTION2_QPI_REQ *pSMB = NULL;
3132 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3136 __u16 params, byte_count;
3139 cFYI(1, "In QPathSymLinkInfo (Unix) for path %s", searchName);
3142 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3147 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3149 cifs_strtoUCS((__le16 *) pSMB->FileName, searchName,
3150 PATH_MAX, nls_codepage);
3151 name_len++; /* trailing null */
3153 } else { /* BB improve the check for buffer overruns BB */
3154 name_len = strnlen(searchName, PATH_MAX);
3155 name_len++; /* trailing null */
3156 strncpy(pSMB->FileName, searchName, name_len);
3159 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3160 pSMB->TotalDataCount = 0;
3161 pSMB->MaxParameterCount = cpu_to_le16(2);
3162 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3163 pSMB->MaxSetupCount = 0;
3167 pSMB->Reserved2 = 0;
3168 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3169 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3170 pSMB->DataCount = 0;
3171 pSMB->DataOffset = 0;
3172 pSMB->SetupCount = 1;
3173 pSMB->Reserved3 = 0;
3174 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3175 byte_count = params + 1 /* pad */ ;
3176 pSMB->TotalParameterCount = cpu_to_le16(params);
3177 pSMB->ParameterCount = pSMB->TotalParameterCount;
3178 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3179 pSMB->Reserved4 = 0;
3180 inc_rfc1001_len(pSMB, byte_count);
3181 pSMB->ByteCount = cpu_to_le16(byte_count);
3183 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3184 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3186 cFYI(1, "Send error in QuerySymLinkInfo = %d", rc);
3188 /* decode response */
3190 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3191 /* BB also check enough total bytes returned */
3192 if (rc || get_bcc(&pSMBr->hdr) < 2)
3196 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3198 data_start = ((char *) &pSMBr->hdr.Protocol) +
3199 le16_to_cpu(pSMBr->t2.DataOffset);
3201 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3206 /* BB FIXME investigate remapping reserved chars here */
3207 *symlinkinfo = cifs_strndup_from_ucs(data_start, count,
3208 is_unicode, nls_codepage);
3213 cifs_buf_release(pSMB);
3215 goto querySymLinkRetry;
3219 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3221 * Recent Windows versions now create symlinks more frequently
3222 * and they use the "reparse point" mechanism below. We can of course
3223 * do symlinks nicely to Samba and other servers which support the
3224 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3225 * "MF" symlinks optionally, but for recent Windows we really need to
3226 * reenable the code below and fix the cifs_symlink callers to handle this.
3227 * In the interim this code has been moved to its own config option so
3228 * it is not compiled in by default until callers fixed up and more tested.
3231 CIFSSMBQueryReparseLinkInfo(const int xid, struct cifs_tcon *tcon,
3232 const unsigned char *searchName,
3233 char *symlinkinfo, const int buflen, __u16 fid,
3234 const struct nls_table *nls_codepage)
3238 struct smb_com_transaction_ioctl_req *pSMB;
3239 struct smb_com_transaction_ioctl_rsp *pSMBr;
3241 cFYI(1, "In Windows reparse style QueryLink for path %s", searchName);
3242 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3247 pSMB->TotalParameterCount = 0 ;
3248 pSMB->TotalDataCount = 0;
3249 pSMB->MaxParameterCount = cpu_to_le32(2);
3250 /* BB find exact data count max from sess structure BB */
3251 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3252 pSMB->MaxSetupCount = 4;
3254 pSMB->ParameterOffset = 0;
3255 pSMB->DataCount = 0;
3256 pSMB->DataOffset = 0;
3257 pSMB->SetupCount = 4;
3258 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3259 pSMB->ParameterCount = pSMB->TotalParameterCount;
3260 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3261 pSMB->IsFsctl = 1; /* FSCTL */
3262 pSMB->IsRootFlag = 0;
3263 pSMB->Fid = fid; /* file handle always le */
3264 pSMB->ByteCount = 0;
3266 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3267 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3269 cFYI(1, "Send error in QueryReparseLinkInfo = %d", rc);
3270 } else { /* decode response */
3271 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
3272 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
3273 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3274 /* BB also check enough total bytes returned */
3275 rc = -EIO; /* bad smb */
3278 if (data_count && (data_count < 2048)) {
3279 char *end_of_smb = 2 /* sizeof byte count */ +
3280 get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3282 struct reparse_data *reparse_buf =
3283 (struct reparse_data *)
3284 ((char *)&pSMBr->hdr.Protocol
3286 if ((char *)reparse_buf >= end_of_smb) {
3290 if ((reparse_buf->LinkNamesBuf +
3291 reparse_buf->TargetNameOffset +
3292 reparse_buf->TargetNameLen) > end_of_smb) {
3293 cFYI(1, "reparse buf beyond SMB");
3298 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3299 cifs_from_ucs2(symlinkinfo, (__le16 *)
3300 (reparse_buf->LinkNamesBuf +
3301 reparse_buf->TargetNameOffset),
3303 reparse_buf->TargetNameLen,
3305 } else { /* ASCII names */
3306 strncpy(symlinkinfo,
3307 reparse_buf->LinkNamesBuf +
3308 reparse_buf->TargetNameOffset,
3309 min_t(const int, buflen,
3310 reparse_buf->TargetNameLen));
3314 cFYI(1, "Invalid return data count on "
3315 "get reparse info ioctl");
3317 symlinkinfo[buflen] = 0; /* just in case so the caller
3318 does not go off the end of the buffer */
3319 cFYI(1, "readlink result - %s", symlinkinfo);
3323 cifs_buf_release(pSMB);
3325 /* Note: On -EAGAIN error only caller can retry on handle based calls
3326 since file handle passed in no longer valid */
3330 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3332 #ifdef CONFIG_CIFS_POSIX
3334 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3335 static void cifs_convert_ace(posix_acl_xattr_entry *ace,
3336 struct cifs_posix_ace *cifs_ace)
3338 /* u8 cifs fields do not need le conversion */
3339 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3340 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3341 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3342 /* cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id); */
3347 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3348 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3349 const int acl_type, const int size_of_data_area)
3354 struct cifs_posix_ace *pACE;
3355 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3356 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
3358 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3361 if (acl_type & ACL_TYPE_ACCESS) {
3362 count = le16_to_cpu(cifs_acl->access_entry_count);
3363 pACE = &cifs_acl->ace_array[0];
3364 size = sizeof(struct cifs_posix_acl);
3365 size += sizeof(struct cifs_posix_ace) * count;
3366 /* check if we would go beyond end of SMB */
3367 if (size_of_data_area < size) {
3368 cFYI(1, "bad CIFS POSIX ACL size %d vs. %d",
3369 size_of_data_area, size);
3372 } else if (acl_type & ACL_TYPE_DEFAULT) {
3373 count = le16_to_cpu(cifs_acl->access_entry_count);
3374 size = sizeof(struct cifs_posix_acl);
3375 size += sizeof(struct cifs_posix_ace) * count;
3376 /* skip past access ACEs to get to default ACEs */
3377 pACE = &cifs_acl->ace_array[count];
3378 count = le16_to_cpu(cifs_acl->default_entry_count);
3379 size += sizeof(struct cifs_posix_ace) * count;
3380 /* check if we would go beyond end of SMB */
3381 if (size_of_data_area < size)
3388 size = posix_acl_xattr_size(count);
3389 if ((buflen == 0) || (local_acl == NULL)) {
3390 /* used to query ACL EA size */
3391 } else if (size > buflen) {
3393 } else /* buffer big enough */ {
3394 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3395 for (i = 0; i < count ; i++) {
3396 cifs_convert_ace(&local_acl->a_entries[i], pACE);
3403 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3404 const posix_acl_xattr_entry *local_ace)
3406 __u16 rc = 0; /* 0 = ACL converted ok */
3408 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3409 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3410 /* BB is there a better way to handle the large uid? */
3411 if (local_ace->e_id == cpu_to_le32(-1)) {
3412 /* Probably no need to le convert -1 on any arch but can not hurt */
3413 cifs_ace->cifs_uid = cpu_to_le64(-1);
3415 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3416 /*cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id);*/
3420 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3421 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3422 const int buflen, const int acl_type)
3425 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3426 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
3430 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3433 count = posix_acl_xattr_count((size_t)buflen);
3434 cFYI(1, "setting acl with %d entries from buf of length %d and "
3436 count, buflen, le32_to_cpu(local_acl->a_version));
3437 if (le32_to_cpu(local_acl->a_version) != 2) {
3438 cFYI(1, "unknown POSIX ACL version %d",
3439 le32_to_cpu(local_acl->a_version));
3442 cifs_acl->version = cpu_to_le16(1);
3443 if (acl_type == ACL_TYPE_ACCESS) {
3444 cifs_acl->access_entry_count = cpu_to_le16(count);
3445 cifs_acl->default_entry_count = __constant_cpu_to_le16(0xFFFF);
3446 } else if (acl_type == ACL_TYPE_DEFAULT) {
3447 cifs_acl->default_entry_count = cpu_to_le16(count);
3448 cifs_acl->access_entry_count = __constant_cpu_to_le16(0xFFFF);
3450 cFYI(1, "unknown ACL type %d", acl_type);
3453 for (i = 0; i < count; i++) {
3454 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3455 &local_acl->a_entries[i]);
3457 /* ACE not converted */
3462 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3463 rc += sizeof(struct cifs_posix_acl);
3464 /* BB add check to make sure ACL does not overflow SMB */
3470 CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
3471 const unsigned char *searchName,
3472 char *acl_inf, const int buflen, const int acl_type,
3473 const struct nls_table *nls_codepage, int remap)
3475 /* SMB_QUERY_POSIX_ACL */
3476 TRANSACTION2_QPI_REQ *pSMB = NULL;
3477 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3481 __u16 params, byte_count;
3483 cFYI(1, "In GetPosixACL (Unix) for path %s", searchName);
3486 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3491 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3493 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3494 PATH_MAX, nls_codepage, remap);
3495 name_len++; /* trailing null */
3497 pSMB->FileName[name_len] = 0;
3498 pSMB->FileName[name_len+1] = 0;
3499 } else { /* BB improve the check for buffer overruns BB */
3500 name_len = strnlen(searchName, PATH_MAX);
3501 name_len++; /* trailing null */
3502 strncpy(pSMB->FileName, searchName, name_len);
3505 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3506 pSMB->TotalDataCount = 0;
3507 pSMB->MaxParameterCount = cpu_to_le16(2);
3508 /* BB find exact max data count below from sess structure BB */
3509 pSMB->MaxDataCount = cpu_to_le16(4000);
3510 pSMB->MaxSetupCount = 0;
3514 pSMB->Reserved2 = 0;
3515 pSMB->ParameterOffset = cpu_to_le16(
3516 offsetof(struct smb_com_transaction2_qpi_req,
3517 InformationLevel) - 4);
3518 pSMB->DataCount = 0;
3519 pSMB->DataOffset = 0;
3520 pSMB->SetupCount = 1;
3521 pSMB->Reserved3 = 0;
3522 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3523 byte_count = params + 1 /* pad */ ;
3524 pSMB->TotalParameterCount = cpu_to_le16(params);
3525 pSMB->ParameterCount = pSMB->TotalParameterCount;
3526 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3527 pSMB->Reserved4 = 0;
3528 inc_rfc1001_len(pSMB, byte_count);
3529 pSMB->ByteCount = cpu_to_le16(byte_count);
3531 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3532 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3533 cifs_stats_inc(&tcon->num_acl_get);
3535 cFYI(1, "Send error in Query POSIX ACL = %d", rc);
3537 /* decode response */
3539 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3540 /* BB also check enough total bytes returned */
3541 if (rc || get_bcc(&pSMBr->hdr) < 2)
3542 rc = -EIO; /* bad smb */
3544 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3545 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3546 rc = cifs_copy_posix_acl(acl_inf,
3547 (char *)&pSMBr->hdr.Protocol+data_offset,
3548 buflen, acl_type, count);
3551 cifs_buf_release(pSMB);
3558 CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
3559 const unsigned char *fileName,
3560 const char *local_acl, const int buflen,
3562 const struct nls_table *nls_codepage, int remap)
3564 struct smb_com_transaction2_spi_req *pSMB = NULL;
3565 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3569 int bytes_returned = 0;
3570 __u16 params, byte_count, data_count, param_offset, offset;
3572 cFYI(1, "In SetPosixACL (Unix) for path %s", fileName);
3574 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3578 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3580 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
3581 PATH_MAX, nls_codepage, remap);
3582 name_len++; /* trailing null */
3584 } else { /* BB improve the check for buffer overruns BB */
3585 name_len = strnlen(fileName, PATH_MAX);
3586 name_len++; /* trailing null */
3587 strncpy(pSMB->FileName, fileName, name_len);
3589 params = 6 + name_len;
3590 pSMB->MaxParameterCount = cpu_to_le16(2);
3591 /* BB find max SMB size from sess */
3592 pSMB->MaxDataCount = cpu_to_le16(1000);
3593 pSMB->MaxSetupCount = 0;
3597 pSMB->Reserved2 = 0;
3598 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3599 InformationLevel) - 4;
3600 offset = param_offset + params;
3601 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3602 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3604 /* convert to on the wire format for POSIX ACL */
3605 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3607 if (data_count == 0) {
3609 goto setACLerrorExit;
3611 pSMB->DataOffset = cpu_to_le16(offset);
3612 pSMB->SetupCount = 1;
3613 pSMB->Reserved3 = 0;
3614 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3615 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3616 byte_count = 3 /* pad */ + params + data_count;
3617 pSMB->DataCount = cpu_to_le16(data_count);
3618 pSMB->TotalDataCount = pSMB->DataCount;
3619 pSMB->ParameterCount = cpu_to_le16(params);
3620 pSMB->TotalParameterCount = pSMB->ParameterCount;
3621 pSMB->Reserved4 = 0;
3622 inc_rfc1001_len(pSMB, byte_count);
3623 pSMB->ByteCount = cpu_to_le16(byte_count);
3624 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3625 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3627 cFYI(1, "Set POSIX ACL returned %d", rc);
3630 cifs_buf_release(pSMB);
3636 /* BB fix tabs in this function FIXME BB */
3638 CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
3639 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3642 struct smb_t2_qfi_req *pSMB = NULL;
3643 struct smb_t2_qfi_rsp *pSMBr = NULL;
3645 __u16 params, byte_count;
3647 cFYI(1, "In GetExtAttr");
3652 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3657 params = 2 /* level */ + 2 /* fid */;
3658 pSMB->t2.TotalDataCount = 0;
3659 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3660 /* BB find exact max data count below from sess structure BB */
3661 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3662 pSMB->t2.MaxSetupCount = 0;
3663 pSMB->t2.Reserved = 0;
3665 pSMB->t2.Timeout = 0;
3666 pSMB->t2.Reserved2 = 0;
3667 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3669 pSMB->t2.DataCount = 0;
3670 pSMB->t2.DataOffset = 0;
3671 pSMB->t2.SetupCount = 1;
3672 pSMB->t2.Reserved3 = 0;
3673 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3674 byte_count = params + 1 /* pad */ ;
3675 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3676 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3677 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3680 inc_rfc1001_len(pSMB, byte_count);
3681 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3683 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3684 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3686 cFYI(1, "error %d in GetExtAttr", rc);
3688 /* decode response */
3689 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3690 /* BB also check enough total bytes returned */
3691 if (rc || get_bcc(&pSMBr->hdr) < 2)
3692 /* If rc should we check for EOPNOSUPP and
3693 disable the srvino flag? or in caller? */
3694 rc = -EIO; /* bad smb */
3696 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3697 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3698 struct file_chattr_info *pfinfo;
3699 /* BB Do we need a cast or hash here ? */
3701 cFYI(1, "Illegal size ret in GetExtAttr");
3705 pfinfo = (struct file_chattr_info *)
3706 (data_offset + (char *) &pSMBr->hdr.Protocol);
3707 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3708 *pMask = le64_to_cpu(pfinfo->mask);
3712 cifs_buf_release(pSMB);
3714 goto GetExtAttrRetry;
3718 #endif /* CONFIG_POSIX */
3720 #ifdef CONFIG_CIFS_ACL
3722 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3723 * all NT TRANSACTS that we init here have total parm and data under about 400
3724 * bytes (to fit in small cifs buffer size), which is the case so far, it
3725 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3726 * returned setup area) and MaxParameterCount (returned parms size) must be set
3730 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3731 const int parm_len, struct cifs_tcon *tcon,
3736 struct smb_com_ntransact_req *pSMB;
3738 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3742 *ret_buf = (void *)pSMB;
3744 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3745 pSMB->TotalDataCount = 0;
3746 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3747 pSMB->ParameterCount = pSMB->TotalParameterCount;
3748 pSMB->DataCount = pSMB->TotalDataCount;
3749 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3750 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3751 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3752 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3753 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3754 pSMB->SubCommand = cpu_to_le16(sub_command);
3759 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3760 __u32 *pparmlen, __u32 *pdatalen)
3763 __u32 data_count, data_offset, parm_count, parm_offset;
3764 struct smb_com_ntransact_rsp *pSMBr;
3773 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3775 bcc = get_bcc(&pSMBr->hdr);
3776 end_of_smb = 2 /* sizeof byte count */ + bcc +
3777 (char *)&pSMBr->ByteCount;
3779 data_offset = le32_to_cpu(pSMBr->DataOffset);
3780 data_count = le32_to_cpu(pSMBr->DataCount);
3781 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3782 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3784 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3785 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3787 /* should we also check that parm and data areas do not overlap? */
3788 if (*ppparm > end_of_smb) {
3789 cFYI(1, "parms start after end of smb");
3791 } else if (parm_count + *ppparm > end_of_smb) {
3792 cFYI(1, "parm end after end of smb");
3794 } else if (*ppdata > end_of_smb) {
3795 cFYI(1, "data starts after end of smb");
3797 } else if (data_count + *ppdata > end_of_smb) {
3798 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
3799 *ppdata, data_count, (data_count + *ppdata),
3802 } else if (parm_count + data_count > bcc) {
3803 cFYI(1, "parm count and data count larger than SMB");
3806 *pdatalen = data_count;
3807 *pparmlen = parm_count;
3811 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3813 CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3814 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3818 QUERY_SEC_DESC_REQ *pSMB;
3821 cFYI(1, "GetCifsACL");
3826 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3827 8 /* parm len */, tcon, (void **) &pSMB);
3831 pSMB->MaxParameterCount = cpu_to_le32(4);
3832 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3833 pSMB->MaxSetupCount = 0;
3834 pSMB->Fid = fid; /* file handle always le */
3835 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3837 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3838 inc_rfc1001_len(pSMB, 11);
3839 iov[0].iov_base = (char *)pSMB;
3840 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3842 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3844 cifs_stats_inc(&tcon->num_acl_get);
3846 cFYI(1, "Send error in QuerySecDesc = %d", rc);
3847 } else { /* decode response */
3851 struct smb_com_ntransact_rsp *pSMBr;
3854 /* validate_nttransact */
3855 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3856 &pdata, &parm_len, pbuflen);
3859 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3861 cFYI(1, "smb %p parm %p data %p", pSMBr, parm, *acl_inf);
3863 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3864 rc = -EIO; /* bad smb */
3869 /* BB check that data area is minimum length and as big as acl_len */
3871 acl_len = le32_to_cpu(*parm);
3872 if (acl_len != *pbuflen) {
3873 cERROR(1, "acl length %d does not match %d",
3875 if (*pbuflen > acl_len)
3879 /* check if buffer is big enough for the acl
3880 header followed by the smallest SID */
3881 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3882 (*pbuflen >= 64 * 1024)) {
3883 cERROR(1, "bad acl length %d", *pbuflen);
3887 *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
3888 if (*acl_inf == NULL) {
3892 memcpy(*acl_inf, pdata, *pbuflen);
3896 if (buf_type == CIFS_SMALL_BUFFER)
3897 cifs_small_buf_release(iov[0].iov_base);
3898 else if (buf_type == CIFS_LARGE_BUFFER)
3899 cifs_buf_release(iov[0].iov_base);
3900 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3905 CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3906 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3908 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3910 int bytes_returned = 0;
3911 SET_SEC_DESC_REQ *pSMB = NULL;
3915 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3919 pSMB->MaxSetupCount = 0;
3923 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3924 data_count = acllen;
3925 data_offset = param_offset + param_count;
3926 byte_count = 3 /* pad */ + param_count;
3928 pSMB->DataCount = cpu_to_le32(data_count);
3929 pSMB->TotalDataCount = pSMB->DataCount;
3930 pSMB->MaxParameterCount = cpu_to_le32(4);
3931 pSMB->MaxDataCount = cpu_to_le32(16384);
3932 pSMB->ParameterCount = cpu_to_le32(param_count);
3933 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3934 pSMB->TotalParameterCount = pSMB->ParameterCount;
3935 pSMB->DataOffset = cpu_to_le32(data_offset);
3936 pSMB->SetupCount = 0;
3937 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3938 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3940 pSMB->Fid = fid; /* file handle always le */
3941 pSMB->Reserved2 = 0;
3942 pSMB->AclFlags = cpu_to_le32(aclflag);
3944 if (pntsd && acllen) {
3945 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3946 data_offset, pntsd, acllen);
3947 inc_rfc1001_len(pSMB, byte_count + data_count);
3949 inc_rfc1001_len(pSMB, byte_count);
3951 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3952 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3954 cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
3956 cFYI(1, "Set CIFS ACL returned %d", rc);
3957 cifs_buf_release(pSMB);
3960 goto setCifsAclRetry;
3965 #endif /* CONFIG_CIFS_ACL */
3967 /* Legacy Query Path Information call for lookup to old servers such
3969 int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
3970 const unsigned char *searchName,
3971 FILE_ALL_INFO *pFinfo,
3972 const struct nls_table *nls_codepage, int remap)
3974 QUERY_INFORMATION_REQ *pSMB;
3975 QUERY_INFORMATION_RSP *pSMBr;
3980 cFYI(1, "In SMBQPath path %s", searchName);
3982 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3987 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3989 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3990 PATH_MAX, nls_codepage, remap);
3991 name_len++; /* trailing null */
3994 name_len = strnlen(searchName, PATH_MAX);
3995 name_len++; /* trailing null */
3996 strncpy(pSMB->FileName, searchName, name_len);
3998 pSMB->BufferFormat = 0x04;
3999 name_len++; /* account for buffer type byte */
4000 inc_rfc1001_len(pSMB, (__u16)name_len);
4001 pSMB->ByteCount = cpu_to_le16(name_len);
4003 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4004 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4006 cFYI(1, "Send error in QueryInfo = %d", rc);
4007 } else if (pFinfo) {
4009 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4011 /* decode response */
4012 /* BB FIXME - add time zone adjustment BB */
4013 memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
4016 /* decode time fields */
4017 pFinfo->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4018 pFinfo->LastWriteTime = pFinfo->ChangeTime;
4019 pFinfo->LastAccessTime = 0;
4020 pFinfo->AllocationSize =
4021 cpu_to_le64(le32_to_cpu(pSMBr->size));
4022 pFinfo->EndOfFile = pFinfo->AllocationSize;
4023 pFinfo->Attributes =
4024 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4026 rc = -EIO; /* bad buffer passed in */
4028 cifs_buf_release(pSMB);
4037 CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
4038 u16 netfid, FILE_ALL_INFO *pFindData)
4040 struct smb_t2_qfi_req *pSMB = NULL;
4041 struct smb_t2_qfi_rsp *pSMBr = NULL;
4044 __u16 params, byte_count;
4047 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4052 params = 2 /* level */ + 2 /* fid */;
4053 pSMB->t2.TotalDataCount = 0;
4054 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4055 /* BB find exact max data count below from sess structure BB */
4056 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4057 pSMB->t2.MaxSetupCount = 0;
4058 pSMB->t2.Reserved = 0;
4060 pSMB->t2.Timeout = 0;
4061 pSMB->t2.Reserved2 = 0;
4062 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4064 pSMB->t2.DataCount = 0;
4065 pSMB->t2.DataOffset = 0;
4066 pSMB->t2.SetupCount = 1;
4067 pSMB->t2.Reserved3 = 0;
4068 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4069 byte_count = params + 1 /* pad */ ;
4070 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4071 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4072 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4075 inc_rfc1001_len(pSMB, byte_count);
4077 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4078 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4080 cFYI(1, "Send error in QPathInfo = %d", rc);
4081 } else { /* decode response */
4082 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4084 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4086 else if (get_bcc(&pSMBr->hdr) < 40)
4087 rc = -EIO; /* bad smb */
4088 else if (pFindData) {
4089 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4090 memcpy((char *) pFindData,
4091 (char *) &pSMBr->hdr.Protocol +
4092 data_offset, sizeof(FILE_ALL_INFO));
4096 cifs_buf_release(pSMB);
4098 goto QFileInfoRetry;
4104 CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
4105 const unsigned char *searchName,
4106 FILE_ALL_INFO *pFindData,
4107 int legacy /* old style infolevel */,
4108 const struct nls_table *nls_codepage, int remap)
4110 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4111 TRANSACTION2_QPI_REQ *pSMB = NULL;
4112 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4116 __u16 params, byte_count;
4118 /* cFYI(1, "In QPathInfo path %s", searchName); */
4120 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4125 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4127 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4128 PATH_MAX, nls_codepage, remap);
4129 name_len++; /* trailing null */
4131 } else { /* BB improve the check for buffer overruns BB */
4132 name_len = strnlen(searchName, PATH_MAX);
4133 name_len++; /* trailing null */
4134 strncpy(pSMB->FileName, searchName, name_len);
4137 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4138 pSMB->TotalDataCount = 0;
4139 pSMB->MaxParameterCount = cpu_to_le16(2);
4140 /* BB find exact max SMB PDU from sess structure BB */
4141 pSMB->MaxDataCount = cpu_to_le16(4000);
4142 pSMB->MaxSetupCount = 0;
4146 pSMB->Reserved2 = 0;
4147 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4148 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4149 pSMB->DataCount = 0;
4150 pSMB->DataOffset = 0;
4151 pSMB->SetupCount = 1;
4152 pSMB->Reserved3 = 0;
4153 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4154 byte_count = params + 1 /* pad */ ;
4155 pSMB->TotalParameterCount = cpu_to_le16(params);
4156 pSMB->ParameterCount = pSMB->TotalParameterCount;
4158 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4160 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4161 pSMB->Reserved4 = 0;
4162 inc_rfc1001_len(pSMB, byte_count);
4163 pSMB->ByteCount = cpu_to_le16(byte_count);
4165 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4166 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4168 cFYI(1, "Send error in QPathInfo = %d", rc);
4169 } else { /* decode response */
4170 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4172 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4174 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4175 rc = -EIO; /* bad smb */
4176 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4177 rc = -EIO; /* 24 or 26 expected but we do not read
4179 else if (pFindData) {
4181 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4183 /* On legacy responses we do not read the last field,
4184 EAsize, fortunately since it varies by subdialect and
4185 also note it differs on Set vs. Get, ie two bytes or 4
4186 bytes depending but we don't care here */
4188 size = sizeof(FILE_INFO_STANDARD);
4190 size = sizeof(FILE_ALL_INFO);
4191 memcpy((char *) pFindData,
4192 (char *) &pSMBr->hdr.Protocol +
4197 cifs_buf_release(pSMB);
4199 goto QPathInfoRetry;
4205 CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
4206 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4208 struct smb_t2_qfi_req *pSMB = NULL;
4209 struct smb_t2_qfi_rsp *pSMBr = NULL;
4212 __u16 params, byte_count;
4215 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4220 params = 2 /* level */ + 2 /* fid */;
4221 pSMB->t2.TotalDataCount = 0;
4222 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4223 /* BB find exact max data count below from sess structure BB */
4224 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4225 pSMB->t2.MaxSetupCount = 0;
4226 pSMB->t2.Reserved = 0;
4228 pSMB->t2.Timeout = 0;
4229 pSMB->t2.Reserved2 = 0;
4230 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4232 pSMB->t2.DataCount = 0;
4233 pSMB->t2.DataOffset = 0;
4234 pSMB->t2.SetupCount = 1;
4235 pSMB->t2.Reserved3 = 0;
4236 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4237 byte_count = params + 1 /* pad */ ;
4238 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4239 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4240 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4243 inc_rfc1001_len(pSMB, byte_count);
4245 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4246 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4248 cFYI(1, "Send error in QPathInfo = %d", rc);
4249 } else { /* decode response */
4250 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4252 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4253 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
4254 "Unix Extensions can be disabled on mount "
4255 "by specifying the nosfu mount option.");
4256 rc = -EIO; /* bad smb */
4258 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4259 memcpy((char *) pFindData,
4260 (char *) &pSMBr->hdr.Protocol +
4262 sizeof(FILE_UNIX_BASIC_INFO));
4266 cifs_buf_release(pSMB);
4268 goto UnixQFileInfoRetry;
4274 CIFSSMBUnixQPathInfo(const int xid, struct cifs_tcon *tcon,
4275 const unsigned char *searchName,
4276 FILE_UNIX_BASIC_INFO *pFindData,
4277 const struct nls_table *nls_codepage, int remap)
4279 /* SMB_QUERY_FILE_UNIX_BASIC */
4280 TRANSACTION2_QPI_REQ *pSMB = NULL;
4281 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4283 int bytes_returned = 0;
4285 __u16 params, byte_count;
4287 cFYI(1, "In QPathInfo (Unix) the path %s", searchName);
4289 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4294 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4296 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4297 PATH_MAX, nls_codepage, remap);
4298 name_len++; /* trailing null */
4300 } else { /* BB improve the check for buffer overruns BB */
4301 name_len = strnlen(searchName, PATH_MAX);
4302 name_len++; /* trailing null */
4303 strncpy(pSMB->FileName, searchName, name_len);
4306 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4307 pSMB->TotalDataCount = 0;
4308 pSMB->MaxParameterCount = cpu_to_le16(2);
4309 /* BB find exact max SMB PDU from sess structure BB */
4310 pSMB->MaxDataCount = cpu_to_le16(4000);
4311 pSMB->MaxSetupCount = 0;
4315 pSMB->Reserved2 = 0;
4316 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4317 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4318 pSMB->DataCount = 0;
4319 pSMB->DataOffset = 0;
4320 pSMB->SetupCount = 1;
4321 pSMB->Reserved3 = 0;
4322 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4323 byte_count = params + 1 /* pad */ ;
4324 pSMB->TotalParameterCount = cpu_to_le16(params);
4325 pSMB->ParameterCount = pSMB->TotalParameterCount;
4326 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4327 pSMB->Reserved4 = 0;
4328 inc_rfc1001_len(pSMB, byte_count);
4329 pSMB->ByteCount = cpu_to_le16(byte_count);
4331 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4332 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4334 cFYI(1, "Send error in QPathInfo = %d", rc);
4335 } else { /* decode response */
4336 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4338 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4339 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
4340 "Unix Extensions can be disabled on mount "
4341 "by specifying the nosfu mount option.");
4342 rc = -EIO; /* bad smb */
4344 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4345 memcpy((char *) pFindData,
4346 (char *) &pSMBr->hdr.Protocol +
4348 sizeof(FILE_UNIX_BASIC_INFO));
4351 cifs_buf_release(pSMB);
4353 goto UnixQPathInfoRetry;
4358 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4360 CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
4361 const char *searchName,
4362 const struct nls_table *nls_codepage,
4363 __u16 *pnetfid, __u16 search_flags,
4364 struct cifs_search_info *psrch_inf, int remap, const char dirsep)
4366 /* level 257 SMB_ */
4367 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4368 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4369 T2_FFIRST_RSP_PARMS *parms;
4371 int bytes_returned = 0;
4373 __u16 params, byte_count;
4375 cFYI(1, "In FindFirst for %s", searchName);
4378 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4383 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4385 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4386 PATH_MAX, nls_codepage, remap);
4387 /* We can not add the asterik earlier in case
4388 it got remapped to 0xF03A as if it were part of the
4389 directory name instead of a wildcard */
4391 pSMB->FileName[name_len] = dirsep;
4392 pSMB->FileName[name_len+1] = 0;
4393 pSMB->FileName[name_len+2] = '*';
4394 pSMB->FileName[name_len+3] = 0;
4395 name_len += 4; /* now the trailing null */
4396 pSMB->FileName[name_len] = 0; /* null terminate just in case */
4397 pSMB->FileName[name_len+1] = 0;
4399 } else { /* BB add check for overrun of SMB buf BB */
4400 name_len = strnlen(searchName, PATH_MAX);
4401 /* BB fix here and in unicode clause above ie
4402 if (name_len > buffersize-header)
4403 free buffer exit; BB */
4404 strncpy(pSMB->FileName, searchName, name_len);
4405 pSMB->FileName[name_len] = dirsep;
4406 pSMB->FileName[name_len+1] = '*';
4407 pSMB->FileName[name_len+2] = 0;
4411 params = 12 + name_len /* includes null */ ;
4412 pSMB->TotalDataCount = 0; /* no EAs */
4413 pSMB->MaxParameterCount = cpu_to_le16(10);
4414 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4415 pSMB->MaxSetupCount = 0;
4419 pSMB->Reserved2 = 0;
4420 byte_count = params + 1 /* pad */ ;
4421 pSMB->TotalParameterCount = cpu_to_le16(params);
4422 pSMB->ParameterCount = pSMB->TotalParameterCount;
4423 pSMB->ParameterOffset = cpu_to_le16(
4424 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4426 pSMB->DataCount = 0;
4427 pSMB->DataOffset = 0;
4428 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4429 pSMB->Reserved3 = 0;
4430 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4431 pSMB->SearchAttributes =
4432 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4434 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4435 pSMB->SearchFlags = cpu_to_le16(search_flags);
4436 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4438 /* BB what should we set StorageType to? Does it matter? BB */
4439 pSMB->SearchStorageType = 0;
4440 inc_rfc1001_len(pSMB, byte_count);
4441 pSMB->ByteCount = cpu_to_le16(byte_count);
4443 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4444 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4445 cifs_stats_inc(&tcon->num_ffirst);
4447 if (rc) {/* BB add logic to retry regular search if Unix search
4448 rejected unexpectedly by server */
4449 /* BB Add code to handle unsupported level rc */
4450 cFYI(1, "Error in FindFirst = %d", rc);
4452 cifs_buf_release(pSMB);
4454 /* BB eventually could optimize out free and realloc of buf */
4457 goto findFirstRetry;
4458 } else { /* decode response */
4459 /* BB remember to free buffer if error BB */
4460 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4464 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4465 psrch_inf->unicode = true;
4467 psrch_inf->unicode = false;
4469 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4470 psrch_inf->smallBuf = 0;
4471 psrch_inf->srch_entries_start =
4472 (char *) &pSMBr->hdr.Protocol +
4473 le16_to_cpu(pSMBr->t2.DataOffset);
4474 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4475 le16_to_cpu(pSMBr->t2.ParameterOffset));
4477 if (parms->EndofSearch)
4478 psrch_inf->endOfSearch = true;
4480 psrch_inf->endOfSearch = false;
4482 psrch_inf->entries_in_buffer =
4483 le16_to_cpu(parms->SearchCount);
4484 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4485 psrch_inf->entries_in_buffer;
4486 lnoff = le16_to_cpu(parms->LastNameOffset);
4487 if (CIFSMaxBufSize < lnoff) {
4488 cERROR(1, "ignoring corrupt resume name");
4489 psrch_inf->last_entry = NULL;
4493 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4496 *pnetfid = parms->SearchHandle;
4498 cifs_buf_release(pSMB);
4505 int CIFSFindNext(const int xid, struct cifs_tcon *tcon, __u16 searchHandle,
4506 __u16 search_flags, struct cifs_search_info *psrch_inf)
4508 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4509 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4510 T2_FNEXT_RSP_PARMS *parms;
4511 char *response_data;
4514 unsigned int name_len;
4515 __u16 params, byte_count;
4517 cFYI(1, "In FindNext");
4519 if (psrch_inf->endOfSearch)
4522 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4527 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4529 pSMB->TotalDataCount = 0; /* no EAs */
4530 pSMB->MaxParameterCount = cpu_to_le16(8);
4531 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4532 pSMB->MaxSetupCount = 0;
4536 pSMB->Reserved2 = 0;
4537 pSMB->ParameterOffset = cpu_to_le16(
4538 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4539 pSMB->DataCount = 0;
4540 pSMB->DataOffset = 0;
4541 pSMB->SetupCount = 1;
4542 pSMB->Reserved3 = 0;
4543 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4544 pSMB->SearchHandle = searchHandle; /* always kept as le */
4546 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4547 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4548 pSMB->ResumeKey = psrch_inf->resume_key;
4549 pSMB->SearchFlags = cpu_to_le16(search_flags);
4551 name_len = psrch_inf->resume_name_len;
4553 if (name_len < PATH_MAX) {
4554 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4555 byte_count += name_len;
4556 /* 14 byte parm len above enough for 2 byte null terminator */
4557 pSMB->ResumeFileName[name_len] = 0;
4558 pSMB->ResumeFileName[name_len+1] = 0;
4561 goto FNext2_err_exit;
4563 byte_count = params + 1 /* pad */ ;
4564 pSMB->TotalParameterCount = cpu_to_le16(params);
4565 pSMB->ParameterCount = pSMB->TotalParameterCount;
4566 inc_rfc1001_len(pSMB, byte_count);
4567 pSMB->ByteCount = cpu_to_le16(byte_count);
4569 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4570 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4571 cifs_stats_inc(&tcon->num_fnext);
4574 psrch_inf->endOfSearch = true;
4575 cifs_buf_release(pSMB);
4576 rc = 0; /* search probably was closed at end of search*/
4578 cFYI(1, "FindNext returned = %d", rc);
4579 } else { /* decode response */
4580 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4585 /* BB fixme add lock for file (srch_info) struct here */
4586 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4587 psrch_inf->unicode = true;
4589 psrch_inf->unicode = false;
4590 response_data = (char *) &pSMBr->hdr.Protocol +
4591 le16_to_cpu(pSMBr->t2.ParameterOffset);
4592 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4593 response_data = (char *)&pSMBr->hdr.Protocol +
4594 le16_to_cpu(pSMBr->t2.DataOffset);
4595 if (psrch_inf->smallBuf)
4596 cifs_small_buf_release(
4597 psrch_inf->ntwrk_buf_start);
4599 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4600 psrch_inf->srch_entries_start = response_data;
4601 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4602 psrch_inf->smallBuf = 0;
4603 if (parms->EndofSearch)
4604 psrch_inf->endOfSearch = true;
4606 psrch_inf->endOfSearch = false;
4607 psrch_inf->entries_in_buffer =
4608 le16_to_cpu(parms->SearchCount);
4609 psrch_inf->index_of_last_entry +=
4610 psrch_inf->entries_in_buffer;
4611 lnoff = le16_to_cpu(parms->LastNameOffset);
4612 if (CIFSMaxBufSize < lnoff) {
4613 cERROR(1, "ignoring corrupt resume name");
4614 psrch_inf->last_entry = NULL;
4617 psrch_inf->last_entry =
4618 psrch_inf->srch_entries_start + lnoff;
4620 /* cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
4621 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4623 /* BB fixme add unlock here */
4628 /* BB On error, should we leave previous search buf (and count and
4629 last entry fields) intact or free the previous one? */
4631 /* Note: On -EAGAIN error only caller can retry on handle based calls
4632 since file handle passed in no longer valid */
4635 cifs_buf_release(pSMB);
4640 CIFSFindClose(const int xid, struct cifs_tcon *tcon,
4641 const __u16 searchHandle)
4644 FINDCLOSE_REQ *pSMB = NULL;
4646 cFYI(1, "In CIFSSMBFindClose");
4647 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4649 /* no sense returning error if session restarted
4650 as file handle has been closed */
4656 pSMB->FileID = searchHandle;
4657 pSMB->ByteCount = 0;
4658 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4660 cERROR(1, "Send error in FindClose = %d", rc);
4662 cifs_stats_inc(&tcon->num_fclose);
4664 /* Since session is dead, search handle closed on server already */
4672 CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
4673 const unsigned char *searchName,
4674 __u64 *inode_number,
4675 const struct nls_table *nls_codepage, int remap)
4678 TRANSACTION2_QPI_REQ *pSMB = NULL;
4679 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4680 int name_len, bytes_returned;
4681 __u16 params, byte_count;
4683 cFYI(1, "In GetSrvInodeNum for %s", searchName);
4687 GetInodeNumberRetry:
4688 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4693 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4695 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4696 PATH_MAX, nls_codepage, remap);
4697 name_len++; /* trailing null */
4699 } else { /* BB improve the check for buffer overruns BB */
4700 name_len = strnlen(searchName, PATH_MAX);
4701 name_len++; /* trailing null */
4702 strncpy(pSMB->FileName, searchName, name_len);
4705 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4706 pSMB->TotalDataCount = 0;
4707 pSMB->MaxParameterCount = cpu_to_le16(2);
4708 /* BB find exact max data count below from sess structure BB */
4709 pSMB->MaxDataCount = cpu_to_le16(4000);
4710 pSMB->MaxSetupCount = 0;
4714 pSMB->Reserved2 = 0;
4715 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4716 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4717 pSMB->DataCount = 0;
4718 pSMB->DataOffset = 0;
4719 pSMB->SetupCount = 1;
4720 pSMB->Reserved3 = 0;
4721 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4722 byte_count = params + 1 /* pad */ ;
4723 pSMB->TotalParameterCount = cpu_to_le16(params);
4724 pSMB->ParameterCount = pSMB->TotalParameterCount;
4725 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4726 pSMB->Reserved4 = 0;
4727 inc_rfc1001_len(pSMB, byte_count);
4728 pSMB->ByteCount = cpu_to_le16(byte_count);
4730 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4731 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4733 cFYI(1, "error %d in QueryInternalInfo", rc);
4735 /* decode response */
4736 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4737 /* BB also check enough total bytes returned */
4738 if (rc || get_bcc(&pSMBr->hdr) < 2)
4739 /* If rc should we check for EOPNOSUPP and
4740 disable the srvino flag? or in caller? */
4741 rc = -EIO; /* bad smb */
4743 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4744 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4745 struct file_internal_info *pfinfo;
4746 /* BB Do we need a cast or hash here ? */
4748 cFYI(1, "Illegal size ret in QryIntrnlInf");
4750 goto GetInodeNumOut;
4752 pfinfo = (struct file_internal_info *)
4753 (data_offset + (char *) &pSMBr->hdr.Protocol);
4754 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4758 cifs_buf_release(pSMB);
4760 goto GetInodeNumberRetry;
4764 /* parses DFS refferal V3 structure
4765 * caller is responsible for freeing target_nodes
4768 * on failure - errno
4771 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4772 unsigned int *num_of_nodes,
4773 struct dfs_info3_param **target_nodes,
4774 const struct nls_table *nls_codepage, int remap,
4775 const char *searchName)
4780 struct dfs_referral_level_3 *ref;
4782 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4786 *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4788 if (*num_of_nodes < 1) {
4789 cERROR(1, "num_referrals: must be at least > 0,"
4790 "but we get num_referrals = %d\n", *num_of_nodes);
4792 goto parse_DFS_referrals_exit;
4795 ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4796 if (ref->VersionNumber != cpu_to_le16(3)) {
4797 cERROR(1, "Referrals of V%d version are not supported,"
4798 "should be V3", le16_to_cpu(ref->VersionNumber));
4800 goto parse_DFS_referrals_exit;
4803 /* get the upper boundary of the resp buffer */
4804 data_end = (char *)(&(pSMBr->PathConsumed)) +
4805 le16_to_cpu(pSMBr->t2.DataCount);
4807 cFYI(1, "num_referrals: %d dfs flags: 0x%x ...\n",
4809 le32_to_cpu(pSMBr->DFSFlags));
4811 *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
4812 *num_of_nodes, GFP_KERNEL);
4813 if (*target_nodes == NULL) {
4814 cERROR(1, "Failed to allocate buffer for target_nodes\n");
4816 goto parse_DFS_referrals_exit;
4819 /* collect necessary data from referrals */
4820 for (i = 0; i < *num_of_nodes; i++) {
4823 struct dfs_info3_param *node = (*target_nodes)+i;
4825 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4827 __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4831 goto parse_DFS_referrals_exit;
4833 cifsConvertToUCS((__le16 *) tmp, searchName,
4834 PATH_MAX, nls_codepage, remap);
4835 node->path_consumed = cifs_ucs2_bytes(tmp,
4836 le16_to_cpu(pSMBr->PathConsumed),
4840 node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4842 node->server_type = le16_to_cpu(ref->ServerType);
4843 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4846 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4847 max_len = data_end - temp;
4848 node->path_name = cifs_strndup_from_ucs(temp, max_len,
4849 is_unicode, nls_codepage);
4850 if (!node->path_name) {
4852 goto parse_DFS_referrals_exit;
4855 /* copy link target UNC */
4856 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4857 max_len = data_end - temp;
4858 node->node_name = cifs_strndup_from_ucs(temp, max_len,
4859 is_unicode, nls_codepage);
4860 if (!node->node_name) {
4862 goto parse_DFS_referrals_exit;
4868 parse_DFS_referrals_exit:
4870 free_dfs_info_array(*target_nodes, *num_of_nodes);
4871 *target_nodes = NULL;
4878 CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
4879 const unsigned char *searchName,
4880 struct dfs_info3_param **target_nodes,
4881 unsigned int *num_of_nodes,
4882 const struct nls_table *nls_codepage, int remap)
4884 /* TRANS2_GET_DFS_REFERRAL */
4885 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4886 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4890 __u16 params, byte_count;
4892 *target_nodes = NULL;
4894 cFYI(1, "In GetDFSRefer the path %s", searchName);
4898 rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4903 /* server pointer checked in called function,
4904 but should never be null here anyway */
4905 pSMB->hdr.Mid = GetNextMid(ses->server);
4906 pSMB->hdr.Tid = ses->ipc_tid;
4907 pSMB->hdr.Uid = ses->Suid;
4908 if (ses->capabilities & CAP_STATUS32)
4909 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4910 if (ses->capabilities & CAP_DFS)
4911 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4913 if (ses->capabilities & CAP_UNICODE) {
4914 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4916 cifsConvertToUCS((__le16 *) pSMB->RequestFileName,
4917 searchName, PATH_MAX, nls_codepage, remap);
4918 name_len++; /* trailing null */
4920 } else { /* BB improve the check for buffer overruns BB */
4921 name_len = strnlen(searchName, PATH_MAX);
4922 name_len++; /* trailing null */
4923 strncpy(pSMB->RequestFileName, searchName, name_len);
4927 if (ses->server->sec_mode &
4928 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4929 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4932 pSMB->hdr.Uid = ses->Suid;
4934 params = 2 /* level */ + name_len /*includes null */ ;
4935 pSMB->TotalDataCount = 0;
4936 pSMB->DataCount = 0;
4937 pSMB->DataOffset = 0;
4938 pSMB->MaxParameterCount = 0;
4939 /* BB find exact max SMB PDU from sess structure BB */
4940 pSMB->MaxDataCount = cpu_to_le16(4000);
4941 pSMB->MaxSetupCount = 0;
4945 pSMB->Reserved2 = 0;
4946 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4947 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4948 pSMB->SetupCount = 1;
4949 pSMB->Reserved3 = 0;
4950 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4951 byte_count = params + 3 /* pad */ ;
4952 pSMB->ParameterCount = cpu_to_le16(params);
4953 pSMB->TotalParameterCount = pSMB->ParameterCount;
4954 pSMB->MaxReferralLevel = cpu_to_le16(3);
4955 inc_rfc1001_len(pSMB, byte_count);
4956 pSMB->ByteCount = cpu_to_le16(byte_count);
4958 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4959 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4961 cFYI(1, "Send error in GetDFSRefer = %d", rc);
4964 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4966 /* BB Also check if enough total bytes returned? */
4967 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4968 rc = -EIO; /* bad smb */
4972 cFYI(1, "Decoding GetDFSRefer response BCC: %d Offset %d",
4973 get_bcc(&pSMBr->hdr),
4974 le16_to_cpu(pSMBr->t2.DataOffset));
4976 /* parse returned result into more usable form */
4977 rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4978 target_nodes, nls_codepage, remap,
4982 cifs_buf_release(pSMB);
4990 /* Query File System Info such as free space to old servers such as Win 9x */
4992 SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4994 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4995 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4996 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4997 FILE_SYSTEM_ALLOC_INFO *response_data;
4999 int bytes_returned = 0;
5000 __u16 params, byte_count;
5002 cFYI(1, "OldQFSInfo");
5004 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5009 params = 2; /* level */
5010 pSMB->TotalDataCount = 0;
5011 pSMB->MaxParameterCount = cpu_to_le16(2);
5012 pSMB->MaxDataCount = cpu_to_le16(1000);
5013 pSMB->MaxSetupCount = 0;
5017 pSMB->Reserved2 = 0;
5018 byte_count = params + 1 /* pad */ ;
5019 pSMB->TotalParameterCount = cpu_to_le16(params);
5020 pSMB->ParameterCount = pSMB->TotalParameterCount;
5021 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5022 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5023 pSMB->DataCount = 0;
5024 pSMB->DataOffset = 0;
5025 pSMB->SetupCount = 1;
5026 pSMB->Reserved3 = 0;
5027 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5028 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
5029 inc_rfc1001_len(pSMB, byte_count);
5030 pSMB->ByteCount = cpu_to_le16(byte_count);
5032 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5033 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5035 cFYI(1, "Send error in QFSInfo = %d", rc);
5036 } else { /* decode response */
5037 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5039 if (rc || get_bcc(&pSMBr->hdr) < 18)
5040 rc = -EIO; /* bad smb */
5042 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5043 cFYI(1, "qfsinf resp BCC: %d Offset %d",
5044 get_bcc(&pSMBr->hdr), data_offset);
5046 response_data = (FILE_SYSTEM_ALLOC_INFO *)
5047 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5049 le16_to_cpu(response_data->BytesPerSector) *
5050 le32_to_cpu(response_data->
5051 SectorsPerAllocationUnit);
5053 le32_to_cpu(response_data->TotalAllocationUnits);
5054 FSData->f_bfree = FSData->f_bavail =
5055 le32_to_cpu(response_data->FreeAllocationUnits);
5056 cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
5057 (unsigned long long)FSData->f_blocks,
5058 (unsigned long long)FSData->f_bfree,
5062 cifs_buf_release(pSMB);
5065 goto oldQFSInfoRetry;
5071 CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
5073 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5074 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5075 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5076 FILE_SYSTEM_INFO *response_data;
5078 int bytes_returned = 0;
5079 __u16 params, byte_count;
5081 cFYI(1, "In QFSInfo");
5083 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5088 params = 2; /* level */
5089 pSMB->TotalDataCount = 0;
5090 pSMB->MaxParameterCount = cpu_to_le16(2);
5091 pSMB->MaxDataCount = cpu_to_le16(1000);
5092 pSMB->MaxSetupCount = 0;
5096 pSMB->Reserved2 = 0;
5097 byte_count = params + 1 /* pad */ ;
5098 pSMB->TotalParameterCount = cpu_to_le16(params);
5099 pSMB->ParameterCount = pSMB->TotalParameterCount;
5100 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5101 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5102 pSMB->DataCount = 0;
5103 pSMB->DataOffset = 0;
5104 pSMB->SetupCount = 1;
5105 pSMB->Reserved3 = 0;
5106 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5107 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5108 inc_rfc1001_len(pSMB, byte_count);
5109 pSMB->ByteCount = cpu_to_le16(byte_count);
5111 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5112 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5114 cFYI(1, "Send error in QFSInfo = %d", rc);
5115 } else { /* decode response */
5116 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5118 if (rc || get_bcc(&pSMBr->hdr) < 24)
5119 rc = -EIO; /* bad smb */
5121 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5125 *) (((char *) &pSMBr->hdr.Protocol) +
5128 le32_to_cpu(response_data->BytesPerSector) *
5129 le32_to_cpu(response_data->
5130 SectorsPerAllocationUnit);
5132 le64_to_cpu(response_data->TotalAllocationUnits);
5133 FSData->f_bfree = FSData->f_bavail =
5134 le64_to_cpu(response_data->FreeAllocationUnits);
5135 cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
5136 (unsigned long long)FSData->f_blocks,
5137 (unsigned long long)FSData->f_bfree,
5141 cifs_buf_release(pSMB);
5150 CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
5152 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5153 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5154 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5155 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5157 int bytes_returned = 0;
5158 __u16 params, byte_count;
5160 cFYI(1, "In QFSAttributeInfo");
5162 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5167 params = 2; /* level */
5168 pSMB->TotalDataCount = 0;
5169 pSMB->MaxParameterCount = cpu_to_le16(2);
5170 /* BB find exact max SMB PDU from sess structure BB */
5171 pSMB->MaxDataCount = cpu_to_le16(1000);
5172 pSMB->MaxSetupCount = 0;
5176 pSMB->Reserved2 = 0;
5177 byte_count = params + 1 /* pad */ ;
5178 pSMB->TotalParameterCount = cpu_to_le16(params);
5179 pSMB->ParameterCount = pSMB->TotalParameterCount;
5180 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5181 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5182 pSMB->DataCount = 0;
5183 pSMB->DataOffset = 0;
5184 pSMB->SetupCount = 1;
5185 pSMB->Reserved3 = 0;
5186 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5187 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5188 inc_rfc1001_len(pSMB, byte_count);
5189 pSMB->ByteCount = cpu_to_le16(byte_count);
5191 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5192 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5194 cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
5195 } else { /* decode response */
5196 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5198 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5199 /* BB also check if enough bytes returned */
5200 rc = -EIO; /* bad smb */
5202 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5204 (FILE_SYSTEM_ATTRIBUTE_INFO
5205 *) (((char *) &pSMBr->hdr.Protocol) +
5207 memcpy(&tcon->fsAttrInfo, response_data,
5208 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5211 cifs_buf_release(pSMB);
5214 goto QFSAttributeRetry;
5220 CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
5222 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5223 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5224 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5225 FILE_SYSTEM_DEVICE_INFO *response_data;
5227 int bytes_returned = 0;
5228 __u16 params, byte_count;
5230 cFYI(1, "In QFSDeviceInfo");
5232 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5237 params = 2; /* level */
5238 pSMB->TotalDataCount = 0;
5239 pSMB->MaxParameterCount = cpu_to_le16(2);
5240 /* BB find exact max SMB PDU from sess structure BB */
5241 pSMB->MaxDataCount = cpu_to_le16(1000);
5242 pSMB->MaxSetupCount = 0;
5246 pSMB->Reserved2 = 0;
5247 byte_count = params + 1 /* pad */ ;
5248 pSMB->TotalParameterCount = cpu_to_le16(params);
5249 pSMB->ParameterCount = pSMB->TotalParameterCount;
5250 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5251 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5253 pSMB->DataCount = 0;
5254 pSMB->DataOffset = 0;
5255 pSMB->SetupCount = 1;
5256 pSMB->Reserved3 = 0;
5257 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5258 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5259 inc_rfc1001_len(pSMB, byte_count);
5260 pSMB->ByteCount = cpu_to_le16(byte_count);
5262 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5263 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5265 cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
5266 } else { /* decode response */
5267 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5269 if (rc || get_bcc(&pSMBr->hdr) <
5270 sizeof(FILE_SYSTEM_DEVICE_INFO))
5271 rc = -EIO; /* bad smb */
5273 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5275 (FILE_SYSTEM_DEVICE_INFO *)
5276 (((char *) &pSMBr->hdr.Protocol) +
5278 memcpy(&tcon->fsDevInfo, response_data,
5279 sizeof(FILE_SYSTEM_DEVICE_INFO));
5282 cifs_buf_release(pSMB);
5285 goto QFSDeviceRetry;
5291 CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
5293 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5294 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5295 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5296 FILE_SYSTEM_UNIX_INFO *response_data;
5298 int bytes_returned = 0;
5299 __u16 params, byte_count;
5301 cFYI(1, "In QFSUnixInfo");
5303 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5304 (void **) &pSMB, (void **) &pSMBr);
5308 params = 2; /* level */
5309 pSMB->TotalDataCount = 0;
5310 pSMB->DataCount = 0;
5311 pSMB->DataOffset = 0;
5312 pSMB->MaxParameterCount = cpu_to_le16(2);
5313 /* BB find exact max SMB PDU from sess structure BB */
5314 pSMB->MaxDataCount = cpu_to_le16(100);
5315 pSMB->MaxSetupCount = 0;
5319 pSMB->Reserved2 = 0;
5320 byte_count = params + 1 /* pad */ ;
5321 pSMB->ParameterCount = cpu_to_le16(params);
5322 pSMB->TotalParameterCount = pSMB->ParameterCount;
5323 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5324 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5325 pSMB->SetupCount = 1;
5326 pSMB->Reserved3 = 0;
5327 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5328 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5329 inc_rfc1001_len(pSMB, byte_count);
5330 pSMB->ByteCount = cpu_to_le16(byte_count);
5332 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5333 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5335 cERROR(1, "Send error in QFSUnixInfo = %d", rc);
5336 } else { /* decode response */
5337 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5339 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5340 rc = -EIO; /* bad smb */
5342 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5344 (FILE_SYSTEM_UNIX_INFO
5345 *) (((char *) &pSMBr->hdr.Protocol) +
5347 memcpy(&tcon->fsUnixInfo, response_data,
5348 sizeof(FILE_SYSTEM_UNIX_INFO));
5351 cifs_buf_release(pSMB);
5361 CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
5363 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5364 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5365 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5367 int bytes_returned = 0;
5368 __u16 params, param_offset, offset, byte_count;
5370 cFYI(1, "In SETFSUnixInfo");
5372 /* BB switch to small buf init to save memory */
5373 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5374 (void **) &pSMB, (void **) &pSMBr);
5378 params = 4; /* 2 bytes zero followed by info level. */
5379 pSMB->MaxSetupCount = 0;
5383 pSMB->Reserved2 = 0;
5384 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5386 offset = param_offset + params;
5388 pSMB->MaxParameterCount = cpu_to_le16(4);
5389 /* BB find exact max SMB PDU from sess structure BB */
5390 pSMB->MaxDataCount = cpu_to_le16(100);
5391 pSMB->SetupCount = 1;
5392 pSMB->Reserved3 = 0;
5393 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5394 byte_count = 1 /* pad */ + params + 12;
5396 pSMB->DataCount = cpu_to_le16(12);
5397 pSMB->ParameterCount = cpu_to_le16(params);
5398 pSMB->TotalDataCount = pSMB->DataCount;
5399 pSMB->TotalParameterCount = pSMB->ParameterCount;
5400 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5401 pSMB->DataOffset = cpu_to_le16(offset);
5405 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5408 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5409 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5410 pSMB->ClientUnixCap = cpu_to_le64(cap);
5412 inc_rfc1001_len(pSMB, byte_count);
5413 pSMB->ByteCount = cpu_to_le16(byte_count);
5415 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5416 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5418 cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
5419 } else { /* decode response */
5420 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5422 rc = -EIO; /* bad smb */
5424 cifs_buf_release(pSMB);
5427 goto SETFSUnixRetry;
5435 CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
5436 struct kstatfs *FSData)
5438 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5439 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5440 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5441 FILE_SYSTEM_POSIX_INFO *response_data;
5443 int bytes_returned = 0;
5444 __u16 params, byte_count;
5446 cFYI(1, "In QFSPosixInfo");
5448 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5453 params = 2; /* level */
5454 pSMB->TotalDataCount = 0;
5455 pSMB->DataCount = 0;
5456 pSMB->DataOffset = 0;
5457 pSMB->MaxParameterCount = cpu_to_le16(2);
5458 /* BB find exact max SMB PDU from sess structure BB */
5459 pSMB->MaxDataCount = cpu_to_le16(100);
5460 pSMB->MaxSetupCount = 0;
5464 pSMB->Reserved2 = 0;
5465 byte_count = params + 1 /* pad */ ;
5466 pSMB->ParameterCount = cpu_to_le16(params);
5467 pSMB->TotalParameterCount = pSMB->ParameterCount;
5468 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5469 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5470 pSMB->SetupCount = 1;
5471 pSMB->Reserved3 = 0;
5472 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5473 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5474 inc_rfc1001_len(pSMB, byte_count);
5475 pSMB->ByteCount = cpu_to_le16(byte_count);
5477 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5478 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5480 cFYI(1, "Send error in QFSUnixInfo = %d", rc);
5481 } else { /* decode response */
5482 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5484 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5485 rc = -EIO; /* bad smb */
5487 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5489 (FILE_SYSTEM_POSIX_INFO
5490 *) (((char *) &pSMBr->hdr.Protocol) +
5493 le32_to_cpu(response_data->BlockSize);
5495 le64_to_cpu(response_data->TotalBlocks);
5497 le64_to_cpu(response_data->BlocksAvail);
5498 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5499 FSData->f_bavail = FSData->f_bfree;
5502 le64_to_cpu(response_data->UserBlocksAvail);
5504 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5506 le64_to_cpu(response_data->TotalFileNodes);
5507 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5509 le64_to_cpu(response_data->FreeFileNodes);
5512 cifs_buf_release(pSMB);
5521 /* We can not use write of zero bytes trick to
5522 set file size due to need for large file support. Also note that
5523 this SetPathInfo is preferred to SetFileInfo based method in next
5524 routine which is only needed to work around a sharing violation bug
5525 in Samba which this routine can run into */
5528 CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
5529 __u64 size, bool SetAllocation,
5530 const struct nls_table *nls_codepage, int remap)
5532 struct smb_com_transaction2_spi_req *pSMB = NULL;
5533 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5534 struct file_end_of_file_info *parm_data;
5537 int bytes_returned = 0;
5538 __u16 params, byte_count, data_count, param_offset, offset;
5540 cFYI(1, "In SetEOF");
5542 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5547 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5549 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
5550 PATH_MAX, nls_codepage, remap);
5551 name_len++; /* trailing null */
5553 } else { /* BB improve the check for buffer overruns BB */
5554 name_len = strnlen(fileName, PATH_MAX);
5555 name_len++; /* trailing null */
5556 strncpy(pSMB->FileName, fileName, name_len);
5558 params = 6 + name_len;
5559 data_count = sizeof(struct file_end_of_file_info);
5560 pSMB->MaxParameterCount = cpu_to_le16(2);
5561 pSMB->MaxDataCount = cpu_to_le16(4100);
5562 pSMB->MaxSetupCount = 0;
5566 pSMB->Reserved2 = 0;
5567 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5568 InformationLevel) - 4;
5569 offset = param_offset + params;
5570 if (SetAllocation) {
5571 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5572 pSMB->InformationLevel =
5573 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5575 pSMB->InformationLevel =
5576 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5577 } else /* Set File Size */ {
5578 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5579 pSMB->InformationLevel =
5580 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5582 pSMB->InformationLevel =
5583 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5587 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5589 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5590 pSMB->DataOffset = cpu_to_le16(offset);
5591 pSMB->SetupCount = 1;
5592 pSMB->Reserved3 = 0;
5593 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5594 byte_count = 3 /* pad */ + params + data_count;
5595 pSMB->DataCount = cpu_to_le16(data_count);
5596 pSMB->TotalDataCount = pSMB->DataCount;
5597 pSMB->ParameterCount = cpu_to_le16(params);
5598 pSMB->TotalParameterCount = pSMB->ParameterCount;
5599 pSMB->Reserved4 = 0;
5600 inc_rfc1001_len(pSMB, byte_count);
5601 parm_data->FileSize = cpu_to_le64(size);
5602 pSMB->ByteCount = cpu_to_le16(byte_count);
5603 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5604 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5606 cFYI(1, "SetPathInfo (file size) returned %d", rc);
5608 cifs_buf_release(pSMB);
5617 CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
5618 __u16 fid, __u32 pid_of_opener, bool SetAllocation)
5620 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5621 struct file_end_of_file_info *parm_data;
5623 __u16 params, param_offset, offset, byte_count, count;
5625 cFYI(1, "SetFileSize (via SetFileInfo) %lld",
5627 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5632 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5633 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5636 pSMB->MaxSetupCount = 0;
5640 pSMB->Reserved2 = 0;
5641 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5642 offset = param_offset + params;
5644 count = sizeof(struct file_end_of_file_info);
5645 pSMB->MaxParameterCount = cpu_to_le16(2);
5646 /* BB find exact max SMB PDU from sess structure BB */
5647 pSMB->MaxDataCount = cpu_to_le16(1000);
5648 pSMB->SetupCount = 1;
5649 pSMB->Reserved3 = 0;
5650 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5651 byte_count = 3 /* pad */ + params + count;
5652 pSMB->DataCount = cpu_to_le16(count);
5653 pSMB->ParameterCount = cpu_to_le16(params);
5654 pSMB->TotalDataCount = pSMB->DataCount;
5655 pSMB->TotalParameterCount = pSMB->ParameterCount;
5656 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5658 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5660 pSMB->DataOffset = cpu_to_le16(offset);
5661 parm_data->FileSize = cpu_to_le64(size);
5663 if (SetAllocation) {
5664 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5665 pSMB->InformationLevel =
5666 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5668 pSMB->InformationLevel =
5669 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5670 } else /* Set File Size */ {
5671 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5672 pSMB->InformationLevel =
5673 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5675 pSMB->InformationLevel =
5676 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5678 pSMB->Reserved4 = 0;
5679 inc_rfc1001_len(pSMB, byte_count);
5680 pSMB->ByteCount = cpu_to_le16(byte_count);
5681 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5683 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
5686 /* Note: On -EAGAIN error only caller can retry on handle based calls
5687 since file handle passed in no longer valid */
5692 /* Some legacy servers such as NT4 require that the file times be set on
5693 an open handle, rather than by pathname - this is awkward due to
5694 potential access conflicts on the open, but it is unavoidable for these
5695 old servers since the only other choice is to go from 100 nanosecond DCE
5696 time and resort to the original setpathinfo level which takes the ancient
5697 DOS time format with 2 second granularity */
5699 CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
5700 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5702 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5705 __u16 params, param_offset, offset, byte_count, count;
5707 cFYI(1, "Set Times (via SetFileInfo)");
5708 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5713 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5714 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5717 pSMB->MaxSetupCount = 0;
5721 pSMB->Reserved2 = 0;
5722 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5723 offset = param_offset + params;
5725 data_offset = (char *)pSMB +
5726 offsetof(struct smb_hdr, Protocol) + offset;
5728 count = sizeof(FILE_BASIC_INFO);
5729 pSMB->MaxParameterCount = cpu_to_le16(2);
5730 /* BB find max SMB PDU from sess */
5731 pSMB->MaxDataCount = cpu_to_le16(1000);
5732 pSMB->SetupCount = 1;
5733 pSMB->Reserved3 = 0;
5734 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5735 byte_count = 3 /* pad */ + params + count;
5736 pSMB->DataCount = cpu_to_le16(count);
5737 pSMB->ParameterCount = cpu_to_le16(params);
5738 pSMB->TotalDataCount = pSMB->DataCount;
5739 pSMB->TotalParameterCount = pSMB->ParameterCount;
5740 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5741 pSMB->DataOffset = cpu_to_le16(offset);
5743 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5744 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5746 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5747 pSMB->Reserved4 = 0;
5748 inc_rfc1001_len(pSMB, byte_count);
5749 pSMB->ByteCount = cpu_to_le16(byte_count);
5750 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5751 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5753 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5755 /* Note: On -EAGAIN error only caller can retry on handle based calls
5756 since file handle passed in no longer valid */
5762 CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
5763 bool delete_file, __u16 fid, __u32 pid_of_opener)
5765 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5768 __u16 params, param_offset, offset, byte_count, count;
5770 cFYI(1, "Set File Disposition (via SetFileInfo)");
5771 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5776 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5777 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5780 pSMB->MaxSetupCount = 0;
5784 pSMB->Reserved2 = 0;
5785 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5786 offset = param_offset + params;
5788 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5791 pSMB->MaxParameterCount = cpu_to_le16(2);
5792 /* BB find max SMB PDU from sess */
5793 pSMB->MaxDataCount = cpu_to_le16(1000);
5794 pSMB->SetupCount = 1;
5795 pSMB->Reserved3 = 0;
5796 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5797 byte_count = 3 /* pad */ + params + count;
5798 pSMB->DataCount = cpu_to_le16(count);
5799 pSMB->ParameterCount = cpu_to_le16(params);
5800 pSMB->TotalDataCount = pSMB->DataCount;
5801 pSMB->TotalParameterCount = pSMB->ParameterCount;
5802 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5803 pSMB->DataOffset = cpu_to_le16(offset);
5805 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5806 pSMB->Reserved4 = 0;
5807 inc_rfc1001_len(pSMB, byte_count);
5808 pSMB->ByteCount = cpu_to_le16(byte_count);
5809 *data_offset = delete_file ? 1 : 0;
5810 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5812 cFYI(1, "Send error in SetFileDisposition = %d", rc);
5818 CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
5819 const char *fileName, const FILE_BASIC_INFO *data,
5820 const struct nls_table *nls_codepage, int remap)
5822 TRANSACTION2_SPI_REQ *pSMB = NULL;
5823 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5826 int bytes_returned = 0;
5828 __u16 params, param_offset, offset, byte_count, count;
5830 cFYI(1, "In SetTimes");
5833 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5838 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5840 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
5841 PATH_MAX, nls_codepage, remap);
5842 name_len++; /* trailing null */
5844 } else { /* BB improve the check for buffer overruns BB */
5845 name_len = strnlen(fileName, PATH_MAX);
5846 name_len++; /* trailing null */
5847 strncpy(pSMB->FileName, fileName, name_len);
5850 params = 6 + name_len;
5851 count = sizeof(FILE_BASIC_INFO);
5852 pSMB->MaxParameterCount = cpu_to_le16(2);
5853 /* BB find max SMB PDU from sess structure BB */
5854 pSMB->MaxDataCount = cpu_to_le16(1000);
5855 pSMB->MaxSetupCount = 0;
5859 pSMB->Reserved2 = 0;
5860 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5861 InformationLevel) - 4;
5862 offset = param_offset + params;
5863 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5864 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5865 pSMB->DataOffset = cpu_to_le16(offset);
5866 pSMB->SetupCount = 1;
5867 pSMB->Reserved3 = 0;
5868 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5869 byte_count = 3 /* pad */ + params + count;
5871 pSMB->DataCount = cpu_to_le16(count);
5872 pSMB->ParameterCount = cpu_to_le16(params);
5873 pSMB->TotalDataCount = pSMB->DataCount;
5874 pSMB->TotalParameterCount = pSMB->ParameterCount;
5875 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5876 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5878 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5879 pSMB->Reserved4 = 0;
5880 inc_rfc1001_len(pSMB, byte_count);
5881 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5882 pSMB->ByteCount = cpu_to_le16(byte_count);
5883 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5884 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5886 cFYI(1, "SetPathInfo (times) returned %d", rc);
5888 cifs_buf_release(pSMB);
5896 /* Can not be used to set time stamps yet (due to old DOS time format) */
5897 /* Can be used to set attributes */
5898 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5899 handling it anyway and NT4 was what we thought it would be needed for
5900 Do not delete it until we prove whether needed for Win9x though */
5902 CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon, char *fileName,
5903 __u16 dos_attrs, const struct nls_table *nls_codepage)
5905 SETATTR_REQ *pSMB = NULL;
5906 SETATTR_RSP *pSMBr = NULL;
5911 cFYI(1, "In SetAttrLegacy");
5914 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5919 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5921 ConvertToUCS((__le16 *) pSMB->fileName, fileName,
5922 PATH_MAX, nls_codepage);
5923 name_len++; /* trailing null */
5925 } else { /* BB improve the check for buffer overruns BB */
5926 name_len = strnlen(fileName, PATH_MAX);
5927 name_len++; /* trailing null */
5928 strncpy(pSMB->fileName, fileName, name_len);
5930 pSMB->attr = cpu_to_le16(dos_attrs);
5931 pSMB->BufferFormat = 0x04;
5932 inc_rfc1001_len(pSMB, name_len + 1);
5933 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5934 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5935 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5937 cFYI(1, "Error in LegacySetAttr = %d", rc);
5939 cifs_buf_release(pSMB);
5942 goto SetAttrLgcyRetry;
5946 #endif /* temporarily unneeded SetAttr legacy function */
5949 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5950 const struct cifs_unix_set_info_args *args)
5952 u64 mode = args->mode;
5955 * Samba server ignores set of file size to zero due to bugs in some
5956 * older clients, but we should be precise - we use SetFileSize to
5957 * set file size and do not want to truncate file size to zero
5958 * accidentally as happened on one Samba server beta by putting
5959 * zero instead of -1 here
5961 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5962 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5963 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5964 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5965 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5966 data_offset->Uid = cpu_to_le64(args->uid);
5967 data_offset->Gid = cpu_to_le64(args->gid);
5968 /* better to leave device as zero when it is */
5969 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5970 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5971 data_offset->Permissions = cpu_to_le64(mode);
5974 data_offset->Type = cpu_to_le32(UNIX_FILE);
5975 else if (S_ISDIR(mode))
5976 data_offset->Type = cpu_to_le32(UNIX_DIR);
5977 else if (S_ISLNK(mode))
5978 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5979 else if (S_ISCHR(mode))
5980 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5981 else if (S_ISBLK(mode))
5982 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5983 else if (S_ISFIFO(mode))
5984 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5985 else if (S_ISSOCK(mode))
5986 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5990 CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
5991 const struct cifs_unix_set_info_args *args,
5992 u16 fid, u32 pid_of_opener)
5994 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5997 u16 params, param_offset, offset, byte_count, count;
5999 cFYI(1, "Set Unix Info (via SetFileInfo)");
6000 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
6005 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
6006 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
6009 pSMB->MaxSetupCount = 0;
6013 pSMB->Reserved2 = 0;
6014 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
6015 offset = param_offset + params;
6017 data_offset = (char *)pSMB +
6018 offsetof(struct smb_hdr, Protocol) + offset;
6020 count = sizeof(FILE_UNIX_BASIC_INFO);
6022 pSMB->MaxParameterCount = cpu_to_le16(2);
6023 /* BB find max SMB PDU from sess */
6024 pSMB->MaxDataCount = cpu_to_le16(1000);
6025 pSMB->SetupCount = 1;
6026 pSMB->Reserved3 = 0;
6027 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
6028 byte_count = 3 /* pad */ + params + count;
6029 pSMB->DataCount = cpu_to_le16(count);
6030 pSMB->ParameterCount = cpu_to_le16(params);
6031 pSMB->TotalDataCount = pSMB->DataCount;
6032 pSMB->TotalParameterCount = pSMB->ParameterCount;
6033 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6034 pSMB->DataOffset = cpu_to_le16(offset);
6036 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6037 pSMB->Reserved4 = 0;
6038 inc_rfc1001_len(pSMB, byte_count);
6039 pSMB->ByteCount = cpu_to_le16(byte_count);
6041 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
6043 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
6045 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
6047 /* Note: On -EAGAIN error only caller can retry on handle based calls
6048 since file handle passed in no longer valid */
6054 CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *tcon, char *fileName,
6055 const struct cifs_unix_set_info_args *args,
6056 const struct nls_table *nls_codepage, int remap)
6058 TRANSACTION2_SPI_REQ *pSMB = NULL;
6059 TRANSACTION2_SPI_RSP *pSMBr = NULL;
6062 int bytes_returned = 0;
6063 FILE_UNIX_BASIC_INFO *data_offset;
6064 __u16 params, param_offset, offset, count, byte_count;
6066 cFYI(1, "In SetUID/GID/Mode");
6068 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6073 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6075 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
6076 PATH_MAX, nls_codepage, remap);
6077 name_len++; /* trailing null */
6079 } else { /* BB improve the check for buffer overruns BB */
6080 name_len = strnlen(fileName, PATH_MAX);
6081 name_len++; /* trailing null */
6082 strncpy(pSMB->FileName, fileName, name_len);
6085 params = 6 + name_len;
6086 count = sizeof(FILE_UNIX_BASIC_INFO);
6087 pSMB->MaxParameterCount = cpu_to_le16(2);
6088 /* BB find max SMB PDU from sess structure BB */
6089 pSMB->MaxDataCount = cpu_to_le16(1000);
6090 pSMB->MaxSetupCount = 0;
6094 pSMB->Reserved2 = 0;
6095 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6096 InformationLevel) - 4;
6097 offset = param_offset + params;
6099 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6101 memset(data_offset, 0, count);
6102 pSMB->DataOffset = cpu_to_le16(offset);
6103 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6104 pSMB->SetupCount = 1;
6105 pSMB->Reserved3 = 0;
6106 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6107 byte_count = 3 /* pad */ + params + count;
6108 pSMB->ParameterCount = cpu_to_le16(params);
6109 pSMB->DataCount = cpu_to_le16(count);
6110 pSMB->TotalParameterCount = pSMB->ParameterCount;
6111 pSMB->TotalDataCount = pSMB->DataCount;
6112 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6113 pSMB->Reserved4 = 0;
6114 inc_rfc1001_len(pSMB, byte_count);
6116 cifs_fill_unix_set_info(data_offset, args);
6118 pSMB->ByteCount = cpu_to_le16(byte_count);
6119 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6120 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6122 cFYI(1, "SetPathInfo (perms) returned %d", rc);
6124 cifs_buf_release(pSMB);
6130 #ifdef CONFIG_CIFS_XATTR
6132 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6133 * function used by listxattr and getxattr type calls. When ea_name is set,
6134 * it looks for that attribute name and stuffs that value into the EAData
6135 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6136 * buffer. In both cases, the return value is either the length of the
6137 * resulting data or a negative error code. If EAData is a NULL pointer then
6138 * the data isn't copied to it, but the length is returned.
6141 CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
6142 const unsigned char *searchName, const unsigned char *ea_name,
6143 char *EAData, size_t buf_size,
6144 const struct nls_table *nls_codepage, int remap)
6146 /* BB assumes one setup word */
6147 TRANSACTION2_QPI_REQ *pSMB = NULL;
6148 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6152 struct fealist *ea_response_data;
6153 struct fea *temp_fea;
6156 __u16 params, byte_count, data_offset;
6157 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6159 cFYI(1, "In Query All EAs path %s", searchName);
6161 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6166 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6168 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
6169 PATH_MAX, nls_codepage, remap);
6170 list_len++; /* trailing null */
6172 } else { /* BB improve the check for buffer overruns BB */
6173 list_len = strnlen(searchName, PATH_MAX);
6174 list_len++; /* trailing null */
6175 strncpy(pSMB->FileName, searchName, list_len);
6178 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6179 pSMB->TotalDataCount = 0;
6180 pSMB->MaxParameterCount = cpu_to_le16(2);
6181 /* BB find exact max SMB PDU from sess structure BB */
6182 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6183 pSMB->MaxSetupCount = 0;
6187 pSMB->Reserved2 = 0;
6188 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6189 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6190 pSMB->DataCount = 0;
6191 pSMB->DataOffset = 0;
6192 pSMB->SetupCount = 1;
6193 pSMB->Reserved3 = 0;
6194 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6195 byte_count = params + 1 /* pad */ ;
6196 pSMB->TotalParameterCount = cpu_to_le16(params);
6197 pSMB->ParameterCount = pSMB->TotalParameterCount;
6198 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6199 pSMB->Reserved4 = 0;
6200 inc_rfc1001_len(pSMB, byte_count);
6201 pSMB->ByteCount = cpu_to_le16(byte_count);
6203 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6204 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6206 cFYI(1, "Send error in QueryAllEAs = %d", rc);
6211 /* BB also check enough total bytes returned */
6212 /* BB we need to improve the validity checking
6213 of these trans2 responses */
6215 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6216 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6217 rc = -EIO; /* bad smb */
6221 /* check that length of list is not more than bcc */
6222 /* check that each entry does not go beyond length
6224 /* check that each element of each entry does not
6225 go beyond end of list */
6226 /* validate_trans2_offsets() */
6227 /* BB check if start of smb + data_offset > &bcc+ bcc */
6229 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6230 ea_response_data = (struct fealist *)
6231 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6233 list_len = le32_to_cpu(ea_response_data->list_len);
6234 cFYI(1, "ea length %d", list_len);
6235 if (list_len <= 8) {
6236 cFYI(1, "empty EA list returned from server");
6240 /* make sure list_len doesn't go past end of SMB */
6241 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6242 if ((char *)ea_response_data + list_len > end_of_smb) {
6243 cFYI(1, "EA list appears to go beyond SMB");
6248 /* account for ea list len */
6250 temp_fea = ea_response_data->list;
6251 temp_ptr = (char *)temp_fea;
6252 while (list_len > 0) {
6253 unsigned int name_len;
6258 /* make sure we can read name_len and value_len */
6260 cFYI(1, "EA entry goes beyond length of list");
6265 name_len = temp_fea->name_len;
6266 value_len = le16_to_cpu(temp_fea->value_len);
6267 list_len -= name_len + 1 + value_len;
6269 cFYI(1, "EA entry goes beyond length of list");
6275 if (ea_name_len == name_len &&
6276 memcmp(ea_name, temp_ptr, name_len) == 0) {
6277 temp_ptr += name_len + 1;
6281 if ((size_t)value_len > buf_size) {
6285 memcpy(EAData, temp_ptr, value_len);
6289 /* account for prefix user. and trailing null */
6290 rc += (5 + 1 + name_len);
6291 if (rc < (int) buf_size) {
6292 memcpy(EAData, "user.", 5);
6294 memcpy(EAData, temp_ptr, name_len);
6296 /* null terminate name */
6299 } else if (buf_size == 0) {
6300 /* skip copy - calc size only */
6302 /* stop before overrun buffer */
6307 temp_ptr += name_len + 1 + value_len;
6308 temp_fea = (struct fea *)temp_ptr;
6311 /* didn't find the named attribute */
6316 cifs_buf_release(pSMB);
6324 CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon, const char *fileName,
6325 const char *ea_name, const void *ea_value,
6326 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6329 struct smb_com_transaction2_spi_req *pSMB = NULL;
6330 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6331 struct fealist *parm_data;
6334 int bytes_returned = 0;
6335 __u16 params, param_offset, byte_count, offset, count;
6337 cFYI(1, "In SetEA");
6339 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6344 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6346 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
6347 PATH_MAX, nls_codepage, remap);
6348 name_len++; /* trailing null */
6350 } else { /* BB improve the check for buffer overruns BB */
6351 name_len = strnlen(fileName, PATH_MAX);
6352 name_len++; /* trailing null */
6353 strncpy(pSMB->FileName, fileName, name_len);
6356 params = 6 + name_len;
6358 /* done calculating parms using name_len of file name,
6359 now use name_len to calculate length of ea name
6360 we are going to create in the inode xattrs */
6361 if (ea_name == NULL)
6364 name_len = strnlen(ea_name, 255);
6366 count = sizeof(*parm_data) + ea_value_len + name_len;
6367 pSMB->MaxParameterCount = cpu_to_le16(2);
6368 /* BB find max SMB PDU from sess */
6369 pSMB->MaxDataCount = cpu_to_le16(1000);
6370 pSMB->MaxSetupCount = 0;
6374 pSMB->Reserved2 = 0;
6375 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6376 InformationLevel) - 4;
6377 offset = param_offset + params;
6378 pSMB->InformationLevel =
6379 cpu_to_le16(SMB_SET_FILE_EA);
6382 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6384 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6385 pSMB->DataOffset = cpu_to_le16(offset);
6386 pSMB->SetupCount = 1;
6387 pSMB->Reserved3 = 0;
6388 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6389 byte_count = 3 /* pad */ + params + count;
6390 pSMB->DataCount = cpu_to_le16(count);
6391 parm_data->list_len = cpu_to_le32(count);
6392 parm_data->list[0].EA_flags = 0;
6393 /* we checked above that name len is less than 255 */
6394 parm_data->list[0].name_len = (__u8)name_len;
6395 /* EA names are always ASCII */
6397 strncpy(parm_data->list[0].name, ea_name, name_len);
6398 parm_data->list[0].name[name_len] = 0;
6399 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6400 /* caller ensures that ea_value_len is less than 64K but
6401 we need to ensure that it fits within the smb */
6403 /*BB add length check to see if it would fit in
6404 negotiated SMB buffer size BB */
6405 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6407 memcpy(parm_data->list[0].name+name_len+1,
6408 ea_value, ea_value_len);
6410 pSMB->TotalDataCount = pSMB->DataCount;
6411 pSMB->ParameterCount = cpu_to_le16(params);
6412 pSMB->TotalParameterCount = pSMB->ParameterCount;
6413 pSMB->Reserved4 = 0;
6414 inc_rfc1001_len(pSMB, byte_count);
6415 pSMB->ByteCount = cpu_to_le16(byte_count);
6416 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6417 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6419 cFYI(1, "SetPathInfo (EA) returned %d", rc);
6421 cifs_buf_release(pSMB);
6430 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6432 * Years ago the kernel added a "dnotify" function for Samba server,
6433 * to allow network clients (such as Windows) to display updated
6434 * lists of files in directory listings automatically when
6435 * files are added by one user when another user has the
6436 * same directory open on their desktop. The Linux cifs kernel
6437 * client hooked into the kernel side of this interface for
6438 * the same reason, but ironically when the VFS moved from
6439 * "dnotify" to "inotify" it became harder to plug in Linux
6440 * network file system clients (the most obvious use case
6441 * for notify interfaces is when multiple users can update
6442 * the contents of the same directory - exactly what network
6443 * file systems can do) although the server (Samba) could
6444 * still use it. For the short term we leave the worker
6445 * function ifdeffed out (below) until inotify is fixed
6446 * in the VFS to make it easier to plug in network file
6447 * system clients. If inotify turns out to be permanently
6448 * incompatible for network fs clients, we could instead simply
6449 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6451 int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
6452 const int notify_subdirs, const __u16 netfid,
6453 __u32 filter, struct file *pfile, int multishot,
6454 const struct nls_table *nls_codepage)
6457 struct smb_com_transaction_change_notify_req *pSMB = NULL;
6458 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6459 struct dir_notify_req *dnotify_req;
6462 cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
6463 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6468 pSMB->TotalParameterCount = 0 ;
6469 pSMB->TotalDataCount = 0;
6470 pSMB->MaxParameterCount = cpu_to_le32(2);
6471 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6472 pSMB->MaxSetupCount = 4;
6474 pSMB->ParameterOffset = 0;
6475 pSMB->DataCount = 0;
6476 pSMB->DataOffset = 0;
6477 pSMB->SetupCount = 4; /* single byte does not need le conversion */
6478 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6479 pSMB->ParameterCount = pSMB->TotalParameterCount;
6481 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6482 pSMB->Reserved2 = 0;
6483 pSMB->CompletionFilter = cpu_to_le32(filter);
6484 pSMB->Fid = netfid; /* file handle always le */
6485 pSMB->ByteCount = 0;
6487 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6488 (struct smb_hdr *)pSMBr, &bytes_returned,
6491 cFYI(1, "Error in Notify = %d", rc);
6493 /* Add file to outstanding requests */
6494 /* BB change to kmem cache alloc */
6495 dnotify_req = kmalloc(
6496 sizeof(struct dir_notify_req),
6499 dnotify_req->Pid = pSMB->hdr.Pid;
6500 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6501 dnotify_req->Mid = pSMB->hdr.Mid;
6502 dnotify_req->Tid = pSMB->hdr.Tid;
6503 dnotify_req->Uid = pSMB->hdr.Uid;
6504 dnotify_req->netfid = netfid;
6505 dnotify_req->pfile = pfile;
6506 dnotify_req->filter = filter;
6507 dnotify_req->multishot = multishot;
6508 spin_lock(&GlobalMid_Lock);
6509 list_add_tail(&dnotify_req->lhead,
6510 &GlobalDnotifyReqList);
6511 spin_unlock(&GlobalMid_Lock);
6515 cifs_buf_release(pSMB);
6518 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */