1 // SPDX-License-Identifier: LGPL-2.1
5 * Copyright (C) International Business Machines Corp., 2002,2010
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 * Note that SMB offsets are from the beginning of SMB which is 4 bytes
878 * in, after RFC1001 field
880 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
881 pRqD->type = cpu_to_le16(type);
882 pSMB->ParameterOffset = cpu_to_le16(param_offset);
883 pSMB->DataOffset = cpu_to_le16(offset);
884 pSMB->SetupCount = 1;
886 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
887 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
889 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
890 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
891 pSMB->ParameterCount = cpu_to_le16(params);
892 pSMB->TotalParameterCount = pSMB->ParameterCount;
893 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
895 inc_rfc1001_len(pSMB, byte_count);
896 pSMB->ByteCount = cpu_to_le16(byte_count);
897 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
898 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
900 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
901 cifs_buf_release(pSMB);
903 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
912 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
913 struct cifs_sb_info *cifs_sb)
915 DELETE_FILE_REQ *pSMB = NULL;
916 DELETE_FILE_RSP *pSMBr = NULL;
920 int remap = cifs_remap(cifs_sb);
923 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
928 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
929 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
930 PATH_MAX, cifs_sb->local_nls,
932 name_len++; /* trailing null */
935 name_len = copy_path_name(pSMB->fileName, name);
937 pSMB->SearchAttributes =
938 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
939 pSMB->BufferFormat = 0x04;
940 inc_rfc1001_len(pSMB, name_len + 1);
941 pSMB->ByteCount = cpu_to_le16(name_len + 1);
942 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
943 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
944 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
946 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
948 cifs_buf_release(pSMB);
956 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
957 struct cifs_sb_info *cifs_sb)
959 DELETE_DIRECTORY_REQ *pSMB = NULL;
960 DELETE_DIRECTORY_RSP *pSMBr = NULL;
964 int remap = cifs_remap(cifs_sb);
966 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
968 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
973 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
974 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
975 PATH_MAX, cifs_sb->local_nls,
977 name_len++; /* trailing null */
980 name_len = copy_path_name(pSMB->DirName, name);
983 pSMB->BufferFormat = 0x04;
984 inc_rfc1001_len(pSMB, name_len + 1);
985 pSMB->ByteCount = cpu_to_le16(name_len + 1);
986 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
987 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
988 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
990 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
992 cifs_buf_release(pSMB);
999 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
1000 struct cifs_tcon *tcon, const char *name,
1001 struct cifs_sb_info *cifs_sb)
1004 CREATE_DIRECTORY_REQ *pSMB = NULL;
1005 CREATE_DIRECTORY_RSP *pSMBr = NULL;
1008 int remap = cifs_remap(cifs_sb);
1010 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
1012 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
1017 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1018 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1019 PATH_MAX, cifs_sb->local_nls,
1021 name_len++; /* trailing null */
1024 name_len = copy_path_name(pSMB->DirName, name);
1027 pSMB->BufferFormat = 0x04;
1028 inc_rfc1001_len(pSMB, name_len + 1);
1029 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1030 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1031 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1032 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1034 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
1036 cifs_buf_release(pSMB);
1043 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1044 __u32 posix_flags, __u64 mode, __u16 *netfid,
1045 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1046 const char *name, const struct nls_table *nls_codepage,
1049 TRANSACTION2_SPI_REQ *pSMB = NULL;
1050 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1053 int bytes_returned = 0;
1054 __u16 params, param_offset, offset, byte_count, count;
1055 OPEN_PSX_REQ *pdata;
1056 OPEN_PSX_RSP *psx_rsp;
1058 cifs_dbg(FYI, "In POSIX Create\n");
1060 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1065 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1067 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1068 PATH_MAX, nls_codepage, remap);
1069 name_len++; /* trailing null */
1072 name_len = copy_path_name(pSMB->FileName, name);
1075 params = 6 + name_len;
1076 count = sizeof(OPEN_PSX_REQ);
1077 pSMB->MaxParameterCount = cpu_to_le16(2);
1078 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1079 pSMB->MaxSetupCount = 0;
1083 pSMB->Reserved2 = 0;
1084 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1085 InformationLevel) - 4;
1086 offset = param_offset + params;
1087 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
1088 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
1089 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1090 pdata->Permissions = cpu_to_le64(mode);
1091 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1092 pdata->OpenFlags = cpu_to_le32(*pOplock);
1093 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1094 pSMB->DataOffset = cpu_to_le16(offset);
1095 pSMB->SetupCount = 1;
1096 pSMB->Reserved3 = 0;
1097 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1098 byte_count = 3 /* pad */ + params + count;
1100 pSMB->DataCount = cpu_to_le16(count);
1101 pSMB->ParameterCount = cpu_to_le16(params);
1102 pSMB->TotalDataCount = pSMB->DataCount;
1103 pSMB->TotalParameterCount = pSMB->ParameterCount;
1104 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1105 pSMB->Reserved4 = 0;
1106 inc_rfc1001_len(pSMB, byte_count);
1107 pSMB->ByteCount = cpu_to_le16(byte_count);
1108 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1109 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1111 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1112 goto psx_create_err;
1115 cifs_dbg(FYI, "copying inode info\n");
1116 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1118 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1119 rc = -EIO; /* bad smb */
1120 goto psx_create_err;
1123 /* copy return information to pRetData */
1124 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1125 + le16_to_cpu(pSMBr->t2.DataOffset));
1127 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1129 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1130 /* Let caller know file was created so we can set the mode. */
1131 /* Do we care about the CreateAction in any other cases? */
1132 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1133 *pOplock |= CIFS_CREATE_ACTION;
1134 /* check to make sure response data is there */
1135 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1136 pRetData->Type = cpu_to_le32(-1); /* unknown */
1137 cifs_dbg(NOISY, "unknown type\n");
1139 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1140 + sizeof(FILE_UNIX_BASIC_INFO)) {
1141 cifs_dbg(VFS, "Open response data too small\n");
1142 pRetData->Type = cpu_to_le32(-1);
1143 goto psx_create_err;
1145 memcpy((char *) pRetData,
1146 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1147 sizeof(FILE_UNIX_BASIC_INFO));
1151 cifs_buf_release(pSMB);
1153 if (posix_flags & SMB_O_DIRECTORY)
1154 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1156 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1164 static __u16 convert_disposition(int disposition)
1168 switch (disposition) {
1169 case FILE_SUPERSEDE:
1170 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1173 ofun = SMBOPEN_OAPPEND;
1176 ofun = SMBOPEN_OCREATE;
1179 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1181 case FILE_OVERWRITE:
1182 ofun = SMBOPEN_OTRUNC;
1184 case FILE_OVERWRITE_IF:
1185 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1188 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1189 ofun = SMBOPEN_OAPPEND; /* regular open */
1195 access_flags_to_smbopen_mode(const int access_flags)
1197 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1199 if (masked_flags == GENERIC_READ)
1200 return SMBOPEN_READ;
1201 else if (masked_flags == GENERIC_WRITE)
1202 return SMBOPEN_WRITE;
1204 /* just go for read/write */
1205 return SMBOPEN_READWRITE;
1209 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1210 const char *fileName, const int openDisposition,
1211 const int access_flags, const int create_options, __u16 *netfid,
1212 int *pOplock, FILE_ALL_INFO *pfile_info,
1213 const struct nls_table *nls_codepage, int remap)
1216 OPENX_REQ *pSMB = NULL;
1217 OPENX_RSP *pSMBr = NULL;
1223 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1228 pSMB->AndXCommand = 0xFF; /* none */
1230 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1231 count = 1; /* account for one byte pad to word boundary */
1233 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1234 fileName, PATH_MAX, nls_codepage, remap);
1235 name_len++; /* trailing null */
1238 count = 0; /* no pad */
1239 name_len = copy_path_name(pSMB->fileName, fileName);
1241 if (*pOplock & REQ_OPLOCK)
1242 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1243 else if (*pOplock & REQ_BATCHOPLOCK)
1244 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1246 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1247 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1248 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1249 /* set file as system file if special file such
1250 as fifo and server expecting SFU style and
1251 no Unix extensions */
1253 if (create_options & CREATE_OPTION_SPECIAL)
1254 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1255 else /* BB FIXME BB */
1256 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1258 if (create_options & CREATE_OPTION_READONLY)
1259 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1262 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1263 CREATE_OPTIONS_MASK); */
1264 /* BB FIXME END BB */
1266 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1267 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1269 inc_rfc1001_len(pSMB, count);
1271 pSMB->ByteCount = cpu_to_le16(count);
1272 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1273 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1274 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1276 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1278 /* BB verify if wct == 15 */
1280 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1282 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1283 /* Let caller know file was created so we can set the mode. */
1284 /* Do we care about the CreateAction in any other cases? */
1286 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1287 *pOplock |= CIFS_CREATE_ACTION; */
1291 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1292 pfile_info->LastAccessTime = 0; /* BB fixme */
1293 pfile_info->LastWriteTime = 0; /* BB fixme */
1294 pfile_info->ChangeTime = 0; /* BB fixme */
1295 pfile_info->Attributes =
1296 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1297 /* the file_info buf is endian converted by caller */
1298 pfile_info->AllocationSize =
1299 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1300 pfile_info->EndOfFile = pfile_info->AllocationSize;
1301 pfile_info->NumberOfLinks = cpu_to_le32(1);
1302 pfile_info->DeletePending = 0;
1306 cifs_buf_release(pSMB);
1313 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1317 OPEN_REQ *req = NULL;
1318 OPEN_RSP *rsp = NULL;
1322 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1323 struct cifs_tcon *tcon = oparms->tcon;
1324 int remap = cifs_remap(cifs_sb);
1325 const struct nls_table *nls = cifs_sb->local_nls;
1326 int create_options = oparms->create_options;
1327 int desired_access = oparms->desired_access;
1328 int disposition = oparms->disposition;
1329 const char *path = oparms->path;
1332 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1337 /* no commands go after this */
1338 req->AndXCommand = 0xFF;
1340 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1341 /* account for one byte pad to word boundary */
1343 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1344 path, PATH_MAX, nls, remap);
1348 req->NameLength = cpu_to_le16(name_len);
1350 /* BB improve check for buffer overruns BB */
1353 name_len = copy_path_name(req->fileName, path);
1354 req->NameLength = cpu_to_le16(name_len);
1357 if (*oplock & REQ_OPLOCK)
1358 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1359 else if (*oplock & REQ_BATCHOPLOCK)
1360 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1362 req->DesiredAccess = cpu_to_le32(desired_access);
1363 req->AllocationSize = 0;
1366 * Set file as system file if special file such as fifo and server
1367 * expecting SFU style and no Unix extensions.
1369 if (create_options & CREATE_OPTION_SPECIAL)
1370 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1372 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1375 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1376 * sensitive checks for other servers such as Samba.
1378 if (tcon->ses->capabilities & CAP_UNIX)
1379 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1381 if (create_options & CREATE_OPTION_READONLY)
1382 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1384 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1385 req->CreateDisposition = cpu_to_le32(disposition);
1386 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1388 /* BB Expirement with various impersonation levels and verify */
1389 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1390 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1393 inc_rfc1001_len(req, count);
1395 req->ByteCount = cpu_to_le16(count);
1396 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1397 (struct smb_hdr *)rsp, &bytes_returned, 0);
1398 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1400 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1401 cifs_buf_release(req);
1407 /* 1 byte no need to le_to_cpu */
1408 *oplock = rsp->OplockLevel;
1409 /* cifs fid stays in le */
1410 oparms->fid->netfid = rsp->Fid;
1411 oparms->fid->access = desired_access;
1413 /* Let caller know file was created so we can set the mode. */
1414 /* Do we care about the CreateAction in any other cases? */
1415 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1416 *oplock |= CIFS_CREATE_ACTION;
1419 /* copy from CreationTime to Attributes */
1420 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1421 /* the file_info buf is endian converted by caller */
1422 buf->AllocationSize = rsp->AllocationSize;
1423 buf->EndOfFile = rsp->EndOfFile;
1424 buf->NumberOfLinks = cpu_to_le32(1);
1425 buf->DeletePending = 0;
1428 cifs_buf_release(req);
1433 * Discard any remaining data in the current SMB. To do this, we borrow the
1437 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1439 unsigned int rfclen = server->pdu_size;
1440 int remaining = rfclen + server->vals->header_preamble_size -
1443 while (remaining > 0) {
1446 length = cifs_discard_from_socket(server,
1447 min_t(size_t, remaining,
1448 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1451 server->total_read += length;
1452 remaining -= length;
1459 __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
1464 length = cifs_discard_remaining_data(server);
1465 dequeue_mid(mid, malformed);
1466 mid->resp_buf = server->smallbuf;
1467 server->smallbuf = NULL;
1472 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1474 struct cifs_readdata *rdata = mid->callback_data;
1476 return __cifs_readv_discard(server, mid, rdata->result);
1480 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1483 unsigned int data_offset, data_len;
1484 struct cifs_readdata *rdata = mid->callback_data;
1485 char *buf = server->smallbuf;
1486 unsigned int buflen = server->pdu_size +
1487 server->vals->header_preamble_size;
1488 bool use_rdma_mr = false;
1490 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1491 __func__, mid->mid, rdata->offset, rdata->bytes);
1494 * read the rest of READ_RSP header (sans Data array), or whatever we
1495 * can if there's not enough data. At this point, we've read down to
1498 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1499 HEADER_SIZE(server) + 1;
1501 length = cifs_read_from_socket(server,
1502 buf + HEADER_SIZE(server) - 1, len);
1505 server->total_read += length;
1507 if (server->ops->is_session_expired &&
1508 server->ops->is_session_expired(buf)) {
1509 cifs_reconnect(server);
1513 if (server->ops->is_status_pending &&
1514 server->ops->is_status_pending(buf, server)) {
1515 cifs_discard_remaining_data(server);
1519 /* set up first two iov for signature check and to get credits */
1520 rdata->iov[0].iov_base = buf;
1521 rdata->iov[0].iov_len = server->vals->header_preamble_size;
1522 rdata->iov[1].iov_base = buf + server->vals->header_preamble_size;
1523 rdata->iov[1].iov_len =
1524 server->total_read - server->vals->header_preamble_size;
1525 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1526 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1527 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
1528 rdata->iov[1].iov_base, rdata->iov[1].iov_len);
1530 /* Was the SMB read successful? */
1531 rdata->result = server->ops->map_error(buf, false);
1532 if (rdata->result != 0) {
1533 cifs_dbg(FYI, "%s: server returned error %d\n",
1534 __func__, rdata->result);
1535 /* normal error on read response */
1536 return __cifs_readv_discard(server, mid, false);
1539 /* Is there enough to get to the rest of the READ_RSP header? */
1540 if (server->total_read < server->vals->read_rsp_size) {
1541 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1542 __func__, server->total_read,
1543 server->vals->read_rsp_size);
1544 rdata->result = -EIO;
1545 return cifs_readv_discard(server, mid);
1548 data_offset = server->ops->read_data_offset(buf) +
1549 server->vals->header_preamble_size;
1550 if (data_offset < server->total_read) {
1552 * win2k8 sometimes sends an offset of 0 when the read
1553 * is beyond the EOF. Treat it as if the data starts just after
1556 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1557 __func__, data_offset);
1558 data_offset = server->total_read;
1559 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1560 /* data_offset is beyond the end of smallbuf */
1561 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1562 __func__, data_offset);
1563 rdata->result = -EIO;
1564 return cifs_readv_discard(server, mid);
1567 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1568 __func__, server->total_read, data_offset);
1570 len = data_offset - server->total_read;
1572 /* read any junk before data into the rest of smallbuf */
1573 length = cifs_read_from_socket(server,
1574 buf + server->total_read, len);
1577 server->total_read += length;
1580 /* how much data is in the response? */
1581 #ifdef CONFIG_CIFS_SMB_DIRECT
1582 use_rdma_mr = rdata->mr;
1584 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1585 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1586 /* data_len is corrupt -- discard frame */
1587 rdata->result = -EIO;
1588 return cifs_readv_discard(server, mid);
1591 length = rdata->read_into_pages(server, rdata, data_len);
1595 server->total_read += length;
1597 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1598 server->total_read, buflen, data_len);
1600 /* discard anything left over */
1601 if (server->total_read < buflen)
1602 return cifs_readv_discard(server, mid);
1604 dequeue_mid(mid, false);
1605 mid->resp_buf = server->smallbuf;
1606 server->smallbuf = NULL;
1611 cifs_readv_callback(struct mid_q_entry *mid)
1613 struct cifs_readdata *rdata = mid->callback_data;
1614 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1615 struct TCP_Server_Info *server = tcon->ses->server;
1616 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1618 .rq_pages = rdata->pages,
1619 .rq_offset = rdata->page_offset,
1620 .rq_npages = rdata->nr_pages,
1621 .rq_pagesz = rdata->pagesz,
1622 .rq_tailsz = rdata->tailsz };
1623 struct cifs_credits credits = { .value = 1, .instance = 0 };
1625 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1626 __func__, mid->mid, mid->mid_state, rdata->result,
1629 switch (mid->mid_state) {
1630 case MID_RESPONSE_RECEIVED:
1631 /* result already set, check signature */
1635 rc = cifs_verify_signature(&rqst, server,
1636 mid->sequence_number);
1638 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1641 /* FIXME: should this be counted toward the initiating task? */
1642 task_io_account_read(rdata->got_bytes);
1643 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1645 case MID_REQUEST_SUBMITTED:
1646 case MID_RETRY_NEEDED:
1647 rdata->result = -EAGAIN;
1648 if (server->sign && rdata->got_bytes)
1649 /* reset bytes number since we can not check a sign */
1650 rdata->got_bytes = 0;
1651 /* FIXME: should this be counted toward the initiating task? */
1652 task_io_account_read(rdata->got_bytes);
1653 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1656 rdata->result = -EIO;
1659 queue_work(cifsiod_wq, &rdata->work);
1660 DeleteMidQEntry(mid);
1661 add_credits(server, &credits, 0);
1664 /* cifs_async_readv - send an async write, and set up mid to handle result */
1666 cifs_async_readv(struct cifs_readdata *rdata)
1669 READ_REQ *smb = NULL;
1671 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1672 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1675 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1676 __func__, rdata->offset, rdata->bytes);
1678 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1681 wct = 10; /* old style read */
1682 if ((rdata->offset >> 32) > 0) {
1683 /* can not handle this big offset for old */
1688 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1692 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1693 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1695 smb->AndXCommand = 0xFF; /* none */
1696 smb->Fid = rdata->cfile->fid.netfid;
1697 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1699 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1701 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1702 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1706 /* old style read */
1707 struct smb_com_readx_req *smbr =
1708 (struct smb_com_readx_req *)smb;
1709 smbr->ByteCount = 0;
1712 /* 4 for RFC1001 length + 1 for BCC */
1713 rdata->iov[0].iov_base = smb;
1714 rdata->iov[0].iov_len = 4;
1715 rdata->iov[1].iov_base = (char *)smb + 4;
1716 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1718 kref_get(&rdata->refcount);
1719 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1720 cifs_readv_callback, NULL, rdata, 0, NULL);
1723 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1725 kref_put(&rdata->refcount, cifs_readdata_release);
1727 cifs_small_buf_release(smb);
1732 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1733 unsigned int *nbytes, char **buf, int *pbuf_type)
1736 READ_REQ *pSMB = NULL;
1737 READ_RSP *pSMBr = NULL;
1738 char *pReadData = NULL;
1740 int resp_buf_type = 0;
1742 struct kvec rsp_iov;
1743 __u32 pid = io_parms->pid;
1744 __u16 netfid = io_parms->netfid;
1745 __u64 offset = io_parms->offset;
1746 struct cifs_tcon *tcon = io_parms->tcon;
1747 unsigned int count = io_parms->length;
1749 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1750 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1753 wct = 10; /* old style read */
1754 if ((offset >> 32) > 0) {
1755 /* can not handle this big offset for old */
1761 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1765 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1766 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1768 /* tcon and ses pointer are checked in smb_init */
1769 if (tcon->ses->server == NULL)
1770 return -ECONNABORTED;
1772 pSMB->AndXCommand = 0xFF; /* none */
1774 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1776 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1778 pSMB->Remaining = 0;
1779 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1780 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1782 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1784 /* old style read */
1785 struct smb_com_readx_req *pSMBW =
1786 (struct smb_com_readx_req *)pSMB;
1787 pSMBW->ByteCount = 0;
1790 iov[0].iov_base = (char *)pSMB;
1791 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1792 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1793 CIFS_LOG_ERROR, &rsp_iov);
1794 cifs_small_buf_release(pSMB);
1795 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1796 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1798 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1800 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1801 data_length = data_length << 16;
1802 data_length += le16_to_cpu(pSMBr->DataLength);
1803 *nbytes = data_length;
1805 /*check that DataLength would not go beyond end of SMB */
1806 if ((data_length > CIFSMaxBufSize)
1807 || (data_length > count)) {
1808 cifs_dbg(FYI, "bad length %d for count %d\n",
1809 data_length, count);
1813 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1814 le16_to_cpu(pSMBr->DataOffset);
1815 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1816 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1818 }*/ /* can not use copy_to_user when using page cache*/
1820 memcpy(*buf, pReadData, data_length);
1825 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1826 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1827 /* return buffer to caller to free */
1828 *buf = rsp_iov.iov_base;
1829 if (resp_buf_type == CIFS_SMALL_BUFFER)
1830 *pbuf_type = CIFS_SMALL_BUFFER;
1831 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1832 *pbuf_type = CIFS_LARGE_BUFFER;
1833 } /* else no valid buffer on return - leave as null */
1835 /* Note: On -EAGAIN error only caller can retry on handle based calls
1836 since file handle passed in no longer valid */
1842 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1843 unsigned int *nbytes, const char *buf)
1846 WRITE_REQ *pSMB = NULL;
1847 WRITE_RSP *pSMBr = NULL;
1848 int bytes_returned, wct;
1851 __u32 pid = io_parms->pid;
1852 __u16 netfid = io_parms->netfid;
1853 __u64 offset = io_parms->offset;
1854 struct cifs_tcon *tcon = io_parms->tcon;
1855 unsigned int count = io_parms->length;
1859 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1860 if (tcon->ses == NULL)
1861 return -ECONNABORTED;
1863 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1867 if ((offset >> 32) > 0) {
1868 /* can not handle big offset for old srv */
1873 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1878 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1879 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1881 /* tcon and ses pointer are checked in smb_init */
1882 if (tcon->ses->server == NULL)
1883 return -ECONNABORTED;
1885 pSMB->AndXCommand = 0xFF; /* none */
1887 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1889 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1891 pSMB->Reserved = 0xFFFFFFFF;
1892 pSMB->WriteMode = 0;
1893 pSMB->Remaining = 0;
1895 /* Can increase buffer size if buffer is big enough in some cases ie we
1896 can send more if LARGE_WRITE_X capability returned by the server and if
1897 our buffer is big enough or if we convert to iovecs on socket writes
1898 and eliminate the copy to the CIFS buffer */
1899 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1900 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1902 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1906 if (bytes_sent > count)
1909 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1911 memcpy(pSMB->Data, buf, bytes_sent);
1912 else if (count != 0) {
1914 cifs_buf_release(pSMB);
1916 } /* else setting file size with write of zero bytes */
1918 byte_count = bytes_sent + 1; /* pad */
1919 else /* wct == 12 */
1920 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1922 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1923 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1924 inc_rfc1001_len(pSMB, byte_count);
1927 pSMB->ByteCount = cpu_to_le16(byte_count);
1928 else { /* old style write has byte count 4 bytes earlier
1930 struct smb_com_writex_req *pSMBW =
1931 (struct smb_com_writex_req *)pSMB;
1932 pSMBW->ByteCount = cpu_to_le16(byte_count);
1935 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1936 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1937 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1939 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1941 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1942 *nbytes = (*nbytes) << 16;
1943 *nbytes += le16_to_cpu(pSMBr->Count);
1946 * Mask off high 16 bits when bytes written as returned by the
1947 * server is greater than bytes requested by the client. Some
1948 * OS/2 servers are known to set incorrect CountHigh values.
1950 if (*nbytes > count)
1954 cifs_buf_release(pSMB);
1956 /* Note: On -EAGAIN error only caller can retry on handle based calls
1957 since file handle passed in no longer valid */
1963 cifs_writedata_release(struct kref *refcount)
1965 struct cifs_writedata *wdata = container_of(refcount,
1966 struct cifs_writedata, refcount);
1967 #ifdef CONFIG_CIFS_SMB_DIRECT
1969 smbd_deregister_mr(wdata->mr);
1975 cifsFileInfo_put(wdata->cfile);
1977 kvfree(wdata->pages);
1982 * Write failed with a retryable error. Resend the write request. It's also
1983 * possible that the page was redirtied so re-clean the page.
1986 cifs_writev_requeue(struct cifs_writedata *wdata)
1989 struct inode *inode = d_inode(wdata->cfile->dentry);
1990 struct TCP_Server_Info *server;
1991 unsigned int rest_len;
1993 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1995 rest_len = wdata->bytes;
1997 struct cifs_writedata *wdata2;
1998 unsigned int j, nr_pages, wsize, tailsz, cur_len;
2000 wsize = server->ops->wp_retry_size(inode);
2001 if (wsize < rest_len) {
2002 nr_pages = wsize / PAGE_SIZE;
2007 cur_len = nr_pages * PAGE_SIZE;
2010 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
2012 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
2015 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
2021 for (j = 0; j < nr_pages; j++) {
2022 wdata2->pages[j] = wdata->pages[i + j];
2023 lock_page(wdata2->pages[j]);
2024 clear_page_dirty_for_io(wdata2->pages[j]);
2027 wdata2->sync_mode = wdata->sync_mode;
2028 wdata2->nr_pages = nr_pages;
2029 wdata2->offset = page_offset(wdata2->pages[0]);
2030 wdata2->pagesz = PAGE_SIZE;
2031 wdata2->tailsz = tailsz;
2032 wdata2->bytes = cur_len;
2034 rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
2036 if (!wdata2->cfile) {
2037 cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
2039 if (!is_retryable_error(rc))
2042 wdata2->pid = wdata2->cfile->pid;
2043 rc = server->ops->async_writev(wdata2,
2044 cifs_writedata_release);
2047 for (j = 0; j < nr_pages; j++) {
2048 unlock_page(wdata2->pages[j]);
2049 if (rc != 0 && !is_retryable_error(rc)) {
2050 SetPageError(wdata2->pages[j]);
2051 end_page_writeback(wdata2->pages[j]);
2052 put_page(wdata2->pages[j]);
2056 kref_put(&wdata2->refcount, cifs_writedata_release);
2058 if (is_retryable_error(rc))
2064 rest_len -= cur_len;
2066 } while (i < wdata->nr_pages);
2068 /* cleanup remaining pages from the original wdata */
2069 for (; i < wdata->nr_pages; i++) {
2070 SetPageError(wdata->pages[i]);
2071 end_page_writeback(wdata->pages[i]);
2072 put_page(wdata->pages[i]);
2075 if (rc != 0 && !is_retryable_error(rc))
2076 mapping_set_error(inode->i_mapping, rc);
2077 kref_put(&wdata->refcount, cifs_writedata_release);
2081 cifs_writev_complete(struct work_struct *work)
2083 struct cifs_writedata *wdata = container_of(work,
2084 struct cifs_writedata, work);
2085 struct inode *inode = d_inode(wdata->cfile->dentry);
2088 if (wdata->result == 0) {
2089 spin_lock(&inode->i_lock);
2090 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2091 spin_unlock(&inode->i_lock);
2092 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2094 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2095 return cifs_writev_requeue(wdata);
2097 for (i = 0; i < wdata->nr_pages; i++) {
2098 struct page *page = wdata->pages[i];
2099 if (wdata->result == -EAGAIN)
2100 __set_page_dirty_nobuffers(page);
2101 else if (wdata->result < 0)
2103 end_page_writeback(page);
2106 if (wdata->result != -EAGAIN)
2107 mapping_set_error(inode->i_mapping, wdata->result);
2108 kref_put(&wdata->refcount, cifs_writedata_release);
2111 struct cifs_writedata *
2112 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2114 struct page **pages =
2115 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2117 return cifs_writedata_direct_alloc(pages, complete);
2122 struct cifs_writedata *
2123 cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2125 struct cifs_writedata *wdata;
2127 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2128 if (wdata != NULL) {
2129 wdata->pages = pages;
2130 kref_init(&wdata->refcount);
2131 INIT_LIST_HEAD(&wdata->list);
2132 init_completion(&wdata->done);
2133 INIT_WORK(&wdata->work, complete);
2139 * Check the mid_state and signature on received buffer (if any), and queue the
2140 * workqueue completion task.
2143 cifs_writev_callback(struct mid_q_entry *mid)
2145 struct cifs_writedata *wdata = mid->callback_data;
2146 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2147 unsigned int written;
2148 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2149 struct cifs_credits credits = { .value = 1, .instance = 0 };
2151 switch (mid->mid_state) {
2152 case MID_RESPONSE_RECEIVED:
2153 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2154 if (wdata->result != 0)
2157 written = le16_to_cpu(smb->CountHigh);
2159 written += le16_to_cpu(smb->Count);
2161 * Mask off high 16 bits when bytes written as returned
2162 * by the server is greater than bytes requested by the
2163 * client. OS/2 servers are known to set incorrect
2166 if (written > wdata->bytes)
2169 if (written < wdata->bytes)
2170 wdata->result = -ENOSPC;
2172 wdata->bytes = written;
2174 case MID_REQUEST_SUBMITTED:
2175 case MID_RETRY_NEEDED:
2176 wdata->result = -EAGAIN;
2179 wdata->result = -EIO;
2183 queue_work(cifsiod_wq, &wdata->work);
2184 DeleteMidQEntry(mid);
2185 add_credits(tcon->ses->server, &credits, 0);
2188 /* cifs_async_writev - send an async write, and set up mid to handle result */
2190 cifs_async_writev(struct cifs_writedata *wdata,
2191 void (*release)(struct kref *kref))
2194 WRITE_REQ *smb = NULL;
2196 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2198 struct smb_rqst rqst = { };
2200 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2204 if (wdata->offset >> 32 > 0) {
2205 /* can not handle big offset for old srv */
2210 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2212 goto async_writev_out;
2214 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2215 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2217 smb->AndXCommand = 0xFF; /* none */
2218 smb->Fid = wdata->cfile->fid.netfid;
2219 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2221 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2222 smb->Reserved = 0xFFFFFFFF;
2227 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2229 /* 4 for RFC1001 length + 1 for BCC */
2231 iov[0].iov_base = smb;
2232 iov[1].iov_len = get_rfc1002_length(smb) + 1;
2233 iov[1].iov_base = (char *)smb + 4;
2237 rqst.rq_pages = wdata->pages;
2238 rqst.rq_offset = wdata->page_offset;
2239 rqst.rq_npages = wdata->nr_pages;
2240 rqst.rq_pagesz = wdata->pagesz;
2241 rqst.rq_tailsz = wdata->tailsz;
2243 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2244 wdata->offset, wdata->bytes);
2246 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2247 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2250 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2251 put_bcc(wdata->bytes + 1, &smb->hdr);
2254 struct smb_com_writex_req *smbw =
2255 (struct smb_com_writex_req *)smb;
2256 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2257 put_bcc(wdata->bytes + 5, &smbw->hdr);
2258 iov[1].iov_len += 4; /* pad bigger by four bytes */
2261 kref_get(&wdata->refcount);
2262 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2263 cifs_writev_callback, NULL, wdata, 0, NULL);
2266 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2268 kref_put(&wdata->refcount, release);
2271 cifs_small_buf_release(smb);
2276 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2277 unsigned int *nbytes, struct kvec *iov, int n_vec)
2280 WRITE_REQ *pSMB = NULL;
2283 int resp_buf_type = 0;
2284 __u32 pid = io_parms->pid;
2285 __u16 netfid = io_parms->netfid;
2286 __u64 offset = io_parms->offset;
2287 struct cifs_tcon *tcon = io_parms->tcon;
2288 unsigned int count = io_parms->length;
2289 struct kvec rsp_iov;
2293 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2295 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2299 if ((offset >> 32) > 0) {
2300 /* can not handle big offset for old srv */
2304 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2308 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2309 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2311 /* tcon and ses pointer are checked in smb_init */
2312 if (tcon->ses->server == NULL)
2313 return -ECONNABORTED;
2315 pSMB->AndXCommand = 0xFF; /* none */
2317 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2319 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2320 pSMB->Reserved = 0xFFFFFFFF;
2321 pSMB->WriteMode = 0;
2322 pSMB->Remaining = 0;
2325 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2327 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2328 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2329 /* header + 1 byte pad */
2330 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2332 inc_rfc1001_len(pSMB, count + 1);
2333 else /* wct == 12 */
2334 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2336 pSMB->ByteCount = cpu_to_le16(count + 1);
2337 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2338 struct smb_com_writex_req *pSMBW =
2339 (struct smb_com_writex_req *)pSMB;
2340 pSMBW->ByteCount = cpu_to_le16(count + 5);
2342 iov[0].iov_base = pSMB;
2344 iov[0].iov_len = smb_hdr_len + 4;
2345 else /* wct == 12 pad bigger by four bytes */
2346 iov[0].iov_len = smb_hdr_len + 8;
2348 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2350 cifs_small_buf_release(pSMB);
2351 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2353 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2354 } else if (resp_buf_type == 0) {
2355 /* presumably this can not happen, but best to be safe */
2358 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2359 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2360 *nbytes = (*nbytes) << 16;
2361 *nbytes += le16_to_cpu(pSMBr->Count);
2364 * Mask off high 16 bits when bytes written as returned by the
2365 * server is greater than bytes requested by the client. OS/2
2366 * servers are known to set incorrect CountHigh values.
2368 if (*nbytes > count)
2372 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2374 /* Note: On -EAGAIN error only caller can retry on handle based calls
2375 since file handle passed in no longer valid */
2380 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2381 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2382 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2385 LOCK_REQ *pSMB = NULL;
2387 struct kvec rsp_iov;
2391 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2392 num_lock, num_unlock);
2394 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2399 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2400 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2401 pSMB->LockType = lock_type;
2402 pSMB->AndXCommand = 0xFF; /* none */
2403 pSMB->Fid = netfid; /* netfid stays le */
2405 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2406 inc_rfc1001_len(pSMB, count);
2407 pSMB->ByteCount = cpu_to_le16(count);
2409 iov[0].iov_base = (char *)pSMB;
2410 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2411 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2412 iov[1].iov_base = (char *)buf;
2413 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2415 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2416 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
2417 CIFS_NO_RSP_BUF, &rsp_iov);
2418 cifs_small_buf_release(pSMB);
2420 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2426 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2427 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2428 const __u64 offset, const __u32 numUnlock,
2429 const __u32 numLock, const __u8 lockType,
2430 const bool waitFlag, const __u8 oplock_level)
2433 LOCK_REQ *pSMB = NULL;
2434 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2439 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2440 (int)waitFlag, numLock);
2441 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2446 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2447 /* no response expected */
2448 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
2450 } else if (waitFlag) {
2451 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2452 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2457 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2458 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2459 pSMB->LockType = lockType;
2460 pSMB->OplockLevel = oplock_level;
2461 pSMB->AndXCommand = 0xFF; /* none */
2462 pSMB->Fid = smb_file_id; /* netfid stays le */
2464 if ((numLock != 0) || (numUnlock != 0)) {
2465 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2466 /* BB where to store pid high? */
2467 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2468 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2469 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2470 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2471 count = sizeof(LOCKING_ANDX_RANGE);
2476 inc_rfc1001_len(pSMB, count);
2477 pSMB->ByteCount = cpu_to_le16(count);
2480 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2481 (struct smb_hdr *) pSMB, &bytes_returned);
2483 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2484 cifs_small_buf_release(pSMB);
2485 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2487 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2489 /* Note: On -EAGAIN error only caller can retry on handle based calls
2490 since file handle passed in no longer valid */
2495 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2496 const __u16 smb_file_id, const __u32 netpid,
2497 const loff_t start_offset, const __u64 len,
2498 struct file_lock *pLockData, const __u16 lock_type,
2499 const bool waitFlag)
2501 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2502 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2503 struct cifs_posix_lock *parm_data;
2506 int bytes_returned = 0;
2507 int resp_buf_type = 0;
2508 __u16 params, param_offset, offset, byte_count, count;
2510 struct kvec rsp_iov;
2512 cifs_dbg(FYI, "Posix Lock\n");
2514 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2519 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2522 pSMB->MaxSetupCount = 0;
2525 pSMB->Reserved2 = 0;
2526 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2527 offset = param_offset + params;
2529 count = sizeof(struct cifs_posix_lock);
2530 pSMB->MaxParameterCount = cpu_to_le16(2);
2531 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2532 pSMB->SetupCount = 1;
2533 pSMB->Reserved3 = 0;
2535 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2537 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2538 byte_count = 3 /* pad */ + params + count;
2539 pSMB->DataCount = cpu_to_le16(count);
2540 pSMB->ParameterCount = cpu_to_le16(params);
2541 pSMB->TotalDataCount = pSMB->DataCount;
2542 pSMB->TotalParameterCount = pSMB->ParameterCount;
2543 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2544 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2545 parm_data = (struct cifs_posix_lock *)
2546 (((char *)pSMB) + offset + 4);
2548 parm_data->lock_type = cpu_to_le16(lock_type);
2550 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2551 parm_data->lock_flags = cpu_to_le16(1);
2552 pSMB->Timeout = cpu_to_le32(-1);
2556 parm_data->pid = cpu_to_le32(netpid);
2557 parm_data->start = cpu_to_le64(start_offset);
2558 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2560 pSMB->DataOffset = cpu_to_le16(offset);
2561 pSMB->Fid = smb_file_id;
2562 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2563 pSMB->Reserved4 = 0;
2564 inc_rfc1001_len(pSMB, byte_count);
2565 pSMB->ByteCount = cpu_to_le16(byte_count);
2567 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2568 (struct smb_hdr *) pSMBr, &bytes_returned);
2570 iov[0].iov_base = (char *)pSMB;
2571 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2572 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2573 &resp_buf_type, timeout, &rsp_iov);
2574 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2576 cifs_small_buf_release(pSMB);
2579 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2580 } else if (pLockData) {
2581 /* lock structure can be returned on get */
2584 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2586 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2587 rc = -EIO; /* bad smb */
2590 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2591 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2592 if (data_count < sizeof(struct cifs_posix_lock)) {
2596 parm_data = (struct cifs_posix_lock *)
2597 ((char *)&pSMBr->hdr.Protocol + data_offset);
2598 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2599 pLockData->fl_type = F_UNLCK;
2601 if (parm_data->lock_type ==
2602 cpu_to_le16(CIFS_RDLCK))
2603 pLockData->fl_type = F_RDLCK;
2604 else if (parm_data->lock_type ==
2605 cpu_to_le16(CIFS_WRLCK))
2606 pLockData->fl_type = F_WRLCK;
2608 pLockData->fl_start = le64_to_cpu(parm_data->start);
2609 pLockData->fl_end = pLockData->fl_start +
2610 le64_to_cpu(parm_data->length) - 1;
2611 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2616 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2618 /* Note: On -EAGAIN error only caller can retry on handle based calls
2619 since file handle passed in no longer valid */
2626 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2629 CLOSE_REQ *pSMB = NULL;
2630 cifs_dbg(FYI, "In CIFSSMBClose\n");
2632 /* do not retry on dead session on close */
2633 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2639 pSMB->FileID = (__u16) smb_file_id;
2640 pSMB->LastWriteTime = 0xFFFFFFFF;
2641 pSMB->ByteCount = 0;
2642 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2643 cifs_small_buf_release(pSMB);
2644 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2647 /* EINTR is expected when user ctl-c to kill app */
2648 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2652 /* Since session is dead, file will be closed on server already */
2660 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2663 FLUSH_REQ *pSMB = NULL;
2664 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2666 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2670 pSMB->FileID = (__u16) smb_file_id;
2671 pSMB->ByteCount = 0;
2672 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2673 cifs_small_buf_release(pSMB);
2674 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2676 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2682 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2683 const char *from_name, const char *to_name,
2684 struct cifs_sb_info *cifs_sb)
2687 RENAME_REQ *pSMB = NULL;
2688 RENAME_RSP *pSMBr = NULL;
2690 int name_len, name_len2;
2692 int remap = cifs_remap(cifs_sb);
2694 cifs_dbg(FYI, "In CIFSSMBRename\n");
2696 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2701 pSMB->BufferFormat = 0x04;
2702 pSMB->SearchAttributes =
2703 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2706 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2707 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2708 from_name, PATH_MAX,
2709 cifs_sb->local_nls, remap);
2710 name_len++; /* trailing null */
2712 pSMB->OldFileName[name_len] = 0x04; /* pad */
2713 /* protocol requires ASCII signature byte on Unicode string */
2714 pSMB->OldFileName[name_len + 1] = 0x00;
2716 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2717 to_name, PATH_MAX, cifs_sb->local_nls,
2719 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2720 name_len2 *= 2; /* convert to bytes */
2722 name_len = copy_path_name(pSMB->OldFileName, from_name);
2723 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2724 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2725 name_len2++; /* signature byte */
2728 count = 1 /* 1st signature byte */ + name_len + name_len2;
2729 inc_rfc1001_len(pSMB, count);
2730 pSMB->ByteCount = cpu_to_le16(count);
2732 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2733 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2734 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2736 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2738 cifs_buf_release(pSMB);
2746 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2747 int netfid, const char *target_name,
2748 const struct nls_table *nls_codepage, int remap)
2750 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2751 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2752 struct set_file_rename *rename_info;
2754 char dummy_string[30];
2756 int bytes_returned = 0;
2758 __u16 params, param_offset, offset, count, byte_count;
2760 cifs_dbg(FYI, "Rename to File by handle\n");
2761 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2767 pSMB->MaxSetupCount = 0;
2771 pSMB->Reserved2 = 0;
2772 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2773 offset = param_offset + params;
2775 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2776 data_offset = (char *)(pSMB) + offset + 4;
2777 rename_info = (struct set_file_rename *) data_offset;
2778 pSMB->MaxParameterCount = cpu_to_le16(2);
2779 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2780 pSMB->SetupCount = 1;
2781 pSMB->Reserved3 = 0;
2782 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2783 byte_count = 3 /* pad */ + params;
2784 pSMB->ParameterCount = cpu_to_le16(params);
2785 pSMB->TotalParameterCount = pSMB->ParameterCount;
2786 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2787 pSMB->DataOffset = cpu_to_le16(offset);
2788 /* construct random name ".cifs_tmp<inodenum><mid>" */
2789 rename_info->overwrite = cpu_to_le32(1);
2790 rename_info->root_fid = 0;
2791 /* unicode only call */
2792 if (target_name == NULL) {
2793 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2795 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2796 dummy_string, 24, nls_codepage, remap);
2799 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2800 target_name, PATH_MAX, nls_codepage,
2803 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2804 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2805 byte_count += count;
2806 pSMB->DataCount = cpu_to_le16(count);
2807 pSMB->TotalDataCount = pSMB->DataCount;
2809 pSMB->InformationLevel =
2810 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2811 pSMB->Reserved4 = 0;
2812 inc_rfc1001_len(pSMB, byte_count);
2813 pSMB->ByteCount = cpu_to_le16(byte_count);
2814 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2815 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2816 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2818 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2821 cifs_buf_release(pSMB);
2823 /* Note: On -EAGAIN error only caller can retry on handle based calls
2824 since file handle passed in no longer valid */
2830 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2831 const char *fromName, const __u16 target_tid, const char *toName,
2832 const int flags, const struct nls_table *nls_codepage, int remap)
2835 COPY_REQ *pSMB = NULL;
2836 COPY_RSP *pSMBr = NULL;
2838 int name_len, name_len2;
2841 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2843 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2848 pSMB->BufferFormat = 0x04;
2849 pSMB->Tid2 = target_tid;
2851 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2853 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2854 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2855 fromName, PATH_MAX, nls_codepage,
2857 name_len++; /* trailing null */
2859 pSMB->OldFileName[name_len] = 0x04; /* pad */
2860 /* protocol requires ASCII signature byte on Unicode string */
2861 pSMB->OldFileName[name_len + 1] = 0x00;
2863 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2864 toName, PATH_MAX, nls_codepage, remap);
2865 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2866 name_len2 *= 2; /* convert to bytes */
2868 name_len = copy_path_name(pSMB->OldFileName, fromName);
2869 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2870 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2871 name_len2++; /* signature byte */
2874 count = 1 /* 1st signature byte */ + name_len + name_len2;
2875 inc_rfc1001_len(pSMB, count);
2876 pSMB->ByteCount = cpu_to_le16(count);
2878 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2879 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2881 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2882 rc, le16_to_cpu(pSMBr->CopyCount));
2884 cifs_buf_release(pSMB);
2893 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2894 const char *fromName, const char *toName,
2895 const struct nls_table *nls_codepage, int remap)
2897 TRANSACTION2_SPI_REQ *pSMB = NULL;
2898 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2901 int name_len_target;
2903 int bytes_returned = 0;
2904 __u16 params, param_offset, offset, byte_count;
2906 cifs_dbg(FYI, "In Symlink Unix style\n");
2908 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2913 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2915 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2916 /* find define for this maxpathcomponent */
2917 PATH_MAX, nls_codepage, remap);
2918 name_len++; /* trailing null */
2922 name_len = copy_path_name(pSMB->FileName, fromName);
2924 params = 6 + name_len;
2925 pSMB->MaxSetupCount = 0;
2929 pSMB->Reserved2 = 0;
2930 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2931 InformationLevel) - 4;
2932 offset = param_offset + params;
2934 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2935 data_offset = (char *)pSMB + offset + 4;
2936 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2938 cifsConvertToUTF16((__le16 *) data_offset, toName,
2939 /* find define for this maxpathcomponent */
2940 PATH_MAX, nls_codepage, remap);
2941 name_len_target++; /* trailing null */
2942 name_len_target *= 2;
2944 name_len_target = copy_path_name(data_offset, toName);
2947 pSMB->MaxParameterCount = cpu_to_le16(2);
2948 /* BB find exact max on data count below from sess */
2949 pSMB->MaxDataCount = cpu_to_le16(1000);
2950 pSMB->SetupCount = 1;
2951 pSMB->Reserved3 = 0;
2952 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2953 byte_count = 3 /* pad */ + params + name_len_target;
2954 pSMB->DataCount = cpu_to_le16(name_len_target);
2955 pSMB->ParameterCount = cpu_to_le16(params);
2956 pSMB->TotalDataCount = pSMB->DataCount;
2957 pSMB->TotalParameterCount = pSMB->ParameterCount;
2958 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2959 pSMB->DataOffset = cpu_to_le16(offset);
2960 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2961 pSMB->Reserved4 = 0;
2962 inc_rfc1001_len(pSMB, byte_count);
2963 pSMB->ByteCount = cpu_to_le16(byte_count);
2964 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2965 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2966 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2968 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2971 cifs_buf_release(pSMB);
2974 goto createSymLinkRetry;
2980 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2981 const char *fromName, const char *toName,
2982 const struct nls_table *nls_codepage, int remap)
2984 TRANSACTION2_SPI_REQ *pSMB = NULL;
2985 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2988 int name_len_target;
2990 int bytes_returned = 0;
2991 __u16 params, param_offset, offset, byte_count;
2993 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2994 createHardLinkRetry:
2995 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3000 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3001 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
3002 PATH_MAX, nls_codepage, remap);
3003 name_len++; /* trailing null */
3007 name_len = copy_path_name(pSMB->FileName, toName);
3009 params = 6 + name_len;
3010 pSMB->MaxSetupCount = 0;
3014 pSMB->Reserved2 = 0;
3015 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3016 InformationLevel) - 4;
3017 offset = param_offset + params;
3019 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
3020 data_offset = (char *)pSMB + offset + 4;
3021 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3023 cifsConvertToUTF16((__le16 *) data_offset, fromName,
3024 PATH_MAX, nls_codepage, remap);
3025 name_len_target++; /* trailing null */
3026 name_len_target *= 2;
3028 name_len_target = copy_path_name(data_offset, fromName);
3031 pSMB->MaxParameterCount = cpu_to_le16(2);
3032 /* BB find exact max on data count below from sess*/
3033 pSMB->MaxDataCount = cpu_to_le16(1000);
3034 pSMB->SetupCount = 1;
3035 pSMB->Reserved3 = 0;
3036 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3037 byte_count = 3 /* pad */ + params + name_len_target;
3038 pSMB->ParameterCount = cpu_to_le16(params);
3039 pSMB->TotalParameterCount = pSMB->ParameterCount;
3040 pSMB->DataCount = cpu_to_le16(name_len_target);
3041 pSMB->TotalDataCount = pSMB->DataCount;
3042 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3043 pSMB->DataOffset = cpu_to_le16(offset);
3044 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3045 pSMB->Reserved4 = 0;
3046 inc_rfc1001_len(pSMB, byte_count);
3047 pSMB->ByteCount = cpu_to_le16(byte_count);
3048 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3049 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3050 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3052 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3055 cifs_buf_release(pSMB);
3057 goto createHardLinkRetry;
3063 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3064 const char *from_name, const char *to_name,
3065 struct cifs_sb_info *cifs_sb)
3068 NT_RENAME_REQ *pSMB = NULL;
3069 RENAME_RSP *pSMBr = NULL;
3071 int name_len, name_len2;
3073 int remap = cifs_remap(cifs_sb);
3075 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3076 winCreateHardLinkRetry:
3078 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3083 pSMB->SearchAttributes =
3084 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3086 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3087 pSMB->ClusterCount = 0;
3089 pSMB->BufferFormat = 0x04;
3091 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3093 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3094 PATH_MAX, cifs_sb->local_nls, remap);
3095 name_len++; /* trailing null */
3098 /* protocol specifies ASCII buffer format (0x04) for unicode */
3099 pSMB->OldFileName[name_len] = 0x04;
3100 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3102 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3103 to_name, PATH_MAX, cifs_sb->local_nls,
3105 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3106 name_len2 *= 2; /* convert to bytes */
3108 name_len = copy_path_name(pSMB->OldFileName, from_name);
3109 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3110 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
3111 name_len2++; /* signature byte */
3114 count = 1 /* string type byte */ + name_len + name_len2;
3115 inc_rfc1001_len(pSMB, count);
3116 pSMB->ByteCount = cpu_to_le16(count);
3118 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3119 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3120 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3122 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3124 cifs_buf_release(pSMB);
3126 goto winCreateHardLinkRetry;
3132 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3133 const unsigned char *searchName, char **symlinkinfo,
3134 const struct nls_table *nls_codepage, int remap)
3136 /* SMB_QUERY_FILE_UNIX_LINK */
3137 TRANSACTION2_QPI_REQ *pSMB = NULL;
3138 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3142 __u16 params, byte_count;
3145 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3148 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3153 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3155 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3156 searchName, PATH_MAX, nls_codepage,
3158 name_len++; /* trailing null */
3161 name_len = copy_path_name(pSMB->FileName, searchName);
3164 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3165 pSMB->TotalDataCount = 0;
3166 pSMB->MaxParameterCount = cpu_to_le16(2);
3167 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3168 pSMB->MaxSetupCount = 0;
3172 pSMB->Reserved2 = 0;
3173 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3174 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3175 pSMB->DataCount = 0;
3176 pSMB->DataOffset = 0;
3177 pSMB->SetupCount = 1;
3178 pSMB->Reserved3 = 0;
3179 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3180 byte_count = params + 1 /* pad */ ;
3181 pSMB->TotalParameterCount = cpu_to_le16(params);
3182 pSMB->ParameterCount = pSMB->TotalParameterCount;
3183 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3184 pSMB->Reserved4 = 0;
3185 inc_rfc1001_len(pSMB, byte_count);
3186 pSMB->ByteCount = cpu_to_le16(byte_count);
3188 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3189 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3191 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3193 /* decode response */
3195 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3196 /* BB also check enough total bytes returned */
3197 if (rc || get_bcc(&pSMBr->hdr) < 2)
3201 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3203 data_start = ((char *) &pSMBr->hdr.Protocol) +
3204 le16_to_cpu(pSMBr->t2.DataOffset);
3206 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3211 /* BB FIXME investigate remapping reserved chars here */
3212 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3213 count, is_unicode, nls_codepage);
3218 cifs_buf_release(pSMB);
3220 goto querySymLinkRetry;
3225 * Recent Windows versions now create symlinks more frequently
3226 * and they use the "reparse point" mechanism below. We can of course
3227 * do symlinks nicely to Samba and other servers which support the
3228 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3229 * "MF" symlinks optionally, but for recent Windows we really need to
3230 * reenable the code below and fix the cifs_symlink callers to handle this.
3231 * In the interim this code has been moved to its own config option so
3232 * it is not compiled in by default until callers fixed up and more tested.
3235 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3236 __u16 fid, char **symlinkinfo,
3237 const struct nls_table *nls_codepage)
3241 struct smb_com_transaction_ioctl_req *pSMB;
3242 struct smb_com_transaction_ioctl_rsp *pSMBr;
3244 unsigned int sub_len;
3246 struct reparse_symlink_data *reparse_buf;
3247 struct reparse_posix_data *posix_buf;
3248 __u32 data_offset, data_count;
3251 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3252 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3257 pSMB->TotalParameterCount = 0 ;
3258 pSMB->TotalDataCount = 0;
3259 pSMB->MaxParameterCount = cpu_to_le32(2);
3260 /* BB find exact data count max from sess structure BB */
3261 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3262 pSMB->MaxSetupCount = 4;
3264 pSMB->ParameterOffset = 0;
3265 pSMB->DataCount = 0;
3266 pSMB->DataOffset = 0;
3267 pSMB->SetupCount = 4;
3268 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3269 pSMB->ParameterCount = pSMB->TotalParameterCount;
3270 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3271 pSMB->IsFsctl = 1; /* FSCTL */
3272 pSMB->IsRootFlag = 0;
3273 pSMB->Fid = fid; /* file handle always le */
3274 pSMB->ByteCount = 0;
3276 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3277 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3279 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3283 data_offset = le32_to_cpu(pSMBr->DataOffset);
3284 data_count = le32_to_cpu(pSMBr->DataCount);
3285 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3286 /* BB also check enough total bytes returned */
3287 rc = -EIO; /* bad smb */
3290 if (!data_count || (data_count > 2048)) {
3292 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3295 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3296 reparse_buf = (struct reparse_symlink_data *)
3297 ((char *)&pSMBr->hdr.Protocol + data_offset);
3298 if ((char *)reparse_buf >= end_of_smb) {
3302 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3303 cifs_dbg(FYI, "NFS style reparse tag\n");
3304 posix_buf = (struct reparse_posix_data *)reparse_buf;
3306 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3307 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3308 le64_to_cpu(posix_buf->InodeType));
3313 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3314 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3315 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3319 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3320 sub_len, is_unicode, nls_codepage);
3322 } else if (reparse_buf->ReparseTag !=
3323 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3328 /* Reparse tag is NTFS symlink */
3329 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3330 reparse_buf->PathBuffer;
3331 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3332 if (sub_start + sub_len > end_of_smb) {
3333 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3337 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3342 /* BB FIXME investigate remapping reserved chars here */
3343 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3348 cifs_buf_release(pSMB);
3351 * Note: On -EAGAIN error only caller can retry on handle based calls
3352 * since file handle passed in no longer valid.
3358 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3363 struct smb_com_transaction_compr_ioctl_req *pSMB;
3364 struct smb_com_transaction_ioctl_rsp *pSMBr;
3366 cifs_dbg(FYI, "Set compression for %u\n", fid);
3367 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3372 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3374 pSMB->TotalParameterCount = 0;
3375 pSMB->TotalDataCount = cpu_to_le32(2);
3376 pSMB->MaxParameterCount = 0;
3377 pSMB->MaxDataCount = 0;
3378 pSMB->MaxSetupCount = 4;
3380 pSMB->ParameterOffset = 0;
3381 pSMB->DataCount = cpu_to_le32(2);
3383 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3384 compression_state) - 4); /* 84 */
3385 pSMB->SetupCount = 4;
3386 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3387 pSMB->ParameterCount = 0;
3388 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3389 pSMB->IsFsctl = 1; /* FSCTL */
3390 pSMB->IsRootFlag = 0;
3391 pSMB->Fid = fid; /* file handle always le */
3392 /* 3 byte pad, followed by 2 byte compress state */
3393 pSMB->ByteCount = cpu_to_le16(5);
3394 inc_rfc1001_len(pSMB, 5);
3396 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3397 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3399 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3401 cifs_buf_release(pSMB);
3404 * Note: On -EAGAIN error only caller can retry on handle based calls
3405 * since file handle passed in no longer valid.
3411 #ifdef CONFIG_CIFS_POSIX
3413 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3414 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3415 struct cifs_posix_ace *cifs_ace)
3417 /* u8 cifs fields do not need le conversion */
3418 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3419 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3420 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3422 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3423 ace->e_perm, ace->e_tag, ace->e_id);
3429 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3430 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3431 const int acl_type, const int size_of_data_area)
3436 struct cifs_posix_ace *pACE;
3437 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3438 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3440 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3443 if (acl_type == ACL_TYPE_ACCESS) {
3444 count = le16_to_cpu(cifs_acl->access_entry_count);
3445 pACE = &cifs_acl->ace_array[0];
3446 size = sizeof(struct cifs_posix_acl);
3447 size += sizeof(struct cifs_posix_ace) * count;
3448 /* check if we would go beyond end of SMB */
3449 if (size_of_data_area < size) {
3450 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3451 size_of_data_area, size);
3454 } else if (acl_type == ACL_TYPE_DEFAULT) {
3455 count = le16_to_cpu(cifs_acl->access_entry_count);
3456 size = sizeof(struct cifs_posix_acl);
3457 size += sizeof(struct cifs_posix_ace) * count;
3458 /* skip past access ACEs to get to default ACEs */
3459 pACE = &cifs_acl->ace_array[count];
3460 count = le16_to_cpu(cifs_acl->default_entry_count);
3461 size += sizeof(struct cifs_posix_ace) * count;
3462 /* check if we would go beyond end of SMB */
3463 if (size_of_data_area < size)
3470 size = posix_acl_xattr_size(count);
3471 if ((buflen == 0) || (local_acl == NULL)) {
3472 /* used to query ACL EA size */
3473 } else if (size > buflen) {
3475 } else /* buffer big enough */ {
3476 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3478 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3479 for (i = 0; i < count ; i++) {
3480 cifs_convert_ace(&ace[i], pACE);
3487 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3488 const struct posix_acl_xattr_entry *local_ace)
3490 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3491 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3492 /* BB is there a better way to handle the large uid? */
3493 if (local_ace->e_id == cpu_to_le32(-1)) {
3494 /* Probably no need to le convert -1 on any arch but can not hurt */
3495 cifs_ace->cifs_uid = cpu_to_le64(-1);
3497 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3499 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3500 ace->e_perm, ace->e_tag, ace->e_id);
3504 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3505 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3506 const int buflen, const int acl_type)
3509 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3510 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3511 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3515 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3518 count = posix_acl_xattr_count((size_t)buflen);
3519 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3520 count, buflen, le32_to_cpu(local_acl->a_version));
3521 if (le32_to_cpu(local_acl->a_version) != 2) {
3522 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3523 le32_to_cpu(local_acl->a_version));
3526 cifs_acl->version = cpu_to_le16(1);
3527 if (acl_type == ACL_TYPE_ACCESS) {
3528 cifs_acl->access_entry_count = cpu_to_le16(count);
3529 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3530 } else if (acl_type == ACL_TYPE_DEFAULT) {
3531 cifs_acl->default_entry_count = cpu_to_le16(count);
3532 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3534 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3537 for (i = 0; i < count; i++)
3538 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3540 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3541 rc += sizeof(struct cifs_posix_acl);
3542 /* BB add check to make sure ACL does not overflow SMB */
3548 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3549 const unsigned char *searchName,
3550 char *acl_inf, const int buflen, const int acl_type,
3551 const struct nls_table *nls_codepage, int remap)
3553 /* SMB_QUERY_POSIX_ACL */
3554 TRANSACTION2_QPI_REQ *pSMB = NULL;
3555 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3559 __u16 params, byte_count;
3561 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3564 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3569 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3571 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3572 searchName, PATH_MAX, nls_codepage,
3574 name_len++; /* trailing null */
3576 pSMB->FileName[name_len] = 0;
3577 pSMB->FileName[name_len+1] = 0;
3579 name_len = copy_path_name(pSMB->FileName, searchName);
3582 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3583 pSMB->TotalDataCount = 0;
3584 pSMB->MaxParameterCount = cpu_to_le16(2);
3585 /* BB find exact max data count below from sess structure BB */
3586 pSMB->MaxDataCount = cpu_to_le16(4000);
3587 pSMB->MaxSetupCount = 0;
3591 pSMB->Reserved2 = 0;
3592 pSMB->ParameterOffset = cpu_to_le16(
3593 offsetof(struct smb_com_transaction2_qpi_req,
3594 InformationLevel) - 4);
3595 pSMB->DataCount = 0;
3596 pSMB->DataOffset = 0;
3597 pSMB->SetupCount = 1;
3598 pSMB->Reserved3 = 0;
3599 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3600 byte_count = params + 1 /* pad */ ;
3601 pSMB->TotalParameterCount = cpu_to_le16(params);
3602 pSMB->ParameterCount = pSMB->TotalParameterCount;
3603 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3604 pSMB->Reserved4 = 0;
3605 inc_rfc1001_len(pSMB, byte_count);
3606 pSMB->ByteCount = cpu_to_le16(byte_count);
3608 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3609 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3610 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3612 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3614 /* decode response */
3616 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3617 /* BB also check enough total bytes returned */
3618 if (rc || get_bcc(&pSMBr->hdr) < 2)
3619 rc = -EIO; /* bad smb */
3621 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3622 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3623 rc = cifs_copy_posix_acl(acl_inf,
3624 (char *)&pSMBr->hdr.Protocol+data_offset,
3625 buflen, acl_type, count);
3628 cifs_buf_release(pSMB);
3635 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3636 const unsigned char *fileName,
3637 const char *local_acl, const int buflen,
3639 const struct nls_table *nls_codepage, int remap)
3641 struct smb_com_transaction2_spi_req *pSMB = NULL;
3642 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3646 int bytes_returned = 0;
3647 __u16 params, byte_count, data_count, param_offset, offset;
3649 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3651 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3655 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3657 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3658 PATH_MAX, nls_codepage, remap);
3659 name_len++; /* trailing null */
3662 name_len = copy_path_name(pSMB->FileName, fileName);
3664 params = 6 + name_len;
3665 pSMB->MaxParameterCount = cpu_to_le16(2);
3666 /* BB find max SMB size from sess */
3667 pSMB->MaxDataCount = cpu_to_le16(1000);
3668 pSMB->MaxSetupCount = 0;
3672 pSMB->Reserved2 = 0;
3673 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3674 InformationLevel) - 4;
3675 offset = param_offset + params;
3676 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3677 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3679 /* convert to on the wire format for POSIX ACL */
3680 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3682 if (data_count == 0) {
3684 goto setACLerrorExit;
3686 pSMB->DataOffset = cpu_to_le16(offset);
3687 pSMB->SetupCount = 1;
3688 pSMB->Reserved3 = 0;
3689 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3690 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3691 byte_count = 3 /* pad */ + params + data_count;
3692 pSMB->DataCount = cpu_to_le16(data_count);
3693 pSMB->TotalDataCount = pSMB->DataCount;
3694 pSMB->ParameterCount = cpu_to_le16(params);
3695 pSMB->TotalParameterCount = pSMB->ParameterCount;
3696 pSMB->Reserved4 = 0;
3697 inc_rfc1001_len(pSMB, byte_count);
3698 pSMB->ByteCount = cpu_to_le16(byte_count);
3699 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3700 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3702 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3705 cifs_buf_release(pSMB);
3711 /* BB fix tabs in this function FIXME BB */
3713 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3714 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3717 struct smb_t2_qfi_req *pSMB = NULL;
3718 struct smb_t2_qfi_rsp *pSMBr = NULL;
3720 __u16 params, byte_count;
3722 cifs_dbg(FYI, "In GetExtAttr\n");
3727 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3732 params = 2 /* level */ + 2 /* fid */;
3733 pSMB->t2.TotalDataCount = 0;
3734 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3735 /* BB find exact max data count below from sess structure BB */
3736 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3737 pSMB->t2.MaxSetupCount = 0;
3738 pSMB->t2.Reserved = 0;
3740 pSMB->t2.Timeout = 0;
3741 pSMB->t2.Reserved2 = 0;
3742 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3744 pSMB->t2.DataCount = 0;
3745 pSMB->t2.DataOffset = 0;
3746 pSMB->t2.SetupCount = 1;
3747 pSMB->t2.Reserved3 = 0;
3748 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3749 byte_count = params + 1 /* pad */ ;
3750 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3751 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3752 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3755 inc_rfc1001_len(pSMB, byte_count);
3756 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3758 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3759 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3761 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3763 /* decode response */
3764 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3765 /* BB also check enough total bytes returned */
3766 if (rc || get_bcc(&pSMBr->hdr) < 2)
3767 /* If rc should we check for EOPNOSUPP and
3768 disable the srvino flag? or in caller? */
3769 rc = -EIO; /* bad smb */
3771 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3772 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3773 struct file_chattr_info *pfinfo;
3774 /* BB Do we need a cast or hash here ? */
3776 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3780 pfinfo = (struct file_chattr_info *)
3781 (data_offset + (char *) &pSMBr->hdr.Protocol);
3782 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3783 *pMask = le64_to_cpu(pfinfo->mask);
3787 cifs_buf_release(pSMB);
3789 goto GetExtAttrRetry;
3793 #endif /* CONFIG_POSIX */
3796 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3797 * all NT TRANSACTS that we init here have total parm and data under about 400
3798 * bytes (to fit in small cifs buffer size), which is the case so far, it
3799 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3800 * returned setup area) and MaxParameterCount (returned parms size) must be set
3804 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3805 const int parm_len, struct cifs_tcon *tcon,
3810 struct smb_com_ntransact_req *pSMB;
3812 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3816 *ret_buf = (void *)pSMB;
3818 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3819 pSMB->TotalDataCount = 0;
3820 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3821 pSMB->ParameterCount = pSMB->TotalParameterCount;
3822 pSMB->DataCount = pSMB->TotalDataCount;
3823 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3824 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3825 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3826 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3827 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3828 pSMB->SubCommand = cpu_to_le16(sub_command);
3833 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3834 __u32 *pparmlen, __u32 *pdatalen)
3837 __u32 data_count, data_offset, parm_count, parm_offset;
3838 struct smb_com_ntransact_rsp *pSMBr;
3847 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3849 bcc = get_bcc(&pSMBr->hdr);
3850 end_of_smb = 2 /* sizeof byte count */ + bcc +
3851 (char *)&pSMBr->ByteCount;
3853 data_offset = le32_to_cpu(pSMBr->DataOffset);
3854 data_count = le32_to_cpu(pSMBr->DataCount);
3855 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3856 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3858 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3859 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3861 /* should we also check that parm and data areas do not overlap? */
3862 if (*ppparm > end_of_smb) {
3863 cifs_dbg(FYI, "parms start after end of smb\n");
3865 } else if (parm_count + *ppparm > end_of_smb) {
3866 cifs_dbg(FYI, "parm end after end of smb\n");
3868 } else if (*ppdata > end_of_smb) {
3869 cifs_dbg(FYI, "data starts after end of smb\n");
3871 } else if (data_count + *ppdata > end_of_smb) {
3872 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3873 *ppdata, data_count, (data_count + *ppdata),
3876 } else if (parm_count + data_count > bcc) {
3877 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3880 *pdatalen = data_count;
3881 *pparmlen = parm_count;
3885 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3887 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3888 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3892 QUERY_SEC_DESC_REQ *pSMB;
3894 struct kvec rsp_iov;
3896 cifs_dbg(FYI, "GetCifsACL\n");
3901 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3902 8 /* parm len */, tcon, (void **) &pSMB);
3906 pSMB->MaxParameterCount = cpu_to_le32(4);
3907 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3908 pSMB->MaxSetupCount = 0;
3909 pSMB->Fid = fid; /* file handle always le */
3910 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3912 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3913 inc_rfc1001_len(pSMB, 11);
3914 iov[0].iov_base = (char *)pSMB;
3915 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3917 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3919 cifs_small_buf_release(pSMB);
3920 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3922 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3923 } else { /* decode response */
3927 struct smb_com_ntransact_rsp *pSMBr;
3930 /* validate_nttransact */
3931 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3932 &pdata, &parm_len, pbuflen);
3935 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3937 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3938 pSMBr, parm, *acl_inf);
3940 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3941 rc = -EIO; /* bad smb */
3946 /* BB check that data area is minimum length and as big as acl_len */
3948 acl_len = le32_to_cpu(*parm);
3949 if (acl_len != *pbuflen) {
3950 cifs_dbg(VFS, "acl length %d does not match %d\n",
3952 if (*pbuflen > acl_len)
3956 /* check if buffer is big enough for the acl
3957 header followed by the smallest SID */
3958 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3959 (*pbuflen >= 64 * 1024)) {
3960 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3964 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3965 if (*acl_inf == NULL) {
3972 free_rsp_buf(buf_type, rsp_iov.iov_base);
3977 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3978 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3980 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3982 int bytes_returned = 0;
3983 SET_SEC_DESC_REQ *pSMB = NULL;
3987 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3991 pSMB->MaxSetupCount = 0;
3995 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3996 data_count = acllen;
3997 data_offset = param_offset + param_count;
3998 byte_count = 3 /* pad */ + param_count;
4000 pSMB->DataCount = cpu_to_le32(data_count);
4001 pSMB->TotalDataCount = pSMB->DataCount;
4002 pSMB->MaxParameterCount = cpu_to_le32(4);
4003 pSMB->MaxDataCount = cpu_to_le32(16384);
4004 pSMB->ParameterCount = cpu_to_le32(param_count);
4005 pSMB->ParameterOffset = cpu_to_le32(param_offset);
4006 pSMB->TotalParameterCount = pSMB->ParameterCount;
4007 pSMB->DataOffset = cpu_to_le32(data_offset);
4008 pSMB->SetupCount = 0;
4009 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
4010 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
4012 pSMB->Fid = fid; /* file handle always le */
4013 pSMB->Reserved2 = 0;
4014 pSMB->AclFlags = cpu_to_le32(aclflag);
4016 if (pntsd && acllen) {
4017 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
4018 data_offset, pntsd, acllen);
4019 inc_rfc1001_len(pSMB, byte_count + data_count);
4021 inc_rfc1001_len(pSMB, byte_count);
4023 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4024 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4026 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4027 bytes_returned, rc);
4029 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
4030 cifs_buf_release(pSMB);
4033 goto setCifsAclRetry;
4039 /* Legacy Query Path Information call for lookup to old servers such
4042 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
4043 const char *search_name, FILE_ALL_INFO *data,
4044 const struct nls_table *nls_codepage, int remap)
4046 QUERY_INFORMATION_REQ *pSMB;
4047 QUERY_INFORMATION_RSP *pSMBr;
4052 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4054 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4059 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4061 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4062 search_name, PATH_MAX, nls_codepage,
4064 name_len++; /* trailing null */
4067 name_len = copy_path_name(pSMB->FileName, search_name);
4069 pSMB->BufferFormat = 0x04;
4070 name_len++; /* account for buffer type byte */
4071 inc_rfc1001_len(pSMB, (__u16)name_len);
4072 pSMB->ByteCount = cpu_to_le16(name_len);
4074 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4075 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4077 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4079 struct timespec64 ts;
4080 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4082 /* decode response */
4083 /* BB FIXME - add time zone adjustment BB */
4084 memset(data, 0, sizeof(FILE_ALL_INFO));
4087 /* decode time fields */
4088 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4089 data->LastWriteTime = data->ChangeTime;
4090 data->LastAccessTime = 0;
4091 data->AllocationSize =
4092 cpu_to_le64(le32_to_cpu(pSMBr->size));
4093 data->EndOfFile = data->AllocationSize;
4095 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4097 rc = -EIO; /* bad buffer passed in */
4099 cifs_buf_release(pSMB);
4108 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4109 u16 netfid, FILE_ALL_INFO *pFindData)
4111 struct smb_t2_qfi_req *pSMB = NULL;
4112 struct smb_t2_qfi_rsp *pSMBr = NULL;
4115 __u16 params, byte_count;
4118 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4123 params = 2 /* level */ + 2 /* fid */;
4124 pSMB->t2.TotalDataCount = 0;
4125 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4126 /* BB find exact max data count below from sess structure BB */
4127 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4128 pSMB->t2.MaxSetupCount = 0;
4129 pSMB->t2.Reserved = 0;
4131 pSMB->t2.Timeout = 0;
4132 pSMB->t2.Reserved2 = 0;
4133 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4135 pSMB->t2.DataCount = 0;
4136 pSMB->t2.DataOffset = 0;
4137 pSMB->t2.SetupCount = 1;
4138 pSMB->t2.Reserved3 = 0;
4139 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4140 byte_count = params + 1 /* pad */ ;
4141 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4142 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4143 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4146 inc_rfc1001_len(pSMB, byte_count);
4147 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4149 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4150 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4152 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
4153 } else { /* decode response */
4154 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4156 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4158 else if (get_bcc(&pSMBr->hdr) < 40)
4159 rc = -EIO; /* bad smb */
4160 else if (pFindData) {
4161 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4162 memcpy((char *) pFindData,
4163 (char *) &pSMBr->hdr.Protocol +
4164 data_offset, sizeof(FILE_ALL_INFO));
4168 cifs_buf_release(pSMB);
4170 goto QFileInfoRetry;
4176 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4177 const char *search_name, FILE_ALL_INFO *data,
4178 int legacy /* old style infolevel */,
4179 const struct nls_table *nls_codepage, int remap)
4181 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4182 TRANSACTION2_QPI_REQ *pSMB = NULL;
4183 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4187 __u16 params, byte_count;
4189 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4191 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4196 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4198 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4199 PATH_MAX, nls_codepage, remap);
4200 name_len++; /* trailing null */
4203 name_len = copy_path_name(pSMB->FileName, search_name);
4206 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4207 pSMB->TotalDataCount = 0;
4208 pSMB->MaxParameterCount = cpu_to_le16(2);
4209 /* BB find exact max SMB PDU from sess structure BB */
4210 pSMB->MaxDataCount = cpu_to_le16(4000);
4211 pSMB->MaxSetupCount = 0;
4215 pSMB->Reserved2 = 0;
4216 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4217 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4218 pSMB->DataCount = 0;
4219 pSMB->DataOffset = 0;
4220 pSMB->SetupCount = 1;
4221 pSMB->Reserved3 = 0;
4222 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4223 byte_count = params + 1 /* pad */ ;
4224 pSMB->TotalParameterCount = cpu_to_le16(params);
4225 pSMB->ParameterCount = pSMB->TotalParameterCount;
4227 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4229 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4230 pSMB->Reserved4 = 0;
4231 inc_rfc1001_len(pSMB, byte_count);
4232 pSMB->ByteCount = cpu_to_le16(byte_count);
4234 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4235 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4237 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4238 } else { /* decode response */
4239 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4241 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4243 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4244 rc = -EIO; /* bad smb */
4245 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4246 rc = -EIO; /* 24 or 26 expected but we do not read
4250 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4253 * On legacy responses we do not read the last field,
4254 * EAsize, fortunately since it varies by subdialect and
4255 * also note it differs on Set vs Get, ie two bytes or 4
4256 * bytes depending but we don't care here.
4259 size = sizeof(FILE_INFO_STANDARD);
4261 size = sizeof(FILE_ALL_INFO);
4262 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4267 cifs_buf_release(pSMB);
4269 goto QPathInfoRetry;
4275 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4276 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4278 struct smb_t2_qfi_req *pSMB = NULL;
4279 struct smb_t2_qfi_rsp *pSMBr = NULL;
4282 __u16 params, byte_count;
4285 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4290 params = 2 /* level */ + 2 /* fid */;
4291 pSMB->t2.TotalDataCount = 0;
4292 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4293 /* BB find exact max data count below from sess structure BB */
4294 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4295 pSMB->t2.MaxSetupCount = 0;
4296 pSMB->t2.Reserved = 0;
4298 pSMB->t2.Timeout = 0;
4299 pSMB->t2.Reserved2 = 0;
4300 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4302 pSMB->t2.DataCount = 0;
4303 pSMB->t2.DataOffset = 0;
4304 pSMB->t2.SetupCount = 1;
4305 pSMB->t2.Reserved3 = 0;
4306 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4307 byte_count = params + 1 /* pad */ ;
4308 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4309 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4310 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4313 inc_rfc1001_len(pSMB, byte_count);
4314 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4316 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4317 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4319 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
4320 } else { /* decode response */
4321 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4323 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4324 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4325 rc = -EIO; /* bad smb */
4327 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4328 memcpy((char *) pFindData,
4329 (char *) &pSMBr->hdr.Protocol +
4331 sizeof(FILE_UNIX_BASIC_INFO));
4335 cifs_buf_release(pSMB);
4337 goto UnixQFileInfoRetry;
4343 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4344 const unsigned char *searchName,
4345 FILE_UNIX_BASIC_INFO *pFindData,
4346 const struct nls_table *nls_codepage, int remap)
4348 /* SMB_QUERY_FILE_UNIX_BASIC */
4349 TRANSACTION2_QPI_REQ *pSMB = NULL;
4350 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4352 int bytes_returned = 0;
4354 __u16 params, byte_count;
4356 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4358 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4363 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4365 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4366 PATH_MAX, nls_codepage, remap);
4367 name_len++; /* trailing null */
4370 name_len = copy_path_name(pSMB->FileName, searchName);
4373 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4374 pSMB->TotalDataCount = 0;
4375 pSMB->MaxParameterCount = cpu_to_le16(2);
4376 /* BB find exact max SMB PDU from sess structure BB */
4377 pSMB->MaxDataCount = cpu_to_le16(4000);
4378 pSMB->MaxSetupCount = 0;
4382 pSMB->Reserved2 = 0;
4383 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4384 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4385 pSMB->DataCount = 0;
4386 pSMB->DataOffset = 0;
4387 pSMB->SetupCount = 1;
4388 pSMB->Reserved3 = 0;
4389 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4390 byte_count = params + 1 /* pad */ ;
4391 pSMB->TotalParameterCount = cpu_to_le16(params);
4392 pSMB->ParameterCount = pSMB->TotalParameterCount;
4393 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4394 pSMB->Reserved4 = 0;
4395 inc_rfc1001_len(pSMB, byte_count);
4396 pSMB->ByteCount = cpu_to_le16(byte_count);
4398 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4399 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4401 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
4402 } else { /* decode response */
4403 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4405 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4406 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4407 rc = -EIO; /* bad smb */
4409 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4410 memcpy((char *) pFindData,
4411 (char *) &pSMBr->hdr.Protocol +
4413 sizeof(FILE_UNIX_BASIC_INFO));
4416 cifs_buf_release(pSMB);
4418 goto UnixQPathInfoRetry;
4423 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4425 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4426 const char *searchName, struct cifs_sb_info *cifs_sb,
4427 __u16 *pnetfid, __u16 search_flags,
4428 struct cifs_search_info *psrch_inf, bool msearch)
4430 /* level 257 SMB_ */
4431 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4432 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4433 T2_FFIRST_RSP_PARMS *parms;
4435 int bytes_returned = 0;
4436 int name_len, remap;
4437 __u16 params, byte_count;
4438 struct nls_table *nls_codepage;
4440 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4443 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4448 nls_codepage = cifs_sb->local_nls;
4449 remap = cifs_remap(cifs_sb);
4451 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4453 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4454 PATH_MAX, nls_codepage, remap);
4455 /* We can not add the asterik earlier in case
4456 it got remapped to 0xF03A as if it were part of the
4457 directory name instead of a wildcard */
4460 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4461 pSMB->FileName[name_len+1] = 0;
4462 pSMB->FileName[name_len+2] = '*';
4463 pSMB->FileName[name_len+3] = 0;
4464 name_len += 4; /* now the trailing null */
4465 /* null terminate just in case */
4466 pSMB->FileName[name_len] = 0;
4467 pSMB->FileName[name_len+1] = 0;
4471 name_len = copy_path_name(pSMB->FileName, searchName);
4473 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4474 name_len = PATH_MAX-2;
4475 /* overwrite nul byte */
4476 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4477 pSMB->FileName[name_len] = '*';
4478 pSMB->FileName[name_len+1] = 0;
4483 params = 12 + name_len /* includes null */ ;
4484 pSMB->TotalDataCount = 0; /* no EAs */
4485 pSMB->MaxParameterCount = cpu_to_le16(10);
4486 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4487 pSMB->MaxSetupCount = 0;
4491 pSMB->Reserved2 = 0;
4492 byte_count = params + 1 /* pad */ ;
4493 pSMB->TotalParameterCount = cpu_to_le16(params);
4494 pSMB->ParameterCount = pSMB->TotalParameterCount;
4495 pSMB->ParameterOffset = cpu_to_le16(
4496 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4498 pSMB->DataCount = 0;
4499 pSMB->DataOffset = 0;
4500 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4501 pSMB->Reserved3 = 0;
4502 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4503 pSMB->SearchAttributes =
4504 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4506 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4507 pSMB->SearchFlags = cpu_to_le16(search_flags);
4508 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4510 /* BB what should we set StorageType to? Does it matter? BB */
4511 pSMB->SearchStorageType = 0;
4512 inc_rfc1001_len(pSMB, byte_count);
4513 pSMB->ByteCount = cpu_to_le16(byte_count);
4515 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4516 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4517 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4519 if (rc) {/* BB add logic to retry regular search if Unix search
4520 rejected unexpectedly by server */
4521 /* BB Add code to handle unsupported level rc */
4522 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4524 cifs_buf_release(pSMB);
4526 /* BB eventually could optimize out free and realloc of buf */
4529 goto findFirstRetry;
4530 } else { /* decode response */
4531 /* BB remember to free buffer if error BB */
4532 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4536 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4537 psrch_inf->unicode = true;
4539 psrch_inf->unicode = false;
4541 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4542 psrch_inf->smallBuf = false;
4543 psrch_inf->srch_entries_start =
4544 (char *) &pSMBr->hdr.Protocol +
4545 le16_to_cpu(pSMBr->t2.DataOffset);
4546 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4547 le16_to_cpu(pSMBr->t2.ParameterOffset));
4549 if (parms->EndofSearch)
4550 psrch_inf->endOfSearch = true;
4552 psrch_inf->endOfSearch = false;
4554 psrch_inf->entries_in_buffer =
4555 le16_to_cpu(parms->SearchCount);
4556 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4557 psrch_inf->entries_in_buffer;
4558 lnoff = le16_to_cpu(parms->LastNameOffset);
4559 if (CIFSMaxBufSize < lnoff) {
4560 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4561 psrch_inf->last_entry = NULL;
4565 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4569 *pnetfid = parms->SearchHandle;
4571 cifs_buf_release(pSMB);
4578 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4579 __u16 searchHandle, __u16 search_flags,
4580 struct cifs_search_info *psrch_inf)
4582 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4583 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4584 T2_FNEXT_RSP_PARMS *parms;
4585 char *response_data;
4588 unsigned int name_len;
4589 __u16 params, byte_count;
4591 cifs_dbg(FYI, "In FindNext\n");
4593 if (psrch_inf->endOfSearch)
4596 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4601 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4603 pSMB->TotalDataCount = 0; /* no EAs */
4604 pSMB->MaxParameterCount = cpu_to_le16(8);
4605 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4606 pSMB->MaxSetupCount = 0;
4610 pSMB->Reserved2 = 0;
4611 pSMB->ParameterOffset = cpu_to_le16(
4612 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4613 pSMB->DataCount = 0;
4614 pSMB->DataOffset = 0;
4615 pSMB->SetupCount = 1;
4616 pSMB->Reserved3 = 0;
4617 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4618 pSMB->SearchHandle = searchHandle; /* always kept as le */
4620 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4621 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4622 pSMB->ResumeKey = psrch_inf->resume_key;
4623 pSMB->SearchFlags = cpu_to_le16(search_flags);
4625 name_len = psrch_inf->resume_name_len;
4627 if (name_len < PATH_MAX) {
4628 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4629 byte_count += name_len;
4630 /* 14 byte parm len above enough for 2 byte null terminator */
4631 pSMB->ResumeFileName[name_len] = 0;
4632 pSMB->ResumeFileName[name_len+1] = 0;
4635 goto FNext2_err_exit;
4637 byte_count = params + 1 /* pad */ ;
4638 pSMB->TotalParameterCount = cpu_to_le16(params);
4639 pSMB->ParameterCount = pSMB->TotalParameterCount;
4640 inc_rfc1001_len(pSMB, byte_count);
4641 pSMB->ByteCount = cpu_to_le16(byte_count);
4643 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4644 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4645 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4648 psrch_inf->endOfSearch = true;
4649 cifs_buf_release(pSMB);
4650 rc = 0; /* search probably was closed at end of search*/
4652 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4653 } else { /* decode response */
4654 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4659 /* BB fixme add lock for file (srch_info) struct here */
4660 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4661 psrch_inf->unicode = true;
4663 psrch_inf->unicode = false;
4664 response_data = (char *) &pSMBr->hdr.Protocol +
4665 le16_to_cpu(pSMBr->t2.ParameterOffset);
4666 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4667 response_data = (char *)&pSMBr->hdr.Protocol +
4668 le16_to_cpu(pSMBr->t2.DataOffset);
4669 if (psrch_inf->smallBuf)
4670 cifs_small_buf_release(
4671 psrch_inf->ntwrk_buf_start);
4673 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4674 psrch_inf->srch_entries_start = response_data;
4675 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4676 psrch_inf->smallBuf = false;
4677 if (parms->EndofSearch)
4678 psrch_inf->endOfSearch = true;
4680 psrch_inf->endOfSearch = false;
4681 psrch_inf->entries_in_buffer =
4682 le16_to_cpu(parms->SearchCount);
4683 psrch_inf->index_of_last_entry +=
4684 psrch_inf->entries_in_buffer;
4685 lnoff = le16_to_cpu(parms->LastNameOffset);
4686 if (CIFSMaxBufSize < lnoff) {
4687 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4688 psrch_inf->last_entry = NULL;
4691 psrch_inf->last_entry =
4692 psrch_inf->srch_entries_start + lnoff;
4694 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4695 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4697 /* BB fixme add unlock here */
4702 /* BB On error, should we leave previous search buf (and count and
4703 last entry fields) intact or free the previous one? */
4705 /* Note: On -EAGAIN error only caller can retry on handle based calls
4706 since file handle passed in no longer valid */
4709 cifs_buf_release(pSMB);
4714 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4715 const __u16 searchHandle)
4718 FINDCLOSE_REQ *pSMB = NULL;
4720 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4721 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4723 /* no sense returning error if session restarted
4724 as file handle has been closed */
4730 pSMB->FileID = searchHandle;
4731 pSMB->ByteCount = 0;
4732 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4733 cifs_small_buf_release(pSMB);
4735 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4737 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4739 /* Since session is dead, search handle closed on server already */
4747 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4748 const char *search_name, __u64 *inode_number,
4749 const struct nls_table *nls_codepage, int remap)
4752 TRANSACTION2_QPI_REQ *pSMB = NULL;
4753 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4754 int name_len, bytes_returned;
4755 __u16 params, byte_count;
4757 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4761 GetInodeNumberRetry:
4762 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4767 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4769 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4770 search_name, PATH_MAX, nls_codepage,
4772 name_len++; /* trailing null */
4775 name_len = copy_path_name(pSMB->FileName, search_name);
4778 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4779 pSMB->TotalDataCount = 0;
4780 pSMB->MaxParameterCount = cpu_to_le16(2);
4781 /* BB find exact max data count below from sess structure BB */
4782 pSMB->MaxDataCount = cpu_to_le16(4000);
4783 pSMB->MaxSetupCount = 0;
4787 pSMB->Reserved2 = 0;
4788 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4789 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4790 pSMB->DataCount = 0;
4791 pSMB->DataOffset = 0;
4792 pSMB->SetupCount = 1;
4793 pSMB->Reserved3 = 0;
4794 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4795 byte_count = params + 1 /* pad */ ;
4796 pSMB->TotalParameterCount = cpu_to_le16(params);
4797 pSMB->ParameterCount = pSMB->TotalParameterCount;
4798 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4799 pSMB->Reserved4 = 0;
4800 inc_rfc1001_len(pSMB, byte_count);
4801 pSMB->ByteCount = cpu_to_le16(byte_count);
4803 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4804 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4806 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4808 /* decode response */
4809 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4810 /* BB also check enough total bytes returned */
4811 if (rc || get_bcc(&pSMBr->hdr) < 2)
4812 /* If rc should we check for EOPNOSUPP and
4813 disable the srvino flag? or in caller? */
4814 rc = -EIO; /* bad smb */
4816 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4817 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4818 struct file_internal_info *pfinfo;
4819 /* BB Do we need a cast or hash here ? */
4821 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4823 goto GetInodeNumOut;
4825 pfinfo = (struct file_internal_info *)
4826 (data_offset + (char *) &pSMBr->hdr.Protocol);
4827 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4831 cifs_buf_release(pSMB);
4833 goto GetInodeNumberRetry;
4838 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4839 const char *search_name, struct dfs_info3_param **target_nodes,
4840 unsigned int *num_of_nodes,
4841 const struct nls_table *nls_codepage, int remap)
4843 /* TRANS2_GET_DFS_REFERRAL */
4844 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4845 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4849 __u16 params, byte_count;
4851 *target_nodes = NULL;
4853 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4854 if (ses == NULL || ses->tcon_ipc == NULL)
4858 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4863 /* server pointer checked in called function,
4864 but should never be null here anyway */
4865 pSMB->hdr.Mid = get_next_mid(ses->server);
4866 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4867 pSMB->hdr.Uid = ses->Suid;
4868 if (ses->capabilities & CAP_STATUS32)
4869 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4870 if (ses->capabilities & CAP_DFS)
4871 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4873 if (ses->capabilities & CAP_UNICODE) {
4874 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4876 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4877 search_name, PATH_MAX, nls_codepage,
4879 name_len++; /* trailing null */
4881 } else { /* BB improve the check for buffer overruns BB */
4882 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4885 if (ses->server->sign)
4886 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4888 pSMB->hdr.Uid = ses->Suid;
4890 params = 2 /* level */ + name_len /*includes null */ ;
4891 pSMB->TotalDataCount = 0;
4892 pSMB->DataCount = 0;
4893 pSMB->DataOffset = 0;
4894 pSMB->MaxParameterCount = 0;
4895 /* BB find exact max SMB PDU from sess structure BB */
4896 pSMB->MaxDataCount = cpu_to_le16(4000);
4897 pSMB->MaxSetupCount = 0;
4901 pSMB->Reserved2 = 0;
4902 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4903 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4904 pSMB->SetupCount = 1;
4905 pSMB->Reserved3 = 0;
4906 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4907 byte_count = params + 3 /* pad */ ;
4908 pSMB->ParameterCount = cpu_to_le16(params);
4909 pSMB->TotalParameterCount = pSMB->ParameterCount;
4910 pSMB->MaxReferralLevel = cpu_to_le16(3);
4911 inc_rfc1001_len(pSMB, byte_count);
4912 pSMB->ByteCount = cpu_to_le16(byte_count);
4914 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4915 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4917 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4920 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4922 /* BB Also check if enough total bytes returned? */
4923 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4924 rc = -EIO; /* bad smb */
4928 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4929 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4931 /* parse returned result into more usable form */
4932 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4933 le16_to_cpu(pSMBr->t2.DataCount),
4934 num_of_nodes, target_nodes, nls_codepage,
4936 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4939 cifs_buf_release(pSMB);
4947 /* Query File System Info such as free space to old servers such as Win 9x */
4949 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4950 struct kstatfs *FSData)
4952 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4953 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4954 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4955 FILE_SYSTEM_ALLOC_INFO *response_data;
4957 int bytes_returned = 0;
4958 __u16 params, byte_count;
4960 cifs_dbg(FYI, "OldQFSInfo\n");
4962 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4967 params = 2; /* level */
4968 pSMB->TotalDataCount = 0;
4969 pSMB->MaxParameterCount = cpu_to_le16(2);
4970 pSMB->MaxDataCount = cpu_to_le16(1000);
4971 pSMB->MaxSetupCount = 0;
4975 pSMB->Reserved2 = 0;
4976 byte_count = params + 1 /* pad */ ;
4977 pSMB->TotalParameterCount = cpu_to_le16(params);
4978 pSMB->ParameterCount = pSMB->TotalParameterCount;
4979 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4980 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4981 pSMB->DataCount = 0;
4982 pSMB->DataOffset = 0;
4983 pSMB->SetupCount = 1;
4984 pSMB->Reserved3 = 0;
4985 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4986 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4987 inc_rfc1001_len(pSMB, byte_count);
4988 pSMB->ByteCount = cpu_to_le16(byte_count);
4990 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4991 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4993 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4994 } else { /* decode response */
4995 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4997 if (rc || get_bcc(&pSMBr->hdr) < 18)
4998 rc = -EIO; /* bad smb */
5000 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5001 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
5002 get_bcc(&pSMBr->hdr), data_offset);
5004 response_data = (FILE_SYSTEM_ALLOC_INFO *)
5005 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5007 le16_to_cpu(response_data->BytesPerSector) *
5008 le32_to_cpu(response_data->
5009 SectorsPerAllocationUnit);
5011 * much prefer larger but if server doesn't report
5012 * a valid size than 4K is a reasonable minimum
5014 if (FSData->f_bsize < 512)
5015 FSData->f_bsize = 4096;
5018 le32_to_cpu(response_data->TotalAllocationUnits);
5019 FSData->f_bfree = FSData->f_bavail =
5020 le32_to_cpu(response_data->FreeAllocationUnits);
5021 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5022 (unsigned long long)FSData->f_blocks,
5023 (unsigned long long)FSData->f_bfree,
5027 cifs_buf_release(pSMB);
5030 goto oldQFSInfoRetry;
5036 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
5037 struct kstatfs *FSData)
5039 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5040 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5041 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5042 FILE_SYSTEM_INFO *response_data;
5044 int bytes_returned = 0;
5045 __u16 params, byte_count;
5047 cifs_dbg(FYI, "In QFSInfo\n");
5049 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5054 params = 2; /* level */
5055 pSMB->TotalDataCount = 0;
5056 pSMB->MaxParameterCount = cpu_to_le16(2);
5057 pSMB->MaxDataCount = cpu_to_le16(1000);
5058 pSMB->MaxSetupCount = 0;
5062 pSMB->Reserved2 = 0;
5063 byte_count = params + 1 /* pad */ ;
5064 pSMB->TotalParameterCount = cpu_to_le16(params);
5065 pSMB->ParameterCount = pSMB->TotalParameterCount;
5066 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5067 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5068 pSMB->DataCount = 0;
5069 pSMB->DataOffset = 0;
5070 pSMB->SetupCount = 1;
5071 pSMB->Reserved3 = 0;
5072 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5073 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5074 inc_rfc1001_len(pSMB, byte_count);
5075 pSMB->ByteCount = cpu_to_le16(byte_count);
5077 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5078 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5080 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5081 } else { /* decode response */
5082 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5084 if (rc || get_bcc(&pSMBr->hdr) < 24)
5085 rc = -EIO; /* bad smb */
5087 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5091 *) (((char *) &pSMBr->hdr.Protocol) +
5094 le32_to_cpu(response_data->BytesPerSector) *
5095 le32_to_cpu(response_data->
5096 SectorsPerAllocationUnit);
5098 * much prefer larger but if server doesn't report
5099 * a valid size than 4K is a reasonable minimum
5101 if (FSData->f_bsize < 512)
5102 FSData->f_bsize = 4096;
5105 le64_to_cpu(response_data->TotalAllocationUnits);
5106 FSData->f_bfree = FSData->f_bavail =
5107 le64_to_cpu(response_data->FreeAllocationUnits);
5108 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5109 (unsigned long long)FSData->f_blocks,
5110 (unsigned long long)FSData->f_bfree,
5114 cifs_buf_release(pSMB);
5123 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5125 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5126 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5127 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5128 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5130 int bytes_returned = 0;
5131 __u16 params, byte_count;
5133 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5135 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5140 params = 2; /* level */
5141 pSMB->TotalDataCount = 0;
5142 pSMB->MaxParameterCount = cpu_to_le16(2);
5143 /* BB find exact max SMB PDU from sess structure BB */
5144 pSMB->MaxDataCount = cpu_to_le16(1000);
5145 pSMB->MaxSetupCount = 0;
5149 pSMB->Reserved2 = 0;
5150 byte_count = params + 1 /* pad */ ;
5151 pSMB->TotalParameterCount = cpu_to_le16(params);
5152 pSMB->ParameterCount = pSMB->TotalParameterCount;
5153 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5154 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5155 pSMB->DataCount = 0;
5156 pSMB->DataOffset = 0;
5157 pSMB->SetupCount = 1;
5158 pSMB->Reserved3 = 0;
5159 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5160 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5161 inc_rfc1001_len(pSMB, byte_count);
5162 pSMB->ByteCount = cpu_to_le16(byte_count);
5164 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5165 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5167 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5168 } else { /* decode response */
5169 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5171 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5172 /* BB also check if enough bytes returned */
5173 rc = -EIO; /* bad smb */
5175 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5177 (FILE_SYSTEM_ATTRIBUTE_INFO
5178 *) (((char *) &pSMBr->hdr.Protocol) +
5180 memcpy(&tcon->fsAttrInfo, response_data,
5181 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5184 cifs_buf_release(pSMB);
5187 goto QFSAttributeRetry;
5193 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5195 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5196 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5197 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5198 FILE_SYSTEM_DEVICE_INFO *response_data;
5200 int bytes_returned = 0;
5201 __u16 params, byte_count;
5203 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5205 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5210 params = 2; /* level */
5211 pSMB->TotalDataCount = 0;
5212 pSMB->MaxParameterCount = cpu_to_le16(2);
5213 /* BB find exact max SMB PDU from sess structure BB */
5214 pSMB->MaxDataCount = cpu_to_le16(1000);
5215 pSMB->MaxSetupCount = 0;
5219 pSMB->Reserved2 = 0;
5220 byte_count = params + 1 /* pad */ ;
5221 pSMB->TotalParameterCount = cpu_to_le16(params);
5222 pSMB->ParameterCount = pSMB->TotalParameterCount;
5223 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5224 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5226 pSMB->DataCount = 0;
5227 pSMB->DataOffset = 0;
5228 pSMB->SetupCount = 1;
5229 pSMB->Reserved3 = 0;
5230 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5231 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5232 inc_rfc1001_len(pSMB, byte_count);
5233 pSMB->ByteCount = cpu_to_le16(byte_count);
5235 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5236 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5238 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5239 } else { /* decode response */
5240 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5242 if (rc || get_bcc(&pSMBr->hdr) <
5243 sizeof(FILE_SYSTEM_DEVICE_INFO))
5244 rc = -EIO; /* bad smb */
5246 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5248 (FILE_SYSTEM_DEVICE_INFO *)
5249 (((char *) &pSMBr->hdr.Protocol) +
5251 memcpy(&tcon->fsDevInfo, response_data,
5252 sizeof(FILE_SYSTEM_DEVICE_INFO));
5255 cifs_buf_release(pSMB);
5258 goto QFSDeviceRetry;
5264 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5266 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5267 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5268 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5269 FILE_SYSTEM_UNIX_INFO *response_data;
5271 int bytes_returned = 0;
5272 __u16 params, byte_count;
5274 cifs_dbg(FYI, "In QFSUnixInfo\n");
5276 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5277 (void **) &pSMB, (void **) &pSMBr);
5281 params = 2; /* level */
5282 pSMB->TotalDataCount = 0;
5283 pSMB->DataCount = 0;
5284 pSMB->DataOffset = 0;
5285 pSMB->MaxParameterCount = cpu_to_le16(2);
5286 /* BB find exact max SMB PDU from sess structure BB */
5287 pSMB->MaxDataCount = cpu_to_le16(100);
5288 pSMB->MaxSetupCount = 0;
5292 pSMB->Reserved2 = 0;
5293 byte_count = params + 1 /* pad */ ;
5294 pSMB->ParameterCount = cpu_to_le16(params);
5295 pSMB->TotalParameterCount = pSMB->ParameterCount;
5296 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5297 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5298 pSMB->SetupCount = 1;
5299 pSMB->Reserved3 = 0;
5300 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5301 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5302 inc_rfc1001_len(pSMB, byte_count);
5303 pSMB->ByteCount = cpu_to_le16(byte_count);
5305 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5306 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5308 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5309 } else { /* decode response */
5310 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5312 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5313 rc = -EIO; /* bad smb */
5315 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5317 (FILE_SYSTEM_UNIX_INFO
5318 *) (((char *) &pSMBr->hdr.Protocol) +
5320 memcpy(&tcon->fsUnixInfo, response_data,
5321 sizeof(FILE_SYSTEM_UNIX_INFO));
5324 cifs_buf_release(pSMB);
5334 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5336 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5337 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5338 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5340 int bytes_returned = 0;
5341 __u16 params, param_offset, offset, byte_count;
5343 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5345 /* BB switch to small buf init to save memory */
5346 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5347 (void **) &pSMB, (void **) &pSMBr);
5351 params = 4; /* 2 bytes zero followed by info level. */
5352 pSMB->MaxSetupCount = 0;
5356 pSMB->Reserved2 = 0;
5357 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5359 offset = param_offset + params;
5361 pSMB->MaxParameterCount = cpu_to_le16(4);
5362 /* BB find exact max SMB PDU from sess structure BB */
5363 pSMB->MaxDataCount = cpu_to_le16(100);
5364 pSMB->SetupCount = 1;
5365 pSMB->Reserved3 = 0;
5366 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5367 byte_count = 1 /* pad */ + params + 12;
5369 pSMB->DataCount = cpu_to_le16(12);
5370 pSMB->ParameterCount = cpu_to_le16(params);
5371 pSMB->TotalDataCount = pSMB->DataCount;
5372 pSMB->TotalParameterCount = pSMB->ParameterCount;
5373 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5374 pSMB->DataOffset = cpu_to_le16(offset);
5378 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5381 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5382 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5383 pSMB->ClientUnixCap = cpu_to_le64(cap);
5385 inc_rfc1001_len(pSMB, byte_count);
5386 pSMB->ByteCount = cpu_to_le16(byte_count);
5388 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5389 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5391 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5392 } else { /* decode response */
5393 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5395 rc = -EIO; /* bad smb */
5397 cifs_buf_release(pSMB);
5400 goto SETFSUnixRetry;
5408 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5409 struct kstatfs *FSData)
5411 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5412 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5413 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5414 FILE_SYSTEM_POSIX_INFO *response_data;
5416 int bytes_returned = 0;
5417 __u16 params, byte_count;
5419 cifs_dbg(FYI, "In QFSPosixInfo\n");
5421 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5426 params = 2; /* level */
5427 pSMB->TotalDataCount = 0;
5428 pSMB->DataCount = 0;
5429 pSMB->DataOffset = 0;
5430 pSMB->MaxParameterCount = cpu_to_le16(2);
5431 /* BB find exact max SMB PDU from sess structure BB */
5432 pSMB->MaxDataCount = cpu_to_le16(100);
5433 pSMB->MaxSetupCount = 0;
5437 pSMB->Reserved2 = 0;
5438 byte_count = params + 1 /* pad */ ;
5439 pSMB->ParameterCount = cpu_to_le16(params);
5440 pSMB->TotalParameterCount = pSMB->ParameterCount;
5441 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5442 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5443 pSMB->SetupCount = 1;
5444 pSMB->Reserved3 = 0;
5445 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5446 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5447 inc_rfc1001_len(pSMB, byte_count);
5448 pSMB->ByteCount = cpu_to_le16(byte_count);
5450 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5451 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5453 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5454 } else { /* decode response */
5455 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5457 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5458 rc = -EIO; /* bad smb */
5460 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5462 (FILE_SYSTEM_POSIX_INFO
5463 *) (((char *) &pSMBr->hdr.Protocol) +
5466 le32_to_cpu(response_data->BlockSize);
5468 * much prefer larger but if server doesn't report
5469 * a valid size than 4K is a reasonable minimum
5471 if (FSData->f_bsize < 512)
5472 FSData->f_bsize = 4096;
5475 le64_to_cpu(response_data->TotalBlocks);
5477 le64_to_cpu(response_data->BlocksAvail);
5478 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5479 FSData->f_bavail = FSData->f_bfree;
5482 le64_to_cpu(response_data->UserBlocksAvail);
5484 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5486 le64_to_cpu(response_data->TotalFileNodes);
5487 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5489 le64_to_cpu(response_data->FreeFileNodes);
5492 cifs_buf_release(pSMB);
5502 * We can not use write of zero bytes trick to set file size due to need for
5503 * large file support. Also note that this SetPathInfo is preferred to
5504 * SetFileInfo based method in next routine which is only needed to work around
5505 * a sharing violation bugin Samba which this routine can run into.
5508 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5509 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5510 bool set_allocation)
5512 struct smb_com_transaction2_spi_req *pSMB = NULL;
5513 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5514 struct file_end_of_file_info *parm_data;
5517 int bytes_returned = 0;
5518 int remap = cifs_remap(cifs_sb);
5520 __u16 params, byte_count, data_count, param_offset, offset;
5522 cifs_dbg(FYI, "In SetEOF\n");
5524 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5529 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5531 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5532 PATH_MAX, cifs_sb->local_nls, remap);
5533 name_len++; /* trailing null */
5536 name_len = copy_path_name(pSMB->FileName, file_name);
5538 params = 6 + name_len;
5539 data_count = sizeof(struct file_end_of_file_info);
5540 pSMB->MaxParameterCount = cpu_to_le16(2);
5541 pSMB->MaxDataCount = cpu_to_le16(4100);
5542 pSMB->MaxSetupCount = 0;
5546 pSMB->Reserved2 = 0;
5547 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5548 InformationLevel) - 4;
5549 offset = param_offset + params;
5550 if (set_allocation) {
5551 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5552 pSMB->InformationLevel =
5553 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5555 pSMB->InformationLevel =
5556 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5557 } else /* Set File Size */ {
5558 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5559 pSMB->InformationLevel =
5560 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5562 pSMB->InformationLevel =
5563 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5567 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5569 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5570 pSMB->DataOffset = cpu_to_le16(offset);
5571 pSMB->SetupCount = 1;
5572 pSMB->Reserved3 = 0;
5573 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5574 byte_count = 3 /* pad */ + params + data_count;
5575 pSMB->DataCount = cpu_to_le16(data_count);
5576 pSMB->TotalDataCount = pSMB->DataCount;
5577 pSMB->ParameterCount = cpu_to_le16(params);
5578 pSMB->TotalParameterCount = pSMB->ParameterCount;
5579 pSMB->Reserved4 = 0;
5580 inc_rfc1001_len(pSMB, byte_count);
5581 parm_data->FileSize = cpu_to_le64(size);
5582 pSMB->ByteCount = cpu_to_le16(byte_count);
5583 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5584 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5586 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5588 cifs_buf_release(pSMB);
5597 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5598 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5600 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5601 struct file_end_of_file_info *parm_data;
5603 __u16 params, param_offset, offset, byte_count, count;
5605 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5607 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5612 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5613 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5616 pSMB->MaxSetupCount = 0;
5620 pSMB->Reserved2 = 0;
5621 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5622 offset = param_offset + params;
5624 count = sizeof(struct file_end_of_file_info);
5625 pSMB->MaxParameterCount = cpu_to_le16(2);
5626 /* BB find exact max SMB PDU from sess structure BB */
5627 pSMB->MaxDataCount = cpu_to_le16(1000);
5628 pSMB->SetupCount = 1;
5629 pSMB->Reserved3 = 0;
5630 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5631 byte_count = 3 /* pad */ + params + count;
5632 pSMB->DataCount = cpu_to_le16(count);
5633 pSMB->ParameterCount = cpu_to_le16(params);
5634 pSMB->TotalDataCount = pSMB->DataCount;
5635 pSMB->TotalParameterCount = pSMB->ParameterCount;
5636 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5637 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5639 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5640 pSMB->DataOffset = cpu_to_le16(offset);
5641 parm_data->FileSize = cpu_to_le64(size);
5642 pSMB->Fid = cfile->fid.netfid;
5643 if (set_allocation) {
5644 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5645 pSMB->InformationLevel =
5646 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5648 pSMB->InformationLevel =
5649 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5650 } else /* Set File Size */ {
5651 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5652 pSMB->InformationLevel =
5653 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5655 pSMB->InformationLevel =
5656 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5658 pSMB->Reserved4 = 0;
5659 inc_rfc1001_len(pSMB, byte_count);
5660 pSMB->ByteCount = cpu_to_le16(byte_count);
5661 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5662 cifs_small_buf_release(pSMB);
5664 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5668 /* Note: On -EAGAIN error only caller can retry on handle based calls
5669 since file handle passed in no longer valid */
5674 /* Some legacy servers such as NT4 require that the file times be set on
5675 an open handle, rather than by pathname - this is awkward due to
5676 potential access conflicts on the open, but it is unavoidable for these
5677 old servers since the only other choice is to go from 100 nanosecond DCE
5678 time and resort to the original setpathinfo level which takes the ancient
5679 DOS time format with 2 second granularity */
5681 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5682 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5684 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5687 __u16 params, param_offset, offset, byte_count, count;
5689 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5690 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5695 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5696 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5699 pSMB->MaxSetupCount = 0;
5703 pSMB->Reserved2 = 0;
5704 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5705 offset = param_offset + params;
5707 data_offset = (char *)pSMB +
5708 offsetof(struct smb_hdr, Protocol) + offset;
5710 count = sizeof(FILE_BASIC_INFO);
5711 pSMB->MaxParameterCount = cpu_to_le16(2);
5712 /* BB find max SMB PDU from sess */
5713 pSMB->MaxDataCount = cpu_to_le16(1000);
5714 pSMB->SetupCount = 1;
5715 pSMB->Reserved3 = 0;
5716 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5717 byte_count = 3 /* pad */ + params + count;
5718 pSMB->DataCount = cpu_to_le16(count);
5719 pSMB->ParameterCount = cpu_to_le16(params);
5720 pSMB->TotalDataCount = pSMB->DataCount;
5721 pSMB->TotalParameterCount = pSMB->ParameterCount;
5722 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5723 pSMB->DataOffset = cpu_to_le16(offset);
5725 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5726 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5728 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5729 pSMB->Reserved4 = 0;
5730 inc_rfc1001_len(pSMB, byte_count);
5731 pSMB->ByteCount = cpu_to_le16(byte_count);
5732 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5733 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5734 cifs_small_buf_release(pSMB);
5736 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5739 /* Note: On -EAGAIN error only caller can retry on handle based calls
5740 since file handle passed in no longer valid */
5746 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5747 bool delete_file, __u16 fid, __u32 pid_of_opener)
5749 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5752 __u16 params, param_offset, offset, byte_count, count;
5754 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5755 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5760 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5761 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5764 pSMB->MaxSetupCount = 0;
5768 pSMB->Reserved2 = 0;
5769 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5770 offset = param_offset + params;
5772 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5773 data_offset = (char *)(pSMB) + offset + 4;
5776 pSMB->MaxParameterCount = cpu_to_le16(2);
5777 /* BB find max SMB PDU from sess */
5778 pSMB->MaxDataCount = cpu_to_le16(1000);
5779 pSMB->SetupCount = 1;
5780 pSMB->Reserved3 = 0;
5781 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5782 byte_count = 3 /* pad */ + params + count;
5783 pSMB->DataCount = cpu_to_le16(count);
5784 pSMB->ParameterCount = cpu_to_le16(params);
5785 pSMB->TotalDataCount = pSMB->DataCount;
5786 pSMB->TotalParameterCount = pSMB->ParameterCount;
5787 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5788 pSMB->DataOffset = cpu_to_le16(offset);
5790 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5791 pSMB->Reserved4 = 0;
5792 inc_rfc1001_len(pSMB, byte_count);
5793 pSMB->ByteCount = cpu_to_le16(byte_count);
5794 *data_offset = delete_file ? 1 : 0;
5795 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5796 cifs_small_buf_release(pSMB);
5798 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5804 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5805 const char *fileName, const FILE_BASIC_INFO *data,
5806 const struct nls_table *nls_codepage,
5807 struct cifs_sb_info *cifs_sb)
5810 struct cifs_open_parms oparms;
5811 struct cifs_fid fid;
5815 oparms.cifs_sb = cifs_sb;
5816 oparms.desired_access = GENERIC_WRITE;
5817 oparms.create_options = cifs_create_options(cifs_sb, 0);
5818 oparms.disposition = FILE_OPEN;
5819 oparms.path = fileName;
5821 oparms.reconnect = false;
5823 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5827 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5828 CIFSSMBClose(xid, tcon, fid.netfid);
5835 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5836 const char *fileName, const FILE_BASIC_INFO *data,
5837 const struct nls_table *nls_codepage,
5838 struct cifs_sb_info *cifs_sb)
5840 TRANSACTION2_SPI_REQ *pSMB = NULL;
5841 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5844 int bytes_returned = 0;
5846 __u16 params, param_offset, offset, byte_count, count;
5847 int remap = cifs_remap(cifs_sb);
5849 cifs_dbg(FYI, "In SetTimes\n");
5852 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5857 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5859 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5860 PATH_MAX, nls_codepage, remap);
5861 name_len++; /* trailing null */
5864 name_len = copy_path_name(pSMB->FileName, fileName);
5867 params = 6 + name_len;
5868 count = sizeof(FILE_BASIC_INFO);
5869 pSMB->MaxParameterCount = cpu_to_le16(2);
5870 /* BB find max SMB PDU from sess structure BB */
5871 pSMB->MaxDataCount = cpu_to_le16(1000);
5872 pSMB->MaxSetupCount = 0;
5876 pSMB->Reserved2 = 0;
5877 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5878 InformationLevel) - 4;
5879 offset = param_offset + params;
5880 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5881 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5882 pSMB->DataOffset = cpu_to_le16(offset);
5883 pSMB->SetupCount = 1;
5884 pSMB->Reserved3 = 0;
5885 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5886 byte_count = 3 /* pad */ + params + count;
5888 pSMB->DataCount = cpu_to_le16(count);
5889 pSMB->ParameterCount = cpu_to_le16(params);
5890 pSMB->TotalDataCount = pSMB->DataCount;
5891 pSMB->TotalParameterCount = pSMB->ParameterCount;
5892 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5893 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5895 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5896 pSMB->Reserved4 = 0;
5897 inc_rfc1001_len(pSMB, byte_count);
5898 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5899 pSMB->ByteCount = cpu_to_le16(byte_count);
5900 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5901 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5903 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5905 cifs_buf_release(pSMB);
5910 if (rc == -EOPNOTSUPP)
5911 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5912 nls_codepage, cifs_sb);
5918 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5919 const struct cifs_unix_set_info_args *args)
5921 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5922 u64 mode = args->mode;
5924 if (uid_valid(args->uid))
5925 uid = from_kuid(&init_user_ns, args->uid);
5926 if (gid_valid(args->gid))
5927 gid = from_kgid(&init_user_ns, args->gid);
5930 * Samba server ignores set of file size to zero due to bugs in some
5931 * older clients, but we should be precise - we use SetFileSize to
5932 * set file size and do not want to truncate file size to zero
5933 * accidentally as happened on one Samba server beta by putting
5934 * zero instead of -1 here
5936 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5937 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5938 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5939 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5940 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5941 data_offset->Uid = cpu_to_le64(uid);
5942 data_offset->Gid = cpu_to_le64(gid);
5943 /* better to leave device as zero when it is */
5944 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5945 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5946 data_offset->Permissions = cpu_to_le64(mode);
5949 data_offset->Type = cpu_to_le32(UNIX_FILE);
5950 else if (S_ISDIR(mode))
5951 data_offset->Type = cpu_to_le32(UNIX_DIR);
5952 else if (S_ISLNK(mode))
5953 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5954 else if (S_ISCHR(mode))
5955 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5956 else if (S_ISBLK(mode))
5957 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5958 else if (S_ISFIFO(mode))
5959 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5960 else if (S_ISSOCK(mode))
5961 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5965 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5966 const struct cifs_unix_set_info_args *args,
5967 u16 fid, u32 pid_of_opener)
5969 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5972 u16 params, param_offset, offset, byte_count, count;
5974 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5975 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5980 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5981 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5984 pSMB->MaxSetupCount = 0;
5988 pSMB->Reserved2 = 0;
5989 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5990 offset = param_offset + params;
5992 data_offset = (char *)pSMB +
5993 offsetof(struct smb_hdr, Protocol) + offset;
5995 count = sizeof(FILE_UNIX_BASIC_INFO);
5997 pSMB->MaxParameterCount = cpu_to_le16(2);
5998 /* BB find max SMB PDU from sess */
5999 pSMB->MaxDataCount = cpu_to_le16(1000);
6000 pSMB->SetupCount = 1;
6001 pSMB->Reserved3 = 0;
6002 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
6003 byte_count = 3 /* pad */ + params + count;
6004 pSMB->DataCount = cpu_to_le16(count);
6005 pSMB->ParameterCount = cpu_to_le16(params);
6006 pSMB->TotalDataCount = pSMB->DataCount;
6007 pSMB->TotalParameterCount = pSMB->ParameterCount;
6008 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6009 pSMB->DataOffset = cpu_to_le16(offset);
6011 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6012 pSMB->Reserved4 = 0;
6013 inc_rfc1001_len(pSMB, byte_count);
6014 pSMB->ByteCount = cpu_to_le16(byte_count);
6016 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
6018 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
6019 cifs_small_buf_release(pSMB);
6021 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
6024 /* Note: On -EAGAIN error only caller can retry on handle based calls
6025 since file handle passed in no longer valid */
6031 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
6032 const char *file_name,
6033 const struct cifs_unix_set_info_args *args,
6034 const struct nls_table *nls_codepage, int remap)
6036 TRANSACTION2_SPI_REQ *pSMB = NULL;
6037 TRANSACTION2_SPI_RSP *pSMBr = NULL;
6040 int bytes_returned = 0;
6041 FILE_UNIX_BASIC_INFO *data_offset;
6042 __u16 params, param_offset, offset, count, byte_count;
6044 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
6046 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6051 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6053 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6054 PATH_MAX, nls_codepage, remap);
6055 name_len++; /* trailing null */
6058 name_len = copy_path_name(pSMB->FileName, file_name);
6061 params = 6 + name_len;
6062 count = sizeof(FILE_UNIX_BASIC_INFO);
6063 pSMB->MaxParameterCount = cpu_to_le16(2);
6064 /* BB find max SMB PDU from sess structure BB */
6065 pSMB->MaxDataCount = cpu_to_le16(1000);
6066 pSMB->MaxSetupCount = 0;
6070 pSMB->Reserved2 = 0;
6071 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6072 InformationLevel) - 4;
6073 offset = param_offset + params;
6074 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
6075 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
6076 memset(data_offset, 0, count);
6077 pSMB->DataOffset = cpu_to_le16(offset);
6078 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6079 pSMB->SetupCount = 1;
6080 pSMB->Reserved3 = 0;
6081 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6082 byte_count = 3 /* pad */ + params + count;
6083 pSMB->ParameterCount = cpu_to_le16(params);
6084 pSMB->DataCount = cpu_to_le16(count);
6085 pSMB->TotalParameterCount = pSMB->ParameterCount;
6086 pSMB->TotalDataCount = pSMB->DataCount;
6087 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6088 pSMB->Reserved4 = 0;
6089 inc_rfc1001_len(pSMB, byte_count);
6091 cifs_fill_unix_set_info(data_offset, args);
6093 pSMB->ByteCount = cpu_to_le16(byte_count);
6094 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6095 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6097 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6099 cifs_buf_release(pSMB);
6105 #ifdef CONFIG_CIFS_XATTR
6107 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6108 * function used by listxattr and getxattr type calls. When ea_name is set,
6109 * it looks for that attribute name and stuffs that value into the EAData
6110 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6111 * buffer. In both cases, the return value is either the length of the
6112 * resulting data or a negative error code. If EAData is a NULL pointer then
6113 * the data isn't copied to it, but the length is returned.
6116 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6117 const unsigned char *searchName, const unsigned char *ea_name,
6118 char *EAData, size_t buf_size,
6119 struct cifs_sb_info *cifs_sb)
6121 /* BB assumes one setup word */
6122 TRANSACTION2_QPI_REQ *pSMB = NULL;
6123 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6124 int remap = cifs_remap(cifs_sb);
6125 struct nls_table *nls_codepage = cifs_sb->local_nls;
6129 struct fealist *ea_response_data;
6130 struct fea *temp_fea;
6133 __u16 params, byte_count, data_offset;
6134 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6136 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6138 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6143 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6145 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6146 PATH_MAX, nls_codepage, remap);
6147 list_len++; /* trailing null */
6150 list_len = copy_path_name(pSMB->FileName, searchName);
6153 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6154 pSMB->TotalDataCount = 0;
6155 pSMB->MaxParameterCount = cpu_to_le16(2);
6156 /* BB find exact max SMB PDU from sess structure BB */
6157 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6158 pSMB->MaxSetupCount = 0;
6162 pSMB->Reserved2 = 0;
6163 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6164 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6165 pSMB->DataCount = 0;
6166 pSMB->DataOffset = 0;
6167 pSMB->SetupCount = 1;
6168 pSMB->Reserved3 = 0;
6169 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6170 byte_count = params + 1 /* pad */ ;
6171 pSMB->TotalParameterCount = cpu_to_le16(params);
6172 pSMB->ParameterCount = pSMB->TotalParameterCount;
6173 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6174 pSMB->Reserved4 = 0;
6175 inc_rfc1001_len(pSMB, byte_count);
6176 pSMB->ByteCount = cpu_to_le16(byte_count);
6178 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6179 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6181 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6186 /* BB also check enough total bytes returned */
6187 /* BB we need to improve the validity checking
6188 of these trans2 responses */
6190 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6191 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6192 rc = -EIO; /* bad smb */
6196 /* check that length of list is not more than bcc */
6197 /* check that each entry does not go beyond length
6199 /* check that each element of each entry does not
6200 go beyond end of list */
6201 /* validate_trans2_offsets() */
6202 /* BB check if start of smb + data_offset > &bcc+ bcc */
6204 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6205 ea_response_data = (struct fealist *)
6206 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6208 list_len = le32_to_cpu(ea_response_data->list_len);
6209 cifs_dbg(FYI, "ea length %d\n", list_len);
6210 if (list_len <= 8) {
6211 cifs_dbg(FYI, "empty EA list returned from server\n");
6212 /* didn't find the named attribute */
6218 /* make sure list_len doesn't go past end of SMB */
6219 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6220 if ((char *)ea_response_data + list_len > end_of_smb) {
6221 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6226 /* account for ea list len */
6228 temp_fea = ea_response_data->list;
6229 temp_ptr = (char *)temp_fea;
6230 while (list_len > 0) {
6231 unsigned int name_len;
6236 /* make sure we can read name_len and value_len */
6238 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6243 name_len = temp_fea->name_len;
6244 value_len = le16_to_cpu(temp_fea->value_len);
6245 list_len -= name_len + 1 + value_len;
6247 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6253 if (ea_name_len == name_len &&
6254 memcmp(ea_name, temp_ptr, name_len) == 0) {
6255 temp_ptr += name_len + 1;
6259 if ((size_t)value_len > buf_size) {
6263 memcpy(EAData, temp_ptr, value_len);
6267 /* account for prefix user. and trailing null */
6268 rc += (5 + 1 + name_len);
6269 if (rc < (int) buf_size) {
6270 memcpy(EAData, "user.", 5);
6272 memcpy(EAData, temp_ptr, name_len);
6274 /* null terminate name */
6277 } else if (buf_size == 0) {
6278 /* skip copy - calc size only */
6280 /* stop before overrun buffer */
6285 temp_ptr += name_len + 1 + value_len;
6286 temp_fea = (struct fea *)temp_ptr;
6289 /* didn't find the named attribute */
6294 cifs_buf_release(pSMB);
6302 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6303 const char *fileName, const char *ea_name, const void *ea_value,
6304 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6305 struct cifs_sb_info *cifs_sb)
6307 struct smb_com_transaction2_spi_req *pSMB = NULL;
6308 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6309 struct fealist *parm_data;
6312 int bytes_returned = 0;
6313 __u16 params, param_offset, byte_count, offset, count;
6314 int remap = cifs_remap(cifs_sb);
6316 cifs_dbg(FYI, "In SetEA\n");
6318 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6323 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6325 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6326 PATH_MAX, nls_codepage, remap);
6327 name_len++; /* trailing null */
6330 name_len = copy_path_name(pSMB->FileName, fileName);
6333 params = 6 + name_len;
6335 /* done calculating parms using name_len of file name,
6336 now use name_len to calculate length of ea name
6337 we are going to create in the inode xattrs */
6338 if (ea_name == NULL)
6341 name_len = strnlen(ea_name, 255);
6343 count = sizeof(*parm_data) + ea_value_len + name_len;
6344 pSMB->MaxParameterCount = cpu_to_le16(2);
6345 /* BB find max SMB PDU from sess */
6346 pSMB->MaxDataCount = cpu_to_le16(1000);
6347 pSMB->MaxSetupCount = 0;
6351 pSMB->Reserved2 = 0;
6352 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6353 InformationLevel) - 4;
6354 offset = param_offset + params;
6355 pSMB->InformationLevel =
6356 cpu_to_le16(SMB_SET_FILE_EA);
6358 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6359 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6360 pSMB->DataOffset = cpu_to_le16(offset);
6361 pSMB->SetupCount = 1;
6362 pSMB->Reserved3 = 0;
6363 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6364 byte_count = 3 /* pad */ + params + count;
6365 pSMB->DataCount = cpu_to_le16(count);
6366 parm_data->list_len = cpu_to_le32(count);
6367 parm_data->list[0].EA_flags = 0;
6368 /* we checked above that name len is less than 255 */
6369 parm_data->list[0].name_len = (__u8)name_len;
6370 /* EA names are always ASCII */
6372 strncpy(parm_data->list[0].name, ea_name, name_len);
6373 parm_data->list[0].name[name_len] = 0;
6374 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6375 /* caller ensures that ea_value_len is less than 64K but
6376 we need to ensure that it fits within the smb */
6378 /*BB add length check to see if it would fit in
6379 negotiated SMB buffer size BB */
6380 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6382 memcpy(parm_data->list[0].name+name_len+1,
6383 ea_value, ea_value_len);
6385 pSMB->TotalDataCount = pSMB->DataCount;
6386 pSMB->ParameterCount = cpu_to_le16(params);
6387 pSMB->TotalParameterCount = pSMB->ParameterCount;
6388 pSMB->Reserved4 = 0;
6389 inc_rfc1001_len(pSMB, byte_count);
6390 pSMB->ByteCount = cpu_to_le16(byte_count);
6391 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6392 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6394 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6396 cifs_buf_release(pSMB);