1 // SPDX-License-Identifier: LGPL-2.1
5 * Copyright (C) International Business Machines Corp., 2002,2010
6 * Author(s): Steve French (sfrench@us.ibm.com)
8 * Contains the routines for constructing the SMB PDUs themselves
12 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
13 /* These are mostly routines that operate on a pathname, or on a tree id */
14 /* (mounted volume), but there are eight handle based routines which must be */
15 /* treated slightly differently for reconnection purposes since we never */
16 /* want to reuse a stale file handle and only the caller knows the file info */
19 #include <linux/kernel.h>
20 #include <linux/vfs.h>
21 #include <linux/slab.h>
22 #include <linux/posix_acl_xattr.h>
23 #include <linux/pagemap.h>
24 #include <linux/swap.h>
25 #include <linux/task_io_accounting_ops.h>
26 #include <linux/uaccess.h>
30 #include "cifsproto.h"
31 #include "cifs_unicode.h"
32 #include "cifs_debug.h"
33 #include "smb2proto.h"
35 #include "smbdirect.h"
36 #ifdef CONFIG_CIFS_DFS_UPCALL
37 #include "dfs_cache.h"
40 #ifdef CONFIG_CIFS_POSIX
45 #ifdef CONFIG_CIFS_WEAK_PW_HASH
46 {LANMAN_PROT, "\2LM1.2X002"},
47 {LANMAN2_PROT, "\2LANMAN2.1"},
48 #endif /* weak password hashing for legacy clients */
49 {CIFS_PROT, "\2NT LM 0.12"},
50 {POSIX_PROT, "\2POSIX 2"},
58 #ifdef CONFIG_CIFS_WEAK_PW_HASH
59 {LANMAN_PROT, "\2LM1.2X002"},
60 {LANMAN2_PROT, "\2LANMAN2.1"},
61 #endif /* weak password hashing for legacy clients */
62 {CIFS_PROT, "\2NT LM 0.12"},
67 /* define the number of elements in the cifs dialect array */
68 #ifdef CONFIG_CIFS_POSIX
69 #ifdef CONFIG_CIFS_WEAK_PW_HASH
70 #define CIFS_NUM_PROT 4
72 #define CIFS_NUM_PROT 2
73 #endif /* CIFS_WEAK_PW_HASH */
75 #ifdef CONFIG_CIFS_WEAK_PW_HASH
76 #define CIFS_NUM_PROT 3
78 #define CIFS_NUM_PROT 1
79 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
80 #endif /* CIFS_POSIX */
83 * Mark as invalid, all open files on tree connections since they
84 * were closed when session to server was lost.
87 cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
89 struct cifsFileInfo *open_file = NULL;
90 struct list_head *tmp;
91 struct list_head *tmp1;
93 /* list all files open on tree connection and mark them invalid */
94 spin_lock(&tcon->open_file_lock);
95 list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
96 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
97 open_file->invalidHandle = true;
98 open_file->oplock_break_cancelled = true;
100 spin_unlock(&tcon->open_file_lock);
102 mutex_lock(&tcon->crfid.fid_mutex);
103 tcon->crfid.is_valid = false;
104 /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
105 close_cached_dir_lease_locked(&tcon->crfid);
106 memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
107 mutex_unlock(&tcon->crfid.fid_mutex);
110 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
115 /* reconnect the socket, tcon, and smb session if needed */
117 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
120 struct cifs_ses *ses;
121 struct TCP_Server_Info *server;
122 struct nls_table *nls_codepage;
126 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
127 * tcp and smb session status done differently for those three - in the
134 server = ses->server;
137 * only tree disconnect, open, and write, (and ulogoff which does not
138 * have tcon) are allowed as we start force umount
140 if (tcon->tidStatus == CifsExiting) {
141 if (smb_command != SMB_COM_WRITE_ANDX &&
142 smb_command != SMB_COM_OPEN_ANDX &&
143 smb_command != SMB_COM_TREE_DISCONNECT) {
144 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
150 retries = server->nr_targets;
153 * Give demultiplex thread up to 10 seconds to each target available for
154 * reconnect -- should be greater than cifs socket timeout which is 7
157 while (server->tcpStatus == CifsNeedReconnect) {
158 rc = wait_event_interruptible_timeout(server->response_q,
159 (server->tcpStatus != CifsNeedReconnect),
162 cifs_dbg(FYI, "%s: aborting reconnect due to a received signal by the process\n",
167 /* are we still trying to reconnect? */
168 if (server->tcpStatus != CifsNeedReconnect)
171 if (retries && --retries)
175 * on "soft" mounts we wait once. Hard mounts keep
176 * retrying until process is killed or server comes
180 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
183 retries = server->nr_targets;
186 if (!ses->need_reconnect && !tcon->need_reconnect)
189 nls_codepage = load_nls_default();
192 * need to prevent multiple threads trying to simultaneously
193 * reconnect the same SMB session
195 mutex_lock(&ses->session_mutex);
198 * Recheck after acquire mutex. If another thread is negotiating
199 * and the server never sends an answer the socket will be closed
200 * and tcpStatus set to reconnect.
202 if (server->tcpStatus == CifsNeedReconnect) {
204 mutex_unlock(&ses->session_mutex);
208 rc = cifs_negotiate_protocol(0, ses);
209 if (rc == 0 && ses->need_reconnect)
210 rc = cifs_setup_session(0, ses, nls_codepage);
212 /* do we need to reconnect tcon? */
213 if (rc || !tcon->need_reconnect) {
214 mutex_unlock(&ses->session_mutex);
218 cifs_mark_open_files_invalid(tcon);
219 rc = cifs_tree_connect(0, tcon, nls_codepage);
220 mutex_unlock(&ses->session_mutex);
221 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
224 pr_warn_once("reconnect tcon failed rc = %d\n", rc);
228 atomic_inc(&tconInfoReconnectCount);
230 /* tell server Unix caps we support */
232 reset_cifs_unix_caps(0, tcon, NULL, NULL);
235 * Removed call to reopen open files here. It is safer (and faster) to
236 * reopen files one at a time as needed in read and write.
238 * FIXME: what about file locks? don't we need to reclaim them ASAP?
243 * Check if handle based operation so we know whether we can continue
244 * or not without returning to caller to reset file handle
246 switch (smb_command) {
247 case SMB_COM_READ_ANDX:
248 case SMB_COM_WRITE_ANDX:
250 case SMB_COM_FIND_CLOSE2:
251 case SMB_COM_LOCKING_ANDX:
255 unload_nls(nls_codepage);
259 /* Allocate and return pointer to an SMB request buffer, and set basic
260 SMB information in the SMB header. If the return code is zero, this
261 function must have filled in request_buf pointer */
263 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
268 rc = cifs_reconnect_tcon(tcon, smb_command);
272 *request_buf = cifs_small_buf_get();
273 if (*request_buf == NULL) {
274 /* BB should we add a retry in here if not a writepage? */
278 header_assemble((struct smb_hdr *) *request_buf, smb_command,
282 cifs_stats_inc(&tcon->num_smbs_sent);
288 small_smb_init_no_tc(const int smb_command, const int wct,
289 struct cifs_ses *ses, void **request_buf)
292 struct smb_hdr *buffer;
294 rc = small_smb_init(smb_command, wct, NULL, request_buf);
298 buffer = (struct smb_hdr *)*request_buf;
299 buffer->Mid = get_next_mid(ses->server);
300 if (ses->capabilities & CAP_UNICODE)
301 buffer->Flags2 |= SMBFLG2_UNICODE;
302 if (ses->capabilities & CAP_STATUS32)
303 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
305 /* uid, tid can stay at zero as set in header assemble */
307 /* BB add support for turning on the signing when
308 this function is used after 1st of session setup requests */
313 /* If the return code is zero, this function must fill in request_buf pointer */
315 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
316 void **request_buf, void **response_buf)
318 *request_buf = cifs_buf_get();
319 if (*request_buf == NULL) {
320 /* BB should we add a retry in here if not a writepage? */
323 /* Although the original thought was we needed the response buf for */
324 /* potential retries of smb operations it turns out we can determine */
325 /* from the mid flags when the request buffer can be resent without */
326 /* having to use a second distinct buffer for the response */
328 *response_buf = *request_buf;
330 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
334 cifs_stats_inc(&tcon->num_smbs_sent);
339 /* If the return code is zero, this function must fill in request_buf pointer */
341 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
342 void **request_buf, void **response_buf)
346 rc = cifs_reconnect_tcon(tcon, smb_command);
350 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
354 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
355 void **request_buf, void **response_buf)
357 if (tcon->ses->need_reconnect || tcon->need_reconnect)
360 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
363 static int validate_t2(struct smb_t2_rsp *pSMB)
365 unsigned int total_size;
367 /* check for plausible wct */
368 if (pSMB->hdr.WordCount < 10)
371 /* check for parm and data offset going beyond end of smb */
372 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
373 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
376 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
377 if (total_size >= 512)
380 /* check that bcc is at least as big as parms + data, and that it is
381 * less than negotiated smb buffer
383 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
384 if (total_size > get_bcc(&pSMB->hdr) ||
385 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
390 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
391 sizeof(struct smb_t2_rsp) + 16);
396 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
400 char *guid = pSMBr->u.extended_response.GUID;
401 struct TCP_Server_Info *server = ses->server;
403 count = get_bcc(&pSMBr->hdr);
404 if (count < SMB1_CLIENT_GUID_SIZE)
407 spin_lock(&cifs_tcp_ses_lock);
408 if (server->srv_count > 1) {
409 spin_unlock(&cifs_tcp_ses_lock);
410 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
411 cifs_dbg(FYI, "server UID changed\n");
412 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
415 spin_unlock(&cifs_tcp_ses_lock);
416 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
419 if (count == SMB1_CLIENT_GUID_SIZE) {
420 server->sec_ntlmssp = true;
422 count -= SMB1_CLIENT_GUID_SIZE;
423 rc = decode_negTokenInit(
424 pSMBr->u.extended_response.SecurityBlob, count, server);
433 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
435 bool srv_sign_required = server->sec_mode & server->vals->signing_required;
436 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
437 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
440 * Is signing required by mnt options? If not then check
441 * global_secflags to see if it is there.
443 if (!mnt_sign_required)
444 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
448 * If signing is required then it's automatically enabled too,
449 * otherwise, check to see if the secflags allow it.
451 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
452 (global_secflags & CIFSSEC_MAY_SIGN);
454 /* If server requires signing, does client allow it? */
455 if (srv_sign_required) {
456 if (!mnt_sign_enabled) {
457 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!\n");
463 /* If client requires signing, does server allow it? */
464 if (mnt_sign_required) {
465 if (!srv_sign_enabled) {
466 cifs_dbg(VFS, "Server does not support signing!\n");
472 if (cifs_rdma_enabled(server) && server->sign)
473 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled\n");
478 #ifdef CONFIG_CIFS_WEAK_PW_HASH
480 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
483 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
485 if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
488 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
489 server->maxReq = min_t(unsigned int,
490 le16_to_cpu(rsp->MaxMpxCount),
492 set_credits(server, server->maxReq);
493 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
494 /* set up max_read for readpages check */
495 server->max_read = server->maxBuf;
496 /* even though we do not use raw we might as well set this
497 accurately, in case we ever find a need for it */
498 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
499 server->max_rw = 0xFF00;
500 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
502 server->max_rw = 0;/* do not need to use raw anyway */
503 server->capabilities = CAP_MPX_MODE;
505 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
507 /* OS/2 often does not set timezone therefore
508 * we must use server time to calc time zone.
509 * Could deviate slightly from the right zone.
510 * Smallest defined timezone difference is 15 minutes
511 * (i.e. Nepal). Rounding up/down is done to match
514 int val, seconds, remain, result;
515 struct timespec64 ts;
516 time64_t utc = ktime_get_real_seconds();
517 ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
518 rsp->SrvTime.Time, 0);
519 cifs_dbg(FYI, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
522 val = (int)(utc - ts.tv_sec);
524 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
525 remain = seconds % MIN_TZ_ADJ;
526 if (remain >= (MIN_TZ_ADJ / 2))
527 result += MIN_TZ_ADJ;
530 server->timeAdj = result;
532 server->timeAdj = (int)tmp;
533 server->timeAdj *= 60; /* also in seconds */
535 cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
538 /* BB get server time for time conversions and add
539 code to use it and timezone since this is not UTC */
541 if (rsp->EncryptionKeyLength ==
542 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
543 memcpy(server->cryptkey, rsp->EncryptionKey,
544 CIFS_CRYPTO_KEY_SIZE);
545 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
546 return -EIO; /* need cryptkey unless plain text */
549 cifs_dbg(FYI, "LANMAN negotiated\n");
554 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
556 cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
562 should_set_ext_sec_flag(enum securityEnum sectype)
569 if (global_secflags &
570 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
579 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
582 NEGOTIATE_RSP *pSMBr;
586 struct TCP_Server_Info *server = ses->server;
590 WARN(1, "%s: server is NULL!\n", __func__);
594 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
595 (void **) &pSMB, (void **) &pSMBr);
599 pSMB->hdr.Mid = get_next_mid(server);
600 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
602 if (should_set_ext_sec_flag(ses->sectype)) {
603 cifs_dbg(FYI, "Requesting extended security\n");
604 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
609 * We know that all the name entries in the protocols array
610 * are short (< 16 bytes anyway) and are NUL terminated.
612 for (i = 0; i < CIFS_NUM_PROT; i++) {
613 size_t len = strlen(protocols[i].name) + 1;
615 memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
618 inc_rfc1001_len(pSMB, count);
619 pSMB->ByteCount = cpu_to_le16(count);
621 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
622 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
626 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
627 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
628 /* Check wct = 1 error case */
629 if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
630 /* core returns wct = 1, but we do not ask for core - otherwise
631 small wct just comes when dialect index is -1 indicating we
632 could not negotiate a common dialect */
635 } else if (pSMBr->hdr.WordCount == 13) {
636 server->negflavor = CIFS_NEGFLAVOR_LANMAN;
637 rc = decode_lanman_negprot_rsp(server, pSMBr);
639 } else if (pSMBr->hdr.WordCount != 17) {
644 /* else wct == 17, NTLM or better */
646 server->sec_mode = pSMBr->SecurityMode;
647 if ((server->sec_mode & SECMODE_USER) == 0)
648 cifs_dbg(FYI, "share mode security\n");
650 /* one byte, so no need to convert this or EncryptionKeyLen from
652 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
654 set_credits(server, server->maxReq);
655 /* probably no need to store and check maxvcs */
656 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
657 /* set up max_read for readpages check */
658 server->max_read = server->maxBuf;
659 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
660 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
661 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
662 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
663 server->timeAdj *= 60;
665 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
666 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
667 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
668 CIFS_CRYPTO_KEY_SIZE);
669 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
670 server->capabilities & CAP_EXTENDED_SECURITY) {
671 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
672 rc = decode_ext_sec_blob(ses, pSMBr);
673 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
674 rc = -EIO; /* no crypt key only if plain text pwd */
676 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
677 server->capabilities &= ~CAP_EXTENDED_SECURITY;
682 rc = cifs_enable_signing(server, ses->sign);
684 cifs_buf_release(pSMB);
686 cifs_dbg(FYI, "negprot rc %d\n", rc);
691 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
693 struct smb_hdr *smb_buffer;
696 cifs_dbg(FYI, "In tree disconnect\n");
698 /* BB: do we need to check this? These should never be NULL. */
699 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
703 * No need to return error on this operation if tid invalidated and
704 * closed on server already e.g. due to tcp session crashing. Also,
705 * the tcon is no longer on the list, so no need to take lock before
708 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
711 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
712 (void **)&smb_buffer);
716 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
717 cifs_small_buf_release(smb_buffer);
719 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
721 /* No need to return error on this operation if tid invalidated and
722 closed on server already e.g. due to tcp session crashing */
730 * This is a no-op for now. We're not really interested in the reply, but
731 * rather in the fact that the server sent one and that server->lstrp
734 * FIXME: maybe we should consider checking that the reply matches request?
737 cifs_echo_callback(struct mid_q_entry *mid)
739 struct TCP_Server_Info *server = mid->callback_data;
740 struct cifs_credits credits = { .value = 1, .instance = 0 };
742 DeleteMidQEntry(mid);
743 add_credits(server, &credits, CIFS_ECHO_OP);
747 CIFSSMBEcho(struct TCP_Server_Info *server)
752 struct smb_rqst rqst = { .rq_iov = iov,
755 cifs_dbg(FYI, "In echo request\n");
757 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
761 if (server->capabilities & CAP_UNICODE)
762 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
764 /* set up echo request */
765 smb->hdr.Tid = 0xffff;
766 smb->hdr.WordCount = 1;
767 put_unaligned_le16(1, &smb->EchoCount);
768 put_bcc(1, &smb->hdr);
770 inc_rfc1001_len(smb, 3);
773 iov[0].iov_base = smb;
774 iov[1].iov_len = get_rfc1002_length(smb);
775 iov[1].iov_base = (char *)smb + 4;
777 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
778 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
780 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
782 cifs_small_buf_release(smb);
788 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
790 LOGOFF_ANDX_REQ *pSMB;
793 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
796 * BB: do we need to check validity of ses and server? They should
797 * always be valid since we have an active reference. If not, that
798 * should probably be a BUG()
800 if (!ses || !ses->server)
803 mutex_lock(&ses->session_mutex);
804 if (ses->need_reconnect)
805 goto session_already_dead; /* no need to send SMBlogoff if uid
806 already closed due to reconnect */
807 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
809 mutex_unlock(&ses->session_mutex);
813 pSMB->hdr.Mid = get_next_mid(ses->server);
815 if (ses->server->sign)
816 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
818 pSMB->hdr.Uid = ses->Suid;
820 pSMB->AndXCommand = 0xFF;
821 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
822 cifs_small_buf_release(pSMB);
823 session_already_dead:
824 mutex_unlock(&ses->session_mutex);
826 /* if session dead then we do not need to do ulogoff,
827 since server closed smb session, no sense reporting
835 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
836 const char *fileName, __u16 type,
837 const struct nls_table *nls_codepage, int remap)
839 TRANSACTION2_SPI_REQ *pSMB = NULL;
840 TRANSACTION2_SPI_RSP *pSMBr = NULL;
841 struct unlink_psx_rq *pRqD;
844 int bytes_returned = 0;
845 __u16 params, param_offset, offset, byte_count;
847 cifs_dbg(FYI, "In POSIX delete\n");
849 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
854 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
856 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
857 PATH_MAX, nls_codepage, remap);
858 name_len++; /* trailing null */
861 name_len = copy_path_name(pSMB->FileName, fileName);
864 params = 6 + name_len;
865 pSMB->MaxParameterCount = cpu_to_le16(2);
866 pSMB->MaxDataCount = 0; /* BB double check this with jra */
867 pSMB->MaxSetupCount = 0;
872 param_offset = offsetof(struct smb_com_transaction2_spi_req,
873 InformationLevel) - 4;
874 offset = param_offset + params;
876 /* Setup pointer to Request Data (inode type) */
877 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
878 pRqD->type = cpu_to_le16(type);
879 pSMB->ParameterOffset = cpu_to_le16(param_offset);
880 pSMB->DataOffset = cpu_to_le16(offset);
881 pSMB->SetupCount = 1;
883 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
884 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
886 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
887 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
888 pSMB->ParameterCount = cpu_to_le16(params);
889 pSMB->TotalParameterCount = pSMB->ParameterCount;
890 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
892 inc_rfc1001_len(pSMB, byte_count);
893 pSMB->ByteCount = cpu_to_le16(byte_count);
894 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
895 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
897 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
898 cifs_buf_release(pSMB);
900 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
909 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
910 struct cifs_sb_info *cifs_sb)
912 DELETE_FILE_REQ *pSMB = NULL;
913 DELETE_FILE_RSP *pSMBr = NULL;
917 int remap = cifs_remap(cifs_sb);
920 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
925 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
926 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
927 PATH_MAX, cifs_sb->local_nls,
929 name_len++; /* trailing null */
932 name_len = copy_path_name(pSMB->fileName, name);
934 pSMB->SearchAttributes =
935 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
936 pSMB->BufferFormat = 0x04;
937 inc_rfc1001_len(pSMB, name_len + 1);
938 pSMB->ByteCount = cpu_to_le16(name_len + 1);
939 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
940 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
941 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
943 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
945 cifs_buf_release(pSMB);
953 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
954 struct cifs_sb_info *cifs_sb)
956 DELETE_DIRECTORY_REQ *pSMB = NULL;
957 DELETE_DIRECTORY_RSP *pSMBr = NULL;
961 int remap = cifs_remap(cifs_sb);
963 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
965 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
970 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
971 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
972 PATH_MAX, cifs_sb->local_nls,
974 name_len++; /* trailing null */
977 name_len = copy_path_name(pSMB->DirName, name);
980 pSMB->BufferFormat = 0x04;
981 inc_rfc1001_len(pSMB, name_len + 1);
982 pSMB->ByteCount = cpu_to_le16(name_len + 1);
983 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
984 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
985 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
987 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
989 cifs_buf_release(pSMB);
996 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
997 struct cifs_tcon *tcon, const char *name,
998 struct cifs_sb_info *cifs_sb)
1001 CREATE_DIRECTORY_REQ *pSMB = NULL;
1002 CREATE_DIRECTORY_RSP *pSMBr = NULL;
1005 int remap = cifs_remap(cifs_sb);
1007 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
1009 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
1014 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1015 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1016 PATH_MAX, cifs_sb->local_nls,
1018 name_len++; /* trailing null */
1021 name_len = copy_path_name(pSMB->DirName, name);
1024 pSMB->BufferFormat = 0x04;
1025 inc_rfc1001_len(pSMB, name_len + 1);
1026 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1027 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1028 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1029 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1031 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
1033 cifs_buf_release(pSMB);
1040 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1041 __u32 posix_flags, __u64 mode, __u16 *netfid,
1042 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1043 const char *name, const struct nls_table *nls_codepage,
1046 TRANSACTION2_SPI_REQ *pSMB = NULL;
1047 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1050 int bytes_returned = 0;
1051 __u16 params, param_offset, offset, byte_count, count;
1052 OPEN_PSX_REQ *pdata;
1053 OPEN_PSX_RSP *psx_rsp;
1055 cifs_dbg(FYI, "In POSIX Create\n");
1057 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1062 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1064 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1065 PATH_MAX, nls_codepage, remap);
1066 name_len++; /* trailing null */
1069 name_len = copy_path_name(pSMB->FileName, name);
1072 params = 6 + name_len;
1073 count = sizeof(OPEN_PSX_REQ);
1074 pSMB->MaxParameterCount = cpu_to_le16(2);
1075 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1076 pSMB->MaxSetupCount = 0;
1080 pSMB->Reserved2 = 0;
1081 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1082 InformationLevel) - 4;
1083 offset = param_offset + params;
1084 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1085 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1086 pdata->Permissions = cpu_to_le64(mode);
1087 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1088 pdata->OpenFlags = cpu_to_le32(*pOplock);
1089 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1090 pSMB->DataOffset = cpu_to_le16(offset);
1091 pSMB->SetupCount = 1;
1092 pSMB->Reserved3 = 0;
1093 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1094 byte_count = 3 /* pad */ + params + count;
1096 pSMB->DataCount = cpu_to_le16(count);
1097 pSMB->ParameterCount = cpu_to_le16(params);
1098 pSMB->TotalDataCount = pSMB->DataCount;
1099 pSMB->TotalParameterCount = pSMB->ParameterCount;
1100 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1101 pSMB->Reserved4 = 0;
1102 inc_rfc1001_len(pSMB, byte_count);
1103 pSMB->ByteCount = cpu_to_le16(byte_count);
1104 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1105 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1107 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1108 goto psx_create_err;
1111 cifs_dbg(FYI, "copying inode info\n");
1112 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1114 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1115 rc = -EIO; /* bad smb */
1116 goto psx_create_err;
1119 /* copy return information to pRetData */
1120 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1121 + le16_to_cpu(pSMBr->t2.DataOffset));
1123 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1125 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1126 /* Let caller know file was created so we can set the mode. */
1127 /* Do we care about the CreateAction in any other cases? */
1128 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1129 *pOplock |= CIFS_CREATE_ACTION;
1130 /* check to make sure response data is there */
1131 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1132 pRetData->Type = cpu_to_le32(-1); /* unknown */
1133 cifs_dbg(NOISY, "unknown type\n");
1135 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1136 + sizeof(FILE_UNIX_BASIC_INFO)) {
1137 cifs_dbg(VFS, "Open response data too small\n");
1138 pRetData->Type = cpu_to_le32(-1);
1139 goto psx_create_err;
1141 memcpy((char *) pRetData,
1142 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1143 sizeof(FILE_UNIX_BASIC_INFO));
1147 cifs_buf_release(pSMB);
1149 if (posix_flags & SMB_O_DIRECTORY)
1150 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1152 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1160 static __u16 convert_disposition(int disposition)
1164 switch (disposition) {
1165 case FILE_SUPERSEDE:
1166 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1169 ofun = SMBOPEN_OAPPEND;
1172 ofun = SMBOPEN_OCREATE;
1175 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1177 case FILE_OVERWRITE:
1178 ofun = SMBOPEN_OTRUNC;
1180 case FILE_OVERWRITE_IF:
1181 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1184 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1185 ofun = SMBOPEN_OAPPEND; /* regular open */
1191 access_flags_to_smbopen_mode(const int access_flags)
1193 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1195 if (masked_flags == GENERIC_READ)
1196 return SMBOPEN_READ;
1197 else if (masked_flags == GENERIC_WRITE)
1198 return SMBOPEN_WRITE;
1200 /* just go for read/write */
1201 return SMBOPEN_READWRITE;
1205 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1206 const char *fileName, const int openDisposition,
1207 const int access_flags, const int create_options, __u16 *netfid,
1208 int *pOplock, FILE_ALL_INFO *pfile_info,
1209 const struct nls_table *nls_codepage, int remap)
1212 OPENX_REQ *pSMB = NULL;
1213 OPENX_RSP *pSMBr = NULL;
1219 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1224 pSMB->AndXCommand = 0xFF; /* none */
1226 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1227 count = 1; /* account for one byte pad to word boundary */
1229 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1230 fileName, PATH_MAX, nls_codepage, remap);
1231 name_len++; /* trailing null */
1234 count = 0; /* no pad */
1235 name_len = copy_path_name(pSMB->fileName, fileName);
1237 if (*pOplock & REQ_OPLOCK)
1238 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1239 else if (*pOplock & REQ_BATCHOPLOCK)
1240 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1242 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1243 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1244 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1245 /* set file as system file if special file such
1246 as fifo and server expecting SFU style and
1247 no Unix extensions */
1249 if (create_options & CREATE_OPTION_SPECIAL)
1250 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1251 else /* BB FIXME BB */
1252 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1254 if (create_options & CREATE_OPTION_READONLY)
1255 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1258 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1259 CREATE_OPTIONS_MASK); */
1260 /* BB FIXME END BB */
1262 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1263 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1265 inc_rfc1001_len(pSMB, count);
1267 pSMB->ByteCount = cpu_to_le16(count);
1268 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1269 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1270 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1272 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1274 /* BB verify if wct == 15 */
1276 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1278 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1279 /* Let caller know file was created so we can set the mode. */
1280 /* Do we care about the CreateAction in any other cases? */
1282 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1283 *pOplock |= CIFS_CREATE_ACTION; */
1287 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1288 pfile_info->LastAccessTime = 0; /* BB fixme */
1289 pfile_info->LastWriteTime = 0; /* BB fixme */
1290 pfile_info->ChangeTime = 0; /* BB fixme */
1291 pfile_info->Attributes =
1292 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1293 /* the file_info buf is endian converted by caller */
1294 pfile_info->AllocationSize =
1295 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1296 pfile_info->EndOfFile = pfile_info->AllocationSize;
1297 pfile_info->NumberOfLinks = cpu_to_le32(1);
1298 pfile_info->DeletePending = 0;
1302 cifs_buf_release(pSMB);
1309 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1313 OPEN_REQ *req = NULL;
1314 OPEN_RSP *rsp = NULL;
1318 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1319 struct cifs_tcon *tcon = oparms->tcon;
1320 int remap = cifs_remap(cifs_sb);
1321 const struct nls_table *nls = cifs_sb->local_nls;
1322 int create_options = oparms->create_options;
1323 int desired_access = oparms->desired_access;
1324 int disposition = oparms->disposition;
1325 const char *path = oparms->path;
1328 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1333 /* no commands go after this */
1334 req->AndXCommand = 0xFF;
1336 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1337 /* account for one byte pad to word boundary */
1339 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1340 path, PATH_MAX, nls, remap);
1344 req->NameLength = cpu_to_le16(name_len);
1346 /* BB improve check for buffer overruns BB */
1349 name_len = copy_path_name(req->fileName, path);
1350 req->NameLength = cpu_to_le16(name_len);
1353 if (*oplock & REQ_OPLOCK)
1354 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1355 else if (*oplock & REQ_BATCHOPLOCK)
1356 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1358 req->DesiredAccess = cpu_to_le32(desired_access);
1359 req->AllocationSize = 0;
1362 * Set file as system file if special file such as fifo and server
1363 * expecting SFU style and no Unix extensions.
1365 if (create_options & CREATE_OPTION_SPECIAL)
1366 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1368 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1371 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1372 * sensitive checks for other servers such as Samba.
1374 if (tcon->ses->capabilities & CAP_UNIX)
1375 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1377 if (create_options & CREATE_OPTION_READONLY)
1378 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1380 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1381 req->CreateDisposition = cpu_to_le32(disposition);
1382 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1384 /* BB Expirement with various impersonation levels and verify */
1385 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1386 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1389 inc_rfc1001_len(req, count);
1391 req->ByteCount = cpu_to_le16(count);
1392 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1393 (struct smb_hdr *)rsp, &bytes_returned, 0);
1394 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1396 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1397 cifs_buf_release(req);
1403 /* 1 byte no need to le_to_cpu */
1404 *oplock = rsp->OplockLevel;
1405 /* cifs fid stays in le */
1406 oparms->fid->netfid = rsp->Fid;
1407 oparms->fid->access = desired_access;
1409 /* Let caller know file was created so we can set the mode. */
1410 /* Do we care about the CreateAction in any other cases? */
1411 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1412 *oplock |= CIFS_CREATE_ACTION;
1415 /* copy from CreationTime to Attributes */
1416 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1417 /* the file_info buf is endian converted by caller */
1418 buf->AllocationSize = rsp->AllocationSize;
1419 buf->EndOfFile = rsp->EndOfFile;
1420 buf->NumberOfLinks = cpu_to_le32(1);
1421 buf->DeletePending = 0;
1424 cifs_buf_release(req);
1429 * Discard any remaining data in the current SMB. To do this, we borrow the
1433 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1435 unsigned int rfclen = server->pdu_size;
1436 int remaining = rfclen + server->vals->header_preamble_size -
1439 while (remaining > 0) {
1442 length = cifs_discard_from_socket(server,
1443 min_t(size_t, remaining,
1444 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1447 server->total_read += length;
1448 remaining -= length;
1455 __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
1460 length = cifs_discard_remaining_data(server);
1461 dequeue_mid(mid, malformed);
1462 mid->resp_buf = server->smallbuf;
1463 server->smallbuf = NULL;
1468 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1470 struct cifs_readdata *rdata = mid->callback_data;
1472 return __cifs_readv_discard(server, mid, rdata->result);
1476 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1479 unsigned int data_offset, data_len;
1480 struct cifs_readdata *rdata = mid->callback_data;
1481 char *buf = server->smallbuf;
1482 unsigned int buflen = server->pdu_size +
1483 server->vals->header_preamble_size;
1484 bool use_rdma_mr = false;
1486 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1487 __func__, mid->mid, rdata->offset, rdata->bytes);
1490 * read the rest of READ_RSP header (sans Data array), or whatever we
1491 * can if there's not enough data. At this point, we've read down to
1494 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1495 HEADER_SIZE(server) + 1;
1497 length = cifs_read_from_socket(server,
1498 buf + HEADER_SIZE(server) - 1, len);
1501 server->total_read += length;
1503 if (server->ops->is_session_expired &&
1504 server->ops->is_session_expired(buf)) {
1505 cifs_reconnect(server);
1509 if (server->ops->is_status_pending &&
1510 server->ops->is_status_pending(buf, server)) {
1511 cifs_discard_remaining_data(server);
1515 /* set up first two iov for signature check and to get credits */
1516 rdata->iov[0].iov_base = buf;
1517 rdata->iov[0].iov_len = server->vals->header_preamble_size;
1518 rdata->iov[1].iov_base = buf + server->vals->header_preamble_size;
1519 rdata->iov[1].iov_len =
1520 server->total_read - server->vals->header_preamble_size;
1521 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1522 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1523 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
1524 rdata->iov[1].iov_base, rdata->iov[1].iov_len);
1526 /* Was the SMB read successful? */
1527 rdata->result = server->ops->map_error(buf, false);
1528 if (rdata->result != 0) {
1529 cifs_dbg(FYI, "%s: server returned error %d\n",
1530 __func__, rdata->result);
1531 /* normal error on read response */
1532 return __cifs_readv_discard(server, mid, false);
1535 /* Is there enough to get to the rest of the READ_RSP header? */
1536 if (server->total_read < server->vals->read_rsp_size) {
1537 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1538 __func__, server->total_read,
1539 server->vals->read_rsp_size);
1540 rdata->result = -EIO;
1541 return cifs_readv_discard(server, mid);
1544 data_offset = server->ops->read_data_offset(buf) +
1545 server->vals->header_preamble_size;
1546 if (data_offset < server->total_read) {
1548 * win2k8 sometimes sends an offset of 0 when the read
1549 * is beyond the EOF. Treat it as if the data starts just after
1552 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1553 __func__, data_offset);
1554 data_offset = server->total_read;
1555 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1556 /* data_offset is beyond the end of smallbuf */
1557 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1558 __func__, data_offset);
1559 rdata->result = -EIO;
1560 return cifs_readv_discard(server, mid);
1563 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1564 __func__, server->total_read, data_offset);
1566 len = data_offset - server->total_read;
1568 /* read any junk before data into the rest of smallbuf */
1569 length = cifs_read_from_socket(server,
1570 buf + server->total_read, len);
1573 server->total_read += length;
1576 /* how much data is in the response? */
1577 #ifdef CONFIG_CIFS_SMB_DIRECT
1578 use_rdma_mr = rdata->mr;
1580 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1581 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1582 /* data_len is corrupt -- discard frame */
1583 rdata->result = -EIO;
1584 return cifs_readv_discard(server, mid);
1587 length = rdata->read_into_pages(server, rdata, data_len);
1591 server->total_read += length;
1593 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1594 server->total_read, buflen, data_len);
1596 /* discard anything left over */
1597 if (server->total_read < buflen)
1598 return cifs_readv_discard(server, mid);
1600 dequeue_mid(mid, false);
1601 mid->resp_buf = server->smallbuf;
1602 server->smallbuf = NULL;
1607 cifs_readv_callback(struct mid_q_entry *mid)
1609 struct cifs_readdata *rdata = mid->callback_data;
1610 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1611 struct TCP_Server_Info *server = tcon->ses->server;
1612 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1614 .rq_pages = rdata->pages,
1615 .rq_offset = rdata->page_offset,
1616 .rq_npages = rdata->nr_pages,
1617 .rq_pagesz = rdata->pagesz,
1618 .rq_tailsz = rdata->tailsz };
1619 struct cifs_credits credits = { .value = 1, .instance = 0 };
1621 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1622 __func__, mid->mid, mid->mid_state, rdata->result,
1625 switch (mid->mid_state) {
1626 case MID_RESPONSE_RECEIVED:
1627 /* result already set, check signature */
1631 rc = cifs_verify_signature(&rqst, server,
1632 mid->sequence_number);
1634 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1637 /* FIXME: should this be counted toward the initiating task? */
1638 task_io_account_read(rdata->got_bytes);
1639 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1641 case MID_REQUEST_SUBMITTED:
1642 case MID_RETRY_NEEDED:
1643 rdata->result = -EAGAIN;
1644 if (server->sign && rdata->got_bytes)
1645 /* reset bytes number since we can not check a sign */
1646 rdata->got_bytes = 0;
1647 /* FIXME: should this be counted toward the initiating task? */
1648 task_io_account_read(rdata->got_bytes);
1649 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1652 rdata->result = -EIO;
1655 queue_work(cifsiod_wq, &rdata->work);
1656 DeleteMidQEntry(mid);
1657 add_credits(server, &credits, 0);
1660 /* cifs_async_readv - send an async write, and set up mid to handle result */
1662 cifs_async_readv(struct cifs_readdata *rdata)
1665 READ_REQ *smb = NULL;
1667 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1668 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1671 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1672 __func__, rdata->offset, rdata->bytes);
1674 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1677 wct = 10; /* old style read */
1678 if ((rdata->offset >> 32) > 0) {
1679 /* can not handle this big offset for old */
1684 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1688 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1689 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1691 smb->AndXCommand = 0xFF; /* none */
1692 smb->Fid = rdata->cfile->fid.netfid;
1693 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1695 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1697 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1698 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1702 /* old style read */
1703 struct smb_com_readx_req *smbr =
1704 (struct smb_com_readx_req *)smb;
1705 smbr->ByteCount = 0;
1708 /* 4 for RFC1001 length + 1 for BCC */
1709 rdata->iov[0].iov_base = smb;
1710 rdata->iov[0].iov_len = 4;
1711 rdata->iov[1].iov_base = (char *)smb + 4;
1712 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1714 kref_get(&rdata->refcount);
1715 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1716 cifs_readv_callback, NULL, rdata, 0, NULL);
1719 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1721 kref_put(&rdata->refcount, cifs_readdata_release);
1723 cifs_small_buf_release(smb);
1728 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1729 unsigned int *nbytes, char **buf, int *pbuf_type)
1732 READ_REQ *pSMB = NULL;
1733 READ_RSP *pSMBr = NULL;
1734 char *pReadData = NULL;
1736 int resp_buf_type = 0;
1738 struct kvec rsp_iov;
1739 __u32 pid = io_parms->pid;
1740 __u16 netfid = io_parms->netfid;
1741 __u64 offset = io_parms->offset;
1742 struct cifs_tcon *tcon = io_parms->tcon;
1743 unsigned int count = io_parms->length;
1745 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1746 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1749 wct = 10; /* old style read */
1750 if ((offset >> 32) > 0) {
1751 /* can not handle this big offset for old */
1757 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1761 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1762 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1764 /* tcon and ses pointer are checked in smb_init */
1765 if (tcon->ses->server == NULL)
1766 return -ECONNABORTED;
1768 pSMB->AndXCommand = 0xFF; /* none */
1770 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1772 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1774 pSMB->Remaining = 0;
1775 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1776 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1778 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1780 /* old style read */
1781 struct smb_com_readx_req *pSMBW =
1782 (struct smb_com_readx_req *)pSMB;
1783 pSMBW->ByteCount = 0;
1786 iov[0].iov_base = (char *)pSMB;
1787 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1788 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1789 CIFS_LOG_ERROR, &rsp_iov);
1790 cifs_small_buf_release(pSMB);
1791 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1792 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1794 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1796 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1797 data_length = data_length << 16;
1798 data_length += le16_to_cpu(pSMBr->DataLength);
1799 *nbytes = data_length;
1801 /*check that DataLength would not go beyond end of SMB */
1802 if ((data_length > CIFSMaxBufSize)
1803 || (data_length > count)) {
1804 cifs_dbg(FYI, "bad length %d for count %d\n",
1805 data_length, count);
1809 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1810 le16_to_cpu(pSMBr->DataOffset);
1811 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1812 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1814 }*/ /* can not use copy_to_user when using page cache*/
1816 memcpy(*buf, pReadData, data_length);
1821 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1822 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1823 /* return buffer to caller to free */
1824 *buf = rsp_iov.iov_base;
1825 if (resp_buf_type == CIFS_SMALL_BUFFER)
1826 *pbuf_type = CIFS_SMALL_BUFFER;
1827 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1828 *pbuf_type = CIFS_LARGE_BUFFER;
1829 } /* else no valid buffer on return - leave as null */
1831 /* Note: On -EAGAIN error only caller can retry on handle based calls
1832 since file handle passed in no longer valid */
1838 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1839 unsigned int *nbytes, const char *buf)
1842 WRITE_REQ *pSMB = NULL;
1843 WRITE_RSP *pSMBr = NULL;
1844 int bytes_returned, wct;
1847 __u32 pid = io_parms->pid;
1848 __u16 netfid = io_parms->netfid;
1849 __u64 offset = io_parms->offset;
1850 struct cifs_tcon *tcon = io_parms->tcon;
1851 unsigned int count = io_parms->length;
1855 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1856 if (tcon->ses == NULL)
1857 return -ECONNABORTED;
1859 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1863 if ((offset >> 32) > 0) {
1864 /* can not handle big offset for old srv */
1869 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1874 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1875 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1877 /* tcon and ses pointer are checked in smb_init */
1878 if (tcon->ses->server == NULL)
1879 return -ECONNABORTED;
1881 pSMB->AndXCommand = 0xFF; /* none */
1883 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1885 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1887 pSMB->Reserved = 0xFFFFFFFF;
1888 pSMB->WriteMode = 0;
1889 pSMB->Remaining = 0;
1891 /* Can increase buffer size if buffer is big enough in some cases ie we
1892 can send more if LARGE_WRITE_X capability returned by the server and if
1893 our buffer is big enough or if we convert to iovecs on socket writes
1894 and eliminate the copy to the CIFS buffer */
1895 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1896 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1898 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1902 if (bytes_sent > count)
1905 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1907 memcpy(pSMB->Data, buf, bytes_sent);
1908 else if (count != 0) {
1910 cifs_buf_release(pSMB);
1912 } /* else setting file size with write of zero bytes */
1914 byte_count = bytes_sent + 1; /* pad */
1915 else /* wct == 12 */
1916 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1918 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1919 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1920 inc_rfc1001_len(pSMB, byte_count);
1923 pSMB->ByteCount = cpu_to_le16(byte_count);
1924 else { /* old style write has byte count 4 bytes earlier
1926 struct smb_com_writex_req *pSMBW =
1927 (struct smb_com_writex_req *)pSMB;
1928 pSMBW->ByteCount = cpu_to_le16(byte_count);
1931 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1932 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1933 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1935 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1937 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1938 *nbytes = (*nbytes) << 16;
1939 *nbytes += le16_to_cpu(pSMBr->Count);
1942 * Mask off high 16 bits when bytes written as returned by the
1943 * server is greater than bytes requested by the client. Some
1944 * OS/2 servers are known to set incorrect CountHigh values.
1946 if (*nbytes > count)
1950 cifs_buf_release(pSMB);
1952 /* Note: On -EAGAIN error only caller can retry on handle based calls
1953 since file handle passed in no longer valid */
1959 cifs_writedata_release(struct kref *refcount)
1961 struct cifs_writedata *wdata = container_of(refcount,
1962 struct cifs_writedata, refcount);
1963 #ifdef CONFIG_CIFS_SMB_DIRECT
1965 smbd_deregister_mr(wdata->mr);
1971 cifsFileInfo_put(wdata->cfile);
1973 kvfree(wdata->pages);
1978 * Write failed with a retryable error. Resend the write request. It's also
1979 * possible that the page was redirtied so re-clean the page.
1982 cifs_writev_requeue(struct cifs_writedata *wdata)
1985 struct inode *inode = d_inode(wdata->cfile->dentry);
1986 struct TCP_Server_Info *server;
1987 unsigned int rest_len;
1989 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1991 rest_len = wdata->bytes;
1993 struct cifs_writedata *wdata2;
1994 unsigned int j, nr_pages, wsize, tailsz, cur_len;
1996 wsize = server->ops->wp_retry_size(inode);
1997 if (wsize < rest_len) {
1998 nr_pages = wsize / PAGE_SIZE;
2003 cur_len = nr_pages * PAGE_SIZE;
2006 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
2008 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
2011 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
2017 for (j = 0; j < nr_pages; j++) {
2018 wdata2->pages[j] = wdata->pages[i + j];
2019 lock_page(wdata2->pages[j]);
2020 clear_page_dirty_for_io(wdata2->pages[j]);
2023 wdata2->sync_mode = wdata->sync_mode;
2024 wdata2->nr_pages = nr_pages;
2025 wdata2->offset = page_offset(wdata2->pages[0]);
2026 wdata2->pagesz = PAGE_SIZE;
2027 wdata2->tailsz = tailsz;
2028 wdata2->bytes = cur_len;
2030 rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
2032 if (!wdata2->cfile) {
2033 cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
2035 if (!is_retryable_error(rc))
2038 wdata2->pid = wdata2->cfile->pid;
2039 rc = server->ops->async_writev(wdata2,
2040 cifs_writedata_release);
2043 for (j = 0; j < nr_pages; j++) {
2044 unlock_page(wdata2->pages[j]);
2045 if (rc != 0 && !is_retryable_error(rc)) {
2046 SetPageError(wdata2->pages[j]);
2047 end_page_writeback(wdata2->pages[j]);
2048 put_page(wdata2->pages[j]);
2052 kref_put(&wdata2->refcount, cifs_writedata_release);
2054 if (is_retryable_error(rc))
2060 rest_len -= cur_len;
2062 } while (i < wdata->nr_pages);
2064 /* cleanup remaining pages from the original wdata */
2065 for (; i < wdata->nr_pages; i++) {
2066 SetPageError(wdata->pages[i]);
2067 end_page_writeback(wdata->pages[i]);
2068 put_page(wdata->pages[i]);
2071 if (rc != 0 && !is_retryable_error(rc))
2072 mapping_set_error(inode->i_mapping, rc);
2073 kref_put(&wdata->refcount, cifs_writedata_release);
2077 cifs_writev_complete(struct work_struct *work)
2079 struct cifs_writedata *wdata = container_of(work,
2080 struct cifs_writedata, work);
2081 struct inode *inode = d_inode(wdata->cfile->dentry);
2084 if (wdata->result == 0) {
2085 spin_lock(&inode->i_lock);
2086 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2087 spin_unlock(&inode->i_lock);
2088 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2090 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2091 return cifs_writev_requeue(wdata);
2093 for (i = 0; i < wdata->nr_pages; i++) {
2094 struct page *page = wdata->pages[i];
2095 if (wdata->result == -EAGAIN)
2096 __set_page_dirty_nobuffers(page);
2097 else if (wdata->result < 0)
2099 end_page_writeback(page);
2102 if (wdata->result != -EAGAIN)
2103 mapping_set_error(inode->i_mapping, wdata->result);
2104 kref_put(&wdata->refcount, cifs_writedata_release);
2107 struct cifs_writedata *
2108 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2110 struct page **pages =
2111 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2113 return cifs_writedata_direct_alloc(pages, complete);
2118 struct cifs_writedata *
2119 cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2121 struct cifs_writedata *wdata;
2123 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2124 if (wdata != NULL) {
2125 wdata->pages = pages;
2126 kref_init(&wdata->refcount);
2127 INIT_LIST_HEAD(&wdata->list);
2128 init_completion(&wdata->done);
2129 INIT_WORK(&wdata->work, complete);
2135 * Check the mid_state and signature on received buffer (if any), and queue the
2136 * workqueue completion task.
2139 cifs_writev_callback(struct mid_q_entry *mid)
2141 struct cifs_writedata *wdata = mid->callback_data;
2142 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2143 unsigned int written;
2144 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2145 struct cifs_credits credits = { .value = 1, .instance = 0 };
2147 switch (mid->mid_state) {
2148 case MID_RESPONSE_RECEIVED:
2149 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2150 if (wdata->result != 0)
2153 written = le16_to_cpu(smb->CountHigh);
2155 written += le16_to_cpu(smb->Count);
2157 * Mask off high 16 bits when bytes written as returned
2158 * by the server is greater than bytes requested by the
2159 * client. OS/2 servers are known to set incorrect
2162 if (written > wdata->bytes)
2165 if (written < wdata->bytes)
2166 wdata->result = -ENOSPC;
2168 wdata->bytes = written;
2170 case MID_REQUEST_SUBMITTED:
2171 case MID_RETRY_NEEDED:
2172 wdata->result = -EAGAIN;
2175 wdata->result = -EIO;
2179 queue_work(cifsiod_wq, &wdata->work);
2180 DeleteMidQEntry(mid);
2181 add_credits(tcon->ses->server, &credits, 0);
2184 /* cifs_async_writev - send an async write, and set up mid to handle result */
2186 cifs_async_writev(struct cifs_writedata *wdata,
2187 void (*release)(struct kref *kref))
2190 WRITE_REQ *smb = NULL;
2192 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2194 struct smb_rqst rqst = { };
2196 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2200 if (wdata->offset >> 32 > 0) {
2201 /* can not handle big offset for old srv */
2206 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2208 goto async_writev_out;
2210 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2211 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2213 smb->AndXCommand = 0xFF; /* none */
2214 smb->Fid = wdata->cfile->fid.netfid;
2215 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2217 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2218 smb->Reserved = 0xFFFFFFFF;
2223 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2225 /* 4 for RFC1001 length + 1 for BCC */
2227 iov[0].iov_base = smb;
2228 iov[1].iov_len = get_rfc1002_length(smb) + 1;
2229 iov[1].iov_base = (char *)smb + 4;
2233 rqst.rq_pages = wdata->pages;
2234 rqst.rq_offset = wdata->page_offset;
2235 rqst.rq_npages = wdata->nr_pages;
2236 rqst.rq_pagesz = wdata->pagesz;
2237 rqst.rq_tailsz = wdata->tailsz;
2239 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2240 wdata->offset, wdata->bytes);
2242 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2243 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2246 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2247 put_bcc(wdata->bytes + 1, &smb->hdr);
2250 struct smb_com_writex_req *smbw =
2251 (struct smb_com_writex_req *)smb;
2252 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2253 put_bcc(wdata->bytes + 5, &smbw->hdr);
2254 iov[1].iov_len += 4; /* pad bigger by four bytes */
2257 kref_get(&wdata->refcount);
2258 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2259 cifs_writev_callback, NULL, wdata, 0, NULL);
2262 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2264 kref_put(&wdata->refcount, release);
2267 cifs_small_buf_release(smb);
2272 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2273 unsigned int *nbytes, struct kvec *iov, int n_vec)
2276 WRITE_REQ *pSMB = NULL;
2279 int resp_buf_type = 0;
2280 __u32 pid = io_parms->pid;
2281 __u16 netfid = io_parms->netfid;
2282 __u64 offset = io_parms->offset;
2283 struct cifs_tcon *tcon = io_parms->tcon;
2284 unsigned int count = io_parms->length;
2285 struct kvec rsp_iov;
2289 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2291 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2295 if ((offset >> 32) > 0) {
2296 /* can not handle big offset for old srv */
2300 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2304 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2305 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2307 /* tcon and ses pointer are checked in smb_init */
2308 if (tcon->ses->server == NULL)
2309 return -ECONNABORTED;
2311 pSMB->AndXCommand = 0xFF; /* none */
2313 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2315 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2316 pSMB->Reserved = 0xFFFFFFFF;
2317 pSMB->WriteMode = 0;
2318 pSMB->Remaining = 0;
2321 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2323 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2324 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2325 /* header + 1 byte pad */
2326 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2328 inc_rfc1001_len(pSMB, count + 1);
2329 else /* wct == 12 */
2330 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2332 pSMB->ByteCount = cpu_to_le16(count + 1);
2333 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2334 struct smb_com_writex_req *pSMBW =
2335 (struct smb_com_writex_req *)pSMB;
2336 pSMBW->ByteCount = cpu_to_le16(count + 5);
2338 iov[0].iov_base = pSMB;
2340 iov[0].iov_len = smb_hdr_len + 4;
2341 else /* wct == 12 pad bigger by four bytes */
2342 iov[0].iov_len = smb_hdr_len + 8;
2344 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2346 cifs_small_buf_release(pSMB);
2347 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2349 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2350 } else if (resp_buf_type == 0) {
2351 /* presumably this can not happen, but best to be safe */
2354 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2355 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2356 *nbytes = (*nbytes) << 16;
2357 *nbytes += le16_to_cpu(pSMBr->Count);
2360 * Mask off high 16 bits when bytes written as returned by the
2361 * server is greater than bytes requested by the client. OS/2
2362 * servers are known to set incorrect CountHigh values.
2364 if (*nbytes > count)
2368 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2370 /* Note: On -EAGAIN error only caller can retry on handle based calls
2371 since file handle passed in no longer valid */
2376 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2377 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2378 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2381 LOCK_REQ *pSMB = NULL;
2383 struct kvec rsp_iov;
2387 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2388 num_lock, num_unlock);
2390 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2395 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2396 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2397 pSMB->LockType = lock_type;
2398 pSMB->AndXCommand = 0xFF; /* none */
2399 pSMB->Fid = netfid; /* netfid stays le */
2401 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2402 inc_rfc1001_len(pSMB, count);
2403 pSMB->ByteCount = cpu_to_le16(count);
2405 iov[0].iov_base = (char *)pSMB;
2406 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2407 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2408 iov[1].iov_base = (char *)buf;
2409 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2411 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2412 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
2413 CIFS_NO_RSP_BUF, &rsp_iov);
2414 cifs_small_buf_release(pSMB);
2416 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2422 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2423 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2424 const __u64 offset, const __u32 numUnlock,
2425 const __u32 numLock, const __u8 lockType,
2426 const bool waitFlag, const __u8 oplock_level)
2429 LOCK_REQ *pSMB = NULL;
2430 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2435 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2436 (int)waitFlag, numLock);
2437 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2442 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2443 /* no response expected */
2444 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
2446 } else if (waitFlag) {
2447 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2448 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2453 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2454 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2455 pSMB->LockType = lockType;
2456 pSMB->OplockLevel = oplock_level;
2457 pSMB->AndXCommand = 0xFF; /* none */
2458 pSMB->Fid = smb_file_id; /* netfid stays le */
2460 if ((numLock != 0) || (numUnlock != 0)) {
2461 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2462 /* BB where to store pid high? */
2463 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2464 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2465 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2466 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2467 count = sizeof(LOCKING_ANDX_RANGE);
2472 inc_rfc1001_len(pSMB, count);
2473 pSMB->ByteCount = cpu_to_le16(count);
2476 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2477 (struct smb_hdr *) pSMB, &bytes_returned);
2479 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2480 cifs_small_buf_release(pSMB);
2481 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2483 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2485 /* Note: On -EAGAIN error only caller can retry on handle based calls
2486 since file handle passed in no longer valid */
2491 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2492 const __u16 smb_file_id, const __u32 netpid,
2493 const loff_t start_offset, const __u64 len,
2494 struct file_lock *pLockData, const __u16 lock_type,
2495 const bool waitFlag)
2497 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2498 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2499 struct cifs_posix_lock *parm_data;
2502 int bytes_returned = 0;
2503 int resp_buf_type = 0;
2504 __u16 params, param_offset, offset, byte_count, count;
2506 struct kvec rsp_iov;
2508 cifs_dbg(FYI, "Posix Lock\n");
2510 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2515 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2518 pSMB->MaxSetupCount = 0;
2521 pSMB->Reserved2 = 0;
2522 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2523 offset = param_offset + params;
2525 count = sizeof(struct cifs_posix_lock);
2526 pSMB->MaxParameterCount = cpu_to_le16(2);
2527 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2528 pSMB->SetupCount = 1;
2529 pSMB->Reserved3 = 0;
2531 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2533 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2534 byte_count = 3 /* pad */ + params + count;
2535 pSMB->DataCount = cpu_to_le16(count);
2536 pSMB->ParameterCount = cpu_to_le16(params);
2537 pSMB->TotalDataCount = pSMB->DataCount;
2538 pSMB->TotalParameterCount = pSMB->ParameterCount;
2539 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2540 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2541 parm_data = (struct cifs_posix_lock *)
2542 (((char *)pSMB) + offset + 4);
2544 parm_data->lock_type = cpu_to_le16(lock_type);
2546 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2547 parm_data->lock_flags = cpu_to_le16(1);
2548 pSMB->Timeout = cpu_to_le32(-1);
2552 parm_data->pid = cpu_to_le32(netpid);
2553 parm_data->start = cpu_to_le64(start_offset);
2554 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2556 pSMB->DataOffset = cpu_to_le16(offset);
2557 pSMB->Fid = smb_file_id;
2558 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2559 pSMB->Reserved4 = 0;
2560 inc_rfc1001_len(pSMB, byte_count);
2561 pSMB->ByteCount = cpu_to_le16(byte_count);
2563 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2564 (struct smb_hdr *) pSMBr, &bytes_returned);
2566 iov[0].iov_base = (char *)pSMB;
2567 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2568 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2569 &resp_buf_type, timeout, &rsp_iov);
2570 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2572 cifs_small_buf_release(pSMB);
2575 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2576 } else if (pLockData) {
2577 /* lock structure can be returned on get */
2580 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2582 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2583 rc = -EIO; /* bad smb */
2586 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2587 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2588 if (data_count < sizeof(struct cifs_posix_lock)) {
2592 parm_data = (struct cifs_posix_lock *)
2593 ((char *)&pSMBr->hdr.Protocol + data_offset);
2594 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2595 pLockData->fl_type = F_UNLCK;
2597 if (parm_data->lock_type ==
2598 cpu_to_le16(CIFS_RDLCK))
2599 pLockData->fl_type = F_RDLCK;
2600 else if (parm_data->lock_type ==
2601 cpu_to_le16(CIFS_WRLCK))
2602 pLockData->fl_type = F_WRLCK;
2604 pLockData->fl_start = le64_to_cpu(parm_data->start);
2605 pLockData->fl_end = pLockData->fl_start +
2606 le64_to_cpu(parm_data->length) - 1;
2607 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2612 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2614 /* Note: On -EAGAIN error only caller can retry on handle based calls
2615 since file handle passed in no longer valid */
2622 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2625 CLOSE_REQ *pSMB = NULL;
2626 cifs_dbg(FYI, "In CIFSSMBClose\n");
2628 /* do not retry on dead session on close */
2629 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2635 pSMB->FileID = (__u16) smb_file_id;
2636 pSMB->LastWriteTime = 0xFFFFFFFF;
2637 pSMB->ByteCount = 0;
2638 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2639 cifs_small_buf_release(pSMB);
2640 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2643 /* EINTR is expected when user ctl-c to kill app */
2644 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2648 /* Since session is dead, file will be closed on server already */
2656 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2659 FLUSH_REQ *pSMB = NULL;
2660 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2662 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2666 pSMB->FileID = (__u16) smb_file_id;
2667 pSMB->ByteCount = 0;
2668 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2669 cifs_small_buf_release(pSMB);
2670 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2672 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2678 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2679 const char *from_name, const char *to_name,
2680 struct cifs_sb_info *cifs_sb)
2683 RENAME_REQ *pSMB = NULL;
2684 RENAME_RSP *pSMBr = NULL;
2686 int name_len, name_len2;
2688 int remap = cifs_remap(cifs_sb);
2690 cifs_dbg(FYI, "In CIFSSMBRename\n");
2692 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2697 pSMB->BufferFormat = 0x04;
2698 pSMB->SearchAttributes =
2699 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2702 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2703 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2704 from_name, PATH_MAX,
2705 cifs_sb->local_nls, remap);
2706 name_len++; /* trailing null */
2708 pSMB->OldFileName[name_len] = 0x04; /* pad */
2709 /* protocol requires ASCII signature byte on Unicode string */
2710 pSMB->OldFileName[name_len + 1] = 0x00;
2712 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2713 to_name, PATH_MAX, cifs_sb->local_nls,
2715 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2716 name_len2 *= 2; /* convert to bytes */
2718 name_len = copy_path_name(pSMB->OldFileName, from_name);
2719 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2720 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2721 name_len2++; /* signature byte */
2724 count = 1 /* 1st signature byte */ + name_len + name_len2;
2725 inc_rfc1001_len(pSMB, count);
2726 pSMB->ByteCount = cpu_to_le16(count);
2728 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2729 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2730 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2732 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2734 cifs_buf_release(pSMB);
2742 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2743 int netfid, const char *target_name,
2744 const struct nls_table *nls_codepage, int remap)
2746 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2747 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2748 struct set_file_rename *rename_info;
2750 char dummy_string[30];
2752 int bytes_returned = 0;
2754 __u16 params, param_offset, offset, count, byte_count;
2756 cifs_dbg(FYI, "Rename to File by handle\n");
2757 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2763 pSMB->MaxSetupCount = 0;
2767 pSMB->Reserved2 = 0;
2768 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2769 offset = param_offset + params;
2771 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2772 data_offset = (char *)(pSMB) + offset + 4;
2773 rename_info = (struct set_file_rename *) data_offset;
2774 pSMB->MaxParameterCount = cpu_to_le16(2);
2775 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2776 pSMB->SetupCount = 1;
2777 pSMB->Reserved3 = 0;
2778 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2779 byte_count = 3 /* pad */ + params;
2780 pSMB->ParameterCount = cpu_to_le16(params);
2781 pSMB->TotalParameterCount = pSMB->ParameterCount;
2782 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2783 pSMB->DataOffset = cpu_to_le16(offset);
2784 /* construct random name ".cifs_tmp<inodenum><mid>" */
2785 rename_info->overwrite = cpu_to_le32(1);
2786 rename_info->root_fid = 0;
2787 /* unicode only call */
2788 if (target_name == NULL) {
2789 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2791 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2792 dummy_string, 24, nls_codepage, remap);
2795 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2796 target_name, PATH_MAX, nls_codepage,
2799 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2800 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2801 byte_count += count;
2802 pSMB->DataCount = cpu_to_le16(count);
2803 pSMB->TotalDataCount = pSMB->DataCount;
2805 pSMB->InformationLevel =
2806 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2807 pSMB->Reserved4 = 0;
2808 inc_rfc1001_len(pSMB, byte_count);
2809 pSMB->ByteCount = cpu_to_le16(byte_count);
2810 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2811 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2812 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2814 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2817 cifs_buf_release(pSMB);
2819 /* Note: On -EAGAIN error only caller can retry on handle based calls
2820 since file handle passed in no longer valid */
2826 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2827 const char *fromName, const __u16 target_tid, const char *toName,
2828 const int flags, const struct nls_table *nls_codepage, int remap)
2831 COPY_REQ *pSMB = NULL;
2832 COPY_RSP *pSMBr = NULL;
2834 int name_len, name_len2;
2837 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2839 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2844 pSMB->BufferFormat = 0x04;
2845 pSMB->Tid2 = target_tid;
2847 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2849 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2850 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2851 fromName, PATH_MAX, nls_codepage,
2853 name_len++; /* trailing null */
2855 pSMB->OldFileName[name_len] = 0x04; /* pad */
2856 /* protocol requires ASCII signature byte on Unicode string */
2857 pSMB->OldFileName[name_len + 1] = 0x00;
2859 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2860 toName, PATH_MAX, nls_codepage, remap);
2861 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2862 name_len2 *= 2; /* convert to bytes */
2864 name_len = copy_path_name(pSMB->OldFileName, fromName);
2865 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2866 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2867 name_len2++; /* signature byte */
2870 count = 1 /* 1st signature byte */ + name_len + name_len2;
2871 inc_rfc1001_len(pSMB, count);
2872 pSMB->ByteCount = cpu_to_le16(count);
2874 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2875 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2877 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2878 rc, le16_to_cpu(pSMBr->CopyCount));
2880 cifs_buf_release(pSMB);
2889 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2890 const char *fromName, const char *toName,
2891 const struct nls_table *nls_codepage, int remap)
2893 TRANSACTION2_SPI_REQ *pSMB = NULL;
2894 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2897 int name_len_target;
2899 int bytes_returned = 0;
2900 __u16 params, param_offset, offset, byte_count;
2902 cifs_dbg(FYI, "In Symlink Unix style\n");
2904 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2909 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2911 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2912 /* find define for this maxpathcomponent */
2913 PATH_MAX, nls_codepage, remap);
2914 name_len++; /* trailing null */
2918 name_len = copy_path_name(pSMB->FileName, fromName);
2920 params = 6 + name_len;
2921 pSMB->MaxSetupCount = 0;
2925 pSMB->Reserved2 = 0;
2926 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2927 InformationLevel) - 4;
2928 offset = param_offset + params;
2930 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2931 data_offset = (char *)pSMB + offset + 4;
2932 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2934 cifsConvertToUTF16((__le16 *) data_offset, toName,
2935 /* find define for this maxpathcomponent */
2936 PATH_MAX, nls_codepage, remap);
2937 name_len_target++; /* trailing null */
2938 name_len_target *= 2;
2940 name_len_target = copy_path_name(data_offset, toName);
2943 pSMB->MaxParameterCount = cpu_to_le16(2);
2944 /* BB find exact max on data count below from sess */
2945 pSMB->MaxDataCount = cpu_to_le16(1000);
2946 pSMB->SetupCount = 1;
2947 pSMB->Reserved3 = 0;
2948 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2949 byte_count = 3 /* pad */ + params + name_len_target;
2950 pSMB->DataCount = cpu_to_le16(name_len_target);
2951 pSMB->ParameterCount = cpu_to_le16(params);
2952 pSMB->TotalDataCount = pSMB->DataCount;
2953 pSMB->TotalParameterCount = pSMB->ParameterCount;
2954 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2955 pSMB->DataOffset = cpu_to_le16(offset);
2956 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2957 pSMB->Reserved4 = 0;
2958 inc_rfc1001_len(pSMB, byte_count);
2959 pSMB->ByteCount = cpu_to_le16(byte_count);
2960 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2961 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2962 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2964 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2967 cifs_buf_release(pSMB);
2970 goto createSymLinkRetry;
2976 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2977 const char *fromName, const char *toName,
2978 const struct nls_table *nls_codepage, int remap)
2980 TRANSACTION2_SPI_REQ *pSMB = NULL;
2981 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2984 int name_len_target;
2986 int bytes_returned = 0;
2987 __u16 params, param_offset, offset, byte_count;
2989 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2990 createHardLinkRetry:
2991 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2996 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2997 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2998 PATH_MAX, nls_codepage, remap);
2999 name_len++; /* trailing null */
3003 name_len = copy_path_name(pSMB->FileName, toName);
3005 params = 6 + name_len;
3006 pSMB->MaxSetupCount = 0;
3010 pSMB->Reserved2 = 0;
3011 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3012 InformationLevel) - 4;
3013 offset = param_offset + params;
3015 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
3016 data_offset = (char *)pSMB + offset + 4;
3017 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3019 cifsConvertToUTF16((__le16 *) data_offset, fromName,
3020 PATH_MAX, nls_codepage, remap);
3021 name_len_target++; /* trailing null */
3022 name_len_target *= 2;
3024 name_len_target = copy_path_name(data_offset, fromName);
3027 pSMB->MaxParameterCount = cpu_to_le16(2);
3028 /* BB find exact max on data count below from sess*/
3029 pSMB->MaxDataCount = cpu_to_le16(1000);
3030 pSMB->SetupCount = 1;
3031 pSMB->Reserved3 = 0;
3032 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3033 byte_count = 3 /* pad */ + params + name_len_target;
3034 pSMB->ParameterCount = cpu_to_le16(params);
3035 pSMB->TotalParameterCount = pSMB->ParameterCount;
3036 pSMB->DataCount = cpu_to_le16(name_len_target);
3037 pSMB->TotalDataCount = pSMB->DataCount;
3038 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3039 pSMB->DataOffset = cpu_to_le16(offset);
3040 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3041 pSMB->Reserved4 = 0;
3042 inc_rfc1001_len(pSMB, byte_count);
3043 pSMB->ByteCount = cpu_to_le16(byte_count);
3044 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3045 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3046 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3048 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3051 cifs_buf_release(pSMB);
3053 goto createHardLinkRetry;
3059 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3060 const char *from_name, const char *to_name,
3061 struct cifs_sb_info *cifs_sb)
3064 NT_RENAME_REQ *pSMB = NULL;
3065 RENAME_RSP *pSMBr = NULL;
3067 int name_len, name_len2;
3069 int remap = cifs_remap(cifs_sb);
3071 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3072 winCreateHardLinkRetry:
3074 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3079 pSMB->SearchAttributes =
3080 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3082 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3083 pSMB->ClusterCount = 0;
3085 pSMB->BufferFormat = 0x04;
3087 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3089 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3090 PATH_MAX, cifs_sb->local_nls, remap);
3091 name_len++; /* trailing null */
3094 /* protocol specifies ASCII buffer format (0x04) for unicode */
3095 pSMB->OldFileName[name_len] = 0x04;
3096 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3098 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3099 to_name, PATH_MAX, cifs_sb->local_nls,
3101 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3102 name_len2 *= 2; /* convert to bytes */
3104 name_len = copy_path_name(pSMB->OldFileName, from_name);
3105 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3106 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
3107 name_len2++; /* signature byte */
3110 count = 1 /* string type byte */ + name_len + name_len2;
3111 inc_rfc1001_len(pSMB, count);
3112 pSMB->ByteCount = cpu_to_le16(count);
3114 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3115 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3116 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3118 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3120 cifs_buf_release(pSMB);
3122 goto winCreateHardLinkRetry;
3128 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3129 const unsigned char *searchName, char **symlinkinfo,
3130 const struct nls_table *nls_codepage, int remap)
3132 /* SMB_QUERY_FILE_UNIX_LINK */
3133 TRANSACTION2_QPI_REQ *pSMB = NULL;
3134 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3138 __u16 params, byte_count;
3141 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3144 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3149 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3151 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3152 searchName, PATH_MAX, nls_codepage,
3154 name_len++; /* trailing null */
3157 name_len = copy_path_name(pSMB->FileName, searchName);
3160 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3161 pSMB->TotalDataCount = 0;
3162 pSMB->MaxParameterCount = cpu_to_le16(2);
3163 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3164 pSMB->MaxSetupCount = 0;
3168 pSMB->Reserved2 = 0;
3169 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3170 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3171 pSMB->DataCount = 0;
3172 pSMB->DataOffset = 0;
3173 pSMB->SetupCount = 1;
3174 pSMB->Reserved3 = 0;
3175 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3176 byte_count = params + 1 /* pad */ ;
3177 pSMB->TotalParameterCount = cpu_to_le16(params);
3178 pSMB->ParameterCount = pSMB->TotalParameterCount;
3179 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3180 pSMB->Reserved4 = 0;
3181 inc_rfc1001_len(pSMB, byte_count);
3182 pSMB->ByteCount = cpu_to_le16(byte_count);
3184 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3185 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3187 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3189 /* decode response */
3191 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3192 /* BB also check enough total bytes returned */
3193 if (rc || get_bcc(&pSMBr->hdr) < 2)
3197 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3199 data_start = ((char *) &pSMBr->hdr.Protocol) +
3200 le16_to_cpu(pSMBr->t2.DataOffset);
3202 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3207 /* BB FIXME investigate remapping reserved chars here */
3208 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3209 count, is_unicode, nls_codepage);
3214 cifs_buf_release(pSMB);
3216 goto querySymLinkRetry;
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 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3232 __u16 fid, char **symlinkinfo,
3233 const struct nls_table *nls_codepage)
3237 struct smb_com_transaction_ioctl_req *pSMB;
3238 struct smb_com_transaction_ioctl_rsp *pSMBr;
3240 unsigned int sub_len;
3242 struct reparse_symlink_data *reparse_buf;
3243 struct reparse_posix_data *posix_buf;
3244 __u32 data_offset, data_count;
3247 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3248 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3253 pSMB->TotalParameterCount = 0 ;
3254 pSMB->TotalDataCount = 0;
3255 pSMB->MaxParameterCount = cpu_to_le32(2);
3256 /* BB find exact data count max from sess structure BB */
3257 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3258 pSMB->MaxSetupCount = 4;
3260 pSMB->ParameterOffset = 0;
3261 pSMB->DataCount = 0;
3262 pSMB->DataOffset = 0;
3263 pSMB->SetupCount = 4;
3264 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3265 pSMB->ParameterCount = pSMB->TotalParameterCount;
3266 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3267 pSMB->IsFsctl = 1; /* FSCTL */
3268 pSMB->IsRootFlag = 0;
3269 pSMB->Fid = fid; /* file handle always le */
3270 pSMB->ByteCount = 0;
3272 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3273 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3275 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3279 data_offset = le32_to_cpu(pSMBr->DataOffset);
3280 data_count = le32_to_cpu(pSMBr->DataCount);
3281 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3282 /* BB also check enough total bytes returned */
3283 rc = -EIO; /* bad smb */
3286 if (!data_count || (data_count > 2048)) {
3288 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3291 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3292 reparse_buf = (struct reparse_symlink_data *)
3293 ((char *)&pSMBr->hdr.Protocol + data_offset);
3294 if ((char *)reparse_buf >= end_of_smb) {
3298 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3299 cifs_dbg(FYI, "NFS style reparse tag\n");
3300 posix_buf = (struct reparse_posix_data *)reparse_buf;
3302 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3303 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3304 le64_to_cpu(posix_buf->InodeType));
3309 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3310 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3311 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3315 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3316 sub_len, is_unicode, nls_codepage);
3318 } else if (reparse_buf->ReparseTag !=
3319 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3324 /* Reparse tag is NTFS symlink */
3325 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3326 reparse_buf->PathBuffer;
3327 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3328 if (sub_start + sub_len > end_of_smb) {
3329 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3333 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3338 /* BB FIXME investigate remapping reserved chars here */
3339 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3344 cifs_buf_release(pSMB);
3347 * Note: On -EAGAIN error only caller can retry on handle based calls
3348 * since file handle passed in no longer valid.
3354 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3359 struct smb_com_transaction_compr_ioctl_req *pSMB;
3360 struct smb_com_transaction_ioctl_rsp *pSMBr;
3362 cifs_dbg(FYI, "Set compression for %u\n", fid);
3363 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3368 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3370 pSMB->TotalParameterCount = 0;
3371 pSMB->TotalDataCount = cpu_to_le32(2);
3372 pSMB->MaxParameterCount = 0;
3373 pSMB->MaxDataCount = 0;
3374 pSMB->MaxSetupCount = 4;
3376 pSMB->ParameterOffset = 0;
3377 pSMB->DataCount = cpu_to_le32(2);
3379 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3380 compression_state) - 4); /* 84 */
3381 pSMB->SetupCount = 4;
3382 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3383 pSMB->ParameterCount = 0;
3384 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3385 pSMB->IsFsctl = 1; /* FSCTL */
3386 pSMB->IsRootFlag = 0;
3387 pSMB->Fid = fid; /* file handle always le */
3388 /* 3 byte pad, followed by 2 byte compress state */
3389 pSMB->ByteCount = cpu_to_le16(5);
3390 inc_rfc1001_len(pSMB, 5);
3392 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3393 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3395 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3397 cifs_buf_release(pSMB);
3400 * Note: On -EAGAIN error only caller can retry on handle based calls
3401 * since file handle passed in no longer valid.
3407 #ifdef CONFIG_CIFS_POSIX
3409 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3410 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3411 struct cifs_posix_ace *cifs_ace)
3413 /* u8 cifs fields do not need le conversion */
3414 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3415 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3416 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3418 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3419 ace->e_perm, ace->e_tag, ace->e_id);
3425 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3426 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3427 const int acl_type, const int size_of_data_area)
3432 struct cifs_posix_ace *pACE;
3433 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3434 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3436 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3439 if (acl_type == ACL_TYPE_ACCESS) {
3440 count = le16_to_cpu(cifs_acl->access_entry_count);
3441 pACE = &cifs_acl->ace_array[0];
3442 size = sizeof(struct cifs_posix_acl);
3443 size += sizeof(struct cifs_posix_ace) * count;
3444 /* check if we would go beyond end of SMB */
3445 if (size_of_data_area < size) {
3446 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3447 size_of_data_area, size);
3450 } else if (acl_type == ACL_TYPE_DEFAULT) {
3451 count = le16_to_cpu(cifs_acl->access_entry_count);
3452 size = sizeof(struct cifs_posix_acl);
3453 size += sizeof(struct cifs_posix_ace) * count;
3454 /* skip past access ACEs to get to default ACEs */
3455 pACE = &cifs_acl->ace_array[count];
3456 count = le16_to_cpu(cifs_acl->default_entry_count);
3457 size += sizeof(struct cifs_posix_ace) * count;
3458 /* check if we would go beyond end of SMB */
3459 if (size_of_data_area < size)
3466 size = posix_acl_xattr_size(count);
3467 if ((buflen == 0) || (local_acl == NULL)) {
3468 /* used to query ACL EA size */
3469 } else if (size > buflen) {
3471 } else /* buffer big enough */ {
3472 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3474 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3475 for (i = 0; i < count ; i++) {
3476 cifs_convert_ace(&ace[i], pACE);
3483 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3484 const struct posix_acl_xattr_entry *local_ace)
3486 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3487 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3488 /* BB is there a better way to handle the large uid? */
3489 if (local_ace->e_id == cpu_to_le32(-1)) {
3490 /* Probably no need to le convert -1 on any arch but can not hurt */
3491 cifs_ace->cifs_uid = cpu_to_le64(-1);
3493 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3495 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3496 ace->e_perm, ace->e_tag, ace->e_id);
3500 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3501 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3502 const int buflen, const int acl_type)
3505 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3506 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3507 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3511 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3514 count = posix_acl_xattr_count((size_t)buflen);
3515 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3516 count, buflen, le32_to_cpu(local_acl->a_version));
3517 if (le32_to_cpu(local_acl->a_version) != 2) {
3518 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3519 le32_to_cpu(local_acl->a_version));
3522 cifs_acl->version = cpu_to_le16(1);
3523 if (acl_type == ACL_TYPE_ACCESS) {
3524 cifs_acl->access_entry_count = cpu_to_le16(count);
3525 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3526 } else if (acl_type == ACL_TYPE_DEFAULT) {
3527 cifs_acl->default_entry_count = cpu_to_le16(count);
3528 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3530 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3533 for (i = 0; i < count; i++)
3534 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3536 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3537 rc += sizeof(struct cifs_posix_acl);
3538 /* BB add check to make sure ACL does not overflow SMB */
3544 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3545 const unsigned char *searchName,
3546 char *acl_inf, const int buflen, const int acl_type,
3547 const struct nls_table *nls_codepage, int remap)
3549 /* SMB_QUERY_POSIX_ACL */
3550 TRANSACTION2_QPI_REQ *pSMB = NULL;
3551 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3555 __u16 params, byte_count;
3557 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3560 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3565 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3567 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3568 searchName, PATH_MAX, nls_codepage,
3570 name_len++; /* trailing null */
3572 pSMB->FileName[name_len] = 0;
3573 pSMB->FileName[name_len+1] = 0;
3575 name_len = copy_path_name(pSMB->FileName, searchName);
3578 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3579 pSMB->TotalDataCount = 0;
3580 pSMB->MaxParameterCount = cpu_to_le16(2);
3581 /* BB find exact max data count below from sess structure BB */
3582 pSMB->MaxDataCount = cpu_to_le16(4000);
3583 pSMB->MaxSetupCount = 0;
3587 pSMB->Reserved2 = 0;
3588 pSMB->ParameterOffset = cpu_to_le16(
3589 offsetof(struct smb_com_transaction2_qpi_req,
3590 InformationLevel) - 4);
3591 pSMB->DataCount = 0;
3592 pSMB->DataOffset = 0;
3593 pSMB->SetupCount = 1;
3594 pSMB->Reserved3 = 0;
3595 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3596 byte_count = params + 1 /* pad */ ;
3597 pSMB->TotalParameterCount = cpu_to_le16(params);
3598 pSMB->ParameterCount = pSMB->TotalParameterCount;
3599 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3600 pSMB->Reserved4 = 0;
3601 inc_rfc1001_len(pSMB, byte_count);
3602 pSMB->ByteCount = cpu_to_le16(byte_count);
3604 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3605 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3606 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3608 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3610 /* decode response */
3612 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3613 /* BB also check enough total bytes returned */
3614 if (rc || get_bcc(&pSMBr->hdr) < 2)
3615 rc = -EIO; /* bad smb */
3617 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3618 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3619 rc = cifs_copy_posix_acl(acl_inf,
3620 (char *)&pSMBr->hdr.Protocol+data_offset,
3621 buflen, acl_type, count);
3624 cifs_buf_release(pSMB);
3631 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3632 const unsigned char *fileName,
3633 const char *local_acl, const int buflen,
3635 const struct nls_table *nls_codepage, int remap)
3637 struct smb_com_transaction2_spi_req *pSMB = NULL;
3638 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3642 int bytes_returned = 0;
3643 __u16 params, byte_count, data_count, param_offset, offset;
3645 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3647 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3651 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3653 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3654 PATH_MAX, nls_codepage, remap);
3655 name_len++; /* trailing null */
3658 name_len = copy_path_name(pSMB->FileName, fileName);
3660 params = 6 + name_len;
3661 pSMB->MaxParameterCount = cpu_to_le16(2);
3662 /* BB find max SMB size from sess */
3663 pSMB->MaxDataCount = cpu_to_le16(1000);
3664 pSMB->MaxSetupCount = 0;
3668 pSMB->Reserved2 = 0;
3669 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3670 InformationLevel) - 4;
3671 offset = param_offset + params;
3672 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3673 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3675 /* convert to on the wire format for POSIX ACL */
3676 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3678 if (data_count == 0) {
3680 goto setACLerrorExit;
3682 pSMB->DataOffset = cpu_to_le16(offset);
3683 pSMB->SetupCount = 1;
3684 pSMB->Reserved3 = 0;
3685 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3686 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3687 byte_count = 3 /* pad */ + params + data_count;
3688 pSMB->DataCount = cpu_to_le16(data_count);
3689 pSMB->TotalDataCount = pSMB->DataCount;
3690 pSMB->ParameterCount = cpu_to_le16(params);
3691 pSMB->TotalParameterCount = pSMB->ParameterCount;
3692 pSMB->Reserved4 = 0;
3693 inc_rfc1001_len(pSMB, byte_count);
3694 pSMB->ByteCount = cpu_to_le16(byte_count);
3695 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3696 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3698 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3701 cifs_buf_release(pSMB);
3707 /* BB fix tabs in this function FIXME BB */
3709 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3710 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3713 struct smb_t2_qfi_req *pSMB = NULL;
3714 struct smb_t2_qfi_rsp *pSMBr = NULL;
3716 __u16 params, byte_count;
3718 cifs_dbg(FYI, "In GetExtAttr\n");
3723 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3728 params = 2 /* level */ + 2 /* fid */;
3729 pSMB->t2.TotalDataCount = 0;
3730 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3731 /* BB find exact max data count below from sess structure BB */
3732 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3733 pSMB->t2.MaxSetupCount = 0;
3734 pSMB->t2.Reserved = 0;
3736 pSMB->t2.Timeout = 0;
3737 pSMB->t2.Reserved2 = 0;
3738 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3740 pSMB->t2.DataCount = 0;
3741 pSMB->t2.DataOffset = 0;
3742 pSMB->t2.SetupCount = 1;
3743 pSMB->t2.Reserved3 = 0;
3744 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3745 byte_count = params + 1 /* pad */ ;
3746 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3747 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3748 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3751 inc_rfc1001_len(pSMB, byte_count);
3752 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3754 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3755 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3757 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3759 /* decode response */
3760 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3761 /* BB also check enough total bytes returned */
3762 if (rc || get_bcc(&pSMBr->hdr) < 2)
3763 /* If rc should we check for EOPNOSUPP and
3764 disable the srvino flag? or in caller? */
3765 rc = -EIO; /* bad smb */
3767 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3768 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3769 struct file_chattr_info *pfinfo;
3770 /* BB Do we need a cast or hash here ? */
3772 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3776 pfinfo = (struct file_chattr_info *)
3777 (data_offset + (char *) &pSMBr->hdr.Protocol);
3778 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3779 *pMask = le64_to_cpu(pfinfo->mask);
3783 cifs_buf_release(pSMB);
3785 goto GetExtAttrRetry;
3789 #endif /* CONFIG_POSIX */
3792 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3793 * all NT TRANSACTS that we init here have total parm and data under about 400
3794 * bytes (to fit in small cifs buffer size), which is the case so far, it
3795 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3796 * returned setup area) and MaxParameterCount (returned parms size) must be set
3800 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3801 const int parm_len, struct cifs_tcon *tcon,
3806 struct smb_com_ntransact_req *pSMB;
3808 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3812 *ret_buf = (void *)pSMB;
3814 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3815 pSMB->TotalDataCount = 0;
3816 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3817 pSMB->ParameterCount = pSMB->TotalParameterCount;
3818 pSMB->DataCount = pSMB->TotalDataCount;
3819 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3820 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3821 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3822 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3823 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3824 pSMB->SubCommand = cpu_to_le16(sub_command);
3829 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3830 __u32 *pparmlen, __u32 *pdatalen)
3833 __u32 data_count, data_offset, parm_count, parm_offset;
3834 struct smb_com_ntransact_rsp *pSMBr;
3843 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3845 bcc = get_bcc(&pSMBr->hdr);
3846 end_of_smb = 2 /* sizeof byte count */ + bcc +
3847 (char *)&pSMBr->ByteCount;
3849 data_offset = le32_to_cpu(pSMBr->DataOffset);
3850 data_count = le32_to_cpu(pSMBr->DataCount);
3851 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3852 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3854 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3855 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3857 /* should we also check that parm and data areas do not overlap? */
3858 if (*ppparm > end_of_smb) {
3859 cifs_dbg(FYI, "parms start after end of smb\n");
3861 } else if (parm_count + *ppparm > end_of_smb) {
3862 cifs_dbg(FYI, "parm end after end of smb\n");
3864 } else if (*ppdata > end_of_smb) {
3865 cifs_dbg(FYI, "data starts after end of smb\n");
3867 } else if (data_count + *ppdata > end_of_smb) {
3868 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3869 *ppdata, data_count, (data_count + *ppdata),
3872 } else if (parm_count + data_count > bcc) {
3873 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3876 *pdatalen = data_count;
3877 *pparmlen = parm_count;
3881 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3883 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3884 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3888 QUERY_SEC_DESC_REQ *pSMB;
3890 struct kvec rsp_iov;
3892 cifs_dbg(FYI, "GetCifsACL\n");
3897 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3898 8 /* parm len */, tcon, (void **) &pSMB);
3902 pSMB->MaxParameterCount = cpu_to_le32(4);
3903 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3904 pSMB->MaxSetupCount = 0;
3905 pSMB->Fid = fid; /* file handle always le */
3906 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3908 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3909 inc_rfc1001_len(pSMB, 11);
3910 iov[0].iov_base = (char *)pSMB;
3911 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3913 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3915 cifs_small_buf_release(pSMB);
3916 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3918 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3919 } else { /* decode response */
3923 struct smb_com_ntransact_rsp *pSMBr;
3926 /* validate_nttransact */
3927 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3928 &pdata, &parm_len, pbuflen);
3931 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3933 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3934 pSMBr, parm, *acl_inf);
3936 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3937 rc = -EIO; /* bad smb */
3942 /* BB check that data area is minimum length and as big as acl_len */
3944 acl_len = le32_to_cpu(*parm);
3945 if (acl_len != *pbuflen) {
3946 cifs_dbg(VFS, "acl length %d does not match %d\n",
3948 if (*pbuflen > acl_len)
3952 /* check if buffer is big enough for the acl
3953 header followed by the smallest SID */
3954 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3955 (*pbuflen >= 64 * 1024)) {
3956 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3960 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3961 if (*acl_inf == NULL) {
3968 free_rsp_buf(buf_type, rsp_iov.iov_base);
3973 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3974 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3976 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3978 int bytes_returned = 0;
3979 SET_SEC_DESC_REQ *pSMB = NULL;
3983 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3987 pSMB->MaxSetupCount = 0;
3991 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3992 data_count = acllen;
3993 data_offset = param_offset + param_count;
3994 byte_count = 3 /* pad */ + param_count;
3996 pSMB->DataCount = cpu_to_le32(data_count);
3997 pSMB->TotalDataCount = pSMB->DataCount;
3998 pSMB->MaxParameterCount = cpu_to_le32(4);
3999 pSMB->MaxDataCount = cpu_to_le32(16384);
4000 pSMB->ParameterCount = cpu_to_le32(param_count);
4001 pSMB->ParameterOffset = cpu_to_le32(param_offset);
4002 pSMB->TotalParameterCount = pSMB->ParameterCount;
4003 pSMB->DataOffset = cpu_to_le32(data_offset);
4004 pSMB->SetupCount = 0;
4005 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
4006 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
4008 pSMB->Fid = fid; /* file handle always le */
4009 pSMB->Reserved2 = 0;
4010 pSMB->AclFlags = cpu_to_le32(aclflag);
4012 if (pntsd && acllen) {
4013 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
4014 data_offset, pntsd, acllen);
4015 inc_rfc1001_len(pSMB, byte_count + data_count);
4017 inc_rfc1001_len(pSMB, byte_count);
4019 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4020 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4022 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4023 bytes_returned, rc);
4025 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
4026 cifs_buf_release(pSMB);
4029 goto setCifsAclRetry;
4035 /* Legacy Query Path Information call for lookup to old servers such
4038 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
4039 const char *search_name, FILE_ALL_INFO *data,
4040 const struct nls_table *nls_codepage, int remap)
4042 QUERY_INFORMATION_REQ *pSMB;
4043 QUERY_INFORMATION_RSP *pSMBr;
4048 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4050 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4055 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4057 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4058 search_name, PATH_MAX, nls_codepage,
4060 name_len++; /* trailing null */
4063 name_len = copy_path_name(pSMB->FileName, search_name);
4065 pSMB->BufferFormat = 0x04;
4066 name_len++; /* account for buffer type byte */
4067 inc_rfc1001_len(pSMB, (__u16)name_len);
4068 pSMB->ByteCount = cpu_to_le16(name_len);
4070 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4071 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4073 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4075 struct timespec64 ts;
4076 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4078 /* decode response */
4079 /* BB FIXME - add time zone adjustment BB */
4080 memset(data, 0, sizeof(FILE_ALL_INFO));
4083 /* decode time fields */
4084 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4085 data->LastWriteTime = data->ChangeTime;
4086 data->LastAccessTime = 0;
4087 data->AllocationSize =
4088 cpu_to_le64(le32_to_cpu(pSMBr->size));
4089 data->EndOfFile = data->AllocationSize;
4091 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4093 rc = -EIO; /* bad buffer passed in */
4095 cifs_buf_release(pSMB);
4104 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4105 u16 netfid, FILE_ALL_INFO *pFindData)
4107 struct smb_t2_qfi_req *pSMB = NULL;
4108 struct smb_t2_qfi_rsp *pSMBr = NULL;
4111 __u16 params, byte_count;
4114 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4119 params = 2 /* level */ + 2 /* fid */;
4120 pSMB->t2.TotalDataCount = 0;
4121 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4122 /* BB find exact max data count below from sess structure BB */
4123 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4124 pSMB->t2.MaxSetupCount = 0;
4125 pSMB->t2.Reserved = 0;
4127 pSMB->t2.Timeout = 0;
4128 pSMB->t2.Reserved2 = 0;
4129 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4131 pSMB->t2.DataCount = 0;
4132 pSMB->t2.DataOffset = 0;
4133 pSMB->t2.SetupCount = 1;
4134 pSMB->t2.Reserved3 = 0;
4135 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4136 byte_count = params + 1 /* pad */ ;
4137 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4138 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4139 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4142 inc_rfc1001_len(pSMB, byte_count);
4143 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4145 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4146 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4148 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
4149 } else { /* decode response */
4150 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4152 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4154 else if (get_bcc(&pSMBr->hdr) < 40)
4155 rc = -EIO; /* bad smb */
4156 else if (pFindData) {
4157 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4158 memcpy((char *) pFindData,
4159 (char *) &pSMBr->hdr.Protocol +
4160 data_offset, sizeof(FILE_ALL_INFO));
4164 cifs_buf_release(pSMB);
4166 goto QFileInfoRetry;
4172 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4173 const char *search_name, FILE_ALL_INFO *data,
4174 int legacy /* old style infolevel */,
4175 const struct nls_table *nls_codepage, int remap)
4177 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4178 TRANSACTION2_QPI_REQ *pSMB = NULL;
4179 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4183 __u16 params, byte_count;
4185 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4187 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4192 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4194 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4195 PATH_MAX, nls_codepage, remap);
4196 name_len++; /* trailing null */
4199 name_len = copy_path_name(pSMB->FileName, search_name);
4202 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4203 pSMB->TotalDataCount = 0;
4204 pSMB->MaxParameterCount = cpu_to_le16(2);
4205 /* BB find exact max SMB PDU from sess structure BB */
4206 pSMB->MaxDataCount = cpu_to_le16(4000);
4207 pSMB->MaxSetupCount = 0;
4211 pSMB->Reserved2 = 0;
4212 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4213 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4214 pSMB->DataCount = 0;
4215 pSMB->DataOffset = 0;
4216 pSMB->SetupCount = 1;
4217 pSMB->Reserved3 = 0;
4218 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4219 byte_count = params + 1 /* pad */ ;
4220 pSMB->TotalParameterCount = cpu_to_le16(params);
4221 pSMB->ParameterCount = pSMB->TotalParameterCount;
4223 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4225 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4226 pSMB->Reserved4 = 0;
4227 inc_rfc1001_len(pSMB, byte_count);
4228 pSMB->ByteCount = cpu_to_le16(byte_count);
4230 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4231 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4233 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4234 } else { /* decode response */
4235 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4237 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4239 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4240 rc = -EIO; /* bad smb */
4241 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4242 rc = -EIO; /* 24 or 26 expected but we do not read
4246 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4249 * On legacy responses we do not read the last field,
4250 * EAsize, fortunately since it varies by subdialect and
4251 * also note it differs on Set vs Get, ie two bytes or 4
4252 * bytes depending but we don't care here.
4255 size = sizeof(FILE_INFO_STANDARD);
4257 size = sizeof(FILE_ALL_INFO);
4258 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4263 cifs_buf_release(pSMB);
4265 goto QPathInfoRetry;
4271 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4272 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4274 struct smb_t2_qfi_req *pSMB = NULL;
4275 struct smb_t2_qfi_rsp *pSMBr = NULL;
4278 __u16 params, byte_count;
4281 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4286 params = 2 /* level */ + 2 /* fid */;
4287 pSMB->t2.TotalDataCount = 0;
4288 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4289 /* BB find exact max data count below from sess structure BB */
4290 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4291 pSMB->t2.MaxSetupCount = 0;
4292 pSMB->t2.Reserved = 0;
4294 pSMB->t2.Timeout = 0;
4295 pSMB->t2.Reserved2 = 0;
4296 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4298 pSMB->t2.DataCount = 0;
4299 pSMB->t2.DataOffset = 0;
4300 pSMB->t2.SetupCount = 1;
4301 pSMB->t2.Reserved3 = 0;
4302 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4303 byte_count = params + 1 /* pad */ ;
4304 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4305 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4306 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4309 inc_rfc1001_len(pSMB, byte_count);
4310 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4312 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4313 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4315 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
4316 } else { /* decode response */
4317 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4319 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4320 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4321 rc = -EIO; /* bad smb */
4323 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4324 memcpy((char *) pFindData,
4325 (char *) &pSMBr->hdr.Protocol +
4327 sizeof(FILE_UNIX_BASIC_INFO));
4331 cifs_buf_release(pSMB);
4333 goto UnixQFileInfoRetry;
4339 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4340 const unsigned char *searchName,
4341 FILE_UNIX_BASIC_INFO *pFindData,
4342 const struct nls_table *nls_codepage, int remap)
4344 /* SMB_QUERY_FILE_UNIX_BASIC */
4345 TRANSACTION2_QPI_REQ *pSMB = NULL;
4346 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4348 int bytes_returned = 0;
4350 __u16 params, byte_count;
4352 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4354 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4359 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4361 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4362 PATH_MAX, nls_codepage, remap);
4363 name_len++; /* trailing null */
4366 name_len = copy_path_name(pSMB->FileName, searchName);
4369 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4370 pSMB->TotalDataCount = 0;
4371 pSMB->MaxParameterCount = cpu_to_le16(2);
4372 /* BB find exact max SMB PDU from sess structure BB */
4373 pSMB->MaxDataCount = cpu_to_le16(4000);
4374 pSMB->MaxSetupCount = 0;
4378 pSMB->Reserved2 = 0;
4379 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4380 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4381 pSMB->DataCount = 0;
4382 pSMB->DataOffset = 0;
4383 pSMB->SetupCount = 1;
4384 pSMB->Reserved3 = 0;
4385 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4386 byte_count = params + 1 /* pad */ ;
4387 pSMB->TotalParameterCount = cpu_to_le16(params);
4388 pSMB->ParameterCount = pSMB->TotalParameterCount;
4389 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4390 pSMB->Reserved4 = 0;
4391 inc_rfc1001_len(pSMB, byte_count);
4392 pSMB->ByteCount = cpu_to_le16(byte_count);
4394 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4395 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4397 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
4398 } else { /* decode response */
4399 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4401 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4402 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4403 rc = -EIO; /* bad smb */
4405 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4406 memcpy((char *) pFindData,
4407 (char *) &pSMBr->hdr.Protocol +
4409 sizeof(FILE_UNIX_BASIC_INFO));
4412 cifs_buf_release(pSMB);
4414 goto UnixQPathInfoRetry;
4419 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4421 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4422 const char *searchName, struct cifs_sb_info *cifs_sb,
4423 __u16 *pnetfid, __u16 search_flags,
4424 struct cifs_search_info *psrch_inf, bool msearch)
4426 /* level 257 SMB_ */
4427 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4428 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4429 T2_FFIRST_RSP_PARMS *parms;
4431 int bytes_returned = 0;
4432 int name_len, remap;
4433 __u16 params, byte_count;
4434 struct nls_table *nls_codepage;
4436 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4439 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4444 nls_codepage = cifs_sb->local_nls;
4445 remap = cifs_remap(cifs_sb);
4447 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4449 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4450 PATH_MAX, nls_codepage, remap);
4451 /* We can not add the asterik earlier in case
4452 it got remapped to 0xF03A as if it were part of the
4453 directory name instead of a wildcard */
4456 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4457 pSMB->FileName[name_len+1] = 0;
4458 pSMB->FileName[name_len+2] = '*';
4459 pSMB->FileName[name_len+3] = 0;
4460 name_len += 4; /* now the trailing null */
4461 /* null terminate just in case */
4462 pSMB->FileName[name_len] = 0;
4463 pSMB->FileName[name_len+1] = 0;
4467 name_len = copy_path_name(pSMB->FileName, searchName);
4469 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4470 name_len = PATH_MAX-2;
4471 /* overwrite nul byte */
4472 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4473 pSMB->FileName[name_len] = '*';
4474 pSMB->FileName[name_len+1] = 0;
4479 params = 12 + name_len /* includes null */ ;
4480 pSMB->TotalDataCount = 0; /* no EAs */
4481 pSMB->MaxParameterCount = cpu_to_le16(10);
4482 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4483 pSMB->MaxSetupCount = 0;
4487 pSMB->Reserved2 = 0;
4488 byte_count = params + 1 /* pad */ ;
4489 pSMB->TotalParameterCount = cpu_to_le16(params);
4490 pSMB->ParameterCount = pSMB->TotalParameterCount;
4491 pSMB->ParameterOffset = cpu_to_le16(
4492 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4494 pSMB->DataCount = 0;
4495 pSMB->DataOffset = 0;
4496 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4497 pSMB->Reserved3 = 0;
4498 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4499 pSMB->SearchAttributes =
4500 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4502 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4503 pSMB->SearchFlags = cpu_to_le16(search_flags);
4504 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4506 /* BB what should we set StorageType to? Does it matter? BB */
4507 pSMB->SearchStorageType = 0;
4508 inc_rfc1001_len(pSMB, byte_count);
4509 pSMB->ByteCount = cpu_to_le16(byte_count);
4511 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4512 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4513 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4515 if (rc) {/* BB add logic to retry regular search if Unix search
4516 rejected unexpectedly by server */
4517 /* BB Add code to handle unsupported level rc */
4518 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4520 cifs_buf_release(pSMB);
4522 /* BB eventually could optimize out free and realloc of buf */
4525 goto findFirstRetry;
4526 } else { /* decode response */
4527 /* BB remember to free buffer if error BB */
4528 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4532 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4533 psrch_inf->unicode = true;
4535 psrch_inf->unicode = false;
4537 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4538 psrch_inf->smallBuf = false;
4539 psrch_inf->srch_entries_start =
4540 (char *) &pSMBr->hdr.Protocol +
4541 le16_to_cpu(pSMBr->t2.DataOffset);
4542 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4543 le16_to_cpu(pSMBr->t2.ParameterOffset));
4545 if (parms->EndofSearch)
4546 psrch_inf->endOfSearch = true;
4548 psrch_inf->endOfSearch = false;
4550 psrch_inf->entries_in_buffer =
4551 le16_to_cpu(parms->SearchCount);
4552 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4553 psrch_inf->entries_in_buffer;
4554 lnoff = le16_to_cpu(parms->LastNameOffset);
4555 if (CIFSMaxBufSize < lnoff) {
4556 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4557 psrch_inf->last_entry = NULL;
4561 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4565 *pnetfid = parms->SearchHandle;
4567 cifs_buf_release(pSMB);
4574 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4575 __u16 searchHandle, __u16 search_flags,
4576 struct cifs_search_info *psrch_inf)
4578 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4579 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4580 T2_FNEXT_RSP_PARMS *parms;
4581 char *response_data;
4584 unsigned int name_len;
4585 __u16 params, byte_count;
4587 cifs_dbg(FYI, "In FindNext\n");
4589 if (psrch_inf->endOfSearch)
4592 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4597 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4599 pSMB->TotalDataCount = 0; /* no EAs */
4600 pSMB->MaxParameterCount = cpu_to_le16(8);
4601 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4602 pSMB->MaxSetupCount = 0;
4606 pSMB->Reserved2 = 0;
4607 pSMB->ParameterOffset = cpu_to_le16(
4608 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4609 pSMB->DataCount = 0;
4610 pSMB->DataOffset = 0;
4611 pSMB->SetupCount = 1;
4612 pSMB->Reserved3 = 0;
4613 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4614 pSMB->SearchHandle = searchHandle; /* always kept as le */
4616 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4617 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4618 pSMB->ResumeKey = psrch_inf->resume_key;
4619 pSMB->SearchFlags = cpu_to_le16(search_flags);
4621 name_len = psrch_inf->resume_name_len;
4623 if (name_len < PATH_MAX) {
4624 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4625 byte_count += name_len;
4626 /* 14 byte parm len above enough for 2 byte null terminator */
4627 pSMB->ResumeFileName[name_len] = 0;
4628 pSMB->ResumeFileName[name_len+1] = 0;
4631 goto FNext2_err_exit;
4633 byte_count = params + 1 /* pad */ ;
4634 pSMB->TotalParameterCount = cpu_to_le16(params);
4635 pSMB->ParameterCount = pSMB->TotalParameterCount;
4636 inc_rfc1001_len(pSMB, byte_count);
4637 pSMB->ByteCount = cpu_to_le16(byte_count);
4639 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4640 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4641 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4644 psrch_inf->endOfSearch = true;
4645 cifs_buf_release(pSMB);
4646 rc = 0; /* search probably was closed at end of search*/
4648 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4649 } else { /* decode response */
4650 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4655 /* BB fixme add lock for file (srch_info) struct here */
4656 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4657 psrch_inf->unicode = true;
4659 psrch_inf->unicode = false;
4660 response_data = (char *) &pSMBr->hdr.Protocol +
4661 le16_to_cpu(pSMBr->t2.ParameterOffset);
4662 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4663 response_data = (char *)&pSMBr->hdr.Protocol +
4664 le16_to_cpu(pSMBr->t2.DataOffset);
4665 if (psrch_inf->smallBuf)
4666 cifs_small_buf_release(
4667 psrch_inf->ntwrk_buf_start);
4669 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4670 psrch_inf->srch_entries_start = response_data;
4671 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4672 psrch_inf->smallBuf = false;
4673 if (parms->EndofSearch)
4674 psrch_inf->endOfSearch = true;
4676 psrch_inf->endOfSearch = false;
4677 psrch_inf->entries_in_buffer =
4678 le16_to_cpu(parms->SearchCount);
4679 psrch_inf->index_of_last_entry +=
4680 psrch_inf->entries_in_buffer;
4681 lnoff = le16_to_cpu(parms->LastNameOffset);
4682 if (CIFSMaxBufSize < lnoff) {
4683 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4684 psrch_inf->last_entry = NULL;
4687 psrch_inf->last_entry =
4688 psrch_inf->srch_entries_start + lnoff;
4690 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4691 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4693 /* BB fixme add unlock here */
4698 /* BB On error, should we leave previous search buf (and count and
4699 last entry fields) intact or free the previous one? */
4701 /* Note: On -EAGAIN error only caller can retry on handle based calls
4702 since file handle passed in no longer valid */
4705 cifs_buf_release(pSMB);
4710 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4711 const __u16 searchHandle)
4714 FINDCLOSE_REQ *pSMB = NULL;
4716 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4717 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4719 /* no sense returning error if session restarted
4720 as file handle has been closed */
4726 pSMB->FileID = searchHandle;
4727 pSMB->ByteCount = 0;
4728 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4729 cifs_small_buf_release(pSMB);
4731 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4733 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4735 /* Since session is dead, search handle closed on server already */
4743 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4744 const char *search_name, __u64 *inode_number,
4745 const struct nls_table *nls_codepage, int remap)
4748 TRANSACTION2_QPI_REQ *pSMB = NULL;
4749 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4750 int name_len, bytes_returned;
4751 __u16 params, byte_count;
4753 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4757 GetInodeNumberRetry:
4758 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4763 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4765 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4766 search_name, PATH_MAX, nls_codepage,
4768 name_len++; /* trailing null */
4771 name_len = copy_path_name(pSMB->FileName, search_name);
4774 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4775 pSMB->TotalDataCount = 0;
4776 pSMB->MaxParameterCount = cpu_to_le16(2);
4777 /* BB find exact max data count below from sess structure BB */
4778 pSMB->MaxDataCount = cpu_to_le16(4000);
4779 pSMB->MaxSetupCount = 0;
4783 pSMB->Reserved2 = 0;
4784 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4785 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4786 pSMB->DataCount = 0;
4787 pSMB->DataOffset = 0;
4788 pSMB->SetupCount = 1;
4789 pSMB->Reserved3 = 0;
4790 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4791 byte_count = params + 1 /* pad */ ;
4792 pSMB->TotalParameterCount = cpu_to_le16(params);
4793 pSMB->ParameterCount = pSMB->TotalParameterCount;
4794 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4795 pSMB->Reserved4 = 0;
4796 inc_rfc1001_len(pSMB, byte_count);
4797 pSMB->ByteCount = cpu_to_le16(byte_count);
4799 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4800 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4802 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4804 /* decode response */
4805 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4806 /* BB also check enough total bytes returned */
4807 if (rc || get_bcc(&pSMBr->hdr) < 2)
4808 /* If rc should we check for EOPNOSUPP and
4809 disable the srvino flag? or in caller? */
4810 rc = -EIO; /* bad smb */
4812 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4813 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4814 struct file_internal_info *pfinfo;
4815 /* BB Do we need a cast or hash here ? */
4817 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4819 goto GetInodeNumOut;
4821 pfinfo = (struct file_internal_info *)
4822 (data_offset + (char *) &pSMBr->hdr.Protocol);
4823 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4827 cifs_buf_release(pSMB);
4829 goto GetInodeNumberRetry;
4834 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4835 const char *search_name, struct dfs_info3_param **target_nodes,
4836 unsigned int *num_of_nodes,
4837 const struct nls_table *nls_codepage, int remap)
4839 /* TRANS2_GET_DFS_REFERRAL */
4840 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4841 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4845 __u16 params, byte_count;
4847 *target_nodes = NULL;
4849 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4850 if (ses == NULL || ses->tcon_ipc == NULL)
4854 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4859 /* server pointer checked in called function,
4860 but should never be null here anyway */
4861 pSMB->hdr.Mid = get_next_mid(ses->server);
4862 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4863 pSMB->hdr.Uid = ses->Suid;
4864 if (ses->capabilities & CAP_STATUS32)
4865 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4866 if (ses->capabilities & CAP_DFS)
4867 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4869 if (ses->capabilities & CAP_UNICODE) {
4870 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4872 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4873 search_name, PATH_MAX, nls_codepage,
4875 name_len++; /* trailing null */
4877 } else { /* BB improve the check for buffer overruns BB */
4878 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4881 if (ses->server->sign)
4882 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4884 pSMB->hdr.Uid = ses->Suid;
4886 params = 2 /* level */ + name_len /*includes null */ ;
4887 pSMB->TotalDataCount = 0;
4888 pSMB->DataCount = 0;
4889 pSMB->DataOffset = 0;
4890 pSMB->MaxParameterCount = 0;
4891 /* BB find exact max SMB PDU from sess structure BB */
4892 pSMB->MaxDataCount = cpu_to_le16(4000);
4893 pSMB->MaxSetupCount = 0;
4897 pSMB->Reserved2 = 0;
4898 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4899 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4900 pSMB->SetupCount = 1;
4901 pSMB->Reserved3 = 0;
4902 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4903 byte_count = params + 3 /* pad */ ;
4904 pSMB->ParameterCount = cpu_to_le16(params);
4905 pSMB->TotalParameterCount = pSMB->ParameterCount;
4906 pSMB->MaxReferralLevel = cpu_to_le16(3);
4907 inc_rfc1001_len(pSMB, byte_count);
4908 pSMB->ByteCount = cpu_to_le16(byte_count);
4910 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4911 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4913 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4916 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4918 /* BB Also check if enough total bytes returned? */
4919 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4920 rc = -EIO; /* bad smb */
4924 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4925 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4927 /* parse returned result into more usable form */
4928 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4929 le16_to_cpu(pSMBr->t2.DataCount),
4930 num_of_nodes, target_nodes, nls_codepage,
4932 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4935 cifs_buf_release(pSMB);
4943 /* Query File System Info such as free space to old servers such as Win 9x */
4945 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4946 struct kstatfs *FSData)
4948 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4949 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4950 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4951 FILE_SYSTEM_ALLOC_INFO *response_data;
4953 int bytes_returned = 0;
4954 __u16 params, byte_count;
4956 cifs_dbg(FYI, "OldQFSInfo\n");
4958 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4963 params = 2; /* level */
4964 pSMB->TotalDataCount = 0;
4965 pSMB->MaxParameterCount = cpu_to_le16(2);
4966 pSMB->MaxDataCount = cpu_to_le16(1000);
4967 pSMB->MaxSetupCount = 0;
4971 pSMB->Reserved2 = 0;
4972 byte_count = params + 1 /* pad */ ;
4973 pSMB->TotalParameterCount = cpu_to_le16(params);
4974 pSMB->ParameterCount = pSMB->TotalParameterCount;
4975 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4976 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4977 pSMB->DataCount = 0;
4978 pSMB->DataOffset = 0;
4979 pSMB->SetupCount = 1;
4980 pSMB->Reserved3 = 0;
4981 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4982 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4983 inc_rfc1001_len(pSMB, byte_count);
4984 pSMB->ByteCount = cpu_to_le16(byte_count);
4986 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4987 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4989 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4990 } else { /* decode response */
4991 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4993 if (rc || get_bcc(&pSMBr->hdr) < 18)
4994 rc = -EIO; /* bad smb */
4996 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4997 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4998 get_bcc(&pSMBr->hdr), data_offset);
5000 response_data = (FILE_SYSTEM_ALLOC_INFO *)
5001 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5003 le16_to_cpu(response_data->BytesPerSector) *
5004 le32_to_cpu(response_data->
5005 SectorsPerAllocationUnit);
5007 * much prefer larger but if server doesn't report
5008 * a valid size than 4K is a reasonable minimum
5010 if (FSData->f_bsize < 512)
5011 FSData->f_bsize = 4096;
5014 le32_to_cpu(response_data->TotalAllocationUnits);
5015 FSData->f_bfree = FSData->f_bavail =
5016 le32_to_cpu(response_data->FreeAllocationUnits);
5017 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5018 (unsigned long long)FSData->f_blocks,
5019 (unsigned long long)FSData->f_bfree,
5023 cifs_buf_release(pSMB);
5026 goto oldQFSInfoRetry;
5032 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
5033 struct kstatfs *FSData)
5035 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5036 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5037 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5038 FILE_SYSTEM_INFO *response_data;
5040 int bytes_returned = 0;
5041 __u16 params, byte_count;
5043 cifs_dbg(FYI, "In QFSInfo\n");
5045 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5050 params = 2; /* level */
5051 pSMB->TotalDataCount = 0;
5052 pSMB->MaxParameterCount = cpu_to_le16(2);
5053 pSMB->MaxDataCount = cpu_to_le16(1000);
5054 pSMB->MaxSetupCount = 0;
5058 pSMB->Reserved2 = 0;
5059 byte_count = params + 1 /* pad */ ;
5060 pSMB->TotalParameterCount = cpu_to_le16(params);
5061 pSMB->ParameterCount = pSMB->TotalParameterCount;
5062 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5063 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5064 pSMB->DataCount = 0;
5065 pSMB->DataOffset = 0;
5066 pSMB->SetupCount = 1;
5067 pSMB->Reserved3 = 0;
5068 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5069 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5070 inc_rfc1001_len(pSMB, byte_count);
5071 pSMB->ByteCount = cpu_to_le16(byte_count);
5073 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5074 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5076 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5077 } else { /* decode response */
5078 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5080 if (rc || get_bcc(&pSMBr->hdr) < 24)
5081 rc = -EIO; /* bad smb */
5083 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5087 *) (((char *) &pSMBr->hdr.Protocol) +
5090 le32_to_cpu(response_data->BytesPerSector) *
5091 le32_to_cpu(response_data->
5092 SectorsPerAllocationUnit);
5094 * much prefer larger but if server doesn't report
5095 * a valid size than 4K is a reasonable minimum
5097 if (FSData->f_bsize < 512)
5098 FSData->f_bsize = 4096;
5101 le64_to_cpu(response_data->TotalAllocationUnits);
5102 FSData->f_bfree = FSData->f_bavail =
5103 le64_to_cpu(response_data->FreeAllocationUnits);
5104 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5105 (unsigned long long)FSData->f_blocks,
5106 (unsigned long long)FSData->f_bfree,
5110 cifs_buf_release(pSMB);
5119 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5121 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5122 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5123 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5124 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5126 int bytes_returned = 0;
5127 __u16 params, byte_count;
5129 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5131 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5136 params = 2; /* level */
5137 pSMB->TotalDataCount = 0;
5138 pSMB->MaxParameterCount = cpu_to_le16(2);
5139 /* BB find exact max SMB PDU from sess structure BB */
5140 pSMB->MaxDataCount = cpu_to_le16(1000);
5141 pSMB->MaxSetupCount = 0;
5145 pSMB->Reserved2 = 0;
5146 byte_count = params + 1 /* pad */ ;
5147 pSMB->TotalParameterCount = cpu_to_le16(params);
5148 pSMB->ParameterCount = pSMB->TotalParameterCount;
5149 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5150 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5151 pSMB->DataCount = 0;
5152 pSMB->DataOffset = 0;
5153 pSMB->SetupCount = 1;
5154 pSMB->Reserved3 = 0;
5155 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5156 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5157 inc_rfc1001_len(pSMB, byte_count);
5158 pSMB->ByteCount = cpu_to_le16(byte_count);
5160 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5161 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5163 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5164 } else { /* decode response */
5165 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5167 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5168 /* BB also check if enough bytes returned */
5169 rc = -EIO; /* bad smb */
5171 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5173 (FILE_SYSTEM_ATTRIBUTE_INFO
5174 *) (((char *) &pSMBr->hdr.Protocol) +
5176 memcpy(&tcon->fsAttrInfo, response_data,
5177 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5180 cifs_buf_release(pSMB);
5183 goto QFSAttributeRetry;
5189 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5191 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5192 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5193 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5194 FILE_SYSTEM_DEVICE_INFO *response_data;
5196 int bytes_returned = 0;
5197 __u16 params, byte_count;
5199 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5201 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5206 params = 2; /* level */
5207 pSMB->TotalDataCount = 0;
5208 pSMB->MaxParameterCount = cpu_to_le16(2);
5209 /* BB find exact max SMB PDU from sess structure BB */
5210 pSMB->MaxDataCount = cpu_to_le16(1000);
5211 pSMB->MaxSetupCount = 0;
5215 pSMB->Reserved2 = 0;
5216 byte_count = params + 1 /* pad */ ;
5217 pSMB->TotalParameterCount = cpu_to_le16(params);
5218 pSMB->ParameterCount = pSMB->TotalParameterCount;
5219 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5220 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5222 pSMB->DataCount = 0;
5223 pSMB->DataOffset = 0;
5224 pSMB->SetupCount = 1;
5225 pSMB->Reserved3 = 0;
5226 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5227 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5228 inc_rfc1001_len(pSMB, byte_count);
5229 pSMB->ByteCount = cpu_to_le16(byte_count);
5231 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5232 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5234 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5235 } else { /* decode response */
5236 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5238 if (rc || get_bcc(&pSMBr->hdr) <
5239 sizeof(FILE_SYSTEM_DEVICE_INFO))
5240 rc = -EIO; /* bad smb */
5242 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5244 (FILE_SYSTEM_DEVICE_INFO *)
5245 (((char *) &pSMBr->hdr.Protocol) +
5247 memcpy(&tcon->fsDevInfo, response_data,
5248 sizeof(FILE_SYSTEM_DEVICE_INFO));
5251 cifs_buf_release(pSMB);
5254 goto QFSDeviceRetry;
5260 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5262 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5263 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5264 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5265 FILE_SYSTEM_UNIX_INFO *response_data;
5267 int bytes_returned = 0;
5268 __u16 params, byte_count;
5270 cifs_dbg(FYI, "In QFSUnixInfo\n");
5272 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5273 (void **) &pSMB, (void **) &pSMBr);
5277 params = 2; /* level */
5278 pSMB->TotalDataCount = 0;
5279 pSMB->DataCount = 0;
5280 pSMB->DataOffset = 0;
5281 pSMB->MaxParameterCount = cpu_to_le16(2);
5282 /* BB find exact max SMB PDU from sess structure BB */
5283 pSMB->MaxDataCount = cpu_to_le16(100);
5284 pSMB->MaxSetupCount = 0;
5288 pSMB->Reserved2 = 0;
5289 byte_count = params + 1 /* pad */ ;
5290 pSMB->ParameterCount = cpu_to_le16(params);
5291 pSMB->TotalParameterCount = pSMB->ParameterCount;
5292 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5293 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5294 pSMB->SetupCount = 1;
5295 pSMB->Reserved3 = 0;
5296 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5297 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5298 inc_rfc1001_len(pSMB, byte_count);
5299 pSMB->ByteCount = cpu_to_le16(byte_count);
5301 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5302 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5304 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5305 } else { /* decode response */
5306 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5308 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5309 rc = -EIO; /* bad smb */
5311 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5313 (FILE_SYSTEM_UNIX_INFO
5314 *) (((char *) &pSMBr->hdr.Protocol) +
5316 memcpy(&tcon->fsUnixInfo, response_data,
5317 sizeof(FILE_SYSTEM_UNIX_INFO));
5320 cifs_buf_release(pSMB);
5330 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5332 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5333 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5334 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5336 int bytes_returned = 0;
5337 __u16 params, param_offset, offset, byte_count;
5339 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5341 /* BB switch to small buf init to save memory */
5342 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5343 (void **) &pSMB, (void **) &pSMBr);
5347 params = 4; /* 2 bytes zero followed by info level. */
5348 pSMB->MaxSetupCount = 0;
5352 pSMB->Reserved2 = 0;
5353 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5355 offset = param_offset + params;
5357 pSMB->MaxParameterCount = cpu_to_le16(4);
5358 /* BB find exact max SMB PDU from sess structure BB */
5359 pSMB->MaxDataCount = cpu_to_le16(100);
5360 pSMB->SetupCount = 1;
5361 pSMB->Reserved3 = 0;
5362 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5363 byte_count = 1 /* pad */ + params + 12;
5365 pSMB->DataCount = cpu_to_le16(12);
5366 pSMB->ParameterCount = cpu_to_le16(params);
5367 pSMB->TotalDataCount = pSMB->DataCount;
5368 pSMB->TotalParameterCount = pSMB->ParameterCount;
5369 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5370 pSMB->DataOffset = cpu_to_le16(offset);
5374 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5377 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5378 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5379 pSMB->ClientUnixCap = cpu_to_le64(cap);
5381 inc_rfc1001_len(pSMB, byte_count);
5382 pSMB->ByteCount = cpu_to_le16(byte_count);
5384 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5385 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5387 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5388 } else { /* decode response */
5389 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5391 rc = -EIO; /* bad smb */
5393 cifs_buf_release(pSMB);
5396 goto SETFSUnixRetry;
5404 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5405 struct kstatfs *FSData)
5407 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5408 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5409 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5410 FILE_SYSTEM_POSIX_INFO *response_data;
5412 int bytes_returned = 0;
5413 __u16 params, byte_count;
5415 cifs_dbg(FYI, "In QFSPosixInfo\n");
5417 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5422 params = 2; /* level */
5423 pSMB->TotalDataCount = 0;
5424 pSMB->DataCount = 0;
5425 pSMB->DataOffset = 0;
5426 pSMB->MaxParameterCount = cpu_to_le16(2);
5427 /* BB find exact max SMB PDU from sess structure BB */
5428 pSMB->MaxDataCount = cpu_to_le16(100);
5429 pSMB->MaxSetupCount = 0;
5433 pSMB->Reserved2 = 0;
5434 byte_count = params + 1 /* pad */ ;
5435 pSMB->ParameterCount = cpu_to_le16(params);
5436 pSMB->TotalParameterCount = pSMB->ParameterCount;
5437 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5438 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5439 pSMB->SetupCount = 1;
5440 pSMB->Reserved3 = 0;
5441 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5442 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5443 inc_rfc1001_len(pSMB, byte_count);
5444 pSMB->ByteCount = cpu_to_le16(byte_count);
5446 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5447 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5449 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5450 } else { /* decode response */
5451 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5453 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5454 rc = -EIO; /* bad smb */
5456 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5458 (FILE_SYSTEM_POSIX_INFO
5459 *) (((char *) &pSMBr->hdr.Protocol) +
5462 le32_to_cpu(response_data->BlockSize);
5464 * much prefer larger but if server doesn't report
5465 * a valid size than 4K is a reasonable minimum
5467 if (FSData->f_bsize < 512)
5468 FSData->f_bsize = 4096;
5471 le64_to_cpu(response_data->TotalBlocks);
5473 le64_to_cpu(response_data->BlocksAvail);
5474 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5475 FSData->f_bavail = FSData->f_bfree;
5478 le64_to_cpu(response_data->UserBlocksAvail);
5480 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5482 le64_to_cpu(response_data->TotalFileNodes);
5483 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5485 le64_to_cpu(response_data->FreeFileNodes);
5488 cifs_buf_release(pSMB);
5498 * We can not use write of zero bytes trick to set file size due to need for
5499 * large file support. Also note that this SetPathInfo is preferred to
5500 * SetFileInfo based method in next routine which is only needed to work around
5501 * a sharing violation bugin Samba which this routine can run into.
5504 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5505 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5506 bool set_allocation)
5508 struct smb_com_transaction2_spi_req *pSMB = NULL;
5509 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5510 struct file_end_of_file_info *parm_data;
5513 int bytes_returned = 0;
5514 int remap = cifs_remap(cifs_sb);
5516 __u16 params, byte_count, data_count, param_offset, offset;
5518 cifs_dbg(FYI, "In SetEOF\n");
5520 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5525 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5527 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5528 PATH_MAX, cifs_sb->local_nls, remap);
5529 name_len++; /* trailing null */
5532 name_len = copy_path_name(pSMB->FileName, file_name);
5534 params = 6 + name_len;
5535 data_count = sizeof(struct file_end_of_file_info);
5536 pSMB->MaxParameterCount = cpu_to_le16(2);
5537 pSMB->MaxDataCount = cpu_to_le16(4100);
5538 pSMB->MaxSetupCount = 0;
5542 pSMB->Reserved2 = 0;
5543 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5544 InformationLevel) - 4;
5545 offset = param_offset + params;
5546 if (set_allocation) {
5547 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5548 pSMB->InformationLevel =
5549 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5551 pSMB->InformationLevel =
5552 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5553 } else /* Set File Size */ {
5554 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5555 pSMB->InformationLevel =
5556 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5558 pSMB->InformationLevel =
5559 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5563 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5565 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5566 pSMB->DataOffset = cpu_to_le16(offset);
5567 pSMB->SetupCount = 1;
5568 pSMB->Reserved3 = 0;
5569 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5570 byte_count = 3 /* pad */ + params + data_count;
5571 pSMB->DataCount = cpu_to_le16(data_count);
5572 pSMB->TotalDataCount = pSMB->DataCount;
5573 pSMB->ParameterCount = cpu_to_le16(params);
5574 pSMB->TotalParameterCount = pSMB->ParameterCount;
5575 pSMB->Reserved4 = 0;
5576 inc_rfc1001_len(pSMB, byte_count);
5577 parm_data->FileSize = cpu_to_le64(size);
5578 pSMB->ByteCount = cpu_to_le16(byte_count);
5579 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5580 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5582 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5584 cifs_buf_release(pSMB);
5593 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5594 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5596 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5597 struct file_end_of_file_info *parm_data;
5599 __u16 params, param_offset, offset, byte_count, count;
5601 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5603 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5608 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5609 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5612 pSMB->MaxSetupCount = 0;
5616 pSMB->Reserved2 = 0;
5617 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5618 offset = param_offset + params;
5620 count = sizeof(struct file_end_of_file_info);
5621 pSMB->MaxParameterCount = cpu_to_le16(2);
5622 /* BB find exact max SMB PDU from sess structure BB */
5623 pSMB->MaxDataCount = cpu_to_le16(1000);
5624 pSMB->SetupCount = 1;
5625 pSMB->Reserved3 = 0;
5626 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5627 byte_count = 3 /* pad */ + params + count;
5628 pSMB->DataCount = cpu_to_le16(count);
5629 pSMB->ParameterCount = cpu_to_le16(params);
5630 pSMB->TotalDataCount = pSMB->DataCount;
5631 pSMB->TotalParameterCount = pSMB->ParameterCount;
5632 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5633 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5635 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5636 pSMB->DataOffset = cpu_to_le16(offset);
5637 parm_data->FileSize = cpu_to_le64(size);
5638 pSMB->Fid = cfile->fid.netfid;
5639 if (set_allocation) {
5640 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5641 pSMB->InformationLevel =
5642 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5644 pSMB->InformationLevel =
5645 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5646 } else /* Set File Size */ {
5647 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5648 pSMB->InformationLevel =
5649 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5651 pSMB->InformationLevel =
5652 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5654 pSMB->Reserved4 = 0;
5655 inc_rfc1001_len(pSMB, byte_count);
5656 pSMB->ByteCount = cpu_to_le16(byte_count);
5657 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5658 cifs_small_buf_release(pSMB);
5660 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5664 /* Note: On -EAGAIN error only caller can retry on handle based calls
5665 since file handle passed in no longer valid */
5670 /* Some legacy servers such as NT4 require that the file times be set on
5671 an open handle, rather than by pathname - this is awkward due to
5672 potential access conflicts on the open, but it is unavoidable for these
5673 old servers since the only other choice is to go from 100 nanosecond DCE
5674 time and resort to the original setpathinfo level which takes the ancient
5675 DOS time format with 2 second granularity */
5677 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5678 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5680 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5683 __u16 params, param_offset, offset, byte_count, count;
5685 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5686 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5691 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5692 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5695 pSMB->MaxSetupCount = 0;
5699 pSMB->Reserved2 = 0;
5700 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5701 offset = param_offset + params;
5703 data_offset = (char *)pSMB +
5704 offsetof(struct smb_hdr, Protocol) + offset;
5706 count = sizeof(FILE_BASIC_INFO);
5707 pSMB->MaxParameterCount = cpu_to_le16(2);
5708 /* BB find max SMB PDU from sess */
5709 pSMB->MaxDataCount = cpu_to_le16(1000);
5710 pSMB->SetupCount = 1;
5711 pSMB->Reserved3 = 0;
5712 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5713 byte_count = 3 /* pad */ + params + count;
5714 pSMB->DataCount = cpu_to_le16(count);
5715 pSMB->ParameterCount = cpu_to_le16(params);
5716 pSMB->TotalDataCount = pSMB->DataCount;
5717 pSMB->TotalParameterCount = pSMB->ParameterCount;
5718 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5719 pSMB->DataOffset = cpu_to_le16(offset);
5721 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5722 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5724 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5725 pSMB->Reserved4 = 0;
5726 inc_rfc1001_len(pSMB, byte_count);
5727 pSMB->ByteCount = cpu_to_le16(byte_count);
5728 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5729 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5730 cifs_small_buf_release(pSMB);
5732 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5735 /* Note: On -EAGAIN error only caller can retry on handle based calls
5736 since file handle passed in no longer valid */
5742 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5743 bool delete_file, __u16 fid, __u32 pid_of_opener)
5745 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5748 __u16 params, param_offset, offset, byte_count, count;
5750 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5751 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5756 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5757 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5760 pSMB->MaxSetupCount = 0;
5764 pSMB->Reserved2 = 0;
5765 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5766 offset = param_offset + params;
5768 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5769 data_offset = (char *)(pSMB) + offset + 4;
5772 pSMB->MaxParameterCount = cpu_to_le16(2);
5773 /* BB find max SMB PDU from sess */
5774 pSMB->MaxDataCount = cpu_to_le16(1000);
5775 pSMB->SetupCount = 1;
5776 pSMB->Reserved3 = 0;
5777 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5778 byte_count = 3 /* pad */ + params + count;
5779 pSMB->DataCount = cpu_to_le16(count);
5780 pSMB->ParameterCount = cpu_to_le16(params);
5781 pSMB->TotalDataCount = pSMB->DataCount;
5782 pSMB->TotalParameterCount = pSMB->ParameterCount;
5783 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5784 pSMB->DataOffset = cpu_to_le16(offset);
5786 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5787 pSMB->Reserved4 = 0;
5788 inc_rfc1001_len(pSMB, byte_count);
5789 pSMB->ByteCount = cpu_to_le16(byte_count);
5790 *data_offset = delete_file ? 1 : 0;
5791 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5792 cifs_small_buf_release(pSMB);
5794 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5800 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5801 const char *fileName, const FILE_BASIC_INFO *data,
5802 const struct nls_table *nls_codepage,
5803 struct cifs_sb_info *cifs_sb)
5806 struct cifs_open_parms oparms;
5807 struct cifs_fid fid;
5811 oparms.cifs_sb = cifs_sb;
5812 oparms.desired_access = GENERIC_WRITE;
5813 oparms.create_options = cifs_create_options(cifs_sb, 0);
5814 oparms.disposition = FILE_OPEN;
5815 oparms.path = fileName;
5817 oparms.reconnect = false;
5819 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5823 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5824 CIFSSMBClose(xid, tcon, fid.netfid);
5831 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5832 const char *fileName, const FILE_BASIC_INFO *data,
5833 const struct nls_table *nls_codepage,
5834 struct cifs_sb_info *cifs_sb)
5836 TRANSACTION2_SPI_REQ *pSMB = NULL;
5837 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5840 int bytes_returned = 0;
5842 __u16 params, param_offset, offset, byte_count, count;
5843 int remap = cifs_remap(cifs_sb);
5845 cifs_dbg(FYI, "In SetTimes\n");
5848 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5853 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5855 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5856 PATH_MAX, nls_codepage, remap);
5857 name_len++; /* trailing null */
5860 name_len = copy_path_name(pSMB->FileName, fileName);
5863 params = 6 + name_len;
5864 count = sizeof(FILE_BASIC_INFO);
5865 pSMB->MaxParameterCount = cpu_to_le16(2);
5866 /* BB find max SMB PDU from sess structure BB */
5867 pSMB->MaxDataCount = cpu_to_le16(1000);
5868 pSMB->MaxSetupCount = 0;
5872 pSMB->Reserved2 = 0;
5873 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5874 InformationLevel) - 4;
5875 offset = param_offset + params;
5876 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5877 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5878 pSMB->DataOffset = cpu_to_le16(offset);
5879 pSMB->SetupCount = 1;
5880 pSMB->Reserved3 = 0;
5881 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5882 byte_count = 3 /* pad */ + params + count;
5884 pSMB->DataCount = cpu_to_le16(count);
5885 pSMB->ParameterCount = cpu_to_le16(params);
5886 pSMB->TotalDataCount = pSMB->DataCount;
5887 pSMB->TotalParameterCount = pSMB->ParameterCount;
5888 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5889 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5891 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5892 pSMB->Reserved4 = 0;
5893 inc_rfc1001_len(pSMB, byte_count);
5894 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5895 pSMB->ByteCount = cpu_to_le16(byte_count);
5896 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5897 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5899 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5901 cifs_buf_release(pSMB);
5906 if (rc == -EOPNOTSUPP)
5907 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5908 nls_codepage, cifs_sb);
5914 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5915 const struct cifs_unix_set_info_args *args)
5917 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5918 u64 mode = args->mode;
5920 if (uid_valid(args->uid))
5921 uid = from_kuid(&init_user_ns, args->uid);
5922 if (gid_valid(args->gid))
5923 gid = from_kgid(&init_user_ns, args->gid);
5926 * Samba server ignores set of file size to zero due to bugs in some
5927 * older clients, but we should be precise - we use SetFileSize to
5928 * set file size and do not want to truncate file size to zero
5929 * accidentally as happened on one Samba server beta by putting
5930 * zero instead of -1 here
5932 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5933 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5934 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5935 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5936 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5937 data_offset->Uid = cpu_to_le64(uid);
5938 data_offset->Gid = cpu_to_le64(gid);
5939 /* better to leave device as zero when it is */
5940 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5941 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5942 data_offset->Permissions = cpu_to_le64(mode);
5945 data_offset->Type = cpu_to_le32(UNIX_FILE);
5946 else if (S_ISDIR(mode))
5947 data_offset->Type = cpu_to_le32(UNIX_DIR);
5948 else if (S_ISLNK(mode))
5949 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5950 else if (S_ISCHR(mode))
5951 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5952 else if (S_ISBLK(mode))
5953 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5954 else if (S_ISFIFO(mode))
5955 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5956 else if (S_ISSOCK(mode))
5957 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5961 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5962 const struct cifs_unix_set_info_args *args,
5963 u16 fid, u32 pid_of_opener)
5965 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5968 u16 params, param_offset, offset, byte_count, count;
5970 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5971 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5976 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5977 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5980 pSMB->MaxSetupCount = 0;
5984 pSMB->Reserved2 = 0;
5985 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5986 offset = param_offset + params;
5988 data_offset = (char *)pSMB +
5989 offsetof(struct smb_hdr, Protocol) + offset;
5991 count = sizeof(FILE_UNIX_BASIC_INFO);
5993 pSMB->MaxParameterCount = cpu_to_le16(2);
5994 /* BB find max SMB PDU from sess */
5995 pSMB->MaxDataCount = cpu_to_le16(1000);
5996 pSMB->SetupCount = 1;
5997 pSMB->Reserved3 = 0;
5998 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5999 byte_count = 3 /* pad */ + params + count;
6000 pSMB->DataCount = cpu_to_le16(count);
6001 pSMB->ParameterCount = cpu_to_le16(params);
6002 pSMB->TotalDataCount = pSMB->DataCount;
6003 pSMB->TotalParameterCount = pSMB->ParameterCount;
6004 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6005 pSMB->DataOffset = cpu_to_le16(offset);
6007 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6008 pSMB->Reserved4 = 0;
6009 inc_rfc1001_len(pSMB, byte_count);
6010 pSMB->ByteCount = cpu_to_le16(byte_count);
6012 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
6014 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
6015 cifs_small_buf_release(pSMB);
6017 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
6020 /* Note: On -EAGAIN error only caller can retry on handle based calls
6021 since file handle passed in no longer valid */
6027 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
6028 const char *file_name,
6029 const struct cifs_unix_set_info_args *args,
6030 const struct nls_table *nls_codepage, int remap)
6032 TRANSACTION2_SPI_REQ *pSMB = NULL;
6033 TRANSACTION2_SPI_RSP *pSMBr = NULL;
6036 int bytes_returned = 0;
6037 FILE_UNIX_BASIC_INFO *data_offset;
6038 __u16 params, param_offset, offset, count, byte_count;
6040 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
6042 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6047 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6049 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6050 PATH_MAX, nls_codepage, remap);
6051 name_len++; /* trailing null */
6054 name_len = copy_path_name(pSMB->FileName, file_name);
6057 params = 6 + name_len;
6058 count = sizeof(FILE_UNIX_BASIC_INFO);
6059 pSMB->MaxParameterCount = cpu_to_le16(2);
6060 /* BB find max SMB PDU from sess structure BB */
6061 pSMB->MaxDataCount = cpu_to_le16(1000);
6062 pSMB->MaxSetupCount = 0;
6066 pSMB->Reserved2 = 0;
6067 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6068 InformationLevel) - 4;
6069 offset = param_offset + params;
6070 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
6071 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
6072 memset(data_offset, 0, count);
6073 pSMB->DataOffset = cpu_to_le16(offset);
6074 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6075 pSMB->SetupCount = 1;
6076 pSMB->Reserved3 = 0;
6077 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6078 byte_count = 3 /* pad */ + params + count;
6079 pSMB->ParameterCount = cpu_to_le16(params);
6080 pSMB->DataCount = cpu_to_le16(count);
6081 pSMB->TotalParameterCount = pSMB->ParameterCount;
6082 pSMB->TotalDataCount = pSMB->DataCount;
6083 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6084 pSMB->Reserved4 = 0;
6085 inc_rfc1001_len(pSMB, byte_count);
6087 cifs_fill_unix_set_info(data_offset, args);
6089 pSMB->ByteCount = cpu_to_le16(byte_count);
6090 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6091 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6093 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6095 cifs_buf_release(pSMB);
6101 #ifdef CONFIG_CIFS_XATTR
6103 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6104 * function used by listxattr and getxattr type calls. When ea_name is set,
6105 * it looks for that attribute name and stuffs that value into the EAData
6106 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6107 * buffer. In both cases, the return value is either the length of the
6108 * resulting data or a negative error code. If EAData is a NULL pointer then
6109 * the data isn't copied to it, but the length is returned.
6112 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6113 const unsigned char *searchName, const unsigned char *ea_name,
6114 char *EAData, size_t buf_size,
6115 struct cifs_sb_info *cifs_sb)
6117 /* BB assumes one setup word */
6118 TRANSACTION2_QPI_REQ *pSMB = NULL;
6119 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6120 int remap = cifs_remap(cifs_sb);
6121 struct nls_table *nls_codepage = cifs_sb->local_nls;
6125 struct fealist *ea_response_data;
6126 struct fea *temp_fea;
6129 __u16 params, byte_count, data_offset;
6130 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6132 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6134 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6139 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6141 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6142 PATH_MAX, nls_codepage, remap);
6143 list_len++; /* trailing null */
6146 list_len = copy_path_name(pSMB->FileName, searchName);
6149 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6150 pSMB->TotalDataCount = 0;
6151 pSMB->MaxParameterCount = cpu_to_le16(2);
6152 /* BB find exact max SMB PDU from sess structure BB */
6153 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6154 pSMB->MaxSetupCount = 0;
6158 pSMB->Reserved2 = 0;
6159 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6160 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6161 pSMB->DataCount = 0;
6162 pSMB->DataOffset = 0;
6163 pSMB->SetupCount = 1;
6164 pSMB->Reserved3 = 0;
6165 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6166 byte_count = params + 1 /* pad */ ;
6167 pSMB->TotalParameterCount = cpu_to_le16(params);
6168 pSMB->ParameterCount = pSMB->TotalParameterCount;
6169 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6170 pSMB->Reserved4 = 0;
6171 inc_rfc1001_len(pSMB, byte_count);
6172 pSMB->ByteCount = cpu_to_le16(byte_count);
6174 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6175 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6177 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6182 /* BB also check enough total bytes returned */
6183 /* BB we need to improve the validity checking
6184 of these trans2 responses */
6186 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6187 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6188 rc = -EIO; /* bad smb */
6192 /* check that length of list is not more than bcc */
6193 /* check that each entry does not go beyond length
6195 /* check that each element of each entry does not
6196 go beyond end of list */
6197 /* validate_trans2_offsets() */
6198 /* BB check if start of smb + data_offset > &bcc+ bcc */
6200 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6201 ea_response_data = (struct fealist *)
6202 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6204 list_len = le32_to_cpu(ea_response_data->list_len);
6205 cifs_dbg(FYI, "ea length %d\n", list_len);
6206 if (list_len <= 8) {
6207 cifs_dbg(FYI, "empty EA list returned from server\n");
6208 /* didn't find the named attribute */
6214 /* make sure list_len doesn't go past end of SMB */
6215 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6216 if ((char *)ea_response_data + list_len > end_of_smb) {
6217 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6222 /* account for ea list len */
6224 temp_fea = ea_response_data->list;
6225 temp_ptr = (char *)temp_fea;
6226 while (list_len > 0) {
6227 unsigned int name_len;
6232 /* make sure we can read name_len and value_len */
6234 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6239 name_len = temp_fea->name_len;
6240 value_len = le16_to_cpu(temp_fea->value_len);
6241 list_len -= name_len + 1 + value_len;
6243 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6249 if (ea_name_len == name_len &&
6250 memcmp(ea_name, temp_ptr, name_len) == 0) {
6251 temp_ptr += name_len + 1;
6255 if ((size_t)value_len > buf_size) {
6259 memcpy(EAData, temp_ptr, value_len);
6263 /* account for prefix user. and trailing null */
6264 rc += (5 + 1 + name_len);
6265 if (rc < (int) buf_size) {
6266 memcpy(EAData, "user.", 5);
6268 memcpy(EAData, temp_ptr, name_len);
6270 /* null terminate name */
6273 } else if (buf_size == 0) {
6274 /* skip copy - calc size only */
6276 /* stop before overrun buffer */
6281 temp_ptr += name_len + 1 + value_len;
6282 temp_fea = (struct fea *)temp_ptr;
6285 /* didn't find the named attribute */
6290 cifs_buf_release(pSMB);
6298 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6299 const char *fileName, const char *ea_name, const void *ea_value,
6300 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6301 struct cifs_sb_info *cifs_sb)
6303 struct smb_com_transaction2_spi_req *pSMB = NULL;
6304 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6305 struct fealist *parm_data;
6308 int bytes_returned = 0;
6309 __u16 params, param_offset, byte_count, offset, count;
6310 int remap = cifs_remap(cifs_sb);
6312 cifs_dbg(FYI, "In SetEA\n");
6314 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6319 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6321 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6322 PATH_MAX, nls_codepage, remap);
6323 name_len++; /* trailing null */
6326 name_len = copy_path_name(pSMB->FileName, fileName);
6329 params = 6 + name_len;
6331 /* done calculating parms using name_len of file name,
6332 now use name_len to calculate length of ea name
6333 we are going to create in the inode xattrs */
6334 if (ea_name == NULL)
6337 name_len = strnlen(ea_name, 255);
6339 count = sizeof(*parm_data) + ea_value_len + name_len;
6340 pSMB->MaxParameterCount = cpu_to_le16(2);
6341 /* BB find max SMB PDU from sess */
6342 pSMB->MaxDataCount = cpu_to_le16(1000);
6343 pSMB->MaxSetupCount = 0;
6347 pSMB->Reserved2 = 0;
6348 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6349 InformationLevel) - 4;
6350 offset = param_offset + params;
6351 pSMB->InformationLevel =
6352 cpu_to_le16(SMB_SET_FILE_EA);
6354 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6355 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6356 pSMB->DataOffset = cpu_to_le16(offset);
6357 pSMB->SetupCount = 1;
6358 pSMB->Reserved3 = 0;
6359 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6360 byte_count = 3 /* pad */ + params + count;
6361 pSMB->DataCount = cpu_to_le16(count);
6362 parm_data->list_len = cpu_to_le32(count);
6363 parm_data->list[0].EA_flags = 0;
6364 /* we checked above that name len is less than 255 */
6365 parm_data->list[0].name_len = (__u8)name_len;
6366 /* EA names are always ASCII */
6368 strncpy(parm_data->list[0].name, ea_name, name_len);
6369 parm_data->list[0].name[name_len] = 0;
6370 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6371 /* caller ensures that ea_value_len is less than 64K but
6372 we need to ensure that it fits within the smb */
6374 /*BB add length check to see if it would fit in
6375 negotiated SMB buffer size BB */
6376 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6378 memcpy(parm_data->list[0].name+name_len+1,
6379 ea_value, ea_value_len);
6381 pSMB->TotalDataCount = pSMB->DataCount;
6382 pSMB->ParameterCount = cpu_to_le16(params);
6383 pSMB->TotalParameterCount = pSMB->ParameterCount;
6384 pSMB->Reserved4 = 0;
6385 inc_rfc1001_len(pSMB, byte_count);
6386 pSMB->ByteCount = cpu_to_le16(byte_count);
6387 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6388 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6390 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6392 cifs_buf_release(pSMB);