4 * Copyright (C) International Business Machines Corp., 2002,2010
7 * Contains the routines for constructing the SMB PDUs themselves
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
25 /* These are mostly routines that operate on a pathname, or on a tree id */
26 /* (mounted volume), but there are eight handle based routines which must be */
27 /* treated slightly differently for reconnection purposes since we never */
28 /* want to reuse a stale file handle and only the caller knows the file info */
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <linux/uaccess.h>
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
46 #include "smbdirect.h"
48 #ifdef CONFIG_CIFS_POSIX
53 #ifdef CONFIG_CIFS_WEAK_PW_HASH
54 {LANMAN_PROT, "\2LM1.2X002"},
55 {LANMAN2_PROT, "\2LANMAN2.1"},
56 #endif /* weak password hashing for legacy clients */
57 {CIFS_PROT, "\2NT LM 0.12"},
58 {POSIX_PROT, "\2POSIX 2"},
66 #ifdef CONFIG_CIFS_WEAK_PW_HASH
67 {LANMAN_PROT, "\2LM1.2X002"},
68 {LANMAN2_PROT, "\2LANMAN2.1"},
69 #endif /* weak password hashing for legacy clients */
70 {CIFS_PROT, "\2NT LM 0.12"},
75 /* define the number of elements in the cifs dialect array */
76 #ifdef CONFIG_CIFS_POSIX
77 #ifdef CONFIG_CIFS_WEAK_PW_HASH
78 #define CIFS_NUM_PROT 4
80 #define CIFS_NUM_PROT 2
81 #endif /* CIFS_WEAK_PW_HASH */
83 #ifdef CONFIG_CIFS_WEAK_PW_HASH
84 #define CIFS_NUM_PROT 3
86 #define CIFS_NUM_PROT 1
87 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
88 #endif /* CIFS_POSIX */
91 * Mark as invalid, all open files on tree connections since they
92 * were closed when session to server was lost.
95 cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
97 struct cifsFileInfo *open_file = NULL;
98 struct list_head *tmp;
99 struct list_head *tmp1;
101 /* list all files open on tree connection and mark them invalid */
102 spin_lock(&tcon->open_file_lock);
103 list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
104 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
105 open_file->invalidHandle = true;
106 open_file->oplock_break_cancelled = true;
108 spin_unlock(&tcon->open_file_lock);
110 mutex_lock(&tcon->crfid.fid_mutex);
111 tcon->crfid.is_valid = false;
112 memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
113 mutex_unlock(&tcon->crfid.fid_mutex);
116 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
121 /* reconnect the socket, tcon, and smb session if needed */
123 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
126 struct cifs_ses *ses;
127 struct TCP_Server_Info *server;
128 struct nls_table *nls_codepage;
131 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
132 * tcp and smb session status done differently for those three - in the
139 server = ses->server;
142 * only tree disconnect, open, and write, (and ulogoff which does not
143 * have tcon) are allowed as we start force umount
145 if (tcon->tidStatus == CifsExiting) {
146 if (smb_command != SMB_COM_WRITE_ANDX &&
147 smb_command != SMB_COM_OPEN_ANDX &&
148 smb_command != SMB_COM_TREE_DISCONNECT) {
149 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
156 * Give demultiplex thread up to 10 seconds to reconnect, should be
157 * greater than cifs socket timeout which is 7 seconds
159 while (server->tcpStatus == CifsNeedReconnect) {
160 rc = wait_event_interruptible_timeout(server->response_q,
161 (server->tcpStatus != CifsNeedReconnect),
164 cifs_dbg(FYI, "%s: aborting reconnect due to a received"
165 " signal by the process\n", __func__);
169 /* are we still trying to reconnect? */
170 if (server->tcpStatus != CifsNeedReconnect)
174 * on "soft" mounts we wait once. Hard mounts keep
175 * retrying until process is killed or server comes
179 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
184 if (!ses->need_reconnect && !tcon->need_reconnect)
187 nls_codepage = load_nls_default();
190 * need to prevent multiple threads trying to simultaneously
191 * reconnect the same SMB session
193 mutex_lock(&ses->session_mutex);
196 * Recheck after acquire mutex. If another thread is negotiating
197 * and the server never sends an answer the socket will be closed
198 * and tcpStatus set to reconnect.
200 if (server->tcpStatus == CifsNeedReconnect) {
202 mutex_unlock(&ses->session_mutex);
206 rc = cifs_negotiate_protocol(0, ses);
207 if (rc == 0 && ses->need_reconnect)
208 rc = cifs_setup_session(0, ses, nls_codepage);
210 /* do we need to reconnect tcon? */
211 if (rc || !tcon->need_reconnect) {
212 mutex_unlock(&ses->session_mutex);
216 cifs_mark_open_files_invalid(tcon);
217 rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
218 mutex_unlock(&ses->session_mutex);
219 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
222 printk_once(KERN_WARNING "reconnect tcon failed rc = %d\n", rc);
226 atomic_inc(&tconInfoReconnectCount);
228 /* tell server Unix caps we support */
229 if (ses->capabilities & CAP_UNIX)
230 reset_cifs_unix_caps(0, tcon, NULL, NULL);
233 * Removed call to reopen open files here. It is safer (and faster) to
234 * reopen files one at a time as needed in read and write.
236 * FIXME: what about file locks? don't we need to reclaim them ASAP?
241 * Check if handle based operation so we know whether we can continue
242 * or not without returning to caller to reset file handle
244 switch (smb_command) {
245 case SMB_COM_READ_ANDX:
246 case SMB_COM_WRITE_ANDX:
248 case SMB_COM_FIND_CLOSE2:
249 case SMB_COM_LOCKING_ANDX:
253 unload_nls(nls_codepage);
257 /* Allocate and return pointer to an SMB request buffer, and set basic
258 SMB information in the SMB header. If the return code is zero, this
259 function must have filled in request_buf pointer */
261 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
266 rc = cifs_reconnect_tcon(tcon, smb_command);
270 *request_buf = cifs_small_buf_get();
271 if (*request_buf == NULL) {
272 /* BB should we add a retry in here if not a writepage? */
276 header_assemble((struct smb_hdr *) *request_buf, smb_command,
280 cifs_stats_inc(&tcon->num_smbs_sent);
286 small_smb_init_no_tc(const int smb_command, const int wct,
287 struct cifs_ses *ses, void **request_buf)
290 struct smb_hdr *buffer;
292 rc = small_smb_init(smb_command, wct, NULL, request_buf);
296 buffer = (struct smb_hdr *)*request_buf;
297 buffer->Mid = get_next_mid(ses->server);
298 if (ses->capabilities & CAP_UNICODE)
299 buffer->Flags2 |= SMBFLG2_UNICODE;
300 if (ses->capabilities & CAP_STATUS32)
301 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
303 /* uid, tid can stay at zero as set in header assemble */
305 /* BB add support for turning on the signing when
306 this function is used after 1st of session setup requests */
311 /* If the return code is zero, this function must fill in request_buf pointer */
313 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
314 void **request_buf, void **response_buf)
316 *request_buf = cifs_buf_get();
317 if (*request_buf == NULL) {
318 /* BB should we add a retry in here if not a writepage? */
321 /* Although the original thought was we needed the response buf for */
322 /* potential retries of smb operations it turns out we can determine */
323 /* from the mid flags when the request buffer can be resent without */
324 /* having to use a second distinct buffer for the response */
326 *response_buf = *request_buf;
328 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
332 cifs_stats_inc(&tcon->num_smbs_sent);
337 /* If the return code is zero, this function must fill in request_buf pointer */
339 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
340 void **request_buf, void **response_buf)
344 rc = cifs_reconnect_tcon(tcon, smb_command);
348 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
352 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
353 void **request_buf, void **response_buf)
355 if (tcon->ses->need_reconnect || tcon->need_reconnect)
358 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
361 static int validate_t2(struct smb_t2_rsp *pSMB)
363 unsigned int total_size;
365 /* check for plausible wct */
366 if (pSMB->hdr.WordCount < 10)
369 /* check for parm and data offset going beyond end of smb */
370 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
371 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
374 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
375 if (total_size >= 512)
378 /* check that bcc is at least as big as parms + data, and that it is
379 * less than negotiated smb buffer
381 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
382 if (total_size > get_bcc(&pSMB->hdr) ||
383 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
388 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
389 sizeof(struct smb_t2_rsp) + 16);
394 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
398 char *guid = pSMBr->u.extended_response.GUID;
399 struct TCP_Server_Info *server = ses->server;
401 count = get_bcc(&pSMBr->hdr);
402 if (count < SMB1_CLIENT_GUID_SIZE)
405 spin_lock(&cifs_tcp_ses_lock);
406 if (server->srv_count > 1) {
407 spin_unlock(&cifs_tcp_ses_lock);
408 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
409 cifs_dbg(FYI, "server UID changed\n");
410 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
413 spin_unlock(&cifs_tcp_ses_lock);
414 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
417 if (count == SMB1_CLIENT_GUID_SIZE) {
418 server->sec_ntlmssp = true;
420 count -= SMB1_CLIENT_GUID_SIZE;
421 rc = decode_negTokenInit(
422 pSMBr->u.extended_response.SecurityBlob, count, server);
431 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
433 bool srv_sign_required = server->sec_mode & server->vals->signing_required;
434 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
435 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
438 * Is signing required by mnt options? If not then check
439 * global_secflags to see if it is there.
441 if (!mnt_sign_required)
442 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
446 * If signing is required then it's automatically enabled too,
447 * otherwise, check to see if the secflags allow it.
449 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
450 (global_secflags & CIFSSEC_MAY_SIGN);
452 /* If server requires signing, does client allow it? */
453 if (srv_sign_required) {
454 if (!mnt_sign_enabled) {
455 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!");
461 /* If client requires signing, does server allow it? */
462 if (mnt_sign_required) {
463 if (!srv_sign_enabled) {
464 cifs_dbg(VFS, "Server does not support signing!");
470 if (cifs_rdma_enabled(server) && server->sign)
471 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled");
476 #ifdef CONFIG_CIFS_WEAK_PW_HASH
478 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
481 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
483 if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
486 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
487 server->maxReq = min_t(unsigned int,
488 le16_to_cpu(rsp->MaxMpxCount),
490 set_credits(server, server->maxReq);
491 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
492 /* even though we do not use raw we might as well set this
493 accurately, in case we ever find a need for it */
494 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
495 server->max_rw = 0xFF00;
496 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
498 server->max_rw = 0;/* do not need to use raw anyway */
499 server->capabilities = CAP_MPX_MODE;
501 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
503 /* OS/2 often does not set timezone therefore
504 * we must use server time to calc time zone.
505 * Could deviate slightly from the right zone.
506 * Smallest defined timezone difference is 15 minutes
507 * (i.e. Nepal). Rounding up/down is done to match
510 int val, seconds, remain, result;
511 struct timespec64 ts;
512 time64_t utc = ktime_get_real_seconds();
513 ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
514 rsp->SrvTime.Time, 0);
515 cifs_dbg(FYI, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
518 val = (int)(utc - ts.tv_sec);
520 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
521 remain = seconds % MIN_TZ_ADJ;
522 if (remain >= (MIN_TZ_ADJ / 2))
523 result += MIN_TZ_ADJ;
526 server->timeAdj = result;
528 server->timeAdj = (int)tmp;
529 server->timeAdj *= 60; /* also in seconds */
531 cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
534 /* BB get server time for time conversions and add
535 code to use it and timezone since this is not UTC */
537 if (rsp->EncryptionKeyLength ==
538 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
539 memcpy(server->cryptkey, rsp->EncryptionKey,
540 CIFS_CRYPTO_KEY_SIZE);
541 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
542 return -EIO; /* need cryptkey unless plain text */
545 cifs_dbg(FYI, "LANMAN negotiated\n");
550 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
552 cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
558 should_set_ext_sec_flag(enum securityEnum sectype)
565 if (global_secflags &
566 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
575 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
578 NEGOTIATE_RSP *pSMBr;
582 struct TCP_Server_Info *server = ses->server;
586 WARN(1, "%s: server is NULL!\n", __func__);
590 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
591 (void **) &pSMB, (void **) &pSMBr);
595 pSMB->hdr.Mid = get_next_mid(server);
596 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
598 if (should_set_ext_sec_flag(ses->sectype)) {
599 cifs_dbg(FYI, "Requesting extended security.");
600 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
604 for (i = 0; i < CIFS_NUM_PROT; i++) {
605 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
606 count += strlen(protocols[i].name) + 1;
607 /* null at end of source and target buffers anyway */
609 inc_rfc1001_len(pSMB, count);
610 pSMB->ByteCount = cpu_to_le16(count);
612 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
613 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
617 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
618 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
619 /* Check wct = 1 error case */
620 if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
621 /* core returns wct = 1, but we do not ask for core - otherwise
622 small wct just comes when dialect index is -1 indicating we
623 could not negotiate a common dialect */
626 } else if (pSMBr->hdr.WordCount == 13) {
627 server->negflavor = CIFS_NEGFLAVOR_LANMAN;
628 rc = decode_lanman_negprot_rsp(server, pSMBr);
630 } else if (pSMBr->hdr.WordCount != 17) {
635 /* else wct == 17, NTLM or better */
637 server->sec_mode = pSMBr->SecurityMode;
638 if ((server->sec_mode & SECMODE_USER) == 0)
639 cifs_dbg(FYI, "share mode security\n");
641 /* one byte, so no need to convert this or EncryptionKeyLen from
643 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
645 set_credits(server, server->maxReq);
646 /* probably no need to store and check maxvcs */
647 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
648 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
649 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
650 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
651 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
652 server->timeAdj *= 60;
654 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
655 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
656 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
657 CIFS_CRYPTO_KEY_SIZE);
658 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
659 server->capabilities & CAP_EXTENDED_SECURITY) {
660 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
661 rc = decode_ext_sec_blob(ses, pSMBr);
662 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
663 rc = -EIO; /* no crypt key only if plain text pwd */
665 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
666 server->capabilities &= ~CAP_EXTENDED_SECURITY;
671 rc = cifs_enable_signing(server, ses->sign);
673 cifs_buf_release(pSMB);
675 cifs_dbg(FYI, "negprot rc %d\n", rc);
680 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
682 struct smb_hdr *smb_buffer;
685 cifs_dbg(FYI, "In tree disconnect\n");
687 /* BB: do we need to check this? These should never be NULL. */
688 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
692 * No need to return error on this operation if tid invalidated and
693 * closed on server already e.g. due to tcp session crashing. Also,
694 * the tcon is no longer on the list, so no need to take lock before
697 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
700 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
701 (void **)&smb_buffer);
705 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
706 cifs_small_buf_release(smb_buffer);
708 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
710 /* No need to return error on this operation if tid invalidated and
711 closed on server already e.g. due to tcp session crashing */
719 * This is a no-op for now. We're not really interested in the reply, but
720 * rather in the fact that the server sent one and that server->lstrp
723 * FIXME: maybe we should consider checking that the reply matches request?
726 cifs_echo_callback(struct mid_q_entry *mid)
728 struct TCP_Server_Info *server = mid->callback_data;
730 DeleteMidQEntry(mid);
731 add_credits(server, 1, CIFS_ECHO_OP);
735 CIFSSMBEcho(struct TCP_Server_Info *server)
740 struct smb_rqst rqst = { .rq_iov = iov,
743 cifs_dbg(FYI, "In echo request\n");
745 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
749 if (server->capabilities & CAP_UNICODE)
750 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
752 /* set up echo request */
753 smb->hdr.Tid = 0xffff;
754 smb->hdr.WordCount = 1;
755 put_unaligned_le16(1, &smb->EchoCount);
756 put_bcc(1, &smb->hdr);
758 inc_rfc1001_len(smb, 3);
761 iov[0].iov_base = smb;
762 iov[1].iov_len = get_rfc1002_length(smb);
763 iov[1].iov_base = (char *)smb + 4;
765 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
766 server, CIFS_ASYNC_OP | CIFS_ECHO_OP);
768 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
770 cifs_small_buf_release(smb);
776 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
778 LOGOFF_ANDX_REQ *pSMB;
781 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
784 * BB: do we need to check validity of ses and server? They should
785 * always be valid since we have an active reference. If not, that
786 * should probably be a BUG()
788 if (!ses || !ses->server)
791 mutex_lock(&ses->session_mutex);
792 if (ses->need_reconnect)
793 goto session_already_dead; /* no need to send SMBlogoff if uid
794 already closed due to reconnect */
795 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
797 mutex_unlock(&ses->session_mutex);
801 pSMB->hdr.Mid = get_next_mid(ses->server);
803 if (ses->server->sign)
804 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
806 pSMB->hdr.Uid = ses->Suid;
808 pSMB->AndXCommand = 0xFF;
809 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
810 cifs_small_buf_release(pSMB);
811 session_already_dead:
812 mutex_unlock(&ses->session_mutex);
814 /* if session dead then we do not need to do ulogoff,
815 since server closed smb session, no sense reporting
823 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
824 const char *fileName, __u16 type,
825 const struct nls_table *nls_codepage, int remap)
827 TRANSACTION2_SPI_REQ *pSMB = NULL;
828 TRANSACTION2_SPI_RSP *pSMBr = NULL;
829 struct unlink_psx_rq *pRqD;
832 int bytes_returned = 0;
833 __u16 params, param_offset, offset, byte_count;
835 cifs_dbg(FYI, "In POSIX delete\n");
837 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
842 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
844 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
845 PATH_MAX, nls_codepage, remap);
846 name_len++; /* trailing null */
848 } else { /* BB add path length overrun check */
849 name_len = strnlen(fileName, PATH_MAX);
850 name_len++; /* trailing null */
851 strncpy(pSMB->FileName, fileName, name_len);
854 params = 6 + name_len;
855 pSMB->MaxParameterCount = cpu_to_le16(2);
856 pSMB->MaxDataCount = 0; /* BB double check this with jra */
857 pSMB->MaxSetupCount = 0;
862 param_offset = offsetof(struct smb_com_transaction2_spi_req,
863 InformationLevel) - 4;
864 offset = param_offset + params;
866 /* Setup pointer to Request Data (inode type) */
867 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
868 pRqD->type = cpu_to_le16(type);
869 pSMB->ParameterOffset = cpu_to_le16(param_offset);
870 pSMB->DataOffset = cpu_to_le16(offset);
871 pSMB->SetupCount = 1;
873 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
874 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
876 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
877 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
878 pSMB->ParameterCount = cpu_to_le16(params);
879 pSMB->TotalParameterCount = pSMB->ParameterCount;
880 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
882 inc_rfc1001_len(pSMB, byte_count);
883 pSMB->ByteCount = cpu_to_le16(byte_count);
884 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
885 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
887 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
888 cifs_buf_release(pSMB);
890 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
899 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
900 struct cifs_sb_info *cifs_sb)
902 DELETE_FILE_REQ *pSMB = NULL;
903 DELETE_FILE_RSP *pSMBr = NULL;
907 int remap = cifs_remap(cifs_sb);
910 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
915 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
916 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
917 PATH_MAX, cifs_sb->local_nls,
919 name_len++; /* trailing null */
921 } else { /* BB improve check for buffer overruns BB */
922 name_len = strnlen(name, PATH_MAX);
923 name_len++; /* trailing null */
924 strncpy(pSMB->fileName, name, name_len);
926 pSMB->SearchAttributes =
927 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
928 pSMB->BufferFormat = 0x04;
929 inc_rfc1001_len(pSMB, name_len + 1);
930 pSMB->ByteCount = cpu_to_le16(name_len + 1);
931 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
932 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
933 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
935 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
937 cifs_buf_release(pSMB);
945 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
946 struct cifs_sb_info *cifs_sb)
948 DELETE_DIRECTORY_REQ *pSMB = NULL;
949 DELETE_DIRECTORY_RSP *pSMBr = NULL;
953 int remap = cifs_remap(cifs_sb);
955 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
957 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
962 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
963 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
964 PATH_MAX, cifs_sb->local_nls,
966 name_len++; /* trailing null */
968 } else { /* BB improve check for buffer overruns BB */
969 name_len = strnlen(name, PATH_MAX);
970 name_len++; /* trailing null */
971 strncpy(pSMB->DirName, name, name_len);
974 pSMB->BufferFormat = 0x04;
975 inc_rfc1001_len(pSMB, name_len + 1);
976 pSMB->ByteCount = cpu_to_le16(name_len + 1);
977 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
978 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
979 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
981 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
983 cifs_buf_release(pSMB);
990 CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
991 struct cifs_sb_info *cifs_sb)
994 CREATE_DIRECTORY_REQ *pSMB = NULL;
995 CREATE_DIRECTORY_RSP *pSMBr = NULL;
998 int remap = cifs_remap(cifs_sb);
1000 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
1002 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
1007 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1008 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1009 PATH_MAX, cifs_sb->local_nls,
1011 name_len++; /* trailing null */
1013 } else { /* BB improve check for buffer overruns BB */
1014 name_len = strnlen(name, PATH_MAX);
1015 name_len++; /* trailing null */
1016 strncpy(pSMB->DirName, name, name_len);
1019 pSMB->BufferFormat = 0x04;
1020 inc_rfc1001_len(pSMB, name_len + 1);
1021 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1022 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1023 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1024 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1026 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
1028 cifs_buf_release(pSMB);
1035 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1036 __u32 posix_flags, __u64 mode, __u16 *netfid,
1037 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1038 const char *name, const struct nls_table *nls_codepage,
1041 TRANSACTION2_SPI_REQ *pSMB = NULL;
1042 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1045 int bytes_returned = 0;
1046 __u16 params, param_offset, offset, byte_count, count;
1047 OPEN_PSX_REQ *pdata;
1048 OPEN_PSX_RSP *psx_rsp;
1050 cifs_dbg(FYI, "In POSIX Create\n");
1052 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1057 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1059 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1060 PATH_MAX, nls_codepage, remap);
1061 name_len++; /* trailing null */
1063 } else { /* BB improve the check for buffer overruns BB */
1064 name_len = strnlen(name, PATH_MAX);
1065 name_len++; /* trailing null */
1066 strncpy(pSMB->FileName, name, name_len);
1069 params = 6 + name_len;
1070 count = sizeof(OPEN_PSX_REQ);
1071 pSMB->MaxParameterCount = cpu_to_le16(2);
1072 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1073 pSMB->MaxSetupCount = 0;
1077 pSMB->Reserved2 = 0;
1078 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1079 InformationLevel) - 4;
1080 offset = param_offset + params;
1081 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1082 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1083 pdata->Permissions = cpu_to_le64(mode);
1084 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1085 pdata->OpenFlags = cpu_to_le32(*pOplock);
1086 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1087 pSMB->DataOffset = cpu_to_le16(offset);
1088 pSMB->SetupCount = 1;
1089 pSMB->Reserved3 = 0;
1090 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1091 byte_count = 3 /* pad */ + params + count;
1093 pSMB->DataCount = cpu_to_le16(count);
1094 pSMB->ParameterCount = cpu_to_le16(params);
1095 pSMB->TotalDataCount = pSMB->DataCount;
1096 pSMB->TotalParameterCount = pSMB->ParameterCount;
1097 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1098 pSMB->Reserved4 = 0;
1099 inc_rfc1001_len(pSMB, byte_count);
1100 pSMB->ByteCount = cpu_to_le16(byte_count);
1101 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1102 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1104 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1105 goto psx_create_err;
1108 cifs_dbg(FYI, "copying inode info\n");
1109 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1111 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1112 rc = -EIO; /* bad smb */
1113 goto psx_create_err;
1116 /* copy return information to pRetData */
1117 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1118 + le16_to_cpu(pSMBr->t2.DataOffset));
1120 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1122 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1123 /* Let caller know file was created so we can set the mode. */
1124 /* Do we care about the CreateAction in any other cases? */
1125 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1126 *pOplock |= CIFS_CREATE_ACTION;
1127 /* check to make sure response data is there */
1128 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1129 pRetData->Type = cpu_to_le32(-1); /* unknown */
1130 cifs_dbg(NOISY, "unknown type\n");
1132 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1133 + sizeof(FILE_UNIX_BASIC_INFO)) {
1134 cifs_dbg(VFS, "Open response data too small\n");
1135 pRetData->Type = cpu_to_le32(-1);
1136 goto psx_create_err;
1138 memcpy((char *) pRetData,
1139 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1140 sizeof(FILE_UNIX_BASIC_INFO));
1144 cifs_buf_release(pSMB);
1146 if (posix_flags & SMB_O_DIRECTORY)
1147 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1149 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1157 static __u16 convert_disposition(int disposition)
1161 switch (disposition) {
1162 case FILE_SUPERSEDE:
1163 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1166 ofun = SMBOPEN_OAPPEND;
1169 ofun = SMBOPEN_OCREATE;
1172 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1174 case FILE_OVERWRITE:
1175 ofun = SMBOPEN_OTRUNC;
1177 case FILE_OVERWRITE_IF:
1178 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1181 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1182 ofun = SMBOPEN_OAPPEND; /* regular open */
1188 access_flags_to_smbopen_mode(const int access_flags)
1190 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1192 if (masked_flags == GENERIC_READ)
1193 return SMBOPEN_READ;
1194 else if (masked_flags == GENERIC_WRITE)
1195 return SMBOPEN_WRITE;
1197 /* just go for read/write */
1198 return SMBOPEN_READWRITE;
1202 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1203 const char *fileName, const int openDisposition,
1204 const int access_flags, const int create_options, __u16 *netfid,
1205 int *pOplock, FILE_ALL_INFO *pfile_info,
1206 const struct nls_table *nls_codepage, int remap)
1209 OPENX_REQ *pSMB = NULL;
1210 OPENX_RSP *pSMBr = NULL;
1216 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1221 pSMB->AndXCommand = 0xFF; /* none */
1223 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1224 count = 1; /* account for one byte pad to word boundary */
1226 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1227 fileName, PATH_MAX, nls_codepage, remap);
1228 name_len++; /* trailing null */
1230 } else { /* BB improve check for buffer overruns BB */
1231 count = 0; /* no pad */
1232 name_len = strnlen(fileName, PATH_MAX);
1233 name_len++; /* trailing null */
1234 strncpy(pSMB->fileName, fileName, name_len);
1236 if (*pOplock & REQ_OPLOCK)
1237 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1238 else if (*pOplock & REQ_BATCHOPLOCK)
1239 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1241 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1242 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1243 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1244 /* set file as system file if special file such
1245 as fifo and server expecting SFU style and
1246 no Unix extensions */
1248 if (create_options & CREATE_OPTION_SPECIAL)
1249 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1250 else /* BB FIXME BB */
1251 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1253 if (create_options & CREATE_OPTION_READONLY)
1254 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1257 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1258 CREATE_OPTIONS_MASK); */
1259 /* BB FIXME END BB */
1261 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1262 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1264 inc_rfc1001_len(pSMB, count);
1266 pSMB->ByteCount = cpu_to_le16(count);
1267 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1268 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1269 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1271 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1273 /* BB verify if wct == 15 */
1275 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1277 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1278 /* Let caller know file was created so we can set the mode. */
1279 /* Do we care about the CreateAction in any other cases? */
1281 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1282 *pOplock |= CIFS_CREATE_ACTION; */
1286 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1287 pfile_info->LastAccessTime = 0; /* BB fixme */
1288 pfile_info->LastWriteTime = 0; /* BB fixme */
1289 pfile_info->ChangeTime = 0; /* BB fixme */
1290 pfile_info->Attributes =
1291 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1292 /* the file_info buf is endian converted by caller */
1293 pfile_info->AllocationSize =
1294 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1295 pfile_info->EndOfFile = pfile_info->AllocationSize;
1296 pfile_info->NumberOfLinks = cpu_to_le32(1);
1297 pfile_info->DeletePending = 0;
1301 cifs_buf_release(pSMB);
1308 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1312 OPEN_REQ *req = NULL;
1313 OPEN_RSP *rsp = NULL;
1317 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1318 struct cifs_tcon *tcon = oparms->tcon;
1319 int remap = cifs_remap(cifs_sb);
1320 const struct nls_table *nls = cifs_sb->local_nls;
1321 int create_options = oparms->create_options;
1322 int desired_access = oparms->desired_access;
1323 int disposition = oparms->disposition;
1324 const char *path = oparms->path;
1327 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1332 /* no commands go after this */
1333 req->AndXCommand = 0xFF;
1335 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1336 /* account for one byte pad to word boundary */
1338 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1339 path, PATH_MAX, nls, remap);
1343 req->NameLength = cpu_to_le16(name_len);
1345 /* BB improve check for buffer overruns BB */
1348 name_len = strnlen(path, PATH_MAX);
1351 req->NameLength = cpu_to_le16(name_len);
1352 strncpy(req->fileName, path, name_len);
1355 if (*oplock & REQ_OPLOCK)
1356 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1357 else if (*oplock & REQ_BATCHOPLOCK)
1358 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1360 req->DesiredAccess = cpu_to_le32(desired_access);
1361 req->AllocationSize = 0;
1364 * Set file as system file if special file such as fifo and server
1365 * expecting SFU style and no Unix extensions.
1367 if (create_options & CREATE_OPTION_SPECIAL)
1368 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1370 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1373 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1374 * sensitive checks for other servers such as Samba.
1376 if (tcon->ses->capabilities & CAP_UNIX)
1377 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1379 if (create_options & CREATE_OPTION_READONLY)
1380 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1382 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1383 req->CreateDisposition = cpu_to_le32(disposition);
1384 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1386 /* BB Expirement with various impersonation levels and verify */
1387 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1388 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1391 inc_rfc1001_len(req, count);
1393 req->ByteCount = cpu_to_le16(count);
1394 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1395 (struct smb_hdr *)rsp, &bytes_returned, 0);
1396 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1398 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1399 cifs_buf_release(req);
1405 /* 1 byte no need to le_to_cpu */
1406 *oplock = rsp->OplockLevel;
1407 /* cifs fid stays in le */
1408 oparms->fid->netfid = rsp->Fid;
1410 /* Let caller know file was created so we can set the mode. */
1411 /* Do we care about the CreateAction in any other cases? */
1412 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1413 *oplock |= CIFS_CREATE_ACTION;
1416 /* copy from CreationTime to Attributes */
1417 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1418 /* the file_info buf is endian converted by caller */
1419 buf->AllocationSize = rsp->AllocationSize;
1420 buf->EndOfFile = rsp->EndOfFile;
1421 buf->NumberOfLinks = cpu_to_le32(1);
1422 buf->DeletePending = 0;
1425 cifs_buf_release(req);
1430 * Discard any remaining data in the current SMB. To do this, we borrow the
1434 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1436 unsigned int rfclen = server->pdu_size;
1437 int remaining = rfclen + server->vals->header_preamble_size -
1440 while (remaining > 0) {
1443 length = cifs_read_from_socket(server, server->bigbuf,
1444 min_t(unsigned int, remaining,
1445 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1448 server->total_read += length;
1449 remaining -= length;
1456 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1459 struct cifs_readdata *rdata = mid->callback_data;
1461 length = cifs_discard_remaining_data(server);
1462 dequeue_mid(mid, rdata->result);
1463 mid->resp_buf = server->smallbuf;
1464 server->smallbuf = NULL;
1469 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1472 unsigned int data_offset, data_len;
1473 struct cifs_readdata *rdata = mid->callback_data;
1474 char *buf = server->smallbuf;
1475 unsigned int buflen = server->pdu_size +
1476 server->vals->header_preamble_size;
1477 bool use_rdma_mr = false;
1479 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1480 __func__, mid->mid, rdata->offset, rdata->bytes);
1483 * read the rest of READ_RSP header (sans Data array), or whatever we
1484 * can if there's not enough data. At this point, we've read down to
1487 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1488 HEADER_SIZE(server) + 1;
1490 length = cifs_read_from_socket(server,
1491 buf + HEADER_SIZE(server) - 1, len);
1494 server->total_read += length;
1496 if (server->ops->is_session_expired &&
1497 server->ops->is_session_expired(buf)) {
1498 cifs_reconnect(server);
1499 wake_up(&server->response_q);
1503 if (server->ops->is_status_pending &&
1504 server->ops->is_status_pending(buf, server, 0)) {
1505 cifs_discard_remaining_data(server);
1509 /* Was the SMB read successful? */
1510 rdata->result = server->ops->map_error(buf, false);
1511 if (rdata->result != 0) {
1512 cifs_dbg(FYI, "%s: server returned error %d\n",
1513 __func__, rdata->result);
1514 return cifs_readv_discard(server, mid);
1517 /* Is there enough to get to the rest of the READ_RSP header? */
1518 if (server->total_read < server->vals->read_rsp_size) {
1519 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1520 __func__, server->total_read,
1521 server->vals->read_rsp_size);
1522 rdata->result = -EIO;
1523 return cifs_readv_discard(server, mid);
1526 data_offset = server->ops->read_data_offset(buf) +
1527 server->vals->header_preamble_size;
1528 if (data_offset < server->total_read) {
1530 * win2k8 sometimes sends an offset of 0 when the read
1531 * is beyond the EOF. Treat it as if the data starts just after
1534 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1535 __func__, data_offset);
1536 data_offset = server->total_read;
1537 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1538 /* data_offset is beyond the end of smallbuf */
1539 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1540 __func__, data_offset);
1541 rdata->result = -EIO;
1542 return cifs_readv_discard(server, mid);
1545 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1546 __func__, server->total_read, data_offset);
1548 len = data_offset - server->total_read;
1550 /* read any junk before data into the rest of smallbuf */
1551 length = cifs_read_from_socket(server,
1552 buf + server->total_read, len);
1555 server->total_read += length;
1558 /* set up first iov for signature check */
1559 rdata->iov[0].iov_base = buf;
1560 rdata->iov[0].iov_len = 4;
1561 rdata->iov[1].iov_base = buf + 4;
1562 rdata->iov[1].iov_len = server->total_read - 4;
1563 cifs_dbg(FYI, "0: iov_base=%p iov_len=%u\n",
1564 rdata->iov[0].iov_base, server->total_read);
1566 /* how much data is in the response? */
1567 #ifdef CONFIG_CIFS_SMB_DIRECT
1568 use_rdma_mr = rdata->mr;
1570 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1571 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1572 /* data_len is corrupt -- discard frame */
1573 rdata->result = -EIO;
1574 return cifs_readv_discard(server, mid);
1577 length = rdata->read_into_pages(server, rdata, data_len);
1581 server->total_read += length;
1583 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1584 server->total_read, buflen, data_len);
1586 /* discard anything left over */
1587 if (server->total_read < buflen)
1588 return cifs_readv_discard(server, mid);
1590 dequeue_mid(mid, false);
1591 mid->resp_buf = server->smallbuf;
1592 server->smallbuf = NULL;
1597 cifs_readv_callback(struct mid_q_entry *mid)
1599 struct cifs_readdata *rdata = mid->callback_data;
1600 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1601 struct TCP_Server_Info *server = tcon->ses->server;
1602 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1604 .rq_pages = rdata->pages,
1605 .rq_npages = rdata->nr_pages,
1606 .rq_pagesz = rdata->pagesz,
1607 .rq_tailsz = rdata->tailsz };
1609 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1610 __func__, mid->mid, mid->mid_state, rdata->result,
1613 switch (mid->mid_state) {
1614 case MID_RESPONSE_RECEIVED:
1615 /* result already set, check signature */
1619 rc = cifs_verify_signature(&rqst, server,
1620 mid->sequence_number);
1622 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1625 /* FIXME: should this be counted toward the initiating task? */
1626 task_io_account_read(rdata->got_bytes);
1627 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1629 case MID_REQUEST_SUBMITTED:
1630 case MID_RETRY_NEEDED:
1631 rdata->result = -EAGAIN;
1632 if (server->sign && rdata->got_bytes)
1633 /* reset bytes number since we can not check a sign */
1634 rdata->got_bytes = 0;
1635 /* FIXME: should this be counted toward the initiating task? */
1636 task_io_account_read(rdata->got_bytes);
1637 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1640 rdata->result = -EIO;
1643 queue_work(cifsiod_wq, &rdata->work);
1644 DeleteMidQEntry(mid);
1645 add_credits(server, 1, 0);
1648 /* cifs_async_readv - send an async write, and set up mid to handle result */
1650 cifs_async_readv(struct cifs_readdata *rdata)
1653 READ_REQ *smb = NULL;
1655 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1656 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1659 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1660 __func__, rdata->offset, rdata->bytes);
1662 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1665 wct = 10; /* old style read */
1666 if ((rdata->offset >> 32) > 0) {
1667 /* can not handle this big offset for old */
1672 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1676 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1677 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1679 smb->AndXCommand = 0xFF; /* none */
1680 smb->Fid = rdata->cfile->fid.netfid;
1681 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1683 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1685 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1686 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1690 /* old style read */
1691 struct smb_com_readx_req *smbr =
1692 (struct smb_com_readx_req *)smb;
1693 smbr->ByteCount = 0;
1696 /* 4 for RFC1001 length + 1 for BCC */
1697 rdata->iov[0].iov_base = smb;
1698 rdata->iov[0].iov_len = 4;
1699 rdata->iov[1].iov_base = (char *)smb + 4;
1700 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1702 kref_get(&rdata->refcount);
1703 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1704 cifs_readv_callback, NULL, rdata, 0);
1707 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1709 kref_put(&rdata->refcount, cifs_readdata_release);
1711 cifs_small_buf_release(smb);
1716 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1717 unsigned int *nbytes, char **buf, int *pbuf_type)
1720 READ_REQ *pSMB = NULL;
1721 READ_RSP *pSMBr = NULL;
1722 char *pReadData = NULL;
1724 int resp_buf_type = 0;
1726 struct kvec rsp_iov;
1727 __u32 pid = io_parms->pid;
1728 __u16 netfid = io_parms->netfid;
1729 __u64 offset = io_parms->offset;
1730 struct cifs_tcon *tcon = io_parms->tcon;
1731 unsigned int count = io_parms->length;
1733 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1734 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1737 wct = 10; /* old style read */
1738 if ((offset >> 32) > 0) {
1739 /* can not handle this big offset for old */
1745 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1749 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1750 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1752 /* tcon and ses pointer are checked in smb_init */
1753 if (tcon->ses->server == NULL)
1754 return -ECONNABORTED;
1756 pSMB->AndXCommand = 0xFF; /* none */
1758 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1760 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1762 pSMB->Remaining = 0;
1763 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1764 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1766 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1768 /* old style read */
1769 struct smb_com_readx_req *pSMBW =
1770 (struct smb_com_readx_req *)pSMB;
1771 pSMBW->ByteCount = 0;
1774 iov[0].iov_base = (char *)pSMB;
1775 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1776 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1777 CIFS_LOG_ERROR, &rsp_iov);
1778 cifs_small_buf_release(pSMB);
1779 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1780 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1782 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1784 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1785 data_length = data_length << 16;
1786 data_length += le16_to_cpu(pSMBr->DataLength);
1787 *nbytes = data_length;
1789 /*check that DataLength would not go beyond end of SMB */
1790 if ((data_length > CIFSMaxBufSize)
1791 || (data_length > count)) {
1792 cifs_dbg(FYI, "bad length %d for count %d\n",
1793 data_length, count);
1797 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1798 le16_to_cpu(pSMBr->DataOffset);
1799 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1800 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1802 }*/ /* can not use copy_to_user when using page cache*/
1804 memcpy(*buf, pReadData, data_length);
1809 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1810 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1811 /* return buffer to caller to free */
1812 *buf = rsp_iov.iov_base;
1813 if (resp_buf_type == CIFS_SMALL_BUFFER)
1814 *pbuf_type = CIFS_SMALL_BUFFER;
1815 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1816 *pbuf_type = CIFS_LARGE_BUFFER;
1817 } /* else no valid buffer on return - leave as null */
1819 /* Note: On -EAGAIN error only caller can retry on handle based calls
1820 since file handle passed in no longer valid */
1826 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1827 unsigned int *nbytes, const char *buf)
1830 WRITE_REQ *pSMB = NULL;
1831 WRITE_RSP *pSMBr = NULL;
1832 int bytes_returned, wct;
1835 __u32 pid = io_parms->pid;
1836 __u16 netfid = io_parms->netfid;
1837 __u64 offset = io_parms->offset;
1838 struct cifs_tcon *tcon = io_parms->tcon;
1839 unsigned int count = io_parms->length;
1843 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1844 if (tcon->ses == NULL)
1845 return -ECONNABORTED;
1847 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1851 if ((offset >> 32) > 0) {
1852 /* can not handle big offset for old srv */
1857 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1862 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1863 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1865 /* tcon and ses pointer are checked in smb_init */
1866 if (tcon->ses->server == NULL)
1867 return -ECONNABORTED;
1869 pSMB->AndXCommand = 0xFF; /* none */
1871 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1873 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1875 pSMB->Reserved = 0xFFFFFFFF;
1876 pSMB->WriteMode = 0;
1877 pSMB->Remaining = 0;
1879 /* Can increase buffer size if buffer is big enough in some cases ie we
1880 can send more if LARGE_WRITE_X capability returned by the server and if
1881 our buffer is big enough or if we convert to iovecs on socket writes
1882 and eliminate the copy to the CIFS buffer */
1883 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1884 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1886 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1890 if (bytes_sent > count)
1893 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1895 memcpy(pSMB->Data, buf, bytes_sent);
1896 else if (count != 0) {
1898 cifs_buf_release(pSMB);
1900 } /* else setting file size with write of zero bytes */
1902 byte_count = bytes_sent + 1; /* pad */
1903 else /* wct == 12 */
1904 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1906 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1907 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1908 inc_rfc1001_len(pSMB, byte_count);
1911 pSMB->ByteCount = cpu_to_le16(byte_count);
1912 else { /* old style write has byte count 4 bytes earlier
1914 struct smb_com_writex_req *pSMBW =
1915 (struct smb_com_writex_req *)pSMB;
1916 pSMBW->ByteCount = cpu_to_le16(byte_count);
1919 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1920 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1921 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1923 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1925 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1926 *nbytes = (*nbytes) << 16;
1927 *nbytes += le16_to_cpu(pSMBr->Count);
1930 * Mask off high 16 bits when bytes written as returned by the
1931 * server is greater than bytes requested by the client. Some
1932 * OS/2 servers are known to set incorrect CountHigh values.
1934 if (*nbytes > count)
1938 cifs_buf_release(pSMB);
1940 /* Note: On -EAGAIN error only caller can retry on handle based calls
1941 since file handle passed in no longer valid */
1947 cifs_writedata_release(struct kref *refcount)
1949 struct cifs_writedata *wdata = container_of(refcount,
1950 struct cifs_writedata, refcount);
1951 #ifdef CONFIG_CIFS_SMB_DIRECT
1953 smbd_deregister_mr(wdata->mr);
1959 cifsFileInfo_put(wdata->cfile);
1961 kvfree(wdata->pages);
1966 * Write failed with a retryable error. Resend the write request. It's also
1967 * possible that the page was redirtied so re-clean the page.
1970 cifs_writev_requeue(struct cifs_writedata *wdata)
1973 struct inode *inode = d_inode(wdata->cfile->dentry);
1974 struct TCP_Server_Info *server;
1975 unsigned int rest_len;
1977 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1979 rest_len = wdata->bytes;
1981 struct cifs_writedata *wdata2;
1982 unsigned int j, nr_pages, wsize, tailsz, cur_len;
1984 wsize = server->ops->wp_retry_size(inode);
1985 if (wsize < rest_len) {
1986 nr_pages = wsize / PAGE_SIZE;
1991 cur_len = nr_pages * PAGE_SIZE;
1994 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
1996 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
1999 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
2005 for (j = 0; j < nr_pages; j++) {
2006 wdata2->pages[j] = wdata->pages[i + j];
2007 lock_page(wdata2->pages[j]);
2008 clear_page_dirty_for_io(wdata2->pages[j]);
2011 wdata2->sync_mode = wdata->sync_mode;
2012 wdata2->nr_pages = nr_pages;
2013 wdata2->offset = page_offset(wdata2->pages[0]);
2014 wdata2->pagesz = PAGE_SIZE;
2015 wdata2->tailsz = tailsz;
2016 wdata2->bytes = cur_len;
2018 wdata2->cfile = find_writable_file(CIFS_I(inode), false);
2019 if (!wdata2->cfile) {
2020 cifs_dbg(VFS, "No writable handles for inode\n");
2024 wdata2->pid = wdata2->cfile->pid;
2025 rc = server->ops->async_writev(wdata2, cifs_writedata_release);
2027 for (j = 0; j < nr_pages; j++) {
2028 unlock_page(wdata2->pages[j]);
2029 if (rc != 0 && rc != -EAGAIN) {
2030 SetPageError(wdata2->pages[j]);
2031 end_page_writeback(wdata2->pages[j]);
2032 put_page(wdata2->pages[j]);
2037 kref_put(&wdata2->refcount, cifs_writedata_release);
2043 rest_len -= cur_len;
2045 } while (i < wdata->nr_pages);
2047 mapping_set_error(inode->i_mapping, rc);
2048 kref_put(&wdata->refcount, cifs_writedata_release);
2052 cifs_writev_complete(struct work_struct *work)
2054 struct cifs_writedata *wdata = container_of(work,
2055 struct cifs_writedata, work);
2056 struct inode *inode = d_inode(wdata->cfile->dentry);
2059 if (wdata->result == 0) {
2060 spin_lock(&inode->i_lock);
2061 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2062 spin_unlock(&inode->i_lock);
2063 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2065 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2066 return cifs_writev_requeue(wdata);
2068 for (i = 0; i < wdata->nr_pages; i++) {
2069 struct page *page = wdata->pages[i];
2070 if (wdata->result == -EAGAIN)
2071 __set_page_dirty_nobuffers(page);
2072 else if (wdata->result < 0)
2074 end_page_writeback(page);
2077 if (wdata->result != -EAGAIN)
2078 mapping_set_error(inode->i_mapping, wdata->result);
2079 kref_put(&wdata->refcount, cifs_writedata_release);
2082 struct cifs_writedata *
2083 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2085 struct page **pages =
2086 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2088 return cifs_writedata_direct_alloc(pages, complete);
2093 struct cifs_writedata *
2094 cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2096 struct cifs_writedata *wdata;
2098 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2099 if (wdata != NULL) {
2100 wdata->pages = pages;
2101 kref_init(&wdata->refcount);
2102 INIT_LIST_HEAD(&wdata->list);
2103 init_completion(&wdata->done);
2104 INIT_WORK(&wdata->work, complete);
2110 * Check the mid_state and signature on received buffer (if any), and queue the
2111 * workqueue completion task.
2114 cifs_writev_callback(struct mid_q_entry *mid)
2116 struct cifs_writedata *wdata = mid->callback_data;
2117 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2118 unsigned int written;
2119 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2121 switch (mid->mid_state) {
2122 case MID_RESPONSE_RECEIVED:
2123 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2124 if (wdata->result != 0)
2127 written = le16_to_cpu(smb->CountHigh);
2129 written += le16_to_cpu(smb->Count);
2131 * Mask off high 16 bits when bytes written as returned
2132 * by the server is greater than bytes requested by the
2133 * client. OS/2 servers are known to set incorrect
2136 if (written > wdata->bytes)
2139 if (written < wdata->bytes)
2140 wdata->result = -ENOSPC;
2142 wdata->bytes = written;
2144 case MID_REQUEST_SUBMITTED:
2145 case MID_RETRY_NEEDED:
2146 wdata->result = -EAGAIN;
2149 wdata->result = -EIO;
2153 queue_work(cifsiod_wq, &wdata->work);
2154 DeleteMidQEntry(mid);
2155 add_credits(tcon->ses->server, 1, 0);
2158 /* cifs_async_writev - send an async write, and set up mid to handle result */
2160 cifs_async_writev(struct cifs_writedata *wdata,
2161 void (*release)(struct kref *kref))
2164 WRITE_REQ *smb = NULL;
2166 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2168 struct smb_rqst rqst = { };
2170 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2174 if (wdata->offset >> 32 > 0) {
2175 /* can not handle big offset for old srv */
2180 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2182 goto async_writev_out;
2184 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2185 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2187 smb->AndXCommand = 0xFF; /* none */
2188 smb->Fid = wdata->cfile->fid.netfid;
2189 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2191 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2192 smb->Reserved = 0xFFFFFFFF;
2197 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2199 /* 4 for RFC1001 length + 1 for BCC */
2201 iov[0].iov_base = smb;
2202 iov[1].iov_len = get_rfc1002_length(smb) + 1;
2203 iov[1].iov_base = (char *)smb + 4;
2207 rqst.rq_pages = wdata->pages;
2208 rqst.rq_npages = wdata->nr_pages;
2209 rqst.rq_pagesz = wdata->pagesz;
2210 rqst.rq_tailsz = wdata->tailsz;
2212 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2213 wdata->offset, wdata->bytes);
2215 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2216 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2219 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2220 put_bcc(wdata->bytes + 1, &smb->hdr);
2223 struct smb_com_writex_req *smbw =
2224 (struct smb_com_writex_req *)smb;
2225 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2226 put_bcc(wdata->bytes + 5, &smbw->hdr);
2227 iov[1].iov_len += 4; /* pad bigger by four bytes */
2230 kref_get(&wdata->refcount);
2231 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2232 cifs_writev_callback, NULL, wdata, 0);
2235 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2237 kref_put(&wdata->refcount, release);
2240 cifs_small_buf_release(smb);
2245 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2246 unsigned int *nbytes, struct kvec *iov, int n_vec)
2249 WRITE_REQ *pSMB = NULL;
2252 int resp_buf_type = 0;
2253 __u32 pid = io_parms->pid;
2254 __u16 netfid = io_parms->netfid;
2255 __u64 offset = io_parms->offset;
2256 struct cifs_tcon *tcon = io_parms->tcon;
2257 unsigned int count = io_parms->length;
2258 struct kvec rsp_iov;
2262 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2264 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2268 if ((offset >> 32) > 0) {
2269 /* can not handle big offset for old srv */
2273 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2277 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2278 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2280 /* tcon and ses pointer are checked in smb_init */
2281 if (tcon->ses->server == NULL)
2282 return -ECONNABORTED;
2284 pSMB->AndXCommand = 0xFF; /* none */
2286 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2288 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2289 pSMB->Reserved = 0xFFFFFFFF;
2290 pSMB->WriteMode = 0;
2291 pSMB->Remaining = 0;
2294 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2296 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2297 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2298 /* header + 1 byte pad */
2299 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2301 inc_rfc1001_len(pSMB, count + 1);
2302 else /* wct == 12 */
2303 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2305 pSMB->ByteCount = cpu_to_le16(count + 1);
2306 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2307 struct smb_com_writex_req *pSMBW =
2308 (struct smb_com_writex_req *)pSMB;
2309 pSMBW->ByteCount = cpu_to_le16(count + 5);
2311 iov[0].iov_base = pSMB;
2313 iov[0].iov_len = smb_hdr_len + 4;
2314 else /* wct == 12 pad bigger by four bytes */
2315 iov[0].iov_len = smb_hdr_len + 8;
2317 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2319 cifs_small_buf_release(pSMB);
2320 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2322 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2323 } else if (resp_buf_type == 0) {
2324 /* presumably this can not happen, but best to be safe */
2327 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2328 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2329 *nbytes = (*nbytes) << 16;
2330 *nbytes += le16_to_cpu(pSMBr->Count);
2333 * Mask off high 16 bits when bytes written as returned by the
2334 * server is greater than bytes requested by the client. OS/2
2335 * servers are known to set incorrect CountHigh values.
2337 if (*nbytes > count)
2341 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2343 /* Note: On -EAGAIN error only caller can retry on handle based calls
2344 since file handle passed in no longer valid */
2349 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2350 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2351 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2354 LOCK_REQ *pSMB = NULL;
2356 struct kvec rsp_iov;
2360 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2361 num_lock, num_unlock);
2363 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2368 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2369 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2370 pSMB->LockType = lock_type;
2371 pSMB->AndXCommand = 0xFF; /* none */
2372 pSMB->Fid = netfid; /* netfid stays le */
2374 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2375 inc_rfc1001_len(pSMB, count);
2376 pSMB->ByteCount = cpu_to_le16(count);
2378 iov[0].iov_base = (char *)pSMB;
2379 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2380 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2381 iov[1].iov_base = (char *)buf;
2382 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2384 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2385 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP,
2387 cifs_small_buf_release(pSMB);
2389 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2395 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2396 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2397 const __u64 offset, const __u32 numUnlock,
2398 const __u32 numLock, const __u8 lockType,
2399 const bool waitFlag, const __u8 oplock_level)
2402 LOCK_REQ *pSMB = NULL;
2403 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2408 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2409 (int)waitFlag, numLock);
2410 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2415 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2416 /* no response expected */
2417 flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP;
2419 } else if (waitFlag) {
2420 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2421 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2426 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2427 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2428 pSMB->LockType = lockType;
2429 pSMB->OplockLevel = oplock_level;
2430 pSMB->AndXCommand = 0xFF; /* none */
2431 pSMB->Fid = smb_file_id; /* netfid stays le */
2433 if ((numLock != 0) || (numUnlock != 0)) {
2434 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2435 /* BB where to store pid high? */
2436 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2437 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2438 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2439 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2440 count = sizeof(LOCKING_ANDX_RANGE);
2445 inc_rfc1001_len(pSMB, count);
2446 pSMB->ByteCount = cpu_to_le16(count);
2449 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2450 (struct smb_hdr *) pSMB, &bytes_returned);
2452 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2453 cifs_small_buf_release(pSMB);
2454 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2456 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2458 /* Note: On -EAGAIN error only caller can retry on handle based calls
2459 since file handle passed in no longer valid */
2464 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2465 const __u16 smb_file_id, const __u32 netpid,
2466 const loff_t start_offset, const __u64 len,
2467 struct file_lock *pLockData, const __u16 lock_type,
2468 const bool waitFlag)
2470 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2471 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2472 struct cifs_posix_lock *parm_data;
2475 int bytes_returned = 0;
2476 int resp_buf_type = 0;
2477 __u16 params, param_offset, offset, byte_count, count;
2479 struct kvec rsp_iov;
2481 cifs_dbg(FYI, "Posix Lock\n");
2483 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2488 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2491 pSMB->MaxSetupCount = 0;
2494 pSMB->Reserved2 = 0;
2495 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2496 offset = param_offset + params;
2498 count = sizeof(struct cifs_posix_lock);
2499 pSMB->MaxParameterCount = cpu_to_le16(2);
2500 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2501 pSMB->SetupCount = 1;
2502 pSMB->Reserved3 = 0;
2504 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2506 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2507 byte_count = 3 /* pad */ + params + count;
2508 pSMB->DataCount = cpu_to_le16(count);
2509 pSMB->ParameterCount = cpu_to_le16(params);
2510 pSMB->TotalDataCount = pSMB->DataCount;
2511 pSMB->TotalParameterCount = pSMB->ParameterCount;
2512 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2513 parm_data = (struct cifs_posix_lock *)
2514 (((char *) &pSMB->hdr.Protocol) + offset);
2516 parm_data->lock_type = cpu_to_le16(lock_type);
2518 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2519 parm_data->lock_flags = cpu_to_le16(1);
2520 pSMB->Timeout = cpu_to_le32(-1);
2524 parm_data->pid = cpu_to_le32(netpid);
2525 parm_data->start = cpu_to_le64(start_offset);
2526 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2528 pSMB->DataOffset = cpu_to_le16(offset);
2529 pSMB->Fid = smb_file_id;
2530 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2531 pSMB->Reserved4 = 0;
2532 inc_rfc1001_len(pSMB, byte_count);
2533 pSMB->ByteCount = cpu_to_le16(byte_count);
2535 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2536 (struct smb_hdr *) pSMBr, &bytes_returned);
2538 iov[0].iov_base = (char *)pSMB;
2539 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2540 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2541 &resp_buf_type, timeout, &rsp_iov);
2542 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2544 cifs_small_buf_release(pSMB);
2547 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2548 } else if (pLockData) {
2549 /* lock structure can be returned on get */
2552 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2554 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2555 rc = -EIO; /* bad smb */
2558 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2559 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2560 if (data_count < sizeof(struct cifs_posix_lock)) {
2564 parm_data = (struct cifs_posix_lock *)
2565 ((char *)&pSMBr->hdr.Protocol + data_offset);
2566 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2567 pLockData->fl_type = F_UNLCK;
2569 if (parm_data->lock_type ==
2570 cpu_to_le16(CIFS_RDLCK))
2571 pLockData->fl_type = F_RDLCK;
2572 else if (parm_data->lock_type ==
2573 cpu_to_le16(CIFS_WRLCK))
2574 pLockData->fl_type = F_WRLCK;
2576 pLockData->fl_start = le64_to_cpu(parm_data->start);
2577 pLockData->fl_end = pLockData->fl_start +
2578 le64_to_cpu(parm_data->length) - 1;
2579 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2584 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2586 /* Note: On -EAGAIN error only caller can retry on handle based calls
2587 since file handle passed in no longer valid */
2594 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2597 CLOSE_REQ *pSMB = NULL;
2598 cifs_dbg(FYI, "In CIFSSMBClose\n");
2600 /* do not retry on dead session on close */
2601 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2607 pSMB->FileID = (__u16) smb_file_id;
2608 pSMB->LastWriteTime = 0xFFFFFFFF;
2609 pSMB->ByteCount = 0;
2610 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2611 cifs_small_buf_release(pSMB);
2612 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2615 /* EINTR is expected when user ctl-c to kill app */
2616 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2620 /* Since session is dead, file will be closed on server already */
2628 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2631 FLUSH_REQ *pSMB = NULL;
2632 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2634 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2638 pSMB->FileID = (__u16) smb_file_id;
2639 pSMB->ByteCount = 0;
2640 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2641 cifs_small_buf_release(pSMB);
2642 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2644 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2650 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2651 const char *from_name, const char *to_name,
2652 struct cifs_sb_info *cifs_sb)
2655 RENAME_REQ *pSMB = NULL;
2656 RENAME_RSP *pSMBr = NULL;
2658 int name_len, name_len2;
2660 int remap = cifs_remap(cifs_sb);
2662 cifs_dbg(FYI, "In CIFSSMBRename\n");
2664 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2669 pSMB->BufferFormat = 0x04;
2670 pSMB->SearchAttributes =
2671 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2674 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2675 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2676 from_name, PATH_MAX,
2677 cifs_sb->local_nls, remap);
2678 name_len++; /* trailing null */
2680 pSMB->OldFileName[name_len] = 0x04; /* pad */
2681 /* protocol requires ASCII signature byte on Unicode string */
2682 pSMB->OldFileName[name_len + 1] = 0x00;
2684 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2685 to_name, PATH_MAX, cifs_sb->local_nls,
2687 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2688 name_len2 *= 2; /* convert to bytes */
2689 } else { /* BB improve the check for buffer overruns BB */
2690 name_len = strnlen(from_name, PATH_MAX);
2691 name_len++; /* trailing null */
2692 strncpy(pSMB->OldFileName, from_name, name_len);
2693 name_len2 = strnlen(to_name, PATH_MAX);
2694 name_len2++; /* trailing null */
2695 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2696 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
2697 name_len2++; /* trailing null */
2698 name_len2++; /* signature byte */
2701 count = 1 /* 1st signature byte */ + name_len + name_len2;
2702 inc_rfc1001_len(pSMB, count);
2703 pSMB->ByteCount = cpu_to_le16(count);
2705 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2706 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2707 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2709 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2711 cifs_buf_release(pSMB);
2719 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2720 int netfid, const char *target_name,
2721 const struct nls_table *nls_codepage, int remap)
2723 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2724 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2725 struct set_file_rename *rename_info;
2727 char dummy_string[30];
2729 int bytes_returned = 0;
2731 __u16 params, param_offset, offset, count, byte_count;
2733 cifs_dbg(FYI, "Rename to File by handle\n");
2734 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2740 pSMB->MaxSetupCount = 0;
2744 pSMB->Reserved2 = 0;
2745 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2746 offset = param_offset + params;
2748 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2749 rename_info = (struct set_file_rename *) data_offset;
2750 pSMB->MaxParameterCount = cpu_to_le16(2);
2751 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2752 pSMB->SetupCount = 1;
2753 pSMB->Reserved3 = 0;
2754 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2755 byte_count = 3 /* pad */ + params;
2756 pSMB->ParameterCount = cpu_to_le16(params);
2757 pSMB->TotalParameterCount = pSMB->ParameterCount;
2758 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2759 pSMB->DataOffset = cpu_to_le16(offset);
2760 /* construct random name ".cifs_tmp<inodenum><mid>" */
2761 rename_info->overwrite = cpu_to_le32(1);
2762 rename_info->root_fid = 0;
2763 /* unicode only call */
2764 if (target_name == NULL) {
2765 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2767 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2768 dummy_string, 24, nls_codepage, remap);
2771 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2772 target_name, PATH_MAX, nls_codepage,
2775 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2776 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2777 byte_count += count;
2778 pSMB->DataCount = cpu_to_le16(count);
2779 pSMB->TotalDataCount = pSMB->DataCount;
2781 pSMB->InformationLevel =
2782 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2783 pSMB->Reserved4 = 0;
2784 inc_rfc1001_len(pSMB, byte_count);
2785 pSMB->ByteCount = cpu_to_le16(byte_count);
2786 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2787 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2788 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2790 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2793 cifs_buf_release(pSMB);
2795 /* Note: On -EAGAIN error only caller can retry on handle based calls
2796 since file handle passed in no longer valid */
2802 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2803 const char *fromName, const __u16 target_tid, const char *toName,
2804 const int flags, const struct nls_table *nls_codepage, int remap)
2807 COPY_REQ *pSMB = NULL;
2808 COPY_RSP *pSMBr = NULL;
2810 int name_len, name_len2;
2813 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2815 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2820 pSMB->BufferFormat = 0x04;
2821 pSMB->Tid2 = target_tid;
2823 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2825 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2826 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2827 fromName, PATH_MAX, nls_codepage,
2829 name_len++; /* trailing null */
2831 pSMB->OldFileName[name_len] = 0x04; /* pad */
2832 /* protocol requires ASCII signature byte on Unicode string */
2833 pSMB->OldFileName[name_len + 1] = 0x00;
2835 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2836 toName, PATH_MAX, nls_codepage, remap);
2837 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2838 name_len2 *= 2; /* convert to bytes */
2839 } else { /* BB improve the check for buffer overruns BB */
2840 name_len = strnlen(fromName, PATH_MAX);
2841 name_len++; /* trailing null */
2842 strncpy(pSMB->OldFileName, fromName, name_len);
2843 name_len2 = strnlen(toName, PATH_MAX);
2844 name_len2++; /* trailing null */
2845 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2846 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2847 name_len2++; /* trailing null */
2848 name_len2++; /* signature byte */
2851 count = 1 /* 1st signature byte */ + name_len + name_len2;
2852 inc_rfc1001_len(pSMB, count);
2853 pSMB->ByteCount = cpu_to_le16(count);
2855 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2856 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2858 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2859 rc, le16_to_cpu(pSMBr->CopyCount));
2861 cifs_buf_release(pSMB);
2870 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2871 const char *fromName, const char *toName,
2872 const struct nls_table *nls_codepage, int remap)
2874 TRANSACTION2_SPI_REQ *pSMB = NULL;
2875 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2878 int name_len_target;
2880 int bytes_returned = 0;
2881 __u16 params, param_offset, offset, byte_count;
2883 cifs_dbg(FYI, "In Symlink Unix style\n");
2885 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2890 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2892 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2893 /* find define for this maxpathcomponent */
2894 PATH_MAX, nls_codepage, remap);
2895 name_len++; /* trailing null */
2898 } else { /* BB improve the check for buffer overruns BB */
2899 name_len = strnlen(fromName, PATH_MAX);
2900 name_len++; /* trailing null */
2901 strncpy(pSMB->FileName, fromName, name_len);
2903 params = 6 + name_len;
2904 pSMB->MaxSetupCount = 0;
2908 pSMB->Reserved2 = 0;
2909 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2910 InformationLevel) - 4;
2911 offset = param_offset + params;
2913 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2914 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2916 cifsConvertToUTF16((__le16 *) data_offset, toName,
2917 /* find define for this maxpathcomponent */
2918 PATH_MAX, nls_codepage, remap);
2919 name_len_target++; /* trailing null */
2920 name_len_target *= 2;
2921 } else { /* BB improve the check for buffer overruns BB */
2922 name_len_target = strnlen(toName, PATH_MAX);
2923 name_len_target++; /* trailing null */
2924 strncpy(data_offset, toName, name_len_target);
2927 pSMB->MaxParameterCount = cpu_to_le16(2);
2928 /* BB find exact max on data count below from sess */
2929 pSMB->MaxDataCount = cpu_to_le16(1000);
2930 pSMB->SetupCount = 1;
2931 pSMB->Reserved3 = 0;
2932 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2933 byte_count = 3 /* pad */ + params + name_len_target;
2934 pSMB->DataCount = cpu_to_le16(name_len_target);
2935 pSMB->ParameterCount = cpu_to_le16(params);
2936 pSMB->TotalDataCount = pSMB->DataCount;
2937 pSMB->TotalParameterCount = pSMB->ParameterCount;
2938 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2939 pSMB->DataOffset = cpu_to_le16(offset);
2940 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2941 pSMB->Reserved4 = 0;
2942 inc_rfc1001_len(pSMB, byte_count);
2943 pSMB->ByteCount = cpu_to_le16(byte_count);
2944 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2945 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2946 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2948 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2951 cifs_buf_release(pSMB);
2954 goto createSymLinkRetry;
2960 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2961 const char *fromName, const char *toName,
2962 const struct nls_table *nls_codepage, int remap)
2964 TRANSACTION2_SPI_REQ *pSMB = NULL;
2965 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2968 int name_len_target;
2970 int bytes_returned = 0;
2971 __u16 params, param_offset, offset, byte_count;
2973 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2974 createHardLinkRetry:
2975 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2980 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2981 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2982 PATH_MAX, nls_codepage, remap);
2983 name_len++; /* trailing null */
2986 } else { /* BB improve the check for buffer overruns BB */
2987 name_len = strnlen(toName, PATH_MAX);
2988 name_len++; /* trailing null */
2989 strncpy(pSMB->FileName, toName, name_len);
2991 params = 6 + name_len;
2992 pSMB->MaxSetupCount = 0;
2996 pSMB->Reserved2 = 0;
2997 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2998 InformationLevel) - 4;
2999 offset = param_offset + params;
3001 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
3002 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3004 cifsConvertToUTF16((__le16 *) data_offset, fromName,
3005 PATH_MAX, nls_codepage, remap);
3006 name_len_target++; /* trailing null */
3007 name_len_target *= 2;
3008 } else { /* BB improve the check for buffer overruns BB */
3009 name_len_target = strnlen(fromName, PATH_MAX);
3010 name_len_target++; /* trailing null */
3011 strncpy(data_offset, fromName, name_len_target);
3014 pSMB->MaxParameterCount = cpu_to_le16(2);
3015 /* BB find exact max on data count below from sess*/
3016 pSMB->MaxDataCount = cpu_to_le16(1000);
3017 pSMB->SetupCount = 1;
3018 pSMB->Reserved3 = 0;
3019 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3020 byte_count = 3 /* pad */ + params + name_len_target;
3021 pSMB->ParameterCount = cpu_to_le16(params);
3022 pSMB->TotalParameterCount = pSMB->ParameterCount;
3023 pSMB->DataCount = cpu_to_le16(name_len_target);
3024 pSMB->TotalDataCount = pSMB->DataCount;
3025 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3026 pSMB->DataOffset = cpu_to_le16(offset);
3027 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3028 pSMB->Reserved4 = 0;
3029 inc_rfc1001_len(pSMB, byte_count);
3030 pSMB->ByteCount = cpu_to_le16(byte_count);
3031 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3032 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3033 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3035 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3038 cifs_buf_release(pSMB);
3040 goto createHardLinkRetry;
3046 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3047 const char *from_name, const char *to_name,
3048 struct cifs_sb_info *cifs_sb)
3051 NT_RENAME_REQ *pSMB = NULL;
3052 RENAME_RSP *pSMBr = NULL;
3054 int name_len, name_len2;
3056 int remap = cifs_remap(cifs_sb);
3058 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3059 winCreateHardLinkRetry:
3061 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3066 pSMB->SearchAttributes =
3067 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3069 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3070 pSMB->ClusterCount = 0;
3072 pSMB->BufferFormat = 0x04;
3074 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3076 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3077 PATH_MAX, cifs_sb->local_nls, remap);
3078 name_len++; /* trailing null */
3081 /* protocol specifies ASCII buffer format (0x04) for unicode */
3082 pSMB->OldFileName[name_len] = 0x04;
3083 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3085 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3086 to_name, PATH_MAX, cifs_sb->local_nls,
3088 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3089 name_len2 *= 2; /* convert to bytes */
3090 } else { /* BB improve the check for buffer overruns BB */
3091 name_len = strnlen(from_name, PATH_MAX);
3092 name_len++; /* trailing null */
3093 strncpy(pSMB->OldFileName, from_name, name_len);
3094 name_len2 = strnlen(to_name, PATH_MAX);
3095 name_len2++; /* trailing null */
3096 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3097 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
3098 name_len2++; /* trailing null */
3099 name_len2++; /* signature byte */
3102 count = 1 /* string type byte */ + name_len + name_len2;
3103 inc_rfc1001_len(pSMB, count);
3104 pSMB->ByteCount = cpu_to_le16(count);
3106 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3107 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3108 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3110 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3112 cifs_buf_release(pSMB);
3114 goto winCreateHardLinkRetry;
3120 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3121 const unsigned char *searchName, char **symlinkinfo,
3122 const struct nls_table *nls_codepage, int remap)
3124 /* SMB_QUERY_FILE_UNIX_LINK */
3125 TRANSACTION2_QPI_REQ *pSMB = NULL;
3126 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3130 __u16 params, byte_count;
3133 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3136 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3141 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3143 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3144 searchName, PATH_MAX, nls_codepage,
3146 name_len++; /* trailing null */
3148 } else { /* BB improve the check for buffer overruns BB */
3149 name_len = strnlen(searchName, PATH_MAX);
3150 name_len++; /* trailing null */
3151 strncpy(pSMB->FileName, searchName, name_len);
3154 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3155 pSMB->TotalDataCount = 0;
3156 pSMB->MaxParameterCount = cpu_to_le16(2);
3157 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3158 pSMB->MaxSetupCount = 0;
3162 pSMB->Reserved2 = 0;
3163 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3164 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3165 pSMB->DataCount = 0;
3166 pSMB->DataOffset = 0;
3167 pSMB->SetupCount = 1;
3168 pSMB->Reserved3 = 0;
3169 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3170 byte_count = params + 1 /* pad */ ;
3171 pSMB->TotalParameterCount = cpu_to_le16(params);
3172 pSMB->ParameterCount = pSMB->TotalParameterCount;
3173 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3174 pSMB->Reserved4 = 0;
3175 inc_rfc1001_len(pSMB, byte_count);
3176 pSMB->ByteCount = cpu_to_le16(byte_count);
3178 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3179 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3181 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3183 /* decode response */
3185 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3186 /* BB also check enough total bytes returned */
3187 if (rc || get_bcc(&pSMBr->hdr) < 2)
3191 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3193 data_start = ((char *) &pSMBr->hdr.Protocol) +
3194 le16_to_cpu(pSMBr->t2.DataOffset);
3196 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3201 /* BB FIXME investigate remapping reserved chars here */
3202 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3203 count, is_unicode, nls_codepage);
3208 cifs_buf_release(pSMB);
3210 goto querySymLinkRetry;
3215 * Recent Windows versions now create symlinks more frequently
3216 * and they use the "reparse point" mechanism below. We can of course
3217 * do symlinks nicely to Samba and other servers which support the
3218 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3219 * "MF" symlinks optionally, but for recent Windows we really need to
3220 * reenable the code below and fix the cifs_symlink callers to handle this.
3221 * In the interim this code has been moved to its own config option so
3222 * it is not compiled in by default until callers fixed up and more tested.
3225 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3226 __u16 fid, char **symlinkinfo,
3227 const struct nls_table *nls_codepage)
3231 struct smb_com_transaction_ioctl_req *pSMB;
3232 struct smb_com_transaction_ioctl_rsp *pSMBr;
3234 unsigned int sub_len;
3236 struct reparse_symlink_data *reparse_buf;
3237 struct reparse_posix_data *posix_buf;
3238 __u32 data_offset, data_count;
3241 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3242 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3247 pSMB->TotalParameterCount = 0 ;
3248 pSMB->TotalDataCount = 0;
3249 pSMB->MaxParameterCount = cpu_to_le32(2);
3250 /* BB find exact data count max from sess structure BB */
3251 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3252 pSMB->MaxSetupCount = 4;
3254 pSMB->ParameterOffset = 0;
3255 pSMB->DataCount = 0;
3256 pSMB->DataOffset = 0;
3257 pSMB->SetupCount = 4;
3258 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3259 pSMB->ParameterCount = pSMB->TotalParameterCount;
3260 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3261 pSMB->IsFsctl = 1; /* FSCTL */
3262 pSMB->IsRootFlag = 0;
3263 pSMB->Fid = fid; /* file handle always le */
3264 pSMB->ByteCount = 0;
3266 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3267 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3269 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3273 data_offset = le32_to_cpu(pSMBr->DataOffset);
3274 data_count = le32_to_cpu(pSMBr->DataCount);
3275 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3276 /* BB also check enough total bytes returned */
3277 rc = -EIO; /* bad smb */
3280 if (!data_count || (data_count > 2048)) {
3282 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3285 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3286 reparse_buf = (struct reparse_symlink_data *)
3287 ((char *)&pSMBr->hdr.Protocol + data_offset);
3288 if ((char *)reparse_buf >= end_of_smb) {
3292 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3293 cifs_dbg(FYI, "NFS style reparse tag\n");
3294 posix_buf = (struct reparse_posix_data *)reparse_buf;
3296 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3297 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3298 le64_to_cpu(posix_buf->InodeType));
3303 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3304 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3305 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3309 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3310 sub_len, is_unicode, nls_codepage);
3312 } else if (reparse_buf->ReparseTag !=
3313 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3318 /* Reparse tag is NTFS symlink */
3319 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3320 reparse_buf->PathBuffer;
3321 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3322 if (sub_start + sub_len > end_of_smb) {
3323 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3327 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3332 /* BB FIXME investigate remapping reserved chars here */
3333 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3338 cifs_buf_release(pSMB);
3341 * Note: On -EAGAIN error only caller can retry on handle based calls
3342 * since file handle passed in no longer valid.
3348 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3353 struct smb_com_transaction_compr_ioctl_req *pSMB;
3354 struct smb_com_transaction_ioctl_rsp *pSMBr;
3356 cifs_dbg(FYI, "Set compression for %u\n", fid);
3357 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3362 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3364 pSMB->TotalParameterCount = 0;
3365 pSMB->TotalDataCount = cpu_to_le32(2);
3366 pSMB->MaxParameterCount = 0;
3367 pSMB->MaxDataCount = 0;
3368 pSMB->MaxSetupCount = 4;
3370 pSMB->ParameterOffset = 0;
3371 pSMB->DataCount = cpu_to_le32(2);
3373 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3374 compression_state) - 4); /* 84 */
3375 pSMB->SetupCount = 4;
3376 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3377 pSMB->ParameterCount = 0;
3378 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3379 pSMB->IsFsctl = 1; /* FSCTL */
3380 pSMB->IsRootFlag = 0;
3381 pSMB->Fid = fid; /* file handle always le */
3382 /* 3 byte pad, followed by 2 byte compress state */
3383 pSMB->ByteCount = cpu_to_le16(5);
3384 inc_rfc1001_len(pSMB, 5);
3386 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3387 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3389 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3391 cifs_buf_release(pSMB);
3394 * Note: On -EAGAIN error only caller can retry on handle based calls
3395 * since file handle passed in no longer valid.
3401 #ifdef CONFIG_CIFS_POSIX
3403 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3404 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3405 struct cifs_posix_ace *cifs_ace)
3407 /* u8 cifs fields do not need le conversion */
3408 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3409 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3410 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3412 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3413 ace->e_perm, ace->e_tag, ace->e_id);
3419 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3420 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3421 const int acl_type, const int size_of_data_area)
3426 struct cifs_posix_ace *pACE;
3427 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3428 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3430 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3433 if (acl_type == ACL_TYPE_ACCESS) {
3434 count = le16_to_cpu(cifs_acl->access_entry_count);
3435 pACE = &cifs_acl->ace_array[0];
3436 size = sizeof(struct cifs_posix_acl);
3437 size += sizeof(struct cifs_posix_ace) * count;
3438 /* check if we would go beyond end of SMB */
3439 if (size_of_data_area < size) {
3440 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3441 size_of_data_area, size);
3444 } else if (acl_type == ACL_TYPE_DEFAULT) {
3445 count = le16_to_cpu(cifs_acl->access_entry_count);
3446 size = sizeof(struct cifs_posix_acl);
3447 size += sizeof(struct cifs_posix_ace) * count;
3448 /* skip past access ACEs to get to default ACEs */
3449 pACE = &cifs_acl->ace_array[count];
3450 count = le16_to_cpu(cifs_acl->default_entry_count);
3451 size += sizeof(struct cifs_posix_ace) * count;
3452 /* check if we would go beyond end of SMB */
3453 if (size_of_data_area < size)
3460 size = posix_acl_xattr_size(count);
3461 if ((buflen == 0) || (local_acl == NULL)) {
3462 /* used to query ACL EA size */
3463 } else if (size > buflen) {
3465 } else /* buffer big enough */ {
3466 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3468 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3469 for (i = 0; i < count ; i++) {
3470 cifs_convert_ace(&ace[i], pACE);
3477 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3478 const struct posix_acl_xattr_entry *local_ace)
3480 __u16 rc = 0; /* 0 = ACL converted ok */
3482 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3483 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3484 /* BB is there a better way to handle the large uid? */
3485 if (local_ace->e_id == cpu_to_le32(-1)) {
3486 /* Probably no need to le convert -1 on any arch but can not hurt */
3487 cifs_ace->cifs_uid = cpu_to_le64(-1);
3489 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3491 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3492 ace->e_perm, ace->e_tag, ace->e_id);
3497 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3498 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3499 const int buflen, const int acl_type)
3502 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3503 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3504 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3508 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3511 count = posix_acl_xattr_count((size_t)buflen);
3512 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3513 count, buflen, le32_to_cpu(local_acl->a_version));
3514 if (le32_to_cpu(local_acl->a_version) != 2) {
3515 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3516 le32_to_cpu(local_acl->a_version));
3519 cifs_acl->version = cpu_to_le16(1);
3520 if (acl_type == ACL_TYPE_ACCESS) {
3521 cifs_acl->access_entry_count = cpu_to_le16(count);
3522 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3523 } else if (acl_type == ACL_TYPE_DEFAULT) {
3524 cifs_acl->default_entry_count = cpu_to_le16(count);
3525 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3527 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3530 for (i = 0; i < count; i++) {
3531 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3533 /* ACE not converted */
3538 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3539 rc += sizeof(struct cifs_posix_acl);
3540 /* BB add check to make sure ACL does not overflow SMB */
3546 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3547 const unsigned char *searchName,
3548 char *acl_inf, const int buflen, const int acl_type,
3549 const struct nls_table *nls_codepage, int remap)
3551 /* SMB_QUERY_POSIX_ACL */
3552 TRANSACTION2_QPI_REQ *pSMB = NULL;
3553 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3557 __u16 params, byte_count;
3559 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3562 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3567 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3569 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3570 searchName, PATH_MAX, nls_codepage,
3572 name_len++; /* trailing null */
3574 pSMB->FileName[name_len] = 0;
3575 pSMB->FileName[name_len+1] = 0;
3576 } else { /* BB improve the check for buffer overruns BB */
3577 name_len = strnlen(searchName, PATH_MAX);
3578 name_len++; /* trailing null */
3579 strncpy(pSMB->FileName, searchName, name_len);
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 */
3661 } else { /* BB improve the check for buffer overruns BB */
3662 name_len = strnlen(fileName, PATH_MAX);
3663 name_len++; /* trailing null */
3664 strncpy(pSMB->FileName, fileName, name_len);
3666 params = 6 + name_len;
3667 pSMB->MaxParameterCount = cpu_to_le16(2);
3668 /* BB find max SMB size from sess */
3669 pSMB->MaxDataCount = cpu_to_le16(1000);
3670 pSMB->MaxSetupCount = 0;
3674 pSMB->Reserved2 = 0;
3675 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3676 InformationLevel) - 4;
3677 offset = param_offset + params;
3678 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3679 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3681 /* convert to on the wire format for POSIX ACL */
3682 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3684 if (data_count == 0) {
3686 goto setACLerrorExit;
3688 pSMB->DataOffset = cpu_to_le16(offset);
3689 pSMB->SetupCount = 1;
3690 pSMB->Reserved3 = 0;
3691 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3692 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3693 byte_count = 3 /* pad */ + params + data_count;
3694 pSMB->DataCount = cpu_to_le16(data_count);
3695 pSMB->TotalDataCount = pSMB->DataCount;
3696 pSMB->ParameterCount = cpu_to_le16(params);
3697 pSMB->TotalParameterCount = pSMB->ParameterCount;
3698 pSMB->Reserved4 = 0;
3699 inc_rfc1001_len(pSMB, byte_count);
3700 pSMB->ByteCount = cpu_to_le16(byte_count);
3701 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3702 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3704 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3707 cifs_buf_release(pSMB);
3713 /* BB fix tabs in this function FIXME BB */
3715 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3716 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3719 struct smb_t2_qfi_req *pSMB = NULL;
3720 struct smb_t2_qfi_rsp *pSMBr = NULL;
3722 __u16 params, byte_count;
3724 cifs_dbg(FYI, "In GetExtAttr\n");
3729 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3734 params = 2 /* level */ + 2 /* fid */;
3735 pSMB->t2.TotalDataCount = 0;
3736 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3737 /* BB find exact max data count below from sess structure BB */
3738 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3739 pSMB->t2.MaxSetupCount = 0;
3740 pSMB->t2.Reserved = 0;
3742 pSMB->t2.Timeout = 0;
3743 pSMB->t2.Reserved2 = 0;
3744 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3746 pSMB->t2.DataCount = 0;
3747 pSMB->t2.DataOffset = 0;
3748 pSMB->t2.SetupCount = 1;
3749 pSMB->t2.Reserved3 = 0;
3750 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3751 byte_count = params + 1 /* pad */ ;
3752 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3753 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3754 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3757 inc_rfc1001_len(pSMB, byte_count);
3758 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3760 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3761 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3763 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3765 /* decode response */
3766 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3767 /* BB also check enough total bytes returned */
3768 if (rc || get_bcc(&pSMBr->hdr) < 2)
3769 /* If rc should we check for EOPNOSUPP and
3770 disable the srvino flag? or in caller? */
3771 rc = -EIO; /* bad smb */
3773 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3774 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3775 struct file_chattr_info *pfinfo;
3776 /* BB Do we need a cast or hash here ? */
3778 cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n");
3782 pfinfo = (struct file_chattr_info *)
3783 (data_offset + (char *) &pSMBr->hdr.Protocol);
3784 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3785 *pMask = le64_to_cpu(pfinfo->mask);
3789 cifs_buf_release(pSMB);
3791 goto GetExtAttrRetry;
3795 #endif /* CONFIG_POSIX */
3797 #ifdef CONFIG_CIFS_ACL
3799 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3800 * all NT TRANSACTS that we init here have total parm and data under about 400
3801 * bytes (to fit in small cifs buffer size), which is the case so far, it
3802 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3803 * returned setup area) and MaxParameterCount (returned parms size) must be set
3807 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3808 const int parm_len, struct cifs_tcon *tcon,
3813 struct smb_com_ntransact_req *pSMB;
3815 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3819 *ret_buf = (void *)pSMB;
3821 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3822 pSMB->TotalDataCount = 0;
3823 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3824 pSMB->ParameterCount = pSMB->TotalParameterCount;
3825 pSMB->DataCount = pSMB->TotalDataCount;
3826 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3827 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3828 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3829 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3830 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3831 pSMB->SubCommand = cpu_to_le16(sub_command);
3836 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3837 __u32 *pparmlen, __u32 *pdatalen)
3840 __u32 data_count, data_offset, parm_count, parm_offset;
3841 struct smb_com_ntransact_rsp *pSMBr;
3850 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3852 bcc = get_bcc(&pSMBr->hdr);
3853 end_of_smb = 2 /* sizeof byte count */ + bcc +
3854 (char *)&pSMBr->ByteCount;
3856 data_offset = le32_to_cpu(pSMBr->DataOffset);
3857 data_count = le32_to_cpu(pSMBr->DataCount);
3858 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3859 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3861 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3862 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3864 /* should we also check that parm and data areas do not overlap? */
3865 if (*ppparm > end_of_smb) {
3866 cifs_dbg(FYI, "parms start after end of smb\n");
3868 } else if (parm_count + *ppparm > end_of_smb) {
3869 cifs_dbg(FYI, "parm end after end of smb\n");
3871 } else if (*ppdata > end_of_smb) {
3872 cifs_dbg(FYI, "data starts after end of smb\n");
3874 } else if (data_count + *ppdata > end_of_smb) {
3875 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3876 *ppdata, data_count, (data_count + *ppdata),
3879 } else if (parm_count + data_count > bcc) {
3880 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3883 *pdatalen = data_count;
3884 *pparmlen = parm_count;
3888 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3890 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3891 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3895 QUERY_SEC_DESC_REQ *pSMB;
3897 struct kvec rsp_iov;
3899 cifs_dbg(FYI, "GetCifsACL\n");
3904 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3905 8 /* parm len */, tcon, (void **) &pSMB);
3909 pSMB->MaxParameterCount = cpu_to_le32(4);
3910 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3911 pSMB->MaxSetupCount = 0;
3912 pSMB->Fid = fid; /* file handle always le */
3913 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3915 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3916 inc_rfc1001_len(pSMB, 11);
3917 iov[0].iov_base = (char *)pSMB;
3918 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3920 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3922 cifs_small_buf_release(pSMB);
3923 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3925 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3926 } else { /* decode response */
3930 struct smb_com_ntransact_rsp *pSMBr;
3933 /* validate_nttransact */
3934 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3935 &pdata, &parm_len, pbuflen);
3938 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3940 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3941 pSMBr, parm, *acl_inf);
3943 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3944 rc = -EIO; /* bad smb */
3949 /* BB check that data area is minimum length and as big as acl_len */
3951 acl_len = le32_to_cpu(*parm);
3952 if (acl_len != *pbuflen) {
3953 cifs_dbg(VFS, "acl length %d does not match %d\n",
3955 if (*pbuflen > acl_len)
3959 /* check if buffer is big enough for the acl
3960 header followed by the smallest SID */
3961 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3962 (*pbuflen >= 64 * 1024)) {
3963 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3967 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3968 if (*acl_inf == NULL) {
3975 free_rsp_buf(buf_type, rsp_iov.iov_base);
3980 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3981 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3983 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3985 int bytes_returned = 0;
3986 SET_SEC_DESC_REQ *pSMB = NULL;
3990 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3994 pSMB->MaxSetupCount = 0;
3998 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3999 data_count = acllen;
4000 data_offset = param_offset + param_count;
4001 byte_count = 3 /* pad */ + param_count;
4003 pSMB->DataCount = cpu_to_le32(data_count);
4004 pSMB->TotalDataCount = pSMB->DataCount;
4005 pSMB->MaxParameterCount = cpu_to_le32(4);
4006 pSMB->MaxDataCount = cpu_to_le32(16384);
4007 pSMB->ParameterCount = cpu_to_le32(param_count);
4008 pSMB->ParameterOffset = cpu_to_le32(param_offset);
4009 pSMB->TotalParameterCount = pSMB->ParameterCount;
4010 pSMB->DataOffset = cpu_to_le32(data_offset);
4011 pSMB->SetupCount = 0;
4012 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
4013 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
4015 pSMB->Fid = fid; /* file handle always le */
4016 pSMB->Reserved2 = 0;
4017 pSMB->AclFlags = cpu_to_le32(aclflag);
4019 if (pntsd && acllen) {
4020 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
4021 data_offset, pntsd, acllen);
4022 inc_rfc1001_len(pSMB, byte_count + data_count);
4024 inc_rfc1001_len(pSMB, byte_count);
4026 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4027 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4029 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4030 bytes_returned, rc);
4032 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
4033 cifs_buf_release(pSMB);
4036 goto setCifsAclRetry;
4041 #endif /* CONFIG_CIFS_ACL */
4043 /* Legacy Query Path Information call for lookup to old servers such
4046 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
4047 const char *search_name, FILE_ALL_INFO *data,
4048 const struct nls_table *nls_codepage, int remap)
4050 QUERY_INFORMATION_REQ *pSMB;
4051 QUERY_INFORMATION_RSP *pSMBr;
4056 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4058 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4063 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4065 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4066 search_name, PATH_MAX, nls_codepage,
4068 name_len++; /* trailing null */
4071 name_len = strnlen(search_name, PATH_MAX);
4072 name_len++; /* trailing null */
4073 strncpy(pSMB->FileName, search_name, name_len);
4075 pSMB->BufferFormat = 0x04;
4076 name_len++; /* account for buffer type byte */
4077 inc_rfc1001_len(pSMB, (__u16)name_len);
4078 pSMB->ByteCount = cpu_to_le16(name_len);
4080 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4081 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4083 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4085 struct timespec64 ts;
4086 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4088 /* decode response */
4089 /* BB FIXME - add time zone adjustment BB */
4090 memset(data, 0, sizeof(FILE_ALL_INFO));
4093 /* decode time fields */
4094 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4095 data->LastWriteTime = data->ChangeTime;
4096 data->LastAccessTime = 0;
4097 data->AllocationSize =
4098 cpu_to_le64(le32_to_cpu(pSMBr->size));
4099 data->EndOfFile = data->AllocationSize;
4101 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4103 rc = -EIO; /* bad buffer passed in */
4105 cifs_buf_release(pSMB);
4114 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4115 u16 netfid, FILE_ALL_INFO *pFindData)
4117 struct smb_t2_qfi_req *pSMB = NULL;
4118 struct smb_t2_qfi_rsp *pSMBr = NULL;
4121 __u16 params, byte_count;
4124 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4129 params = 2 /* level */ + 2 /* fid */;
4130 pSMB->t2.TotalDataCount = 0;
4131 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4132 /* BB find exact max data count below from sess structure BB */
4133 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4134 pSMB->t2.MaxSetupCount = 0;
4135 pSMB->t2.Reserved = 0;
4137 pSMB->t2.Timeout = 0;
4138 pSMB->t2.Reserved2 = 0;
4139 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4141 pSMB->t2.DataCount = 0;
4142 pSMB->t2.DataOffset = 0;
4143 pSMB->t2.SetupCount = 1;
4144 pSMB->t2.Reserved3 = 0;
4145 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4146 byte_count = params + 1 /* pad */ ;
4147 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4148 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4149 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4152 inc_rfc1001_len(pSMB, byte_count);
4153 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4155 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4156 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4158 cifs_dbg(FYI, "Send error in QFileInfo = %d", rc);
4159 } else { /* decode response */
4160 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4162 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4164 else if (get_bcc(&pSMBr->hdr) < 40)
4165 rc = -EIO; /* bad smb */
4166 else if (pFindData) {
4167 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4168 memcpy((char *) pFindData,
4169 (char *) &pSMBr->hdr.Protocol +
4170 data_offset, sizeof(FILE_ALL_INFO));
4174 cifs_buf_release(pSMB);
4176 goto QFileInfoRetry;
4182 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4183 const char *search_name, FILE_ALL_INFO *data,
4184 int legacy /* old style infolevel */,
4185 const struct nls_table *nls_codepage, int remap)
4187 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4188 TRANSACTION2_QPI_REQ *pSMB = NULL;
4189 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4193 __u16 params, byte_count;
4195 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4197 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4202 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4204 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4205 PATH_MAX, nls_codepage, remap);
4206 name_len++; /* trailing null */
4208 } else { /* BB improve the check for buffer overruns BB */
4209 name_len = strnlen(search_name, PATH_MAX);
4210 name_len++; /* trailing null */
4211 strncpy(pSMB->FileName, search_name, name_len);
4214 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4215 pSMB->TotalDataCount = 0;
4216 pSMB->MaxParameterCount = cpu_to_le16(2);
4217 /* BB find exact max SMB PDU from sess structure BB */
4218 pSMB->MaxDataCount = cpu_to_le16(4000);
4219 pSMB->MaxSetupCount = 0;
4223 pSMB->Reserved2 = 0;
4224 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4225 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4226 pSMB->DataCount = 0;
4227 pSMB->DataOffset = 0;
4228 pSMB->SetupCount = 1;
4229 pSMB->Reserved3 = 0;
4230 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4231 byte_count = params + 1 /* pad */ ;
4232 pSMB->TotalParameterCount = cpu_to_le16(params);
4233 pSMB->ParameterCount = pSMB->TotalParameterCount;
4235 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4237 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4238 pSMB->Reserved4 = 0;
4239 inc_rfc1001_len(pSMB, byte_count);
4240 pSMB->ByteCount = cpu_to_le16(byte_count);
4242 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4243 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4245 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4246 } else { /* decode response */
4247 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4249 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4251 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4252 rc = -EIO; /* bad smb */
4253 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4254 rc = -EIO; /* 24 or 26 expected but we do not read
4258 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4261 * On legacy responses we do not read the last field,
4262 * EAsize, fortunately since it varies by subdialect and
4263 * also note it differs on Set vs Get, ie two bytes or 4
4264 * bytes depending but we don't care here.
4267 size = sizeof(FILE_INFO_STANDARD);
4269 size = sizeof(FILE_ALL_INFO);
4270 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4275 cifs_buf_release(pSMB);
4277 goto QPathInfoRetry;
4283 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4284 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4286 struct smb_t2_qfi_req *pSMB = NULL;
4287 struct smb_t2_qfi_rsp *pSMBr = NULL;
4290 __u16 params, byte_count;
4293 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4298 params = 2 /* level */ + 2 /* fid */;
4299 pSMB->t2.TotalDataCount = 0;
4300 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4301 /* BB find exact max data count below from sess structure BB */
4302 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4303 pSMB->t2.MaxSetupCount = 0;
4304 pSMB->t2.Reserved = 0;
4306 pSMB->t2.Timeout = 0;
4307 pSMB->t2.Reserved2 = 0;
4308 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4310 pSMB->t2.DataCount = 0;
4311 pSMB->t2.DataOffset = 0;
4312 pSMB->t2.SetupCount = 1;
4313 pSMB->t2.Reserved3 = 0;
4314 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4315 byte_count = params + 1 /* pad */ ;
4316 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4317 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4318 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4321 inc_rfc1001_len(pSMB, byte_count);
4322 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4324 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4325 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4327 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d", rc);
4328 } else { /* decode response */
4329 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4331 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4332 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4333 rc = -EIO; /* bad smb */
4335 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4336 memcpy((char *) pFindData,
4337 (char *) &pSMBr->hdr.Protocol +
4339 sizeof(FILE_UNIX_BASIC_INFO));
4343 cifs_buf_release(pSMB);
4345 goto UnixQFileInfoRetry;
4351 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4352 const unsigned char *searchName,
4353 FILE_UNIX_BASIC_INFO *pFindData,
4354 const struct nls_table *nls_codepage, int remap)
4356 /* SMB_QUERY_FILE_UNIX_BASIC */
4357 TRANSACTION2_QPI_REQ *pSMB = NULL;
4358 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4360 int bytes_returned = 0;
4362 __u16 params, byte_count;
4364 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4366 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4371 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4373 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4374 PATH_MAX, nls_codepage, remap);
4375 name_len++; /* trailing null */
4377 } else { /* BB improve the check for buffer overruns BB */
4378 name_len = strnlen(searchName, PATH_MAX);
4379 name_len++; /* trailing null */
4380 strncpy(pSMB->FileName, searchName, name_len);
4383 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4384 pSMB->TotalDataCount = 0;
4385 pSMB->MaxParameterCount = cpu_to_le16(2);
4386 /* BB find exact max SMB PDU from sess structure BB */
4387 pSMB->MaxDataCount = cpu_to_le16(4000);
4388 pSMB->MaxSetupCount = 0;
4392 pSMB->Reserved2 = 0;
4393 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4394 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4395 pSMB->DataCount = 0;
4396 pSMB->DataOffset = 0;
4397 pSMB->SetupCount = 1;
4398 pSMB->Reserved3 = 0;
4399 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4400 byte_count = params + 1 /* pad */ ;
4401 pSMB->TotalParameterCount = cpu_to_le16(params);
4402 pSMB->ParameterCount = pSMB->TotalParameterCount;
4403 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4404 pSMB->Reserved4 = 0;
4405 inc_rfc1001_len(pSMB, byte_count);
4406 pSMB->ByteCount = cpu_to_le16(byte_count);
4408 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4409 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4411 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d", rc);
4412 } else { /* decode response */
4413 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4415 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4416 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4417 rc = -EIO; /* bad smb */
4419 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4420 memcpy((char *) pFindData,
4421 (char *) &pSMBr->hdr.Protocol +
4423 sizeof(FILE_UNIX_BASIC_INFO));
4426 cifs_buf_release(pSMB);
4428 goto UnixQPathInfoRetry;
4433 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4435 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4436 const char *searchName, struct cifs_sb_info *cifs_sb,
4437 __u16 *pnetfid, __u16 search_flags,
4438 struct cifs_search_info *psrch_inf, bool msearch)
4440 /* level 257 SMB_ */
4441 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4442 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4443 T2_FFIRST_RSP_PARMS *parms;
4445 int bytes_returned = 0;
4446 int name_len, remap;
4447 __u16 params, byte_count;
4448 struct nls_table *nls_codepage;
4450 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4453 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4458 nls_codepage = cifs_sb->local_nls;
4459 remap = cifs_remap(cifs_sb);
4461 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4463 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4464 PATH_MAX, nls_codepage, remap);
4465 /* We can not add the asterik earlier in case
4466 it got remapped to 0xF03A as if it were part of the
4467 directory name instead of a wildcard */
4470 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4471 pSMB->FileName[name_len+1] = 0;
4472 pSMB->FileName[name_len+2] = '*';
4473 pSMB->FileName[name_len+3] = 0;
4474 name_len += 4; /* now the trailing null */
4475 /* null terminate just in case */
4476 pSMB->FileName[name_len] = 0;
4477 pSMB->FileName[name_len+1] = 0;
4480 } else { /* BB add check for overrun of SMB buf BB */
4481 name_len = strnlen(searchName, PATH_MAX);
4482 /* BB fix here and in unicode clause above ie
4483 if (name_len > buffersize-header)
4484 free buffer exit; BB */
4485 strncpy(pSMB->FileName, searchName, name_len);
4487 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4488 pSMB->FileName[name_len+1] = '*';
4489 pSMB->FileName[name_len+2] = 0;
4494 params = 12 + name_len /* includes null */ ;
4495 pSMB->TotalDataCount = 0; /* no EAs */
4496 pSMB->MaxParameterCount = cpu_to_le16(10);
4497 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4498 pSMB->MaxSetupCount = 0;
4502 pSMB->Reserved2 = 0;
4503 byte_count = params + 1 /* pad */ ;
4504 pSMB->TotalParameterCount = cpu_to_le16(params);
4505 pSMB->ParameterCount = pSMB->TotalParameterCount;
4506 pSMB->ParameterOffset = cpu_to_le16(
4507 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4509 pSMB->DataCount = 0;
4510 pSMB->DataOffset = 0;
4511 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4512 pSMB->Reserved3 = 0;
4513 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4514 pSMB->SearchAttributes =
4515 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4517 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4518 pSMB->SearchFlags = cpu_to_le16(search_flags);
4519 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4521 /* BB what should we set StorageType to? Does it matter? BB */
4522 pSMB->SearchStorageType = 0;
4523 inc_rfc1001_len(pSMB, byte_count);
4524 pSMB->ByteCount = cpu_to_le16(byte_count);
4526 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4527 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4528 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4530 if (rc) {/* BB add logic to retry regular search if Unix search
4531 rejected unexpectedly by server */
4532 /* BB Add code to handle unsupported level rc */
4533 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4535 cifs_buf_release(pSMB);
4537 /* BB eventually could optimize out free and realloc of buf */
4540 goto findFirstRetry;
4541 } else { /* decode response */
4542 /* BB remember to free buffer if error BB */
4543 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4547 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4548 psrch_inf->unicode = true;
4550 psrch_inf->unicode = false;
4552 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4553 psrch_inf->smallBuf = 0;
4554 psrch_inf->srch_entries_start =
4555 (char *) &pSMBr->hdr.Protocol +
4556 le16_to_cpu(pSMBr->t2.DataOffset);
4557 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4558 le16_to_cpu(pSMBr->t2.ParameterOffset));
4560 if (parms->EndofSearch)
4561 psrch_inf->endOfSearch = true;
4563 psrch_inf->endOfSearch = false;
4565 psrch_inf->entries_in_buffer =
4566 le16_to_cpu(parms->SearchCount);
4567 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4568 psrch_inf->entries_in_buffer;
4569 lnoff = le16_to_cpu(parms->LastNameOffset);
4570 if (CIFSMaxBufSize < lnoff) {
4571 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4572 psrch_inf->last_entry = NULL;
4576 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4580 *pnetfid = parms->SearchHandle;
4582 cifs_buf_release(pSMB);
4589 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4590 __u16 searchHandle, __u16 search_flags,
4591 struct cifs_search_info *psrch_inf)
4593 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4594 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4595 T2_FNEXT_RSP_PARMS *parms;
4596 char *response_data;
4599 unsigned int name_len;
4600 __u16 params, byte_count;
4602 cifs_dbg(FYI, "In FindNext\n");
4604 if (psrch_inf->endOfSearch)
4607 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4612 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4614 pSMB->TotalDataCount = 0; /* no EAs */
4615 pSMB->MaxParameterCount = cpu_to_le16(8);
4616 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4617 pSMB->MaxSetupCount = 0;
4621 pSMB->Reserved2 = 0;
4622 pSMB->ParameterOffset = cpu_to_le16(
4623 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4624 pSMB->DataCount = 0;
4625 pSMB->DataOffset = 0;
4626 pSMB->SetupCount = 1;
4627 pSMB->Reserved3 = 0;
4628 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4629 pSMB->SearchHandle = searchHandle; /* always kept as le */
4631 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4632 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4633 pSMB->ResumeKey = psrch_inf->resume_key;
4634 pSMB->SearchFlags = cpu_to_le16(search_flags);
4636 name_len = psrch_inf->resume_name_len;
4638 if (name_len < PATH_MAX) {
4639 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4640 byte_count += name_len;
4641 /* 14 byte parm len above enough for 2 byte null terminator */
4642 pSMB->ResumeFileName[name_len] = 0;
4643 pSMB->ResumeFileName[name_len+1] = 0;
4646 goto FNext2_err_exit;
4648 byte_count = params + 1 /* pad */ ;
4649 pSMB->TotalParameterCount = cpu_to_le16(params);
4650 pSMB->ParameterCount = pSMB->TotalParameterCount;
4651 inc_rfc1001_len(pSMB, byte_count);
4652 pSMB->ByteCount = cpu_to_le16(byte_count);
4654 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4655 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4656 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4659 psrch_inf->endOfSearch = true;
4660 cifs_buf_release(pSMB);
4661 rc = 0; /* search probably was closed at end of search*/
4663 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4664 } else { /* decode response */
4665 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4670 /* BB fixme add lock for file (srch_info) struct here */
4671 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4672 psrch_inf->unicode = true;
4674 psrch_inf->unicode = false;
4675 response_data = (char *) &pSMBr->hdr.Protocol +
4676 le16_to_cpu(pSMBr->t2.ParameterOffset);
4677 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4678 response_data = (char *)&pSMBr->hdr.Protocol +
4679 le16_to_cpu(pSMBr->t2.DataOffset);
4680 if (psrch_inf->smallBuf)
4681 cifs_small_buf_release(
4682 psrch_inf->ntwrk_buf_start);
4684 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4685 psrch_inf->srch_entries_start = response_data;
4686 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4687 psrch_inf->smallBuf = 0;
4688 if (parms->EndofSearch)
4689 psrch_inf->endOfSearch = true;
4691 psrch_inf->endOfSearch = false;
4692 psrch_inf->entries_in_buffer =
4693 le16_to_cpu(parms->SearchCount);
4694 psrch_inf->index_of_last_entry +=
4695 psrch_inf->entries_in_buffer;
4696 lnoff = le16_to_cpu(parms->LastNameOffset);
4697 if (CIFSMaxBufSize < lnoff) {
4698 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4699 psrch_inf->last_entry = NULL;
4702 psrch_inf->last_entry =
4703 psrch_inf->srch_entries_start + lnoff;
4705 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4706 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4708 /* BB fixme add unlock here */
4713 /* BB On error, should we leave previous search buf (and count and
4714 last entry fields) intact or free the previous one? */
4716 /* Note: On -EAGAIN error only caller can retry on handle based calls
4717 since file handle passed in no longer valid */
4720 cifs_buf_release(pSMB);
4725 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4726 const __u16 searchHandle)
4729 FINDCLOSE_REQ *pSMB = NULL;
4731 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4732 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4734 /* no sense returning error if session restarted
4735 as file handle has been closed */
4741 pSMB->FileID = searchHandle;
4742 pSMB->ByteCount = 0;
4743 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4744 cifs_small_buf_release(pSMB);
4746 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4748 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4750 /* Since session is dead, search handle closed on server already */
4758 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4759 const char *search_name, __u64 *inode_number,
4760 const struct nls_table *nls_codepage, int remap)
4763 TRANSACTION2_QPI_REQ *pSMB = NULL;
4764 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4765 int name_len, bytes_returned;
4766 __u16 params, byte_count;
4768 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4772 GetInodeNumberRetry:
4773 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4778 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4780 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4781 search_name, PATH_MAX, nls_codepage,
4783 name_len++; /* trailing null */
4785 } else { /* BB improve the check for buffer overruns BB */
4786 name_len = strnlen(search_name, PATH_MAX);
4787 name_len++; /* trailing null */
4788 strncpy(pSMB->FileName, search_name, name_len);
4791 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4792 pSMB->TotalDataCount = 0;
4793 pSMB->MaxParameterCount = cpu_to_le16(2);
4794 /* BB find exact max data count below from sess structure BB */
4795 pSMB->MaxDataCount = cpu_to_le16(4000);
4796 pSMB->MaxSetupCount = 0;
4800 pSMB->Reserved2 = 0;
4801 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4802 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4803 pSMB->DataCount = 0;
4804 pSMB->DataOffset = 0;
4805 pSMB->SetupCount = 1;
4806 pSMB->Reserved3 = 0;
4807 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4808 byte_count = params + 1 /* pad */ ;
4809 pSMB->TotalParameterCount = cpu_to_le16(params);
4810 pSMB->ParameterCount = pSMB->TotalParameterCount;
4811 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4812 pSMB->Reserved4 = 0;
4813 inc_rfc1001_len(pSMB, byte_count);
4814 pSMB->ByteCount = cpu_to_le16(byte_count);
4816 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4817 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4819 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4821 /* decode response */
4822 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4823 /* BB also check enough total bytes returned */
4824 if (rc || get_bcc(&pSMBr->hdr) < 2)
4825 /* If rc should we check for EOPNOSUPP and
4826 disable the srvino flag? or in caller? */
4827 rc = -EIO; /* bad smb */
4829 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4830 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4831 struct file_internal_info *pfinfo;
4832 /* BB Do we need a cast or hash here ? */
4834 cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n");
4836 goto GetInodeNumOut;
4838 pfinfo = (struct file_internal_info *)
4839 (data_offset + (char *) &pSMBr->hdr.Protocol);
4840 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4844 cifs_buf_release(pSMB);
4846 goto GetInodeNumberRetry;
4851 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4852 const char *search_name, struct dfs_info3_param **target_nodes,
4853 unsigned int *num_of_nodes,
4854 const struct nls_table *nls_codepage, int remap)
4856 /* TRANS2_GET_DFS_REFERRAL */
4857 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4858 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4862 __u16 params, byte_count;
4864 *target_nodes = NULL;
4866 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4867 if (ses == NULL || ses->tcon_ipc == NULL)
4871 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4876 /* server pointer checked in called function,
4877 but should never be null here anyway */
4878 pSMB->hdr.Mid = get_next_mid(ses->server);
4879 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4880 pSMB->hdr.Uid = ses->Suid;
4881 if (ses->capabilities & CAP_STATUS32)
4882 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4883 if (ses->capabilities & CAP_DFS)
4884 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4886 if (ses->capabilities & CAP_UNICODE) {
4887 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4889 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4890 search_name, PATH_MAX, nls_codepage,
4892 name_len++; /* trailing null */
4894 } else { /* BB improve the check for buffer overruns BB */
4895 name_len = strnlen(search_name, PATH_MAX);
4896 name_len++; /* trailing null */
4897 strncpy(pSMB->RequestFileName, search_name, name_len);
4900 if (ses->server->sign)
4901 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4903 pSMB->hdr.Uid = ses->Suid;
4905 params = 2 /* level */ + name_len /*includes null */ ;
4906 pSMB->TotalDataCount = 0;
4907 pSMB->DataCount = 0;
4908 pSMB->DataOffset = 0;
4909 pSMB->MaxParameterCount = 0;
4910 /* BB find exact max SMB PDU from sess structure BB */
4911 pSMB->MaxDataCount = cpu_to_le16(4000);
4912 pSMB->MaxSetupCount = 0;
4916 pSMB->Reserved2 = 0;
4917 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4918 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4919 pSMB->SetupCount = 1;
4920 pSMB->Reserved3 = 0;
4921 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4922 byte_count = params + 3 /* pad */ ;
4923 pSMB->ParameterCount = cpu_to_le16(params);
4924 pSMB->TotalParameterCount = pSMB->ParameterCount;
4925 pSMB->MaxReferralLevel = cpu_to_le16(3);
4926 inc_rfc1001_len(pSMB, byte_count);
4927 pSMB->ByteCount = cpu_to_le16(byte_count);
4929 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4930 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4932 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4935 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4937 /* BB Also check if enough total bytes returned? */
4938 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4939 rc = -EIO; /* bad smb */
4943 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4944 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4946 /* parse returned result into more usable form */
4947 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4948 le16_to_cpu(pSMBr->t2.DataCount),
4949 num_of_nodes, target_nodes, nls_codepage,
4951 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4954 cifs_buf_release(pSMB);
4962 /* Query File System Info such as free space to old servers such as Win 9x */
4964 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4965 struct kstatfs *FSData)
4967 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4968 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4969 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4970 FILE_SYSTEM_ALLOC_INFO *response_data;
4972 int bytes_returned = 0;
4973 __u16 params, byte_count;
4975 cifs_dbg(FYI, "OldQFSInfo\n");
4977 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4982 params = 2; /* level */
4983 pSMB->TotalDataCount = 0;
4984 pSMB->MaxParameterCount = cpu_to_le16(2);
4985 pSMB->MaxDataCount = cpu_to_le16(1000);
4986 pSMB->MaxSetupCount = 0;
4990 pSMB->Reserved2 = 0;
4991 byte_count = params + 1 /* pad */ ;
4992 pSMB->TotalParameterCount = cpu_to_le16(params);
4993 pSMB->ParameterCount = pSMB->TotalParameterCount;
4994 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4995 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4996 pSMB->DataCount = 0;
4997 pSMB->DataOffset = 0;
4998 pSMB->SetupCount = 1;
4999 pSMB->Reserved3 = 0;
5000 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5001 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
5002 inc_rfc1001_len(pSMB, byte_count);
5003 pSMB->ByteCount = cpu_to_le16(byte_count);
5005 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5006 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5008 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5009 } else { /* decode response */
5010 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5012 if (rc || get_bcc(&pSMBr->hdr) < 18)
5013 rc = -EIO; /* bad smb */
5015 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5016 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
5017 get_bcc(&pSMBr->hdr), data_offset);
5019 response_data = (FILE_SYSTEM_ALLOC_INFO *)
5020 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5022 le16_to_cpu(response_data->BytesPerSector) *
5023 le32_to_cpu(response_data->
5024 SectorsPerAllocationUnit);
5026 le32_to_cpu(response_data->TotalAllocationUnits);
5027 FSData->f_bfree = FSData->f_bavail =
5028 le32_to_cpu(response_data->FreeAllocationUnits);
5029 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5030 (unsigned long long)FSData->f_blocks,
5031 (unsigned long long)FSData->f_bfree,
5035 cifs_buf_release(pSMB);
5038 goto oldQFSInfoRetry;
5044 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
5045 struct kstatfs *FSData)
5047 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5048 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5049 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5050 FILE_SYSTEM_INFO *response_data;
5052 int bytes_returned = 0;
5053 __u16 params, byte_count;
5055 cifs_dbg(FYI, "In QFSInfo\n");
5057 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5062 params = 2; /* level */
5063 pSMB->TotalDataCount = 0;
5064 pSMB->MaxParameterCount = cpu_to_le16(2);
5065 pSMB->MaxDataCount = cpu_to_le16(1000);
5066 pSMB->MaxSetupCount = 0;
5070 pSMB->Reserved2 = 0;
5071 byte_count = params + 1 /* pad */ ;
5072 pSMB->TotalParameterCount = cpu_to_le16(params);
5073 pSMB->ParameterCount = pSMB->TotalParameterCount;
5074 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5075 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5076 pSMB->DataCount = 0;
5077 pSMB->DataOffset = 0;
5078 pSMB->SetupCount = 1;
5079 pSMB->Reserved3 = 0;
5080 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5081 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5082 inc_rfc1001_len(pSMB, byte_count);
5083 pSMB->ByteCount = cpu_to_le16(byte_count);
5085 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5086 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5088 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5089 } else { /* decode response */
5090 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5092 if (rc || get_bcc(&pSMBr->hdr) < 24)
5093 rc = -EIO; /* bad smb */
5095 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5099 *) (((char *) &pSMBr->hdr.Protocol) +
5102 le32_to_cpu(response_data->BytesPerSector) *
5103 le32_to_cpu(response_data->
5104 SectorsPerAllocationUnit);
5106 le64_to_cpu(response_data->TotalAllocationUnits);
5107 FSData->f_bfree = FSData->f_bavail =
5108 le64_to_cpu(response_data->FreeAllocationUnits);
5109 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5110 (unsigned long long)FSData->f_blocks,
5111 (unsigned long long)FSData->f_bfree,
5115 cifs_buf_release(pSMB);
5124 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5126 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5127 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5128 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5129 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5131 int bytes_returned = 0;
5132 __u16 params, byte_count;
5134 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5136 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5141 params = 2; /* level */
5142 pSMB->TotalDataCount = 0;
5143 pSMB->MaxParameterCount = cpu_to_le16(2);
5144 /* BB find exact max SMB PDU from sess structure BB */
5145 pSMB->MaxDataCount = cpu_to_le16(1000);
5146 pSMB->MaxSetupCount = 0;
5150 pSMB->Reserved2 = 0;
5151 byte_count = params + 1 /* pad */ ;
5152 pSMB->TotalParameterCount = cpu_to_le16(params);
5153 pSMB->ParameterCount = pSMB->TotalParameterCount;
5154 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5155 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5156 pSMB->DataCount = 0;
5157 pSMB->DataOffset = 0;
5158 pSMB->SetupCount = 1;
5159 pSMB->Reserved3 = 0;
5160 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5161 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5162 inc_rfc1001_len(pSMB, byte_count);
5163 pSMB->ByteCount = cpu_to_le16(byte_count);
5165 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5166 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5168 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5169 } else { /* decode response */
5170 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5172 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5173 /* BB also check if enough bytes returned */
5174 rc = -EIO; /* bad smb */
5176 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5178 (FILE_SYSTEM_ATTRIBUTE_INFO
5179 *) (((char *) &pSMBr->hdr.Protocol) +
5181 memcpy(&tcon->fsAttrInfo, response_data,
5182 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5185 cifs_buf_release(pSMB);
5188 goto QFSAttributeRetry;
5194 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5196 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5197 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5198 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5199 FILE_SYSTEM_DEVICE_INFO *response_data;
5201 int bytes_returned = 0;
5202 __u16 params, byte_count;
5204 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5206 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5211 params = 2; /* level */
5212 pSMB->TotalDataCount = 0;
5213 pSMB->MaxParameterCount = cpu_to_le16(2);
5214 /* BB find exact max SMB PDU from sess structure BB */
5215 pSMB->MaxDataCount = cpu_to_le16(1000);
5216 pSMB->MaxSetupCount = 0;
5220 pSMB->Reserved2 = 0;
5221 byte_count = params + 1 /* pad */ ;
5222 pSMB->TotalParameterCount = cpu_to_le16(params);
5223 pSMB->ParameterCount = pSMB->TotalParameterCount;
5224 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5225 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5227 pSMB->DataCount = 0;
5228 pSMB->DataOffset = 0;
5229 pSMB->SetupCount = 1;
5230 pSMB->Reserved3 = 0;
5231 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5232 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5233 inc_rfc1001_len(pSMB, byte_count);
5234 pSMB->ByteCount = cpu_to_le16(byte_count);
5236 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5237 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5239 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5240 } else { /* decode response */
5241 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5243 if (rc || get_bcc(&pSMBr->hdr) <
5244 sizeof(FILE_SYSTEM_DEVICE_INFO))
5245 rc = -EIO; /* bad smb */
5247 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5249 (FILE_SYSTEM_DEVICE_INFO *)
5250 (((char *) &pSMBr->hdr.Protocol) +
5252 memcpy(&tcon->fsDevInfo, response_data,
5253 sizeof(FILE_SYSTEM_DEVICE_INFO));
5256 cifs_buf_release(pSMB);
5259 goto QFSDeviceRetry;
5265 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5267 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5268 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5269 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5270 FILE_SYSTEM_UNIX_INFO *response_data;
5272 int bytes_returned = 0;
5273 __u16 params, byte_count;
5275 cifs_dbg(FYI, "In QFSUnixInfo\n");
5277 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5278 (void **) &pSMB, (void **) &pSMBr);
5282 params = 2; /* level */
5283 pSMB->TotalDataCount = 0;
5284 pSMB->DataCount = 0;
5285 pSMB->DataOffset = 0;
5286 pSMB->MaxParameterCount = cpu_to_le16(2);
5287 /* BB find exact max SMB PDU from sess structure BB */
5288 pSMB->MaxDataCount = cpu_to_le16(100);
5289 pSMB->MaxSetupCount = 0;
5293 pSMB->Reserved2 = 0;
5294 byte_count = params + 1 /* pad */ ;
5295 pSMB->ParameterCount = cpu_to_le16(params);
5296 pSMB->TotalParameterCount = pSMB->ParameterCount;
5297 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5298 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5299 pSMB->SetupCount = 1;
5300 pSMB->Reserved3 = 0;
5301 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5302 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5303 inc_rfc1001_len(pSMB, byte_count);
5304 pSMB->ByteCount = cpu_to_le16(byte_count);
5306 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5307 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5309 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5310 } else { /* decode response */
5311 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5313 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5314 rc = -EIO; /* bad smb */
5316 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5318 (FILE_SYSTEM_UNIX_INFO
5319 *) (((char *) &pSMBr->hdr.Protocol) +
5321 memcpy(&tcon->fsUnixInfo, response_data,
5322 sizeof(FILE_SYSTEM_UNIX_INFO));
5325 cifs_buf_release(pSMB);
5335 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5337 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5338 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5339 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5341 int bytes_returned = 0;
5342 __u16 params, param_offset, offset, byte_count;
5344 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5346 /* BB switch to small buf init to save memory */
5347 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5348 (void **) &pSMB, (void **) &pSMBr);
5352 params = 4; /* 2 bytes zero followed by info level. */
5353 pSMB->MaxSetupCount = 0;
5357 pSMB->Reserved2 = 0;
5358 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5360 offset = param_offset + params;
5362 pSMB->MaxParameterCount = cpu_to_le16(4);
5363 /* BB find exact max SMB PDU from sess structure BB */
5364 pSMB->MaxDataCount = cpu_to_le16(100);
5365 pSMB->SetupCount = 1;
5366 pSMB->Reserved3 = 0;
5367 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5368 byte_count = 1 /* pad */ + params + 12;
5370 pSMB->DataCount = cpu_to_le16(12);
5371 pSMB->ParameterCount = cpu_to_le16(params);
5372 pSMB->TotalDataCount = pSMB->DataCount;
5373 pSMB->TotalParameterCount = pSMB->ParameterCount;
5374 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5375 pSMB->DataOffset = cpu_to_le16(offset);
5379 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5382 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5383 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5384 pSMB->ClientUnixCap = cpu_to_le64(cap);
5386 inc_rfc1001_len(pSMB, byte_count);
5387 pSMB->ByteCount = cpu_to_le16(byte_count);
5389 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5390 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5392 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5393 } else { /* decode response */
5394 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5396 rc = -EIO; /* bad smb */
5398 cifs_buf_release(pSMB);
5401 goto SETFSUnixRetry;
5409 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5410 struct kstatfs *FSData)
5412 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5413 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5414 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5415 FILE_SYSTEM_POSIX_INFO *response_data;
5417 int bytes_returned = 0;
5418 __u16 params, byte_count;
5420 cifs_dbg(FYI, "In QFSPosixInfo\n");
5422 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5427 params = 2; /* level */
5428 pSMB->TotalDataCount = 0;
5429 pSMB->DataCount = 0;
5430 pSMB->DataOffset = 0;
5431 pSMB->MaxParameterCount = cpu_to_le16(2);
5432 /* BB find exact max SMB PDU from sess structure BB */
5433 pSMB->MaxDataCount = cpu_to_le16(100);
5434 pSMB->MaxSetupCount = 0;
5438 pSMB->Reserved2 = 0;
5439 byte_count = params + 1 /* pad */ ;
5440 pSMB->ParameterCount = cpu_to_le16(params);
5441 pSMB->TotalParameterCount = pSMB->ParameterCount;
5442 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5443 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5444 pSMB->SetupCount = 1;
5445 pSMB->Reserved3 = 0;
5446 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5447 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5448 inc_rfc1001_len(pSMB, byte_count);
5449 pSMB->ByteCount = cpu_to_le16(byte_count);
5451 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5452 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5454 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5455 } else { /* decode response */
5456 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5458 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5459 rc = -EIO; /* bad smb */
5461 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5463 (FILE_SYSTEM_POSIX_INFO
5464 *) (((char *) &pSMBr->hdr.Protocol) +
5467 le32_to_cpu(response_data->BlockSize);
5469 le64_to_cpu(response_data->TotalBlocks);
5471 le64_to_cpu(response_data->BlocksAvail);
5472 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5473 FSData->f_bavail = FSData->f_bfree;
5476 le64_to_cpu(response_data->UserBlocksAvail);
5478 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5480 le64_to_cpu(response_data->TotalFileNodes);
5481 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5483 le64_to_cpu(response_data->FreeFileNodes);
5486 cifs_buf_release(pSMB);
5496 * We can not use write of zero bytes trick to set file size due to need for
5497 * large file support. Also note that this SetPathInfo is preferred to
5498 * SetFileInfo based method in next routine which is only needed to work around
5499 * a sharing violation bugin Samba which this routine can run into.
5502 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5503 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5504 bool set_allocation)
5506 struct smb_com_transaction2_spi_req *pSMB = NULL;
5507 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5508 struct file_end_of_file_info *parm_data;
5511 int bytes_returned = 0;
5512 int remap = cifs_remap(cifs_sb);
5514 __u16 params, byte_count, data_count, param_offset, offset;
5516 cifs_dbg(FYI, "In SetEOF\n");
5518 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5523 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5525 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5526 PATH_MAX, cifs_sb->local_nls, remap);
5527 name_len++; /* trailing null */
5529 } else { /* BB improve the check for buffer overruns BB */
5530 name_len = strnlen(file_name, PATH_MAX);
5531 name_len++; /* trailing null */
5532 strncpy(pSMB->FileName, file_name, name_len);
5534 params = 6 + name_len;
5535 data_count = sizeof(struct file_end_of_file_info);
5536 pSMB->MaxParameterCount = cpu_to_le16(2);
5537 pSMB->MaxDataCount = cpu_to_le16(4100);
5538 pSMB->MaxSetupCount = 0;
5542 pSMB->Reserved2 = 0;
5543 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5544 InformationLevel) - 4;
5545 offset = param_offset + params;
5546 if (set_allocation) {
5547 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5548 pSMB->InformationLevel =
5549 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5551 pSMB->InformationLevel =
5552 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5553 } else /* Set File Size */ {
5554 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5555 pSMB->InformationLevel =
5556 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5558 pSMB->InformationLevel =
5559 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5563 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5565 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5566 pSMB->DataOffset = cpu_to_le16(offset);
5567 pSMB->SetupCount = 1;
5568 pSMB->Reserved3 = 0;
5569 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5570 byte_count = 3 /* pad */ + params + data_count;
5571 pSMB->DataCount = cpu_to_le16(data_count);
5572 pSMB->TotalDataCount = pSMB->DataCount;
5573 pSMB->ParameterCount = cpu_to_le16(params);
5574 pSMB->TotalParameterCount = pSMB->ParameterCount;
5575 pSMB->Reserved4 = 0;
5576 inc_rfc1001_len(pSMB, byte_count);
5577 parm_data->FileSize = cpu_to_le64(size);
5578 pSMB->ByteCount = cpu_to_le16(byte_count);
5579 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5580 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5582 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5584 cifs_buf_release(pSMB);
5593 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5594 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5596 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5597 struct file_end_of_file_info *parm_data;
5599 __u16 params, param_offset, offset, byte_count, count;
5601 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5603 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5608 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5609 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5612 pSMB->MaxSetupCount = 0;
5616 pSMB->Reserved2 = 0;
5617 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5618 offset = param_offset + params;
5620 count = sizeof(struct file_end_of_file_info);
5621 pSMB->MaxParameterCount = cpu_to_le16(2);
5622 /* BB find exact max SMB PDU from sess structure BB */
5623 pSMB->MaxDataCount = cpu_to_le16(1000);
5624 pSMB->SetupCount = 1;
5625 pSMB->Reserved3 = 0;
5626 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5627 byte_count = 3 /* pad */ + params + count;
5628 pSMB->DataCount = cpu_to_le16(count);
5629 pSMB->ParameterCount = cpu_to_le16(params);
5630 pSMB->TotalDataCount = pSMB->DataCount;
5631 pSMB->TotalParameterCount = pSMB->ParameterCount;
5632 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5634 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5636 pSMB->DataOffset = cpu_to_le16(offset);
5637 parm_data->FileSize = cpu_to_le64(size);
5638 pSMB->Fid = cfile->fid.netfid;
5639 if (set_allocation) {
5640 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5641 pSMB->InformationLevel =
5642 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5644 pSMB->InformationLevel =
5645 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5646 } else /* Set File Size */ {
5647 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5648 pSMB->InformationLevel =
5649 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5651 pSMB->InformationLevel =
5652 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5654 pSMB->Reserved4 = 0;
5655 inc_rfc1001_len(pSMB, byte_count);
5656 pSMB->ByteCount = cpu_to_le16(byte_count);
5657 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5658 cifs_small_buf_release(pSMB);
5660 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5664 /* Note: On -EAGAIN error only caller can retry on handle based calls
5665 since file handle passed in no longer valid */
5670 /* Some legacy servers such as NT4 require that the file times be set on
5671 an open handle, rather than by pathname - this is awkward due to
5672 potential access conflicts on the open, but it is unavoidable for these
5673 old servers since the only other choice is to go from 100 nanosecond DCE
5674 time and resort to the original setpathinfo level which takes the ancient
5675 DOS time format with 2 second granularity */
5677 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5678 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5680 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5683 __u16 params, param_offset, offset, byte_count, count;
5685 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5686 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5691 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5692 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5695 pSMB->MaxSetupCount = 0;
5699 pSMB->Reserved2 = 0;
5700 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5701 offset = param_offset + params;
5703 data_offset = (char *)pSMB +
5704 offsetof(struct smb_hdr, Protocol) + offset;
5706 count = sizeof(FILE_BASIC_INFO);
5707 pSMB->MaxParameterCount = cpu_to_le16(2);
5708 /* BB find max SMB PDU from sess */
5709 pSMB->MaxDataCount = cpu_to_le16(1000);
5710 pSMB->SetupCount = 1;
5711 pSMB->Reserved3 = 0;
5712 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5713 byte_count = 3 /* pad */ + params + count;
5714 pSMB->DataCount = cpu_to_le16(count);
5715 pSMB->ParameterCount = cpu_to_le16(params);
5716 pSMB->TotalDataCount = pSMB->DataCount;
5717 pSMB->TotalParameterCount = pSMB->ParameterCount;
5718 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5719 pSMB->DataOffset = cpu_to_le16(offset);
5721 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5722 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5724 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5725 pSMB->Reserved4 = 0;
5726 inc_rfc1001_len(pSMB, byte_count);
5727 pSMB->ByteCount = cpu_to_le16(byte_count);
5728 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5729 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5730 cifs_small_buf_release(pSMB);
5732 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5735 /* Note: On -EAGAIN error only caller can retry on handle based calls
5736 since file handle passed in no longer valid */
5742 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5743 bool delete_file, __u16 fid, __u32 pid_of_opener)
5745 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5748 __u16 params, param_offset, offset, byte_count, count;
5750 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5751 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5756 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5757 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5760 pSMB->MaxSetupCount = 0;
5764 pSMB->Reserved2 = 0;
5765 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5766 offset = param_offset + params;
5768 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5771 pSMB->MaxParameterCount = cpu_to_le16(2);
5772 /* BB find max SMB PDU from sess */
5773 pSMB->MaxDataCount = cpu_to_le16(1000);
5774 pSMB->SetupCount = 1;
5775 pSMB->Reserved3 = 0;
5776 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5777 byte_count = 3 /* pad */ + params + count;
5778 pSMB->DataCount = cpu_to_le16(count);
5779 pSMB->ParameterCount = cpu_to_le16(params);
5780 pSMB->TotalDataCount = pSMB->DataCount;
5781 pSMB->TotalParameterCount = pSMB->ParameterCount;
5782 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5783 pSMB->DataOffset = cpu_to_le16(offset);
5785 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5786 pSMB->Reserved4 = 0;
5787 inc_rfc1001_len(pSMB, byte_count);
5788 pSMB->ByteCount = cpu_to_le16(byte_count);
5789 *data_offset = delete_file ? 1 : 0;
5790 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5791 cifs_small_buf_release(pSMB);
5793 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5799 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5800 const char *fileName, const FILE_BASIC_INFO *data,
5801 const struct nls_table *nls_codepage, int remap)
5803 TRANSACTION2_SPI_REQ *pSMB = NULL;
5804 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5807 int bytes_returned = 0;
5809 __u16 params, param_offset, offset, byte_count, count;
5811 cifs_dbg(FYI, "In SetTimes\n");
5814 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5819 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5821 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5822 PATH_MAX, nls_codepage, remap);
5823 name_len++; /* trailing null */
5825 } else { /* BB improve the check for buffer overruns BB */
5826 name_len = strnlen(fileName, PATH_MAX);
5827 name_len++; /* trailing null */
5828 strncpy(pSMB->FileName, fileName, name_len);
5831 params = 6 + name_len;
5832 count = sizeof(FILE_BASIC_INFO);
5833 pSMB->MaxParameterCount = cpu_to_le16(2);
5834 /* BB find max SMB PDU from sess structure BB */
5835 pSMB->MaxDataCount = cpu_to_le16(1000);
5836 pSMB->MaxSetupCount = 0;
5840 pSMB->Reserved2 = 0;
5841 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5842 InformationLevel) - 4;
5843 offset = param_offset + params;
5844 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5845 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5846 pSMB->DataOffset = cpu_to_le16(offset);
5847 pSMB->SetupCount = 1;
5848 pSMB->Reserved3 = 0;
5849 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5850 byte_count = 3 /* pad */ + params + count;
5852 pSMB->DataCount = cpu_to_le16(count);
5853 pSMB->ParameterCount = cpu_to_le16(params);
5854 pSMB->TotalDataCount = pSMB->DataCount;
5855 pSMB->TotalParameterCount = pSMB->ParameterCount;
5856 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5857 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5859 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5860 pSMB->Reserved4 = 0;
5861 inc_rfc1001_len(pSMB, byte_count);
5862 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5863 pSMB->ByteCount = cpu_to_le16(byte_count);
5864 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5865 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5867 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5869 cifs_buf_release(pSMB);
5877 /* Can not be used to set time stamps yet (due to old DOS time format) */
5878 /* Can be used to set attributes */
5879 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5880 handling it anyway and NT4 was what we thought it would be needed for
5881 Do not delete it until we prove whether needed for Win9x though */
5883 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
5884 __u16 dos_attrs, const struct nls_table *nls_codepage)
5886 SETATTR_REQ *pSMB = NULL;
5887 SETATTR_RSP *pSMBr = NULL;
5892 cifs_dbg(FYI, "In SetAttrLegacy\n");
5895 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5900 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5902 ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5903 PATH_MAX, nls_codepage);
5904 name_len++; /* trailing null */
5906 } else { /* BB improve the check for buffer overruns BB */
5907 name_len = strnlen(fileName, PATH_MAX);
5908 name_len++; /* trailing null */
5909 strncpy(pSMB->fileName, fileName, name_len);
5911 pSMB->attr = cpu_to_le16(dos_attrs);
5912 pSMB->BufferFormat = 0x04;
5913 inc_rfc1001_len(pSMB, name_len + 1);
5914 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5915 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5916 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5918 cifs_dbg(FYI, "Error in LegacySetAttr = %d\n", rc);
5920 cifs_buf_release(pSMB);
5923 goto SetAttrLgcyRetry;
5927 #endif /* temporarily unneeded SetAttr legacy function */
5930 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5931 const struct cifs_unix_set_info_args *args)
5933 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5934 u64 mode = args->mode;
5936 if (uid_valid(args->uid))
5937 uid = from_kuid(&init_user_ns, args->uid);
5938 if (gid_valid(args->gid))
5939 gid = from_kgid(&init_user_ns, args->gid);
5942 * Samba server ignores set of file size to zero due to bugs in some
5943 * older clients, but we should be precise - we use SetFileSize to
5944 * set file size and do not want to truncate file size to zero
5945 * accidentally as happened on one Samba server beta by putting
5946 * zero instead of -1 here
5948 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5949 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5950 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5951 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5952 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5953 data_offset->Uid = cpu_to_le64(uid);
5954 data_offset->Gid = cpu_to_le64(gid);
5955 /* better to leave device as zero when it is */
5956 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5957 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5958 data_offset->Permissions = cpu_to_le64(mode);
5961 data_offset->Type = cpu_to_le32(UNIX_FILE);
5962 else if (S_ISDIR(mode))
5963 data_offset->Type = cpu_to_le32(UNIX_DIR);
5964 else if (S_ISLNK(mode))
5965 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5966 else if (S_ISCHR(mode))
5967 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5968 else if (S_ISBLK(mode))
5969 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5970 else if (S_ISFIFO(mode))
5971 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5972 else if (S_ISSOCK(mode))
5973 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5977 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5978 const struct cifs_unix_set_info_args *args,
5979 u16 fid, u32 pid_of_opener)
5981 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5984 u16 params, param_offset, offset, byte_count, count;
5986 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5987 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5992 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5993 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5996 pSMB->MaxSetupCount = 0;
6000 pSMB->Reserved2 = 0;
6001 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
6002 offset = param_offset + params;
6004 data_offset = (char *)pSMB +
6005 offsetof(struct smb_hdr, Protocol) + offset;
6007 count = sizeof(FILE_UNIX_BASIC_INFO);
6009 pSMB->MaxParameterCount = cpu_to_le16(2);
6010 /* BB find max SMB PDU from sess */
6011 pSMB->MaxDataCount = cpu_to_le16(1000);
6012 pSMB->SetupCount = 1;
6013 pSMB->Reserved3 = 0;
6014 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
6015 byte_count = 3 /* pad */ + params + count;
6016 pSMB->DataCount = cpu_to_le16(count);
6017 pSMB->ParameterCount = cpu_to_le16(params);
6018 pSMB->TotalDataCount = pSMB->DataCount;
6019 pSMB->TotalParameterCount = pSMB->ParameterCount;
6020 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6021 pSMB->DataOffset = cpu_to_le16(offset);
6023 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6024 pSMB->Reserved4 = 0;
6025 inc_rfc1001_len(pSMB, byte_count);
6026 pSMB->ByteCount = cpu_to_le16(byte_count);
6028 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
6030 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
6031 cifs_small_buf_release(pSMB);
6033 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
6036 /* Note: On -EAGAIN error only caller can retry on handle based calls
6037 since file handle passed in no longer valid */
6043 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
6044 const char *file_name,
6045 const struct cifs_unix_set_info_args *args,
6046 const struct nls_table *nls_codepage, int remap)
6048 TRANSACTION2_SPI_REQ *pSMB = NULL;
6049 TRANSACTION2_SPI_RSP *pSMBr = NULL;
6052 int bytes_returned = 0;
6053 FILE_UNIX_BASIC_INFO *data_offset;
6054 __u16 params, param_offset, offset, count, byte_count;
6056 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
6058 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6063 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6065 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6066 PATH_MAX, nls_codepage, remap);
6067 name_len++; /* trailing null */
6069 } else { /* BB improve the check for buffer overruns BB */
6070 name_len = strnlen(file_name, PATH_MAX);
6071 name_len++; /* trailing null */
6072 strncpy(pSMB->FileName, file_name, name_len);
6075 params = 6 + name_len;
6076 count = sizeof(FILE_UNIX_BASIC_INFO);
6077 pSMB->MaxParameterCount = cpu_to_le16(2);
6078 /* BB find max SMB PDU from sess structure BB */
6079 pSMB->MaxDataCount = cpu_to_le16(1000);
6080 pSMB->MaxSetupCount = 0;
6084 pSMB->Reserved2 = 0;
6085 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6086 InformationLevel) - 4;
6087 offset = param_offset + params;
6089 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6091 memset(data_offset, 0, count);
6092 pSMB->DataOffset = cpu_to_le16(offset);
6093 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6094 pSMB->SetupCount = 1;
6095 pSMB->Reserved3 = 0;
6096 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6097 byte_count = 3 /* pad */ + params + count;
6098 pSMB->ParameterCount = cpu_to_le16(params);
6099 pSMB->DataCount = cpu_to_le16(count);
6100 pSMB->TotalParameterCount = pSMB->ParameterCount;
6101 pSMB->TotalDataCount = pSMB->DataCount;
6102 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6103 pSMB->Reserved4 = 0;
6104 inc_rfc1001_len(pSMB, byte_count);
6106 cifs_fill_unix_set_info(data_offset, args);
6108 pSMB->ByteCount = cpu_to_le16(byte_count);
6109 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6110 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6112 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6114 cifs_buf_release(pSMB);
6120 #ifdef CONFIG_CIFS_XATTR
6122 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6123 * function used by listxattr and getxattr type calls. When ea_name is set,
6124 * it looks for that attribute name and stuffs that value into the EAData
6125 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6126 * buffer. In both cases, the return value is either the length of the
6127 * resulting data or a negative error code. If EAData is a NULL pointer then
6128 * the data isn't copied to it, but the length is returned.
6131 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6132 const unsigned char *searchName, const unsigned char *ea_name,
6133 char *EAData, size_t buf_size,
6134 struct cifs_sb_info *cifs_sb)
6136 /* BB assumes one setup word */
6137 TRANSACTION2_QPI_REQ *pSMB = NULL;
6138 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6139 int remap = cifs_remap(cifs_sb);
6140 struct nls_table *nls_codepage = cifs_sb->local_nls;
6144 struct fealist *ea_response_data;
6145 struct fea *temp_fea;
6148 __u16 params, byte_count, data_offset;
6149 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6151 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6153 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6158 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6160 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6161 PATH_MAX, nls_codepage, remap);
6162 list_len++; /* trailing null */
6164 } else { /* BB improve the check for buffer overruns BB */
6165 list_len = strnlen(searchName, PATH_MAX);
6166 list_len++; /* trailing null */
6167 strncpy(pSMB->FileName, searchName, list_len);
6170 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6171 pSMB->TotalDataCount = 0;
6172 pSMB->MaxParameterCount = cpu_to_le16(2);
6173 /* BB find exact max SMB PDU from sess structure BB */
6174 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6175 pSMB->MaxSetupCount = 0;
6179 pSMB->Reserved2 = 0;
6180 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6181 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6182 pSMB->DataCount = 0;
6183 pSMB->DataOffset = 0;
6184 pSMB->SetupCount = 1;
6185 pSMB->Reserved3 = 0;
6186 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6187 byte_count = params + 1 /* pad */ ;
6188 pSMB->TotalParameterCount = cpu_to_le16(params);
6189 pSMB->ParameterCount = pSMB->TotalParameterCount;
6190 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6191 pSMB->Reserved4 = 0;
6192 inc_rfc1001_len(pSMB, byte_count);
6193 pSMB->ByteCount = cpu_to_le16(byte_count);
6195 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6196 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6198 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6203 /* BB also check enough total bytes returned */
6204 /* BB we need to improve the validity checking
6205 of these trans2 responses */
6207 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6208 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6209 rc = -EIO; /* bad smb */
6213 /* check that length of list is not more than bcc */
6214 /* check that each entry does not go beyond length
6216 /* check that each element of each entry does not
6217 go beyond end of list */
6218 /* validate_trans2_offsets() */
6219 /* BB check if start of smb + data_offset > &bcc+ bcc */
6221 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6222 ea_response_data = (struct fealist *)
6223 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6225 list_len = le32_to_cpu(ea_response_data->list_len);
6226 cifs_dbg(FYI, "ea length %d\n", list_len);
6227 if (list_len <= 8) {
6228 cifs_dbg(FYI, "empty EA list returned from server\n");
6229 /* didn't find the named attribute */
6235 /* make sure list_len doesn't go past end of SMB */
6236 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6237 if ((char *)ea_response_data + list_len > end_of_smb) {
6238 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6243 /* account for ea list len */
6245 temp_fea = ea_response_data->list;
6246 temp_ptr = (char *)temp_fea;
6247 while (list_len > 0) {
6248 unsigned int name_len;
6253 /* make sure we can read name_len and value_len */
6255 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6260 name_len = temp_fea->name_len;
6261 value_len = le16_to_cpu(temp_fea->value_len);
6262 list_len -= name_len + 1 + value_len;
6264 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6270 if (ea_name_len == name_len &&
6271 memcmp(ea_name, temp_ptr, name_len) == 0) {
6272 temp_ptr += name_len + 1;
6276 if ((size_t)value_len > buf_size) {
6280 memcpy(EAData, temp_ptr, value_len);
6284 /* account for prefix user. and trailing null */
6285 rc += (5 + 1 + name_len);
6286 if (rc < (int) buf_size) {
6287 memcpy(EAData, "user.", 5);
6289 memcpy(EAData, temp_ptr, name_len);
6291 /* null terminate name */
6294 } else if (buf_size == 0) {
6295 /* skip copy - calc size only */
6297 /* stop before overrun buffer */
6302 temp_ptr += name_len + 1 + value_len;
6303 temp_fea = (struct fea *)temp_ptr;
6306 /* didn't find the named attribute */
6311 cifs_buf_release(pSMB);
6319 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6320 const char *fileName, const char *ea_name, const void *ea_value,
6321 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6322 struct cifs_sb_info *cifs_sb)
6324 struct smb_com_transaction2_spi_req *pSMB = NULL;
6325 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6326 struct fealist *parm_data;
6329 int bytes_returned = 0;
6330 __u16 params, param_offset, byte_count, offset, count;
6331 int remap = cifs_remap(cifs_sb);
6333 cifs_dbg(FYI, "In SetEA\n");
6335 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6340 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6342 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6343 PATH_MAX, nls_codepage, remap);
6344 name_len++; /* trailing null */
6346 } else { /* BB improve the check for buffer overruns BB */
6347 name_len = strnlen(fileName, PATH_MAX);
6348 name_len++; /* trailing null */
6349 strncpy(pSMB->FileName, fileName, name_len);
6352 params = 6 + name_len;
6354 /* done calculating parms using name_len of file name,
6355 now use name_len to calculate length of ea name
6356 we are going to create in the inode xattrs */
6357 if (ea_name == NULL)
6360 name_len = strnlen(ea_name, 255);
6362 count = sizeof(*parm_data) + ea_value_len + name_len;
6363 pSMB->MaxParameterCount = cpu_to_le16(2);
6364 /* BB find max SMB PDU from sess */
6365 pSMB->MaxDataCount = cpu_to_le16(1000);
6366 pSMB->MaxSetupCount = 0;
6370 pSMB->Reserved2 = 0;
6371 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6372 InformationLevel) - 4;
6373 offset = param_offset + params;
6374 pSMB->InformationLevel =
6375 cpu_to_le16(SMB_SET_FILE_EA);
6377 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6378 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6379 pSMB->DataOffset = cpu_to_le16(offset);
6380 pSMB->SetupCount = 1;
6381 pSMB->Reserved3 = 0;
6382 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6383 byte_count = 3 /* pad */ + params + count;
6384 pSMB->DataCount = cpu_to_le16(count);
6385 parm_data->list_len = cpu_to_le32(count);
6386 parm_data->list[0].EA_flags = 0;
6387 /* we checked above that name len is less than 255 */
6388 parm_data->list[0].name_len = (__u8)name_len;
6389 /* EA names are always ASCII */
6391 strncpy(parm_data->list[0].name, ea_name, name_len);
6392 parm_data->list[0].name[name_len] = 0;
6393 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6394 /* caller ensures that ea_value_len is less than 64K but
6395 we need to ensure that it fits within the smb */
6397 /*BB add length check to see if it would fit in
6398 negotiated SMB buffer size BB */
6399 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6401 memcpy(parm_data->list[0].name+name_len+1,
6402 ea_value, ea_value_len);
6404 pSMB->TotalDataCount = pSMB->DataCount;
6405 pSMB->ParameterCount = cpu_to_le16(params);
6406 pSMB->TotalParameterCount = pSMB->ParameterCount;
6407 pSMB->Reserved4 = 0;
6408 inc_rfc1001_len(pSMB, byte_count);
6409 pSMB->ByteCount = cpu_to_le16(byte_count);
6410 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6411 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6413 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6415 cifs_buf_release(pSMB);
6424 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6426 * Years ago the kernel added a "dnotify" function for Samba server,
6427 * to allow network clients (such as Windows) to display updated
6428 * lists of files in directory listings automatically when
6429 * files are added by one user when another user has the
6430 * same directory open on their desktop. The Linux cifs kernel
6431 * client hooked into the kernel side of this interface for
6432 * the same reason, but ironically when the VFS moved from
6433 * "dnotify" to "inotify" it became harder to plug in Linux
6434 * network file system clients (the most obvious use case
6435 * for notify interfaces is when multiple users can update
6436 * the contents of the same directory - exactly what network
6437 * file systems can do) although the server (Samba) could
6438 * still use it. For the short term we leave the worker
6439 * function ifdeffed out (below) until inotify is fixed
6440 * in the VFS to make it easier to plug in network file
6441 * system clients. If inotify turns out to be permanently
6442 * incompatible for network fs clients, we could instead simply
6443 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6445 int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
6446 const int notify_subdirs, const __u16 netfid,
6447 __u32 filter, struct file *pfile, int multishot,
6448 const struct nls_table *nls_codepage)
6451 struct smb_com_transaction_change_notify_req *pSMB = NULL;
6452 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6453 struct dir_notify_req *dnotify_req;
6456 cifs_dbg(FYI, "In CIFSSMBNotify for file handle %d\n", (int)netfid);
6457 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6462 pSMB->TotalParameterCount = 0 ;
6463 pSMB->TotalDataCount = 0;
6464 pSMB->MaxParameterCount = cpu_to_le32(2);
6465 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6466 pSMB->MaxSetupCount = 4;
6468 pSMB->ParameterOffset = 0;
6469 pSMB->DataCount = 0;
6470 pSMB->DataOffset = 0;
6471 pSMB->SetupCount = 4; /* single byte does not need le conversion */
6472 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6473 pSMB->ParameterCount = pSMB->TotalParameterCount;
6475 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6476 pSMB->Reserved2 = 0;
6477 pSMB->CompletionFilter = cpu_to_le32(filter);
6478 pSMB->Fid = netfid; /* file handle always le */
6479 pSMB->ByteCount = 0;
6481 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6482 (struct smb_hdr *)pSMBr, &bytes_returned,
6485 cifs_dbg(FYI, "Error in Notify = %d\n", rc);
6487 /* Add file to outstanding requests */
6488 /* BB change to kmem cache alloc */
6489 dnotify_req = kmalloc(
6490 sizeof(struct dir_notify_req),
6493 dnotify_req->Pid = pSMB->hdr.Pid;
6494 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6495 dnotify_req->Mid = pSMB->hdr.Mid;
6496 dnotify_req->Tid = pSMB->hdr.Tid;
6497 dnotify_req->Uid = pSMB->hdr.Uid;
6498 dnotify_req->netfid = netfid;
6499 dnotify_req->pfile = pfile;
6500 dnotify_req->filter = filter;
6501 dnotify_req->multishot = multishot;
6502 spin_lock(&GlobalMid_Lock);
6503 list_add_tail(&dnotify_req->lhead,
6504 &GlobalDnotifyReqList);
6505 spin_unlock(&GlobalMid_Lock);
6509 cifs_buf_release(pSMB);
6512 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */